使用Xamarin开发移动应用示例——数独游戏(六)使用数据库

博客 动态
0 308
羽尘
羽尘 2022-02-04 09:54:53
悬赏:0 积分 收藏

使用Xamarin开发移动应用示例——数独游戏(六)使用数据库

项目代码可以从Github下载:https://github.com/zhenl/ZL.Shudu 。代码随项目进度更新。

现在我们希望为应用增加更多的功能,比如记录每个完成的游戏,可以让用户自己添加新的数独游戏等等,这些功能需要数据库的支持。我们使用Sqlite数据库保存游戏的数据。Sqlite是基于文件的单机关系型数据库,使用起来非常方便,首先安装程序包sqlite-net-pcl,可以在Visual Studio 2022中使用Nuget管理器安装最新版本,然后,添加POCO类的定义和数据库访问的方法,这里我们需要记录完成的游戏和输入的游戏。在使用数据库时,首先根据指定数据库的路径创建数据库连接,如果数据库文件不存在,则创建新的数据库文件:

 readonly SQLiteAsyncConnection _database; _database = new SQLiteAsyncConnection(dbPath);

然后根据定义的POCO创建数据库表(如果不存在):

 _database.CreateTableAsync<InputGameInfo>().Wait(); _database.CreateTableAsync<FinishGame>().Wait();

接下来就可以使用相应的CRUD函数进行操作了。

下面是记录完成游戏的POCO。数独的初始状态和完成状态是9X9矩阵,由于每个格子只是1-9的数字,采用字符串存储,长度是固定的,恢复为矩阵也比较方便,所以这里采用string类型。完成的步骤是一个列表,每个步骤保存行、列和输入值,这里也用字符串保存,每个步骤之间用指定分隔符隔开。

