全民数独游戏自动计算程序(1)
2018-03-29 16:33
253 查看
最近玩一游戏——全民数独,类似九宫图,玩到后面难度提升,挺难得。就想到用程序实现数独游戏的计算,此程序仅为娱乐,好像违背了数独游戏本身的宗旨,希望玩这游戏的伙伴们不要用程序取巧,人家本来是益智类游戏的。
游戏规则就是让表格中每行、每列、每个区域的六个格子都有1、2、3、4、5、6个数字。
游戏界面如下
仿照游戏界面做了一个程序界面
提示按钮给出一个答案
清除按钮将选择格子数字清空
求解按钮算出所有答案
重置按钮将所有格子数据清空
使用方法就是:输入游戏中给定格子的相关数据,点击求解,得出结果。
程序运行结果如下:
主要思路是:每行、每列、每个区域的六个格子有且仅有1、2、3、4、5、6个数字
获取格子
获取格子所在行、列、区域的12个格子数字(除本身外)
这12个相关的格子数据是否包含了1、2、3、4、5、6中的5个,如果是则该格子数字为第6个
循环遍历,直到找到所有数据
其实可以尝试任意输入一下数字,探索哪些情况有解,哪些情况存在多个解,下一步有空可以试一试
程序是C#winform程序,https://download.csdn.net/download/qq_36724994/10315937
代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace sudoku { public partial class Frm_Sudo : Form { public Frm_Sudo() { InitializeComponent(); } const int N = 6; //按钮的行、列数 const int inputBtnCount = 6; Button[,] buttons = new Button[N, N]; //按钮的数组 Button[] buttonsInput = new Button[inputBtnCount]; //按钮的数组 Button selectedBtn;//被选中的btn private void Frm_Sudo_Load(object sender, EventArgs e) { //产生所有按钮 GenerateAllButtons(); selectedBtn = buttons[0, 0];//选中第一个按钮 selectedBtn.BackColor = Color.Blue; //产生输入按钮 GenerateInputButtons(); } //生成所有的按钮 void GenerateAllButtons() { int x0 = 100, y0 = 10, w = 45, d = 50; for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) { int num = r * N + c; Button btn = new Button(); btn.Text = ""; btn.Top = y0 + r * d; btn.Left = x0 + c * d; btn.Width = w; btn.Height = w; btn.Visible = true; btn.Tag = r * N + c; //这个数据用来表示它所在行列位置 btn.BackColor = Color.White; //注册事件 btn.Click += new EventHandler(btn_Click); buttons[r, c] = btn; //放到数组中 this.Controls.Add(btn); //加到界面上 } } //按钮点击事件处理 void btn_Click(object sender, EventArgs e) { Button btn = sender as Button; //当前点中的按钮 selectedBtn.BackColor = Color.White; selectedBtn = btn; //当前点中的按钮 selectedBtn.BackColor = Color.Blue; } //生成输入按钮 void GenerateInputButtons() { int x0 = 100, y0 = 350, w = 45, d = 50; for (int c = 0; c < inputBtnCount; c++) { int num = c; Button btn = new Button(); btn.Text = (num + 1).ToString(); btn.Top = y0; btn.Left = x0 + c * d; btn.Width = w; btn.Height = w; btn.Visible = true; btn.Tag = c; //这个数据用来表示它所在行列位置 //注册事件 btn.Click += new EventHandler(btnInput_Click); buttonsInput[c] = btn; //放到数组中 this.Controls.Add(btn); //加到界面上 } } //输入按钮点击事件 void btnInput_Click(object sender, EventArgs e) { Button btn = sender as Button; //当前点中的按钮 selectedBtn.Text = btn.Text; } //求解 private void btn_Solve_Click(object sender, EventArgs e) { int cc = GetZeroCount(); while (cc > 0) { for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) { Button btn = buttons[r, c]; int value = CalculateBtnValue(btn); if (value != -1) btn.Text = value.ToString(); } cc--; } } //获取按钮相关的12个按钮 List<Button> GetRelatedBtn(Button selectedBtn) { List<Button> relatedBtn = new List<Button>(); //获取当前选中selectedBtn行列号 int rowIndex = Int16.Parse(selectedBtn.Tag.ToString()) / N;//0至5 int ColumnIndex = Int16.Parse(selectedBtn.Tag.ToString()) % N;//0至5 int leftRow = rowIndex % 2;//剩余行 int leftColume = ColumnIndex % 3; int r1, r2, c1, c2; r1 = -1; r2 = -1; c1 = -1; c2 = -1; switch (leftRow) { case 0: r1 = rowIndex + 1; r2 = rowIndex + 1; break; case 1: r1 = rowIndex - 1; r2 = rowIndex - 1; break; } switch (leftColume) { case 0: c1 = ColumnIndex + 1; c2 = ColumnIndex + 2; break; case 1: c1 = ColumnIndex + 1; c2 = ColumnIndex - 1; break; case 2: c1 = ColumnIndex - 1; c2 = ColumnIndex - 2; break; } relatedBtn.Add(buttons[r1, c1]); relatedBtn.Add(buttons[r2, c2]); for (int i = 0; i < N; i++) { if (i != ColumnIndex) relatedBtn.Add(buttons[rowIndex, i]); if (i != rowIndex) relatedBtn.Add(buttons[i, ColumnIndex]); } return relatedBtn; } //算出这个点的真实值 int CalculateBtnValue(Button btn) { int reValue = -1; List<Button> relatedBtn = GetRelatedBtn(btn); List<int> btnNumbers = new List<int>(); foreach (Button b in relatedBtn) { if (b.Text != "") { int a = Int16.Parse(b.Text); if (!btnNumbers.Contains(a)) btnNumbers.Add(a); } } btnNumbers.Sort(); if (btnNumbers.Count == (N-1)) { for (int i = 1; i <= N; i++) { if (!btnNumbers.Contains(i)) { reValue = i; break; } } } return reValue; } int GetZeroCount() { int count = 0; for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) { Button btn = buttons[r, c]; if (btn.Text.Equals("")) count++; } return count; } //提示按钮点击事件,给出一个提示答案 private void btn_Prompt_Click(object sender, EventArgs e) { for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) { Button btn = buttons[r, c]; int value = CalculateBtnValue(btn); if (value != -1) btn.Text = value.ToString(); } } //重置按钮点击事件,将所有数据清零 private void btn_Reset_Click(object sender, EventArgs e) { for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) { buttons[r, c].Text = "0"; } } private void btn_Clear_Click(object sender, EventArgs e) { selectedBtn.Text = ""; } } }
相关文章推荐
- 数独游戏(只完成几个普通的自动计算功能)
- ECshop网点程序优化-后台添加类目自动选择上次父类目并计算Sort Order
- (五)用swift4写iOS微信跳一跳的自动跳(开挂)程序——计算按压时间,基于WebDriverAgent进行模拟触屏
- windows游戏程序自动备份与更新
- 使用java编写计算24点游戏程序
- 尽管是一个CS专业的学生,小B的数学基础很好并对数值计算有着特别的兴趣,喜欢用计算机程序来解决数学问题。现在,她正在玩一个数值变换的游戏。她发现计算机中经常用不同的进制表示同一个数,如十进制数123表达为16进制时只包含两位数7、11(B),用八进制表示时为三位数1、7、3。按不同进制表达时,各个位数的和也不同,如上述例子中十六进制和八进制中各位数的和分别是18和11。
- 第一个SilverLight小程序-数独游戏
- 计算数独的小程序-.-
- Python_猜数字游戏_初次尝试(遗留问题:猜错后程序自动循环执行未实现)---加入循环搞定
- 1.有一个游戏,50关,前20关是每关得分是他们关卡数,21-40关是每关20分,41-49 每关30分,50关一次性加1000分。求,输入关卡数,求得分。 2.写一个程序,要求,输入一个数,求从这个数前面15个数开始计算的和
- DS1302的程序(适应AVR,含星期自动计算功能)
- 数独计算程序
- python 学习记录(4)—本金+利息计算及简单的游戏猜测程序
- 数独游戏程序
- 数独游戏求解程序
- Android数字游戏之数独(自动随机生成不同难度的数独)
- 使用Python编写程序求解数独游戏答案
- 一个标准数独游戏的题目生成和解题的程序
- 9 * 9 数独游戏小程序 (DFS)
- 正在编写推箱子游戏的自动求解程序