C/C++教程

C++畅玩五子棋项目

本文主要是介绍C++畅玩五子棋项目,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

畅玩五子棋项目说明

​ 项目创建环境:Windows 10 + Visual Studio 2019

​ 棋子类型:实心●和空心◎。其中,棋子彩色棋子为当前落子

​ 实现功能:对战模式(人人对战)、人机模式(人机模式)、加载历史、帮助反馈

功能介绍:

1.对战模式

​ 选择该模式,直接进入人人对战,默认实心棋子先手。

2.人机模式

​ 选择该模式,需要再选择一次先手和后手,再进入人机对战。

​ 进入游戏后,在你落子之后,机器落子需要1s的“停顿”时间,以方便你查看当前局势。

3.加载历史

​ 当下完一局棋后(已分出胜负),系统为你自动保存对局状态。若查看,选择此项。

4.帮助反馈

​ 按R可悔棋:在对战模式下,按一下R则退回一步;在人机模式下,按一下R则棋手和机器人各退回一步。对战中可N次按R且悔N步棋。

源代码文件列表

main.cpp
WelcomeMenu.h
WelcomeMenu.cpp
SetBoardValue.h
AbstractPlayer.h
AbstractPlayer.cpp
HumanPlayer.h
HumanPlayer.cpp
HumanAnalysic.h
HumanAnalysic.cpp
RebotPlayer.h
RebotPlayer.cpp
RebotAnalysis.h
RebotAnalysis.cpp
HistoryFun.h
HistoryFun.cpp

源代码文件

main.cpp

#include<iostream>
#include"SetBoardValue.h"
#include"WelcomeMenu.h"
#include"HumanPlayer.h"
#include"RebotPlayer.h"
#include"HumanAnalysic.h"
#include"HistoryFun.h"

using namespace std;

//这是一个打印字符集,并使用关键字extern作了全局声明。在原版中通过形状来标识当前落子,改版后通过颜色标识
string symbol[14] = { "?" , "┏" , "┓" , "┗" , "┛" , "┠" , "┨" , "┯" , "┷" , "┼" , "●" , "◎" , "●" , "◎" };
int mode;	//对战模式
int step = 0;	//下棋步数

int main()
{
	enum chessSign { black = 12, white = 13 };
	mode = WelcomeMenu();
	AbstractPlayer::ClearBoardArray();
	AbstractPlayer::DisplayBoard();

	switch (mode)
	{
	case 1:
	{
		HumanPlayer Student1(black);
		HumanPlayer Student2(white);

		while (true)
		{
			if (HumanAnalysic(Student1))
			{
				break;
			}

			if (HumanAnalysic(Student2))
			{
				break;
			}
		}
		break;


		//RebotPlayer Student1(black);
		//RebotPlayer Student2(white);

		//while (true)
		//{
		//	if (Student1.ComputerPlacePieces())
		//	{
		//		break;
		//	}

		//	if (Student2.ComputerPlacePieces())
		//	{
		//		break;
		//	}
		//}
		//break;
	}
	case 2:
	{
		HumanPlayer Student1(black);
		RebotPlayer Student2(white);
		while (true)
		{
			if (HumanAnalysic(Student1))
			{
				break;
			}

			if (Student2.ComputerPlacePieces())
			{
				break;
			}
		}
		break;
	}
	case 3:
	{
		HumanPlayer Student1(white);
		RebotPlayer Student2(black);
		while (true)
		{
			if (Student2.ComputerPlacePieces())
			{
				break;
			}
			if (HumanAnalysic(Student1))
			{
				break;
			}
		}
		break;
	}
	}

	if (SaveHistory())
	{
		cout << endl;
		cout << "    ";
		cout << "当前对战已保存!" << endl;
	}
	cout << endl;
	system("pause");
	return 0;
}

WelcomeMenu.h

#pragma once

int WelcomeMenu();

bool WelcomeView();

WelcomeMenu.cpp

/*进入模式选择界面
* 模式选择:
*   1.人人对战
*   2.人机对战[先手/后手]
*   3.加载历史
*   4.帮助反馈
*/

#include<iostream>
#include<string>
#include"WelcomeMenu.h"
#include"HistoryFun.h"

using namespace std;

