01 - brief introduction of man-machine game algorithm
previously, we introduced in detail the packaging of chessboard class, the packaging of chess sub class and the implementation of chess walking algorithm of various types of chess pieces. With the foreshadowing in front, we can take the first step of computer intelligent chess.
the computer should realize the man-machine game, and the chess game is divided into three steps:
(1) the computer obtains all accessible paths of the chess pieces;
(2) calculate the optimal path to the computer from all the paths that can be taken by the chess pieces;
(3) computer realizes chess.
02 - relevant members and methods
before writing code, look in advance to see what classes and members have been added. Create a new QVector container to save the attribute information of chess pieces and facilitate the calculation of the optimal path to the computer. The specific contents are as follows:
#ifndef STEP_H #define STEP_H #include <QObject> class Step : public QObject { Q_OBJECT public: int moveID; //ID of walking chess piece int killID; //Kill the ID of the chess piece int rowFrom; //Starting line coordinates int colFrom; //Starting column coordinates int rowTo; //Target line coordinates int colTo; //Target position column coordinates signals: public slots: }; #endif // STEP_H
also in chessarea H add computer to realize man-machine game and chess related methods and slot functions:
// Get all chess paths and store them in steps void getAllPossibleMove(QVector<Step *>& steps); void fakeMove(Step* step); // The chess piece pretended to take a step void unfakeMove(Step* step); // The pawn pretended to move back Step* getBestMove(); // Get the best chess path int calcScore(); // Assessment situation score private slots: void computerMove(bool run); // Computer chess //Implement signal and slot () on widget constructor connect(chessarea, SIGNAL(sendCompute(bool)), chessarea, SLOT(computerMove(bool)));
03 - get the path that computer chess pieces can take
traverse all computer (black) pieces in front, traverse all positions of the piece on the chessboard, input each position information into the canMove function, and the "Step" returned by the canMove function returns true is stored in the container Step.
/** * * @brief :Get the best mobile path of the computer * * @param : nothing * * @return: The attribute of the optimal chess piece information (original coordinate, target coordinate, ID, target ID) * **/ Step *ChessArea::getBestMove() { QVector<Step *> steps; // Get all chess paths of the computer getAllPossibleMove(steps); // Initialization specific gravity int maxScore = -100000; Step* ret; for(QVector<Step*>::iterator it=steps.begin(); it!=steps.end(); ++it) { Step* step= *it; //Try walking fakeMove(step); //Assessment situation score int score = calcScore(); //Come back again unfakeMove(step); //Take the highest score if(score > maxScore) { maxScore = score; ret = step; } } return ret; }
about fakeMove function and unfakeMove function
/** * * @brief : The chess piece pretends to move and takes a step * * @param : steps : Save the attributes of the moving chess piece information (original coordinates, target coordinates, ID, target ID) * * @return: nothing * **/ void ChessArea::fakeMove(Step *step) { //Kill the chess pieces killStone(step->killID); if(step->killID != -1) { myChess[step->killID].row = -1; myChess[step->killID].col = -1; } myChess[step->moveID].row = step->rowTo; myChess[step->moveID].col = step->colTo; } /** * * @brief : The chess piece pretends to move back one step * * @param : steps : Save the attributes of the moving chess piece information (original coordinates, target coordinates, ID, target ID) * * @return: nothing * **/ void ChessArea::unfakeMove(Step *step) { //Resurrection chess piece reliveStone(step->killID); if(step->killID != -1) { myChess[step->killID].row = step->rowTo; myChess[step->killID].col = step->colTo; } myChess[step->moveID].row = step->rowFrom; myChess[step->moveID].col = step->colFrom; }
chess game scoring algorithm: first assign weights to all chess pieces. According to the importance of chess pieces, they will be the most important chess pieces. Therefore, the weight is the highest and set to 1500; Next to the car, set it to 100; Horse and gun are the second, set to 50; Soldiers are set as 20, and scholars and phase are the least important, set as 10. Traverse all the pieces of the Red Square and accumulate the weight of the living pieces of the Red Square to a total score; Traverse all the pieces on the black side and add up the weight of the living pieces on the black side to a total score. The default computer is black, so the returned situation score should be calculated from the perspective of black, and return the total score of black chess - the total score of red flag. The following is the function implementation:
/** * * @brief : Get the score of the chess game * * @param : nothing * * @return: nothing * **/ int ChessArea::calcScore() { //Enumerated cars = 0 horses = 1 gun = 2 soldiers = 3 generals = 4 Shi = 5 phases = 6 static int chessScore[]={100, 80, 80, 20, 1500, 10, 10}; int redTotalScore = 0; int blackTotalScore = 0; //Calculate the total score of red chess for(int i=0; i<16; i++) { //If the piece is dead, skip accumulation if(myChess[i].isDead) continue; redTotalScore += chessScore[myChess[i].chessType]; } //Calculate the total score of black chess for(int i=16; i<32; i++) { //If the piece is dead, skip accumulation if(myChess[i].isDead) continue; blackTotalScore += chessScore[myChess[i].chessType]; } //Return the total score of black chess - the total score of red chess return blackTotalScore - redTotalScore; }
04 - computer chess
humans take the red flag and computers take the black chess. When the human walks the red flag, directly move the mouse to finish the chess piece, and then trigger the signal. It's the black side's turn to walk the chess piece. The computer calls getBestMove function to calculate the optimal path of walking the chess piece, and then obtains the optimal Step to move the chess piece directly.
/** * * @brief : Computer chess (slot function) * * @param : Boolean type, signaled by * * @return: nothing * **/ void ChessArea::computerMove(bool run) { if(run == false) { if(this->bRedTurn) return; else { Step* step = getBestMove(); // Move chess pieces moveChess(step->moveID, step->killID, step->rowTo, step->colTo); bRedTurn = true; // It's human's turn to play chess emit redTrueGo(bRedTurn); } } else { qDebug() << "computer move failed"; return; } }
05 - Summary
here, we can already realize the preliminary man-machine game, but at this time, the computer is not very smart. It can only "take one step and watch one step". In the next issue, we will explain the advanced version of man-machine game algorithm, so that the computer can "take one step and watch three steps" when playing chess.
- 01_ Introduction to developing chess games
- 02_ Drawing chess board
- 03_ Chess pieces placement
- 04_ Rules of chess - car, gun and player
- 05_ Rules of chess - elephant, horse, general and soldier
- 06_ Chess game rules
- 07_ The beginning of man-machine game algorithm
- 08_ Higher order algorithm of man-machine game
- 09_ Cross compiling and Porting Linux system