项目创建环境: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; }