int WelcomeMenu()
{
	int mode1, mode2;
	string command;

	do
	{
		WelcomeView();
		cout << "         ";
		cout << "您好!请选择游戏模式: _" << '\b';
		getline(cin, command);
		//cin >> command;
		cout << endl;
		if (command.length() != 1 || command.at(0) < '1' || command.at(0) > '4')
		{
			cout << "           ";
			cout << "输入错误, 请重试!" << endl << endl;
			system("pause");
			continue;
		}
		mode1 = command.at(0) - '0';

		if (mode1 == 1)
		{
			return 1;
		}
		else if (mode1 == 2)
		{
			do
			{
				cout << "       ";
				cout << "请选择模式[先手1/后手2]: _" << '\b';
				getline(cin, command);
				//cin >> command;
				if (command.length() != 1 || command.at(0) < '1' || command.at(0) > '2')
				{
					cout << "           ";
					cout << "输入错误, 请重试!" << endl << endl;
					system("pause");
					continue;
				}
				mode2 = command.at(0) - '0';

				if (mode2 == 1)
				{
					return 2;
				}
				else if (mode2 == 2)
				{
					return 3;
				}
			} while (true);
		}
		else if (mode1 == 3)
		{
			if (!loadHistory())
			{
				cout << "             ";
				cout << "找不到历史对战!" << endl << endl;
				system("pause");
				continue;
			}
			else
			{
				cout << "             ";
				cout << "已加载完毕!" << endl << endl;
				system("pause");
				continue;
			}
		}
		else if (mode1 == 4)
		{
			cout << "           ";
			cout << " 按R: 悔一手棋!" << endl << endl;
			system("pause");
			continue;
		}
	} while (true);

}

bool WelcomeView()
{
	system("cls");
	const int WIDTH_N = 32;
	int i;
	cout << "    ";
	for (i = 0; i < WIDTH_N; i++)
	{
		cout << "=";
	}
	cout << endl;

	cout << "    ";
	cout << "*   |> 欢迎进入五子棋游戏 <|   *" << endl;
	cout << "    ";
	cout << "***                          ***" << endl;
	cout << "    ";
	cout << "*     [ AUTHOR:CAO ZHEN ]     *" << endl;

	cout << "    ";
	for (i = 0; i < WIDTH_N; i++)
	{
		cout << "=";
	}
	cout << endl;

	cout << endl;
	cout << "    ";
	cout << "     ┌-------------------┐       " << endl;
	cout << "    ";
	cout << "     │  → 1-对战模式 ← │         " << endl;
	cout << "    ";
	cout << "     └-------------------┘       " << endl;

	cout << "    ";
	cout << "     ┌-------------------┐       " << endl;
	cout << "    ";
	cout << "     │  → 2-人机模式 ← │         " << endl;
	cout << "    ";
	cout << "     └-------------------┘       " << endl;

	cout << "    ";
	cout << "     ┌-------------------┐       " << endl;
	cout << "    ";
	cout << "     │  → 3-加载历史 ← │         " << endl;
	cout << "    ";
	cout << "     └-------------------┘       " << endl;

	cout << "    ";
	cout << "     ┌-------------------┐       " << endl;
	cout << "    ";
	cout << "     │  → 4-帮助反馈 ← │         " << endl;
	cout << "    ";
	cout << "     └-------------------┘       " << endl;

	cout << endl;
	cout << "    ";
	for (i = 0; i < WIDTH_N; i++)
	{
		cout << "-";
	}
	cout << endl << endl;

	return true;
}

SetBoardValue.h

#pragma once

#include<iostream>
#define M 15
#define N 15

//预定义棋子颜色
#define RESET "\033[0m"
#define RED "\033[31m" /* Red */
#define GREEN "\033[32m" /* Green */
#define BLUE "\033[34m" /* Blue */

extern std::string symbol[14];
extern int mode;
extern int step;

AbstractPlayer.h

#pragma once

#include"SetBoardValue.h"

class AbstractPlayer
{
public:
	int GetChessSign();
	static bool ClearBoardArray();
	static bool DisplayBoard();
	static int JudgeOutcome();

	static int BoardArray[M * N];	//棋局矩阵
	static int StorageBoardArray[M * N * 225];	//保存历史

	int m_ChessSign;	//棋子类型

};

AbstractPlayer.cpp

#include "AbstractPlayer.h"
#include<iostream>
#include<string>
#include<iomanip>
#include"HistoryFun.h"

using namespace std;

int AbstractPlayer::BoardArray[M * N] = { 0 };
int AbstractPlayer::StorageBoardArray[M * N * 225] = { 0 };


