C++黑框框实现数独小游戏

C++黑框框实现数独小游戏

效果图

C++黑框框实现数独小游戏_第1张图片
C++黑框框实现数独小游戏_第2张图片

#include
#include
#include
//_getch()函数的头文件
#include
#include
#include
//用于获取时间
#include
//用于后续设置字体颜色
#include
using namespace std;
//数独游戏类
class SudoGame
{
private:
	//字符数独数组
	vector<string>sudo;
	//9个字符组成的数组,一个数组对应一个数字
	vector<char>sudoch;
	//将字符和数字一一对应
	map<char, int>hash_map;
	//点的信息
	struct PointValue {
		//点的数值
		int value;
		//点的状态,1为只读,0为可读写
		int state;
		PointValue()
			:value(0),state(0)
		{}
	};
	//点数组
	vector<vector<PointValue>>pv;
	//光标位置
	int x;
	int y;
	//用户选择
	int select;
private:
	//初始化字符串数独数组
	void initSudo() {
		//生成字符串数独数组,后续用map将字符对应为数字
		sudo.push_back("ighcabfde");
		sudo.push_back("cabfdeigh");
		sudo.push_back("fdeighcab");
		sudo.push_back("ghiabcdef");
		sudo.push_back("abcdefghi");
		sudo.push_back("defghiabc");
		sudo.push_back("higbcaefd");
		sudo.push_back("bcaefdhig");
		sudo.push_back("efdhigbca");
		//设置字符数组
		for (int i = 0; i < 9; ++i)
			sudoch.push_back('a' + i);
		//产生字母到数字的随机映射
		for (int i = 1; i <= 9; ++i)
		{
			int r = rand() % sudoch.size();
			char key = sudoch[r];
			//删除字母,防止后续重新一个数字对应多个字母的现象
			sudoch.erase(sudoch.begin() + r);
			//字符到数字的映射,即该字符代表该数字
			hash_map[key] = i;
		}
	}
	//初始化pv数组
	void init()
	{
		pv.resize(9);
		for (int i = 0; i < 9; ++i)
		{
			pv[i].resize(9);
			for (int j = 0; j < 9; ++j)
			{
				//设置数字
				pv[i][j].value = hash_map[sudo[i][j]];
				//设置为只读状态
				pv[i][j].state = 1;
			}
		}
		//获取挖空的数量
		int count = 0;
		if (select == 1)
			count = 12;
		else if (select == 2)
			count = 16;
		else
			count = 22;
		int xx = 0;
		int yy = 0;
		int num = 0;
		//挖空
		while (num < count)
		{
			xx = rand() % 9;
			yy = rand() % 9;
			++num;
			//挖空,设置为可读写状态
			pv[yy][xx].state = 0;
			pv[yy][xx].value = 0;
		}
	}
public:
	SudoGame()
		:x(0),y(0),select(0)
	{}
	//打印九宫格
	void Print() {
	//清屏操作
		system("cls");
		for (int i = 0; i < 9; ++i)
		{
			cout << "|";
			for (int j = 0; j < 9; ++j)
			{
				if (pv[i][j].value == 0)
					cout << "   ";
				else
				{
					//挖空填空的位置颜色设置为绿色
					if (pv[i][j].state == 0)
						//设置字体颜色
						SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
					cout << " " << pv[i][j].value << " ";
					//恢复字体颜色
					SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY|FOREGROUND_RED |
						FOREGROUND_GREEN | FOREGROUND_BLUE);
				}
				cout << "|";
			}
			cout << endl;
			cout << " ";
			if (i != y)
			{
				for (int j = 0; j < 9; ++j)
					cout << "----";
				cout << endl;
			}
			else
			{
				for (int j = 0; j < 9; ++j)
				{
					if (j == x)
					{
						cout << "-";
						//给光标亮色
						SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
						cout << "^^";
						//恢复颜色
						SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED |
							FOREGROUND_GREEN | FOREGROUND_BLUE);
						cout << "-";
					}
					else
						cout << "----";
				}
				cout << endl;
			}
		}
		cout << endl;
	}
	//设置数字
	bool SetValue(int xx, int yy, char value)
	{
	//状态为1时不可重新设置数字
		if (pv[yy][xx].state == 1)
			return false;
		else
		{
			if (value <= '0' || value > '9')
				return false;
		}
		pv[yy][xx].value = value - '0';
		return true;
	}
	//判断是否成功
	bool IfWin()
	{
		for (int i = 0; i < 9; ++i)
		{
			map<int, int>mp;
			//判断行
			for (int j = 0; j < 9; ++j)
			{
				if (mp.find(pv[i][j].value) == mp.end())
				{
					mp.insert(make_pair(pv[i][j].value, 1));
				}
				else
					return false;
			}
			mp.clear();
			//判断列
			for (int j = 0; j < 9; ++j)
			{
				if (mp.find(pv[j][i].value) == mp.end())
				{
					mp.insert(make_pair(pv[j][i].value, 1));
				}
				else
					return false;
			}
		}
		//判断九宫格
		for (int i = 0; i < 9; i += 3)
		{
			for (int j = 0; j < 9; j += 3)
			{
				int ii, jj;
				map<int, int>mp;
				for (ii = i; ii < i + 3; ++ii)
				{
					for (jj = j; jj < j + 3; ++jj)
					{
						if (mp.find(pv[ii][jj].value) != mp.end())
							return false;
						else
							mp.insert(make_pair(pv[ii][jj].value, 1));
					}
				}
				mp.clear();
			}
		}
		return true;
	}
	//开始游戏
	void Game()
	{
		cout << "1.简单" << endl;
		cout << "2.中等" << endl;
		cout << "3.困难" << endl;
		while (1)
		{
			cout << "请输入难度:";
			cin >> select;
			if (select == 1 || select == 2 || select == 3)
			{
				initSudo();
				init();
				break;
			}
			else
				cout << "输入有误,请重新输入" << endl;
		}
		char ch = ' ';
		//判断是否填充完毕
		bool flag = false;
		bool win = true;
		//记录起始时间
		clock_t start = clock();
		while (win)
		{
			Print();
			while (ch == ' ')
			{
				ch = _getch();
				//移动光标
				if (ch == 'a' || ch == 'A')
				{
					if (x > 0)
					{
						--x;
					}
					else
						x = 8;
					break;
				}
				else if (ch == 'd' || ch == 'D')
				{
					if (x < 8)
					{
						++x;
					}
					else
						x = 0;
					break;
				}
				else if (ch == 'w' || ch == 'W')
				{
					if (y > 0)
					{
						--y;
					}
					else
						y = 8;
					break;
				}
				else if (ch == 's' || ch == 'S')
				{
					if (y < 8)
					{
						++y;
					}
					else
						y = 0;
					break;
				}
				//填入数字
				else if (SetValue(x, y, ch))
					break;
				else
				{
					if (flag)
					{
						win = false;
						break;
					}
					else
						continue;
				}
			}
			ch = ' ';
			//判断是否填满
			if (!flag)
			{
				flag = true;
				for (int i = 0; i < 9; ++i)
				{
					for (int j = 0; j < 9; ++j)
					{
						if (pv[i][j].value == 0)
						{
							flag = false;
							break;
						}
					}
					if (!flag)
						break;
				}
			}
		}
		clock_t end = clock();
		if (IfWin())
			cout << "成功了" << endl;
		else
			cout << "失败了" << endl;
		cout << "用时:" << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl;
	}
};
int main()
{
	//设置随机数种子
	srand(time(0));
	SudoGame sdgame;
	sdgame.Game();
	return 0;
}

你可能感兴趣的:(笔记,c++,开发语言,后端)