diff --git a/AI.cpp b/AI.cpp new file mode 100644 index 0000000..a0dce57 --- /dev/null +++ b/AI.cpp @@ -0,0 +1,212 @@ +#include "AI.h" + + +void AI::init(Chess* chess) +{ + this->chess = chess; + int size = chess->getGradeSize(); + for (int i = 0; i < size; ++i) + { + vectorrow; + for (int j = 0; j < size; ++j) + { + row.push_back(0); + } + scoreMap.push_back(row); + } +} + +void AI::go() +{ + ChessPos pos = think(); + + //假。反应时间 + Sleep(1000); + + chess->ChessMove(&pos, CHESS_WHITE); +} + +void AI::calculateScore() +{ + int playerNum = 0; + int aiNum = 0; + int emptyNum = 0; + + for (int i = 0; i < scoreMap.size(); ++i) + for (int j = 0; j < scoreMap[i].size(); ++j) + scoreMap[i][j] = 0; + + int size = chess->getGradeSize(); + for (int row = 0; row < size; ++row) + for (int col = 0; col < size; ++col) + { + if(chess->getChessData(row,col)) + continue; + for (int y = -1; y <= 0; ++y) + { + for (int x = -1; x <= 1; ++x) + { + if (y == 0 && x == 0) + continue; + if (y == 0 && x != 1) + continue; + playerNum = 0; + aiNum = 0; + emptyNum = 0; + + //推测黑棋落子的棋形 + for (int i = 1; i <= 4; ++i) + { + int curRow = row + i * y; + int curCol = col + i * x; + + if (curRow >= 0 && curRow < size && curCol >= 0 && curCol < size && chess->getChessData(curRow, curCol) == 1) + playerNum++; + else if (curRow >= 0 && curRow < size && curCol >= 0 && curCol < size && chess->getChessData(curRow, curCol) == 0) + { + emptyNum++; + break; + } + else + break; + } + //反向 + for (int i = 1; i <= 4; ++i) + { + int curRow = row - i * y; + int curCol = col - i * x; + if (curRow >= 0 && curRow < size && curCol >= 0 && curCol < size && chess->getChessData(curRow, curCol) == 1) + playerNum++; + else if (curRow >= 0 && curRow < size && curCol >= 0 && curCol < size && chess->getChessData(curRow, curCol) == 0) + { + emptyNum++; + break; + } + else + break; + } + + //评估 + if (playerNum == 1) + //连2 + scoreMap[row][col] += 10; + else if (playerNum == 2) + { + //死3 + if (emptyNum == 1) + scoreMap[row][col] += 30; + //活3 + else if (emptyNum == 2) + scoreMap[row][col] += 40; + } + else if(playerNum == 3) + { + //死4 + if(emptyNum == 1) + scoreMap[row][col] += 60; + //活4 + else if (emptyNum == 2) + scoreMap[row][col] += 2000; + } + else if (playerNum == 4) + { + //连5 + scoreMap[row][col] += 20000; + } + + //推测白棋落子的棋形 + emptyNum = 0; + for (int i = 1; i <= 4; ++i) + { + int curRow = row + i * y; + int curCol = col + i * x; + + if (curRow >= 0 && curRow < size && curCol >= 0 && curCol < size && chess->getChessData(curRow, curCol) == -1) + aiNum++; + else if (curRow >= 0 && curRow < size && curCol >= 0 && curCol < size && chess->getChessData(curRow, curCol) == 0) + { + emptyNum++; + break; + } + else + break; + } + //反向 + for (int i = 1; i <= 4; ++i) + { + int curRow = row - i * y; + int curCol = col - i * x; + if (curRow >= 0 && curRow < size && curCol >= 0 && curCol < size && chess->getChessData(curRow, curCol) == -1) + aiNum++; + else if (curRow >= 0 && curRow < size && curCol >= 0 && curCol < size && chess->getChessData(curRow, curCol) == 0) + { + emptyNum++; + break; + } + else + break; + } + + //评估 + if (aiNum == 0) + scoreMap[row][col] += 5; + if (aiNum == 1) + //连2 + scoreMap[row][col] += 10; + else if (aiNum == 2) + { + //死3 + if (emptyNum == 1) + scoreMap[row][col] += 25; + //活3 + else if (emptyNum == 2) + scoreMap[row][col] += 50; + } + else if (aiNum == 3) + { + //死4 + if (emptyNum == 1) + scoreMap[row][col] += 55; + //活4 + else if (emptyNum == 2) + scoreMap[row][col] += 10000; + } + else if (aiNum >= 4) + { + //连5赢棋 + scoreMap[row][col] += 30000; + } + } + } + + } +} + +ChessPos AI::think() +{ + calculateScore(); + + vectormaxPoints; + int maxScore = 0; + int size = scoreMap.size(); + for (int row = 0; row < size; ++row) + { + for (int col = 0; col < size; ++col) + { + if (chess->getChessData(row, col) == 0) + { + if (scoreMap[row][col] > maxScore) + { + maxScore = scoreMap[row][col]; + maxPoints.clear(); + maxPoints.push_back(ChessPos(row, col)); + } + else if (scoreMap[row][col] == maxScore) + maxPoints.push_back(ChessPos(row,col)); + } + } + } + + int index = rand() % maxPoints.size(); + return maxPoints[index]; +}