/**************************** 获取当前类的符号 *******************************/
int AbstractPlayer::GetChessSign()
{
	return m_ChessSign - 2;
}


/********************* 静态成员函数:清空棋局,开局 ***************************/
bool AbstractPlayer::ClearBoardArray()
{
	int i, j;
	BoardArray[0] = 1;
	BoardArray[N - 1] = 2;
	BoardArray[(M - 1) * N] = 3;
	BoardArray[(M - 1) * N + N - 1] = 4;

	for (i = 1; i < M - 1; i++)
	{
		BoardArray[i * N + 0] = 5;
		BoardArray[i * N + N - 1] = 6;
	}

	for (j = 1; j < N - 1; j++)
	{
		BoardArray[0 * N + j] = 7;
		BoardArray[(M - 1) * N + j] = 8;
	}

	for (i = 1; i < M - 1; i++)
	{
		for (j = 1; j < N - 1; j++)
		{
			BoardArray[i * N + j] = 9;
		}
	}
	StorageHistoryArray(BoardArray);
	return true;
}


/************************静态成员函数: 显示棋局状态 *************************/
bool AbstractPlayer::DisplayBoard()
{
	system("cls");
	cout << endl;;
	cout << setw(N - 5) << " ";
	if (mode == 1)
	{
		cout << " 畅玩五子棋(对战版)" << endl;
	}
	else if (mode == 2 || mode == 3)
	{
		cout << " 畅玩五子棋(人机版)" << endl;
	}
	else
	{
		cout << "畅玩五子棋(历史对战)" << endl;
	}

	int i, j;
	char ch_y = 'A';

	for (i = 0; i < M; i++)
	{
		cout << setw(4) << M - i;
		for (j = 0; j < N; j++)
		{
			if (BoardArray[i * N + j] < 10)
			{
				if (j != 0 && BoardArray[i * N + j - 1] >= 10)
				{
					cout << setw(2) << symbol[BoardArray[i * N + j]];
				}
				else
				{
					cout << setw(3) << symbol[BoardArray[i * N + j]];
				}
			}
			else if (BoardArray[i * N + j] == 10 || BoardArray[i * N + j] == 11)
			{
				if (j != 0 && BoardArray[i * N + j - 1] >= 10)
				{
					cout << setw(2) << symbol[BoardArray[i * N + j]];
				}
				else
				{
					cout << setw(3) << symbol[BoardArray[i * N + j]];
				}

			}
			else if (BoardArray[i * N + j] == 12)
			{
				if (j != 0 && BoardArray[i * N + j - 1] >= 10)
				{
					cout << setw(5) << RED << symbol[BoardArray[i * N + j]] << RESET;
				}
				else
				{
					cout << setw(6) << RED << symbol[BoardArray[i * N + j]] << RESET;
				}

			}
			else if (BoardArray[i * N + j] == 13)
			{
				if (j != 0 && BoardArray[i * N + j - 1] >= 10)
				{
					cout << setw(5) << RED << symbol[BoardArray[i * N + j]] << RESET;
				}
				else
				{
					cout << setw(6) << GREEN << symbol[BoardArray[i * N + j]] << RESET;
				}

			}
		}
		cout << endl;
	}

	cout << setw(4) << " ";
	for (j = 0; j < N; j++)
	{
		cout << setw(2) << ch_y++;
	}
	cout << endl << endl;
	return true;
}


