C++项目1——五子棋游戏

参考视频

【C/C++】大一学年设计:五子棋(含GUI/网络/算法)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1V54y1D7pD?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click

目录

一、控制台版本

1.1 代码

1.2 实现效果

二、存储功能的实现

三、简化下棋的过程


一、控制台版本

1.1 代码

#include 
#include 
#include 
#include 

#define BLACK 1
#define WHITE 2

using namespace std;

class ChessNode {
public:
	ChessNode() {
		location_x = 0;
		location_y = 0;
		player_id = -1;
	}

	void SetLocation(int x, int y)
	{
		location_x = x;
		location_y = y;
	}

	void SetPlayerId(int id) {
		player_id = id;
	}

	void SetChessNode(int x, int y, int id) {
		location_x = x;
		location_y = y;
		player_id = id;
	}

	int GetLocationX()
	{
		return location_x;
	}

	int GetLocationY()
	{
		return location_y;

	}

	int GetPlayerId()
	{
		return player_id;
	}

private:
	int location_x;
	int location_y;
	int player_id;
};

class CheckerBoard {
public:
	CheckerBoard(int size)
	{
		this->Size = size;
		board = new ChessNode * [size + 2];
		for (int i = 0; i < size + 2; i++) {
			board[i] = new ChessNode[size + 2];
			for (int j = 0; j < size + 2; j++) {
				board[i][j].SetChessNode(i, j, -1);
			}
		}
	}
	~CheckerBoard()
	{
		for (int i = 0; i < Size + 2; i++) {
			delete[] board[i];
			board[i] = nullptr;
		}
		delete board;
		board = nullptr;
	}

	void PlaceNode(int x, int y, int id)
	{
		if (board[x][y].GetPlayerId() != -1) {
			return;
		}
		if (x >= 1 && y >= 1 && x <= Size && y <= Size) {
			board[x][y].SetChessNode(x, y, id);
			AddStep(board[x][y]);
		}
	}

	void AddStep(ChessNode c) {
		route.push(c);
	}

	ChessNode ShowNode(int x, int y)
	{
		if (x >= 1 && y >= 1 && x <= Size && y <= Size) {
			return board[x][y];
		}
		return board[0][0];
	}

	ChessNode ShowRecentStep()
	{
		if (!route.empty()) {
			return route.top();
		}
		return board[0][0];
	}

	void RepentStep()
	{
		if (!route.empty()) {
			ChessNode tmp = route.top();
			board[tmp.GetLocationX()][tmp.GetLocationY()].SetChessNode(tmp.GetLocationX(), tmp.GetLocationY(), -1);
			route.pop();
		}
	}

	void Display()
	{
		cout << "\t";
		for (int i = 1; i <= Size; i++) {
			cout << i << "\t";
		}
		cout << endl;

		for (int i = 1; i <= Size; i++) {
			cout << i << "\t";
			for (int j = 1; j <= Size; j++) {
				if (board[i][j].GetPlayerId() == BLACK) {
					cout << "x\t";
				}
				else if (board[i][j].GetPlayerId() == WHITE) {
					cout << "o\t";
				}
				else {
					cout << "#\t";
				}
			}
			cout << endl;
		}

	}

	// 存储路径
	void StorageRoute() {
		while (!route.empty()) {
			route2.push(route.top());
			route.pop();
		}

		ofstream ofs;
		ofs.open("test.txt", ios::out);

		while (!route2.empty()) {
			ofs << char(route2.top().GetLocationX() + 48);
			ofs << " ";
			ofs << char(route2.top().GetLocationY() + 48);
			ofs << " ";
			ofs << char(route2.top().GetPlayerId() + 48);
			ofs << "\n";
			route2.pop();
		}
		ofs.close();
	}

private:
	int Size;
	ChessNode** board;
	stack route;
	stack route2;
};

class Client {
public:
	Client()
	{
		Size = 0;
	}
	void LoopRun()
	{
		int sig = -1;
		while (sig != 1) {
			cout << "\t\t五子棋游戏菜单" << endl;
			cout << "(1) 关闭客户端" << "\t\t" << "(2) 开始新的游戏" << endl;
			cout << "(3) 设置棋盘尺寸" << "\t" << "(4) 删除当前的游戏" << endl;
			cout << "(5) 进入当前的游戏" << "\t" << "(6) 查看游戏相关信息" << endl;
			cout << "(7) 当前游戏存档" << "\t" << "(8) 读取存档" << endl;
			cout << "输入数字并且回车: ";
			cin >> sig;
			cout << endl;
			if (sig == 2) {
				RunNewGame();
			}
			else if (sig == 3) {
				SetSize();
			}
			else if (sig == 4) {
				DeleteCheckerBoard_Max();
			}
			else if (sig == 5) {
				RunNowGame();
			}
			else if (sig == 6) {
				ShowGameInf();
			}
			else if (sig == 7) {
				StorageRouteMax();
			}
			else if (sig == 8) {
				ReadRoute();
			}
			cout << endl;
			cout << "-----------------------------------------------" << endl;
		}
	}

