#include <utility>
#include <stdlib.h>
#include <time.h>
#include "GameModel.h"
GameModel::GameModel()
{
}
void GameModel::startGame(GameType type)
{
gameType = type;
// 初始棋盘
gameMapVec.clear();
for (int i = 0; i < kBoardSizeNum; i++)
{
std::vector<int> lineBoard;
for (int j = 0; j < kBoardSizeNum; j++)
lineBoard.push_back(0);
gameMapVec.push_back(lineBoard);
}
// 如果是AI模式,需要初始化评分数组
if (gameType == BOT)
{
scoreMapVec.clear();
for (int i = 0; i < kBoardSizeNum; i++)
{
std::vector<int> lineScores;
for (int j = 0; j < kBoardSizeNum; j++)
lineScores.push_back(0);
scoreMapVec.push_back(lineScores);
}
}
// 己方下为true,对方下位false
playerFlag = true;
}
void GameModel::updateGameMap(int row, int col)
{
if (playerFlag)
gameMapVec[row][col] = 1;
else
gameMapVec[row][col] = -1;
// 换手
playerFlag = !playerFlag;
}
void GameModel::actionByPerson(int row, int col)
{
updateGameMap(row, col);
}
void GameModel::actionByAI(int &clickRow, int &clickCol)
{
// 计算评分
calculateScore();
// 从评分中找出最大分数的位置
int maxScore = 0;
std::vector<std::pair<int, int>> maxPoints;
for (int row = 1; row < kBoardSizeNum; row++)
for (int col = 1; col < kBoardSizeNum; col++)
{
// 前提是这个坐标是空的
if (gameMapVec[row][col] == 0)
{
if (scoreMapVec[row][col] > maxScore) // 找最大的数和坐标
{
maxPoints.clear();
maxScore = scoreMapVec[row][col];
maxPoints.push_back(std::make_pair(row, col));
}
else if (scoreMapVec[row][col] == maxScore) // 如果有多个最大的数,都存起来
maxPoints.push_back(std::make_pair(row, col));
}
}
// 随机落子,如果有多个点的话
srand((unsigned)time(0));
int index = rand() % maxPoints.size();
std::pair<int, int> pointPair = maxPoints.at(index);
clickRow = pointPair.first; // 记录落子点
clickCol = pointPair.second;
updateGameMap(clickRow, clickCol);
}
// 最关键的计算评分函数
void GameModel::calculateScore()
{
// 统计玩家或者电脑连成的子
int personNum = 0; // 玩家连成子的个数
int botNum = 0; // AI连成子的个数
int emptyNum = 0; // 各方向空白位的个数
// 清空评分数组
scoreMapVec.clear();
for (int i = 0; i < kBoardSizeNum; i++)
{
std::vector<int> lineScores;
for (int j = 0; j < kBoardSizeNum; j++)
lineScores.push_back(0);
scoreMapVec.push_back(lineScores);
}
// 计分(此处是完全遍历,其实可以用bfs或者dfs加减枝降低复杂度,通过调整权重值,调整AI智能程度以及攻守风格)
for (int row = 0; row < kBoardSizeNum; row++)
for (int col = 0; col < kBoardSizeNum; col++)
{
// 空白点就算
if (row > 0 && col > 0 &&
gameMapVec[row][col] == 0)
{
// 遍历周围八个方向
for (int y = -1; y <= 1; y++)
for (int x = -1; x <= 1; x++)
{
// 重置
personNum = 0;
botNum = 0;
emptyNum = 0;
// 原坐标不算
if (!(y == 0 && x == 0))
{
// 每个方向延伸4个子
// 对玩家白子评分(正反两个方向)
for (int i = 1; i <= 4; i++)
{
if (row + i * y > 0 && row + i * y < kBoardSizeNum &&
col + i * x > 0 && col + i * x < kBoardSizeNum &&
gameMapVec[row + i * y][col + i * x] == 1) // 玩家的子
{
personNum++;
}
else if (row + i * y > 0 && row + i * y < kBoardSizeNum &&
col + i * x > 0 && col + i * x < kBoardSizeNum &&
gameMapVec[row + i * y][col + i * x] == 0) // 空白位
{
emptyNum++;
break;
}
else // 出边界
break;
}
for (int i = 1; i <= 4; i++)
{
if (row - i * y > 0 && row - i * y < kBoardSizeNum &&
col - i * x > 0 && col - i * x < kBoardSizeNum &&
gameMapVec[row - i * y][col - i * x] == 1) // 玩家的子
{
personNum++;
}
else if (row - i * y > 0 && row - i * y < kBoardSizeNum &&
col - i * x > 0 && col - i * x < kBoardSizeNum &&
gameMapVec[row - i * y][col - i * x] == 0) // 空白位
{
emptyNum++;
break;
}
else // 出边界
break;
}
if (personNum == 1) // 杀二
scoreMapVec[row][col] += 10;
else if (personNum == 2) // 杀三
{
if (emptyNum == 1)
scoreMapVec[row][col] += 30;
else if (emptyNum == 2)
scoreMapVec[row][col] += 40;
}
else if (personNum == 3) // 杀四
{
// 量变空位不一样,优先级不一样
if (emptyNum == 1)
scoreMapVec[row][col] += 60;
else if (emptyNum == 2)
scoreMapVec[row][col] += 110;
}
else if (personNum == 4) // 杀五
scoreMapVec[row][col] += 10100;
// 进行一次清空
emptyNum = 0;
// 对AI黑子评分
for (int i = 1; i <= 4; i++)
{
if (row + i * y > 0 && row + i * y < kBoardSizeNum &&
col + i * x > 0 && col + i * x < kBoardSizeNum &&
gameMapVec[row + i * y][col + i * x] == 1) // 玩家的子
{
botNum++;
}
else if (row + i * y > 0 && row + i * y < kBoardSizeNum &&
col + i * x > 0 && col + i * x < kBoardSizeNum &&
gameMapVec[row +i * y][col + i * x] == 0) // 空白位
基于QT设计人工智能五子棋游戏,包括AI模式对战和双人模式对战
版权申诉
5星 · 超过95%的资源 96 浏览量
2023-04-11
09:13:32
上传
评论
收藏 100KB ZIP 举报
不脱发的程序猿
- 粉丝: 24w+
- 资源: 5773