/*************************** 构造判断矩阵,判断是否有人赢棋*************************/
int AbstractPlayer::JudgeOutcome()
{
	int i, j, JudgeBoardArray[M][N];

	//构造一个判断矩阵,这里设未落子位置值为0,棋手1落子位置值为-1,棋手2落子位置值为1
	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			if (BoardArray[i * N + j] == 10)
			{
				JudgeBoardArray[i][j] = -1;
			}
			else if (BoardArray[i * N + j] == 11)
			{
				JudgeBoardArray[i][j] = 1;
			}
			else
			{
				JudgeBoardArray[i][j] = 0;
			}
		}
	}

	//判断 ' - ' ,是否有棋手赢棋
	for (i = 0; i < M; i++)
	{
		for (j = 0; j <= N - 5; j++)
		{
			if (JudgeBoardArray[i][j] == -1 && JudgeBoardArray[i][j + 1] == -1 && JudgeBoardArray[i][j + 2] == -1 && JudgeBoardArray[i][j + 3] == -1 && JudgeBoardArray[i][j + 4] == -1)
			{

				return -1;
			}
			if (JudgeBoardArray[i][j] == 1 && JudgeBoardArray[i][j + 1] == 1 && JudgeBoardArray[i][j + 2] == 1 && JudgeBoardArray[i][j + 3] == 1 && JudgeBoardArray[i][j + 4] == 1)
			{

				return 1;
			}
		}
	}

	//判断 ' | ' ,是否有棋手赢棋
	for (i = 0; i <= M - 5; i++)
	{
		for (j = 0; j < N; j++)
		{
			if (JudgeBoardArray[i][j] == -1 && JudgeBoardArray[i + 1][j] == -1 && JudgeBoardArray[i + 2][j] == -1 && JudgeBoardArray[i + 3][j] == -1 && JudgeBoardArray[i + 4][j] == -1)
			{
				return -1;
			}
			if (JudgeBoardArray[i][j] == 1 && JudgeBoardArray[i + 1][j] == 1 && JudgeBoardArray[i + 2][j] == 1 && JudgeBoardArray[i + 3][j] == 1 && JudgeBoardArray[i + 4][j] == 1)
			{
				return 1;
			}
		}
	}

	//判断 ' \ ' ,是否有棋手赢棋
	for (i = 0; i <= M - 5; i++)
	{
		for (j = 0; j <= N - 5; j++)
		{
			if (JudgeBoardArray[i][j] == -1 && JudgeBoardArray[i + 1][j + 1] == -1 && JudgeBoardArray[i + 2][j + 2] == -1 && JudgeBoardArray[i + 3][j + 3] == -1 && JudgeBoardArray[i + 4][j + 4] == -1)
			{
				return -1;
			}
			if (JudgeBoardArray[i][j] == 1 && JudgeBoardArray[i + 1][j + 1] == 1 && JudgeBoardArray[i + 2][j + 2] == 1 && JudgeBoardArray[i + 3][j + 3] == 1 && JudgeBoardArray[i + 4][j + 4] == 1)
			{
				return 1;
			}
		}
	}

	//判断 ' / ' ,是否有棋手赢棋
	for (i = 0; i <= M - 5; i++)
	{
		for (j = 4; j <= N; j++)
		{
			if (JudgeBoardArray[i][j] == -1 && JudgeBoardArray[i + 1][j - 1] == -1 && JudgeBoardArray[i + 2][j - 2] == -1 && JudgeBoardArray[i + 3][j - 3] == -1 && JudgeBoardArray[i + 4][j - 4] == -1)
			{
				return -1;
			}
			if (JudgeBoardArray[i][j] == 1 && JudgeBoardArray[i + 1][j - 1] == 1 && JudgeBoardArray[i + 2][j - 2] == 1 && JudgeBoardArray[i + 3][j - 3] == 1 && JudgeBoardArray[i + 4][j - 4] == 1)
			{
				return 1;
			}
		}
	}

	return 0;
}

HumanPlayer.h

#pragma once

#include"AbstractPlayer.h"

class HumanPlayer :public AbstractPlayer
{
public:
	HumanPlayer(int ChessSign);
	bool PlacePieces();

private:
	int m_X;	//当前落子的x坐标
	int m_Y;	//当前落子的y坐标
};

HumanPlayer.cpp

/*人工棋手类[继承抽象棋手类]的实现(cao zhen 2020/11/15)
* 继承方法:
*   GetChessSign 获取当前类的棋子符号(黑或白)
*   ClearBoardArray [静态]清空棋局,开局
*   DisplayBoard [静态]显示棋局状态
*   JudgeOutcome 判断是否有人赢棋
* 创建方法:
*  HumanPlayer 有参构造函数
*  PlacePieces 棋手落子
*/

#include<iostream>
#include<string>
#include<iomanip>
#include "HumanPlayer.h"
#include"HistoryFun.h"

using namespace std;


HumanPlayer::HumanPlayer(int ChessSign)
{
	m_ChessSign = ChessSign;
}


