您的位置:首页 > 其它

全民数独游戏自动计算程序(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 = "";
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  游戏 娱乐 全民数独
相关文章推荐