基于第二次数独游戏,添加GUI界面

Posted muyang2

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于第二次数独游戏,添加GUI界面相关的知识,希望对你有一定的参考价值。

项目需求:

  1. 生成任意数量的数独题目并将数独棋局依次显示,棋盘上总空格数大于30,小于60,每3*3小棋盘中挖空不少于2个。
  2. 数独题目有且仅有唯一解。
  3. 用户可以在界面上通过编辑输入完成数独题目。
  4. 用户完成数独题目后可以得到正确性反馈。
  5. 友好的使用说明。

sudo2源码:

#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <fstream>
#include <stdlib.h>
#include "sudo2.h"
using namespace std;
#define Random(x) (rand()%x)
int sudo[9][9];
bool flag = false;//冲突标志

void Init_sudo(int(*sudo)[9])
{
	for (int r = 0; r<9; r++)
	{
		for (int c = 0; c < 9; c++)
			sudo[r][c] = 0;
	}
	srand((unsigned)time(NULL));
	for (int i = 1; i<10; i++)
	{
		int j = Random(9);
		sudo[i - 1][j] = i;
	}
}
void Init_sudo_part(int(*sudo)[9])
{
	for (int r = 3; r < 9; r++)
	{
		for (int c = 0; c < 9; c++)
			sudo[r][c] = 0;
	}
	for (int r = 0; r < 3; r++)
	{
		for (int c = 3; c < 9; c++)
			sudo[r][c] = 0;
	}
}
bool check_sudo(int sudo[9])
{
	int temp;
	for (int i = 0; i < 9; i++)
	{
		temp = sudo[i];
		for (int j = i + 1; j < 9; j++)
		{
			if (sudo[j] == temp)
				return false;
		}
	}
	return true;
}
//行检查
bool Sudoku_Row(int sudo[9][9], int row, int num)
{
	for (int i = 0; i < 9; i++)
	{
		if (sudo[row][i] == num)
		{
			flag = true;
			break;
		}
	}
	return flag;
}
//列检查
bool Sudoku_Col(int sudo[9][9], int col, int num)
{
	for (int i = 0; i < 9; i++)
	{
		if (sudo[i][col] == num)
		{
			flag = true;
			break;
		}
	}
	return flag;
}
//宫检查
bool Sudoku_Square(int sudo[9][9], int row, int col, int num)
{
	int Square_Row = row / 3 * 3;
	int Square_col = col / 3 * 3;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{

			if (sudo[Square_Row + i][Square_col + j] == num)
			{
				flag = true;
				break;
			}
		}
	}
	return flag;
}
void print_sudoku(int sudo[9][9])
{
	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			cout << sudo[i][j] << ‘ ‘;
		}
		cout << endl;
	}
	cout << endl;
}
//生成宫格
bool makeSquare(int sudo[9][9], int num)
{
	int square_row = (num / 3) * 3;
	int square_col = (num % 3) * 3;
	int x, y;
	int temp;
	if (num = 0) //第一个宫格
	{
		for (int i = 1; i < 9; i++)
		{
			x = square_row + i / 3;
			y = square_col + i % 3;
			temp = Random(8) + 2;//生成2~9的随机数
			if (!Sudoku_Square(sudo, x, y, temp) && !Sudoku_Col(sudo,
				y, temp) && !Sudoku_Row(sudo, x, temp))
			{
				sudo[x][y] = temp;
			}
			else i--;
		}
	}
	else //生成其他宫格
	{
		int try_count = 0;
		temp = Random(9) + 1;//生成1~9的随机数
		for (int i = 0; i < 9; i++)
		{
			x = square_row + i / 3;
			y = square_col + i % 3;
			temp++;
			temp = temp % 10;//循环随机数在1~9范围内
			if (!Sudoku_Square(sudo, x, y, temp) && !Sudoku_Col(sudo,
				y, temp) && !Sudoku_Row(sudo, x, temp) && temp != 0)
			{
				sudo[x][y] = temp;
				try_count = 0;
			}
			else
			{
				i--;
				try_count++;
			}
			if (try_count > 10)
			{
				return false;
				break;
			}//若所有可能试完则返回无解
		}

	}
	return true;//有解
}
//随机选择挖空点
void GetPoint()
{
	int temp = 0;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			temp = Random(5) + 2;
			while (temp > 0)
			{
				int local = Random(9);
				int r = local / 3;
				int row = r + i * 3;
				int col = local - 3 * r + j * 3;
				if (sudo[row][col] == ‘0‘) { continue; }
				else { sudo[row][col] = ‘0‘; }
				temp--;
			}
		}
	}
		
}
int main(int argc, char *argv[])
{
	int N = atoi(argv[argc - 1]);
	int(*sudo)[9] = new int[9][9];
	ofstream outfile;
	outfile.open("sudoku.text");//输出到文档
	if (N > 0 && N <= 1000000)
	{
		srand(unsigned int(time(NULL)));//初始化种子为当前时间
		bool retry;//重试
		int retry_count = 0;//重试次数
		for (int i = 0; i < N;)
		{
			retry = false;
			if (retry_count == 0)
			{
				Init_sudo(sudo);
				makeSquare(sudo, 0);
				GetPoint();
				print_sudoku(sudo);
			}
			else Init_sudo_part(sudo);
			for (int j = 1; j < 9; j++)
			{
				bool flag = makeSquare(sudo, j);
				if (!flag)
				{
					retry = true;
					break;
				}
			}
			if (!retry)
			{
				for (int row = 0; row < 9; row++)
				{
					for (int col = 0; col < 9; col++)
					{
						GetPoint();
						outfile << sudo[row][col] << ‘ ‘;
						print_sudoku(sudo);
					}
					outfile << endl;
				}
				outfile << endl;
				retry_count = 0;
				i++;
			}
			else
			{
				retry_count++;
			}//无解重试
		}
		outfile.close();
	}
		return 0;
}

  coding地址:https://coding.net/u/dhlg_201810812009/p/sudo2/git

       性能分析:编译起来耗时较短,生成的数独具有唯一解,这是在原来的基础上改动了一些地方。

       心得体会:没有做出GUI界面,没有完成老师布置的任务,只完成部分要求。编程基础薄弱,这次项目用的时间很多,但收之甚少。期间查书,百度,参考别人代码和经验也花比较多的时间,在学习MFC时卡了好久,用的时候老是出错,对类的使用也比较模糊不能很好地衔接起来。虽然耗时多,但感到比较空虚掌握不到什么,因为大多程序里面的知识点我在这些天只是了解表面并没有深入去理解,导致动手的时候效率低下。参考别人代码和经验时会有一定启发但同时也会让自己的思路有点混乱,这也纠结了一些时间。总的来说,学而不精,甚至有点过于求成,导致一事无成。接下来要好好静下心来学习,多琢磨多动手,形成自己的编程思路。

 

以上是关于基于第二次数独游戏,添加GUI界面的主要内容,如果未能解决你的问题,请参考以下文章

150+行Python代码实现带界面的数独游戏

150+行Python代码实现带界面的数独游戏!益智烧脑了解一下!

基于SAT的数独游戏求解程序,求C语言代码

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

软件工程——数独 数独GUI用户手册

如何基于声网互动白板实现一个多人数独游戏