/******************************** 棋手落子 ********************************/
bool HumanPlayer::PlacePieces()
{
	string command;

	do
	{
		getline(cin, command);
		//cin >> command;
		if (command.length() == 1)
		{
			if (command.at(0) == 'R')
			{
				if (mode == 1)
				{
					RegretMove();
				}
				else
				{
					RegretMove();
					RegretMove();
				}

				cout << symbol[GetChessSign()] << "方请落子:" << flush;
			}
			else
			{
				break;
			}
		}
		else
		{
			break;
		}
	} while (true);



	if (!(command.length() == 2 || command.length() == 3))
	{
		return false;
	}

	if (!(command.at(0) >= 'A' && command.at(0) <= 'O'))
	{
		return false;
	}

	if (command.length() == 2)
	{
		if (!(command.at(1) >= '1' && command.at(1) <= '9'))
		{
			return false;
		}
		m_X = 14 - (command.at(1) - '1');
		m_Y = command.at(0) - 'A';

	}

	if (command.length() == 3)
	{
		if (!(command.at(1) == '1' && command.at(2) >= '0' && command.at(2) <= '5'))
		{
			return false;
		}
		m_X = 14 - (9 + command.at(2) - '0');
		m_Y = command.at(0) - 'A';
	}
	if (BoardArray[m_X * N + m_Y] >= 10)
	{
		return false;
	}

	BoardArray[m_X * N + m_Y] = m_ChessSign;
	DisplayBoard();
	StorageHistoryArray(BoardArray);
	BoardArray[m_X * N + m_Y] = m_ChessSign - 2;

	return true;
}

HumanAnalysic.h

#pragma once

#include"HumanPlayer.h"

int HumanAnalysic(HumanPlayer& Student);

HumanAnalysic.cpp

#include<iostream>
#include<string>
#include"SetBoardValue.h"
#include"HumanPlayer.h"
#include"HumanAnalysic.h"


using namespace std;

int HumanAnalysic(HumanPlayer& Student)
{
	int outcome;
	cout << symbol[Student.GetChessSign()] << "方请落子:" << flush;
	while (Student.PlacePieces() == false)
	{
		cout << "    输入格式错误,请重新输入!" << endl;
		cout << symbol[Student.GetChessSign()] << "方请落子:" << flush;
	};

	if (outcome = AbstractPlayer::JudgeOutcome())
	{
		cout << "    ";
		cout << symbol[Student.GetChessSign()] << "胜出!" << endl;
	}

	return outcome;
}

RebotPlayer.h

#pragma once

#include"AbstractPlayer.h"

class RebotPlayer :public AbstractPlayer
{
public:
	RebotPlayer(int ChessSign);
	int ComputerPlacePieces();
};

RebotPlayer.cpp

/*电脑棋手类[继承抽象棋手类]的实现(cao zhen 2020/11/15)
* 继承方法:
*   GetChessSign 获取当前类的棋子符号(黑或白)
*   ClearBoardArray [静态]清空棋局,开局
*   DisplayBoard [静态]显示棋局状态
*   JudgeOutcome [静态]判断是否有人赢棋
* 创建方法:
*   RebotPlayer 有参构造函数
*   ComputerPlacePieces 电脑落子
*/

#include<iostream>
#include<string>
#include<windows.h>
#include "RebotPlayer.h"
#include"RebotAnalysis.h"
#include"HistoryFun.h"

using namespace std;

RebotPlayer::RebotPlayer(int ChessSign)
{
	m_ChessSign = ChessSign;
}

/******************************* 电脑落子 **************************************/
int RebotPlayer::ComputerPlacePieces()
{
	int i, j, JudgeBoardArray[M][N] = { 0 };
	int labX, labY;
	int chessSign = 0, outcome = 0;

	//构造一个判断矩阵,这里设未落子位置值为0,棋手1落子位置值为-1,棋手2落子位置值为1
	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			if (BoardArray[i * N + j] == 10)
			{
				JudgeBoardArray[i][j] = -1;
			}
			else if (BoardArray[i * N + j] == 11)
			{
				JudgeBoardArray[i][j] = 1;
			}
			else
			{
				JudgeBoardArray[i][j] = 0;
			}
		}
	}

	if (this->m_ChessSign == 12)
	{
		chessSign = -1;
	}
	else if (this->m_ChessSign == 13)
	{
		chessSign = 1;
	}

	//以经典开局方式开局。其中若机器先手,则落子天元
	if (JudgeClassicStart(*JudgeBoardArray, &labX, &labY, chessSign))
	{
		BoardArray[labX * N + labY] = this->m_ChessSign;
		DisplayBoard();
		StorageHistoryArray(BoardArray);
		BoardArray[labX * N + labY] = this->m_ChessSign - 2;
		return 0;
	}

	//经典开局后,布局评分
	if (BoardAnalysis(*JudgeBoardArray, &labX, &labY, chessSign))
	{
		BoardArray[labX * N + labY] = this->m_ChessSign;
		Sleep(1000);
		DisplayBoard();
		StorageHistoryArray(BoardArray);
		BoardArray[labX * N + labY] = this->m_ChessSign - 2;
	}

	if (outcome = JudgeOutcome())
	{
		cout << "    ";
		cout << symbol[GetChessSign()] << "胜出!" << endl;
	}

	return outcome;
}