using SQLite;using System;namespace ZL.Shudu.Services{    public class FinishGame    {        [PrimaryKey, AutoIncrement]        public int Id { get; set; }        /// <summary>        /// 游戏的初始状态        /// </summary>        public string Sudoku { get; set; }        /// <summary>        /// 游戏的结果        /// </summary>        public string Result { get; set; }        /// <summary>        /// 游戏过程        /// </summary>        public string Steps { get; set; }        /// <summary>        /// 游戏完成日期        /// </summary>        public DateTime PlayDate { get; set; }        /// <summary>        /// 使用时间        /// </summary>        public long TotalTime { get; set; }    }}

输入游戏的POCO:

using SQLite;using System;namespace ZL.Shudu.Services{    public class InputGameInfo    {        [PrimaryKey, AutoIncrement]        public int ID { get; set; }        /// <summary>        /// 游戏的初始状态        /// </summary>        public string Sudoku { get; set; }        /// <summary>        /// 输入日期        /// </summary>        public DateTime InputDate { get; set; }        /// <summary>        /// 是否在游戏中使用        /// </summary>        public bool UsedInGame { get; set; }    }}

操作数据库的类:

using SQLite;using System;using System.Collections.Generic;using System.Text;using System.Threading.Tasks;namespace ShuduApp.Db{    public class Database    {        readonly SQLiteAsyncConnection _database;        public Database(string dbPath)        {            _database = new SQLiteAsyncConnection(dbPath);            _database.CreateTableAsync<InputGameInfo>().Wait();            _database.CreateTableAsync<FinishGame>().Wait();        }        #region InputGameInfo        public Task<List<InputGameInfo>> GetGamesAsync()        {            return _database.Table<InputGameInfo>().ToListAsync();        }        public Task<int> SaveGameAsync(InputGameInfo game)        {            return _database.InsertAsync(game);        }        public Task<int> UpdateGameAsync(InputGameInfo game)        {            return _database.UpdateAsync(game);        }        public Task<int> DeleteGameAsync(InputGameInfo game)        {            return _database.DeleteAsync(game);        }        #endregion        #region FinishGame        public Task<List<FinishGame>> GetFinishGamesAsync()        {            return _database.Table<FinishGame>().ToListAsync();        }        public Task<int> SaveFinishGameAsync(FinishGame game)        {            return _database.InsertAsync(game);        }        public Task<int> UpdateFinishGameAsync(FinishGame game)        {            return _database.UpdateAsync(game);        }        public Task<int> DeleteFinishGameAsync(FinishGame game)        {            return _database.DeleteAsync(game);        }        #endregion    }}

完成这些以后,我们改造Game页面,增加保存结果到数据和从数据库产生新游戏的代码。
首先是保存结果到数据库:

       private async Task SaveToDb()        {            try            {                var finobj = new FinishGame();                for (var i = 0; i < 9; i++)                {                    for (var j = 0; j < 9; j++)                    {                        finobj.Sudoku += chess[i, j].ToString();                    }                }                for (var i = 0; i < 9; i++)                {                    for (var j = 0; j < 9; j++)                    {                        finobj.Result += string.IsNullOrEmpty(buttons[i, j].Text) ? "0" : buttons[i, j].Text;                    }                }                foreach (var str in steps)                {                    finobj.Steps += str + ";";                }                finobj.TotalTime = (DateTime.Now - dtBegin).Ticks;                finobj.PlayDate = DateTime.Now;                var id=await App.Database.SaveFinishGameAsync(finobj);            }            catch (Exception ex)            {                lbMessage.Text = ex.Message;            }        }

在判断结束的代码中加入上述方法。然后是在初始化时从数据库中获取游戏:

      private async Task<List<InputGameInfo>> LoadFromDb()        {            var leng = chesses.GetLength(0);            var task = App.Database.GetGamesAsync();            var lst = task.Result;            for (int k = 0; k < leng; k++)            {                var sudoku = "";                for (var i = 0; i < 9; i++)                {                    for (var j = 0; j < 9; j++)                    {                        sudoku += chesses[k, i, j].ToString();                    }                }                var obj = lst.FirstOrDefault(o => o.Sudoku == sudoku);                if (obj == null)                {                    await App.Database.SaveGameAsync(new InputGameInfo                    {                        Sudoku = sudoku,                        InputDate = DateTime.Now,                        UsedInGame = true                    });                }            }            var l= await App.Database.GetGamesAsync();            lst = l.Where(o => o.UsedInGame).ToList();            return lst;        }

在这里我们判断数据库中是否有游戏,如果没有,将预制的游戏保存到数据库,然后从数据库中生成新的游戏。
我们增加一个新的页面,用来查看现有的游戏:

<?xml version="1.0" encoding="utf-8" ?><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms" xmlns:d1="http://xamarin.com/schemas/2014/forms/design"             x:>    <ContentPage.Content>        <StackLayout>            <ListView x:Name="MyListView"            d1:ItemsSource="{Binding Items}"            CachingStrategy="RecycleElement"                   IsVisible="True">                <d:ListView.ItemsSource>                    <x:Array Type="{x:Type x:String}">                        <x:String>Item 1</x:String>                        <x:String>Item 2</x:String>                        <x:String>Item 3</x:String>                        <x:String>Item 4</x:String>                        <x:String>Item 5</x:String>                    </x:Array>                </d:ListView.ItemsSource>            </ListView>        </StackLayout>    </ContentPage.Content></ContentPage>

后台代码:

using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Linq;using System.Text;using System.Threading.Tasks;using Xamarin.Forms;using Xamarin.Forms.Xaml;namespace ZL.Shudu.Views{    [XamlCompilation(XamlCompilationOptions.Compile)]    public partial class GameList : ContentPage    {        public ObservableCollection<string> Items { get; set; }        public GameList()        {            InitializeComponent();            RefreshList();        }        public async Task RefreshList()        {            Items = await GetItems();            MyListView.ItemsSource = Items;            MyListView.IsVisible = true;        }        public async Task<ObservableCollection<string>> GetItems()        {            var items = new ObservableCollection<string>();            var lst = await App.Database.GetGamesAsync();            foreach (var obj in lst)            {                items.Add(obj.ID.ToString());            }            return items;        }    }}

在导航页面中增加对这个页面的导航:

    <TabBar>        <ShellContent Title="游戏" Icon="icon_about.png" Route="Game"  ContentTemplate="{DataTemplate local:Game}" />        <ShellContent Title="游戏列表" Icon="icon_about.png" Route="GameList"  ContentTemplate="{DataTemplate local:GameList}" />    </TabBar>

使用这个页面,可以查看现有的游戏。
下一步,我们编写查看完成游戏的列表和增加新游戏的页面。

本文来自博客园,作者:寻找无名的特质,转载请注明原文链接:https://www.cnblogs.com/zhenl/p/15834953.html

posted @ 2022-02-04 09:48 寻找无名的特质 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    羽尘

    羽尘 (王者 段位)

    2335 积分 (2)粉丝 (11)源码

     

    温馨提示

    亦奇源码

    最新会员