• 基于第二次数独游戏,添加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时卡了好久,用的时候老是出错,对类的使用也比较模糊不能很好地衔接起来。虽然耗时多,但感到比较空虚掌握不到什么,因为大多程序里面的知识点我在这些天只是了解表面并没有深入去理解,导致动手的时候效率低下。参考别人代码和经验时会有一定启发但同时也会让自己的思路有点混乱,这也纠结了一些时间。总的来说,学而不精,甚至有点过于求成,导致一事无成。接下来要好好静下心来学习,多琢磨多动手,形成自己的编程思路。

  • 相关阅读:
    【转载】实用VC++6.0插件
    关于无标题栏窗口拖动的问题
    VC6配置CXimage库
    扎实基础深入篇(七):函数和类没那么复杂
    扎实基础深入篇(六):while循环带动生产力
    扎实基础深入篇(五):字典也就是个弟弟
    扎实基础深入篇(四):听说if语句很叼?
    lxml类库的xpath的使用
    json与re的再次复习
    python基础汇总(四)
  • 原文地址:https://www.cnblogs.com/muyang2/p/9823317.html
Copyright © 2020-2023  润新知