RebotAnalysis.h

#pragma once

bool JudgeClassicStart(int* judgeArray, int* labX, int* labY, int chessSign);

bool BoardAnalysis(int* judgeArray, int* x, int* y, int chessSign);

int scoreFunction(const int* judgeArray, int i, int j, int chessSign);

int GetLocalChessSign(const int* judgeArray, int labX, int labY, int direction, int distance);

RebotAnalysis.cpp

#include<time.h>
#include"SetBoardValue.h"
#include"RebotAnalysis.h"

/**************** 对矩阵进行判断,若为经典开局,则返回1;否,则返回0 ***************/
bool JudgeClassicStart(int* judgeArray, int* labX, int* labY, int chessSign)
{
	int i, j, delta1, delta2;
	int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
	int num1 = 0, num2 = 0;

	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			if (judgeArray[i * N + j] == -1)
			{
				x1 = i;
				y1 = j;
				if (++num1 > 1)
				{
					return false;
				}
			}
			if (judgeArray[i * N + j] == 1)
			{
				x2 = i;
				y2 = j;
				if (++num2 > 1)
				{
					return false;
				}
			}
		}
	}
	if (num1 == 0 && num2 == 0)
	{
		*labX = 7;
		*labY = 7;
		return true;
	}

	if ((num1 == 0 && num2 == 1) || (num1 == 1 && num2 == 0))
	{
		if (judgeArray[7 * N + 7] == 0)
		{
			*labX = 7;
			*labY = 7;
		}
		else
		{
			int dx = 0, dy = 0;
			do
			{
				srand(time(NULL));
				dx = rand() % 3 - 1;
				srand(time(NULL));
				dy = rand() % 3 - 1;
			} while (dx == 0 && dy == 0);

			*labX = 7 + dx;
			*labY = 7 + dy;
		}
		return true;
	}

	if (num1 == 1 && num2 == 1)
	{
		delta1 = abs(x2 - x1);
		delta2 = abs(y2 - y1);
		if (delta1 <= 1 && delta2 <= 1)
		{
			if (chessSign == -1)
			{
				int dx = 0, dy = 0;
				do
				{
					srand(time(NULL));
					dx = rand() % 3 - 1;
					srand(time(NULL));
					dy = rand() % 3 - 1;
				} while (dx == 0 && dy == 0 || ((x1 + dx)==x2 &&(y1+dy)==y2));

				*labX = x1 + dx;
				*labY = y1 + dy;
			}
			else if (chessSign == 1)
			{
				int dx = 0, dy = 0;
				do
				{
					srand(time(NULL));
					dx = rand() % 3 - 1;
					srand(time(NULL));
					dy = rand() % 3 - 1;
				} while (dx == 0 && dy == 0 || ((x2 + dx) == x1 && (y2 + dy) == y1));

				*labX = x2 + dx;
				*labY = y2 + dy;
			}
		}
		else
		{
			int dx = 0, dy = 0;
			do
			{
				srand(time(NULL));
				dx = rand() % 3 - 1;
				srand(time(NULL));
				dy = rand() % 3 - 1;
			} while (dx == 0 && dy == 0);

			*labX = 7 + dx;
			*labY = 7 + dy;
		}
		return true;
	}
}


/*************** 权值法给当前布局打分,并返回最优反馈坐标 ********************/
bool BoardAnalysis(int* judgeArray, int* x, int* y, int chessSign)
{
	int i, j, scoreArray[M * N] = { 0 };
	int maxScore=-250000;
	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			if (judgeArray[i * N + j] == 0)
			{
				scoreArray[i * N + j] = scoreFunction(judgeArray, i, j, chessSign);
				if (scoreArray[i * N + j] > maxScore)
				{
					maxScore = scoreArray[i * N + j];
					*x = i;
					*y = j;
				}
			}
		}
	}

	return true;
}


