You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
4.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "AI.h"
void AI::init(Chess* chess)
{
this->chess = chess;
int size = chess->getGradeSize();
for (int i = 0; i < size; i++)
{
vector<int> row;
for (int j = 0; j < size; j++)
{
row.push_back(0);
}
scoreMap.push_back(row);
}
}
void AI::go()
{
ChessPos pos = think();
Sleep(1000);//假装思考
chess->chessDown(&pos, CHESS_WHITE);
}
void AI::calculateScore()
{
int personNum = 0; //棋手方(黑棋)多少个连续的棋子
int aiNum = 0; //AI方白棋连续有多少个连续的棋子
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;
personNum = 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) {
personNum++;
}
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) {
personNum++;
}
else if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == 0) {
emptyNum++;
break;
}
else {
break;
}
}
if (personNum == 1) {
scoreMap[row][col] += 10;
}
else if (personNum == 2) {
if (emptyNum == 1) {
scoreMap[row][col] += 30;
}
else if (emptyNum == 2) {
scoreMap[row][col] += 40;
}
}
else if (personNum == 3) {
if (emptyNum == 1) {
scoreMap[row][col] = 60;
}
else if (emptyNum == 2) {
scoreMap[row][col] = 5000;
}
}
else if (personNum == 4) {
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;
}
else if (aiNum == 1) {
scoreMap[row][col] += 10;
}
else if (aiNum == 2) {
if (emptyNum == 1) {
scoreMap[row][col] += 25;
}
else if (emptyNum == 2) {
scoreMap[row][col] += 50;
}
}
else if (aiNum == 3) {
if (emptyNum == 1) {
scoreMap[row][col] += 55;
}
else if (emptyNum == 2) {
scoreMap[row][col] += 10000;
}
}
else if (aiNum >= 4) {
scoreMap[row][col] += 30000;
}
}
}
}
}
}
ChessPos AI::think()
{
calculateScore();
vector<ChessPos> maxPoints;
int maxScore = 0;
int size = chess->getGradeSize();
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];
}