	bool JudgeSize()
	{
		if (Size == 0) {
			return true;
		}
		return false;
	}

	void DeleteCheckerBoard()
	{
		delete checkerboard;
		checkerboard = nullptr;
	}

	void DeleteCheckerBoard_Max()
	{
		StorageRouteMax();
	}

	void RunNewGame() {
		int x;
		int y;
		int id;

		DeleteCheckerBoard();
		if (JudgeSize()) {
			cout << "Size = 0,请设置棋盘尺寸" << endl;
			return;
		}
		checkerboard = new CheckerBoard(Size);
		checkerboard->Display();

		while (cin >> x >> y) {
			if (x > Size || y > Size || x < 1 || y < 1) {
				cout << "返回主菜单成功!" << endl;
				break;
			}

			if (checkerboard->ShowRecentStep().GetPlayerId() == -1) {
				id = BLACK;
			}
			else if (checkerboard->ShowRecentStep().GetPlayerId() == WHITE) {
				id = BLACK;
			}
			else if (checkerboard->ShowRecentStep().GetPlayerId() == BLACK) {
				id = WHITE;
			}
			else {
				cout << "程序出现了错误,请重新打开游戏" << endl;
			}

			checkerboard->PlaceNode(x, y, id);
			checkerboard->Display();
			if (JudgePlay()) {
				cout << "游戏胜利" << endl;
			}
			else {
				cout << "未出现赢家" << endl;
			}
		}
	}

	void RunNowGame() {
		int x;
		int y;
		int id;

		if (checkerboard == nullptr) {
			cout << "当前后台没有游戏在运行" << endl;
			return;
		}
		checkerboard->Display();

		while (cin >> x >> y >> id) {
			if (x > Size || y > Size || x < 1 || y < 1) {
				break;
			}
			checkerboard->PlaceNode(x, y, id);
			checkerboard->Display();
		}
	}

	void SetSize()
	{
		cout << "请输入需要的棋盘尺寸: ";
		cin >> Size;
		int x = 1;
		if (Size < 5) {
			while (x != 0) {
				if (Size < 5) {
					cout << "  ->棋盘的大小太小为: " << Size << ",请重新设置" << endl;
					cout << "  ->不进行设置,请输入0后回车" << endl;
				}
				else {
					break;
				}
				cout << "请重新输入需要的棋盘尺寸: ";
				cin >> Size;
				x = Size;
			}
		}
		cout << "  ->棋盘的大小设置成功为: " << Size << endl;
	}

	void ShowGameInf()
	{
		cout << "  当前游戏尺寸: " << Size << endl;
		cout << "    游戏开发者: 胡安" << endl;
		cout << "      游戏版本: 1.0.0" << endl;
		cout << "当前是否有棋盘: ";
		if (checkerboard == nullptr) {
			cout << "no" << endl;
		}
		else {
			cout << "yes" << endl;
		}
	}

	// 用来判断是否是否五子连线的函数(深度优先搜索)
	bool JudgePlay()
	{
		ChessNode c;
		int id;
		int counter;
		for (int i = 5; i <= Size; i++) {
			for (int j = 5; j <= Size; j++) {
				c = checkerboard->ShowNode(i, j);
				id = c.GetPlayerId();
				if (id != 1 && id != 2) {
					continue;
				}
				counter = 1;
				while (counter < 5) {
					if (checkerboard->ShowNode(i - counter, j - counter).GetPlayerId() == id) {
						if (counter == 4) {
							return true;
						}
					}
					else {
						break;
					}
					counter++;
				}
				counter = 1;
				while (counter < 5) {
					if (checkerboard->ShowNode(i - counter, j).GetPlayerId() == id) {
						if (counter == 4) {
							return true;
						}
					}
					else {
						break;
					}
					counter++;
				}
				counter = 1;
				while (counter < 5) {
					if (checkerboard->ShowNode(i, j - counter).GetPlayerId() == id) {
						if (counter == 4) {
							return true;
						}
					}
					else {
						break;
					}
					counter++;
				}
			}
		}
		return false;
	}

	// 存储下棋路径的函数
	void StorageRouteMax() {
		if (checkerboard == nullptr) {
			cout << "没有棋盘,存储失败了" << endl;
			return;
		}
		checkerboard->StorageRoute();
		delete checkerboard;
		checkerboard = nullptr;
		cout << "棋盘路径已经被存储到文件中" << endl;
	}