/**************************** 统计某个点的得分 *********************************/
int scoreFunction(const int* judgeArray, int i, int j, int chessSign)
{
	int score = 0;
	for (int maySign = -1; maySign <= 1; maySign += 2)
	{
		int twoNum = 0;
		for (int direction = 1; direction <= 8; direction++)
		{
			//活四: 0 1 1 1 1 *
			if (GetLocalChessSign(judgeArray, i, j, direction, -1) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -2) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -3) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -4) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -5) == 0)
			{
				score += 300000;
				if (maySign != chessSign)
				{
					score -= 500;
				}
				continue;
			}


			//死四(一): -1 1 1 1 1 *
			if (GetLocalChessSign(judgeArray, i, j, direction, -1) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -2) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -3) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -4) == maySign &&
				(GetLocalChessSign(judgeArray, i, j, direction, -5) == -maySign ||
					GetLocalChessSign(judgeArray, i, j, direction, -5) == -2))
			{
				score += 250000;
				if (maySign != chessSign)
				{
					score -= 500;
				}
				continue;
			}


			//死四(二): 1 1 1 * 1
			if (GetLocalChessSign(judgeArray, i, j, direction, -1) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -2) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -3) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, 1) == maySign)
			{
				score += 240000;
				if (maySign != chessSign)
				{
					score -= 500;
				}
				continue;
			}


			//死四(三): 1 1 * 1 1
			if (GetLocalChessSign(judgeArray, i, j, direction, -1) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -2) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, 1) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, 2) == maySign)
			{
				score += 230000;
				if (maySign != chessSign)
				{
					score -= 500;
				}
				continue;
			}


			//活三(一): 1 1 1 * 0
			if (GetLocalChessSign(judgeArray, i, j, direction, -1) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -2) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -3) == maySign)
			{
				if (GetLocalChessSign(judgeArray, i, j, direction, 1) == 0)
				{
					score += 750;
					if (GetLocalChessSign(judgeArray, i, j, direction, -4) == 0)
					{
						score += 3150;
						if (maySign != chessSign)
						{
							score -= 300;
						}
					}
				}

				if ((GetLocalChessSign(judgeArray, i, j, direction, 1) == -maySign ||
					GetLocalChessSign(judgeArray, i, j, direction, 1) == -2)
					&& GetLocalChessSign(judgeArray, i, j, direction, -4) == 0)
				{
					score += 500;
				}
				continue;
			}

			//活三(二): 1 1 1 0 *
			if (GetLocalChessSign(judgeArray, i, j, direction, -1) == 0 &&
				GetLocalChessSign(judgeArray, i, j, direction, -2) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -3) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -4) == maySign)
			{
				score += 350;
				continue;
			}

			// 死三: 1 1 * 1
			if (GetLocalChessSign(judgeArray, i, j, direction, -1) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -2) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, 1) == maySign)
			{
				score += 600;
				if (GetLocalChessSign(judgeArray, i, j, direction, -3) == 0 &&
					GetLocalChessSign(judgeArray, i, j, direction, 2) == 0)
				{
					score += 3150;
					continue;
				}
				else if ((GetLocalChessSign(judgeArray, i, j, direction, -3) == -maySign ||
					GetLocalChessSign(judgeArray, i, j, direction, -3) == -2) &&
					(GetLocalChessSign(judgeArray, i, j, direction, 2) == -maySign ||
						GetLocalChessSign(judgeArray, i, j, direction, 2) == -2))
				{
					continue;
				}
				else
				{
					score += 700;
					continue;
				}
			}

			//活二数量(twoNum)
			if (GetLocalChessSign(judgeArray, i, j, direction, -1) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -2) == maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, -3) != -maySign &&
				GetLocalChessSign(judgeArray, i, j, direction, 1) != -maySign)
			{
				++twoNum;
			}

			//散棋数量(plyerNum)
			int plyerNum = 0;
			for (int si = -4; si <= 0; si++)
			{
				int tempPlayerNum = 0;
				for (int sj = 0; sj <= 4; sj++)
				{
					if (GetLocalChessSign(judgeArray, i, j, direction, si + sj) == maySign)
					{
						tempPlayerNum++;
					}
					else if (GetLocalChessSign(judgeArray, i, j, direction, si + sj) == -maySign ||
						GetLocalChessSign(judgeArray, i, j, direction, si + sj) == -2)
					{
						tempPlayerNum = 0;
						break;
					}
				}
				plyerNum += tempPlayerNum;
			}

			score += plyerNum * 15;

		}

		if (twoNum >= 2)
		{
			score += 3000;
			if (chessSign != maySign)
			{
				score -= 100;
			}
		}
	}

	return score;
}


