畅玩五子棋项目说明

​ 项目创建环境: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 onceint 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落子位置值为1for (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落子位置值为1for (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 oncebool 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 * 1if (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 1if (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 * 0if (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 * 1if (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 oncebool 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++畅玩五子棋项目相关推荐

  1. 济宁市机器人科技乐园_人工智能的“游乐场”,邀你免费畅玩!

    原标题:人工智能的"游乐场",邀你免费畅玩! 好奇心与荷尔蒙,探索欲与脑洞大开 AI就像一座多种多类游乐园 家.学校.公司.商场-- 无论在哪个地方,AI都在努力的创造更优越的应用 ...

  2. 五子棋项目结束总结_五子棋项目总结

    五子棋项目是在我加入蓝杰后第一个接触的小型游戏项目,有着非同寻常的意义,所以本人也是相当的重视. 在胡哥的指导下,我们通过完成一个简单的登录界面,初步对桌面应用程序的开发有了一定的了解,即UI的相关知 ...

  3. 纯java编写的联机五子棋项目(附带开源链接)

    文章目录 说明 功能展示 客户端说明 服务端说明 总结 说明 这是用java写的一个联机五子棋项目,该项目是我大二上期的时候写的,那时候学完了java基础,想要把学的技术都综合使用一下,于是就在国庆节 ...

  4. java图形化五子棋总结,Java从此丰富多彩-五子棋项目总结

    当前位置:我的异常网» 编程 » Java从此丰富多彩-五子棋项目总结 Java从此丰富多彩-五子棋项目总结 www.myexceptions.net  网友分享于:2013-11-08  浏览:7次 ...

  5. 小孩子才做选择,成年人都要,linux各发行版畅玩,建议收藏!

    前言 由于linux内核开源,所以linux的发行版本非常多,各有各的优劣,到底哪个好,大家众说纷纭,所以二当家的我决定自己都装上畅玩一遍.如果不是亲身体验,我能乱说? 之前有详细写过如何安装linu ...

  6. 吃鸡游戏计算机配置,畅玩主流游戏吃鸡LOL组装电脑配置清单

    上个月intel发布了十代系列处理器,十代酷睿系列处理器的核心线程规格整体提升,其中i3 10100的规格来到了4核8线程(九代i3是4核4线程).下面就为大家带来一套i3 10100的电脑配置清单, ...

  7. 荣耀畅玩4x android 6,安卓首款全网通手机 荣耀畅玩4X综合评测

    1荣耀畅玩4X综合评测 [天极网手机频道]10月28日,首款安卓全网通新品--荣耀畅玩4X的发布会如期举行,华为荣耀终于在官网正式公布了"4号特工"的真实身份.与此前猜测大致相同, ...

  8. Java自此丰富多彩--五子棋项目总结

    历经数天的艰苦奋战,五子棋的项目终于拿下了. 我觉得,这里面的精华是平常我们所不注意的东西. 最开始我是有5个文件来实现的,但是我发现自己不善于整合(至少是现在), 所以:我把一开始的判断输赢类和后来 ...

  9. ov5640帧率配置_一文看懂赛博朋克2077中低配置的设置方法和能畅玩的电脑有哪些?...

    <赛博朋克2077>是12月10号上线的网络游戏.一句话,这款游戏确实很火 很火 很火.但是由于这款游戏对电脑的配置要求很高.像GTX1650.GTX1650Ti这样的显卡也只能算入门级的 ...

最新文章

  1. HDU2896(AC自动机模版题)
  2. 以CSGO为例 分析不同网络延时下FPS游戏同步的实现
  3. plesk 打不开php,Laravel在Plesk背后,遇到PHP版本困难
  4. FreeBSD 创始人-Jordan Hubbard
  5. Keras笔记(一)关于Keras模型
  6. WPF 基础控件之Window样式
  7. mysql自增id用完了_MySQL表自增id用完了该怎么办?
  8. 前端学习(2830):条件渲染
  9. 【技术博客】基于JsPlumb和JQuery-UI的流程图的保存和再生成
  10. Docker创建一个镜像
  11. Docker安装Zookeeper并进行操作
  12. 怎样更改itunes备份位置_iphone备份太大,严重挤占C盘空间,怎么把备份放在其他的硬盘?...
  13. Netflix Ribbon 负载均衡 概述 与 基本使用
  14. cocos2dx-3.0(8)------Label、LabelTTF、LabelAtlas、LabelBMFont使用之法
  15. java 项目启动后页面乱码_java生成的Html打开后展示乱码
  16. 用matlab解系统框图,控制系统框图(请教matlab中怎么画控制系统流程框图?)
  17. Java 敏感词过滤工具类及文本
  18. LOMO效果的PS Action
  19. [R]_使用mutate_all(),mutate_at(),mutate_if()操纵数据框的列
  20. 每日新闻:麦肯锡:未来10年 人工智能为全球GDP贡献1.2%增长;工信部下发第19批CDN、云服务牌照...

热门文章

  1. MPAndroidChart的详细使用——BarChart叠状条形图(四)
  2. clion之Clion License Activation破解
  3. Java SimpleDateFormat用法
  4. 重启mysql的cmd命令
  5. Xshell连接ubuntu后vi编辑器中数字小键盘乱码
  6. !!!---1588|Sum of All Odd Length Subarrays(新)
  7. cmake时添加-fPIC编译选项
  8. 【金融风险管理】python进行股票标准差、方差、均值、离散系数、标准化、对数收益率
  9. 自动生成Changelog
  10. 学生管理系统(大数据实验室)