	// 读取路径的函数
	void ReadRoute() {
		if (checkerboard != nullptr) {
			DeleteCheckerBoard();
		}
		Size = 10;
		checkerboard = new CheckerBoard(Size);

		ifstream ifs;
		ifs.open("test.txt", ios::in);

		if (!ifs.is_open())
		{
			cout << "test.txt文件,读取失败" << endl;
			return;
		}

		string xx;
		string yy;
		string dd;

		string buf;
		while (getline(ifs, buf))
		{
			xx = buf.substr(0, 1);
			int j = 0;
			string s = " ";
			for (int i = 0; i < size(buf); i++) {
				string s2 = buf.substr(i, 1);
				if (s.compare(s2) == 0)
				{
					j++;
					if (j == 1) {
						yy = buf.substr(i + 1, 1);
					}
					else if (j == 2) {
						dd = buf.substr(i + 1, 1);
					}
				}
			}
			int xxx = (int)(xx[0] - 48);
			int yyy = (int)(yy[0] - 48);
			int ddd = (int)(dd[0] - 48);
			checkerboard->PlaceNode(xxx, yyy, ddd);
		}
		ifs.close();

		cout << "棋盘路径已经被读取!如下图: " << endl;
		checkerboard->Display();
	}

public:
	int Size;
	CheckerBoard* checkerboard;
};

int main(void)
{
	Client* client = new Client;
	client->LoopRun();

	return 0;
}

1.2 实现效果

C++项目1——五子棋游戏_第1张图片

C++项目1——五子棋游戏_第2张图片 C++项目1——五子棋游戏_第3张图片

二、存储功能的实现

这里弄好的功能丢掉了,就不重新再弄了,但是大致思路是下面这样的,下面的函数都是放到客户端类里面,然后使用 LoopRun 函数进行调用

#include 
#include 
#include 
#include 

using namespace std;

class ChessNode {
public:
	ChessNode(int x, int y, int id) {
		location_x = x;
		location_y = y;
		player_id = id;
	}
public:
	int location_x;
	int location_y;
	int player_id;
};

class CheckerBoard {
public:
	void AddStep(ChessNode c) {
		route.push(c);
	}
public:
	stack route;
	stack route2;
};

int main(void)
{
	CheckerBoard* b = new CheckerBoard;

	ChessNode n1(1, 1, 1);
	b->AddStep(n1);
	ChessNode n2(1, 2, 2);
	b->AddStep(n2);
	ChessNode n3(1, 3, 1);
	b->AddStep(n3);

	while (!b->route.empty()) {
		b->route2.push(b->route.top());
		b->route.pop();
	}

	ofstream ofs;
	ofs.open("test.txt", ios::out);

	while (!b->route2.empty()) {
		ofs << char(b->route2.top().location_x + 48);
		ofs << " ";
		ofs << char(b->route2.top().location_y + 48);
		ofs << " ";
		ofs << char(b->route2.top().player_id + 48);
		ofs << "\n";
		b->route2.pop();
	}
	ofs.close();

	// 2、创建流对象
	ifstream ifs;

	// 3、打开文件并判断文件是否打开成功
	ifs.open("test.txt", ios::in);

	if (!ifs.is_open())
	{
		cout << "文件打开失败" << endl;
	}

	string xx;
	string yy;
	string dd;

	// 4、读数据
	string buf;
	while (getline(ifs, buf))
	{
		// cout << buf << endl;
		xx = buf.substr(0, 1);
		int j = 0;
		string s = " ";
		for (int i = 0; i < size(buf); i++) {
			string s2 = buf.substr(i, 1);
			if (s.compare(s2) == 0)
			{
				j++;
				if (j == 1) {
					yy = buf.substr(i + 1, 1);
				}
				else if (j == 2) {
					dd = buf.substr(i + 1, 1);
				}
			}
		}
		int xxx = (int)(xx[0] - 48);
		int yyy = (int)(yy[0] - 48);
		int ddd = (int)(dd[0] - 48);
		ChessNode n(xxx, yyy, ddd);
		b->AddStep(n);
	}

	while (!b->route.empty()) {
		cout << b->route.top().location_x << " " << b->route.top().location_y << " " << b->route.top().player_id << endl;
		b->route.pop();
	}


	// 5、关闭文件
	ifs.close();

	return 0;
}

三、简化下棋的过程

简化1:可以一人一手,每次读取栈顶元素对应的是黑棋或者白棋。如果是黑棋,下次就下白棋;如果是白棋,下次就下黑棋;如果没有棋,下次就下白棋

你可能感兴趣的:(C/C++,游戏)