/*************************** 搜索将要落子位置的附近值 *******************************/
int GetLocalChessSign(const int* judgeArray, int labX, int labY, int direction, int distance)
{
	int x = labX, y = labY;
	switch (direction) {
	case 1:
		x = labX + distance;
		break;
	case 2:
		x = labX + distance;
		y = labY + distance;
		break;
	case 3:
		y = labY + distance;
		break;
	case 4:
		x = labX - distance;
		y = labY + distance;
		break;
	case 5:
		x = labX - distance;
		break;
	case 6:
		x = labX - distance;
		y = labY - distance;
		break;
	case 7:
		y = labY - distance;
		break;
	case 8:
		x = labX + distance;
		y = labY - distance;
	}

	if (x < 0 || y < 0 || x > 14 || y > 14)
	{
		return -2;
	}
	return judgeArray[x * N + y];
}

HistoryFun.h

#pragma once

bool RegretMove();

bool StorageHistoryArray(const int* currentArray);

bool SaveHistory();

bool loadHistory();

HistoryFun.cpp

#include<fstream>
#include"HistoryFun.h"
#include"HumanPlayer.h"
#include"RebotPlayer.h"

using namespace std;

const bool TurnOn = true;
const bool TurnOff = false;
bool turn;


/***************************** 悔一步棋 *********************************/
bool RegretMove()
{
	int i, j;
	if (turn == TurnOn)
	{
		if ((step = step - 2) < 0)
		{
			return false;
		}
	}
	else
	{
		if ((step = step - 1) < 0)
		{
			return false;
		}
	}

	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			AbstractPlayer::BoardArray[i * N + j] = AbstractPlayer::StorageBoardArray[(step * M + i) * N + j];
			AbstractPlayer::StorageBoardArray[(step * M + i) * N + j] = 0;
		}
	}

	AbstractPlayer::DisplayBoard();

	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			if (AbstractPlayer::BoardArray[i * N + j] == 12 || AbstractPlayer::BoardArray[i * N + j] == 13)
			{
				AbstractPlayer::BoardArray[i * N + j] -= 2;
			}
		}
	}

	turn = TurnOff;

	return 1;
}


/***************************** 内存存储当前布局 *********************************/
bool StorageHistoryArray(const int* currentArray)
{
	int i, j;
	for (i = 0; i < M; i++)
	{
		for (j = 0; j < N; j++)
		{
			AbstractPlayer::StorageBoardArray[(step * M + i) * N + j] = currentArray[i * N + j];
		}
	}
	++step;
	turn = TurnOn;

	return true;
}


/***************************** 保存历史对战 *********************************/
bool SaveHistory()
{
	int i, j, k;
	ofstream outBuff;
	outBuff.open("history.txt", ios::out);

	outBuff << step << '\t';
	for (k = 0; k < step; k++)
	{
		for (i = 0; i < M; i++)
		{
			for (j = 0; j < N; j++)
			{
				outBuff << AbstractPlayer::StorageBoardArray[(k * M + i) * N + j] << '\t';
			}
		}
	}

	outBuff.close();
	return true;
}


/***************************** 加载历史对战 *********************************/
bool loadHistory()
{
	int i, j, k;
	ifstream inBuff;
	inBuff.open("history.txt", ios::in);
	if (!inBuff.is_open())
	{
		return false;
	}

	inBuff >> step;
	for (k = 0; k < step; k++)
	{
		for (i = 0; i < M; i++)
		{
			for (j = 0; j < N; j++)
			{
				inBuff >> AbstractPlayer::StorageBoardArray[(k * M + i) * N + j];
			}
		}
	}
	inBuff.close();

	for (k = 0; k < step; k++)
	{
		for (i = 0; i < M; i++)
		{
			for (j = 0; j < N; j++)
			{
				AbstractPlayer::BoardArray[i * N + j] = AbstractPlayer::StorageBoardArray[(k * M + i) * N + j];
			}
		}
		AbstractPlayer::DisplayBoard();
		cout << "     ";
		cout << "查看历史对战[按任意键继续]" << endl;
		cout << endl;
		system("pause");
	}

	return true;
}
这篇关于C++畅玩五子棋项目的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!