QQ录屏20220807164624
1.数据模型
构思好代码的数据,并实现相应的算法
#ifndef GAMEMODLE_H
#define GAMEMODLE_H
//五指棋模型
#include<vector>
//游戏类型
enum GameType{
MAN,//人人对战
AI,//人机对战
};
enum GameStatus{
PLAYING,//正在执行
WIN, //胜利
DEAD //
};
//棋盘尺寸
const int BOARD_GRAD_SZIE =15;//15 x 15;
const int MARGIN =30; //棋盘边缘空白
const int CHESS_RADIUS= 15;//棋子半径
const int MARK_SIZE =6; //落子标记边长
const int BLOCK_SIZE =40;//格子大小
const int POS_OFFSET =BLOCK_SIZE *0.4;//鼠标点击模糊距离上限
const int AI_THINK_TIME =100; //AI延迟的速度
class GameModel
{
public:
GameModel();
public:
//存储当前游戏棋盘和棋子的情况,空白为0,黑子为1,白子为-1
std::vector<std::vector<int>> gameMapVec;
//存储各个点的评分情况,作为AI下棋依据
std::vector<std::vector<int>> scoreMapVec;
//标识下下棋放,true:黑棋,false//AI白棋
bool playerFlag;
GameType gameType;//游戏模式
GameStatus gameStatus;//游戏状态
void startGame(GameType type);//开始游戏
void calculateScore();//计算评分
void actionByPerson(int row,int col);//人执行下棋
void actionByAI(int &clickRow, int &clickcol);//机器执行下棋
void updateGameMap(int row,int col);//每次落子更行游戏棋盘
bool isWin(int row,int col);//判断游戏是否胜利
bool isDeadGame();//判断是否和棋
};
#endif // GAMEMODLE_H
绘制棋盘
QPainter p1(this);
p1.setRenderHint(QPainter::Antialiasing);//设置抗锯齿
//画棋盘
for(int i=0;i<BOARD_GRAD_SZIE+1;i++)
{
//C从左到右画(i+1)第一条竖线
p1.drawLine(
MARGIN+BLOCK_SIZE*i,MARGIN,
MARGIN+BLOCK_SIZE*i,size().height()-MARGIN);
//从上到下,第(i+1)条横线
p1.drawLine(
MARGIN,MARGIN+BLOCK_SIZE*i,
width()-MARGIN,MARGIN+BLOCK_SIZE*i);
}
//实现模糊标记
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
//通过鼠标的移动确定落子标记
int x = event->x();
int y =event->y();
//棋子边缘不能落子
if(x >= MARGIN+BLOCK_SIZE/2&&
x<size().width()-MARGIN-BLOCK_SIZE/2&&
y>=MARGIN+BLOCK_SIZE/2&&
y<this->height()-MARGIN-BLOCK_SIZE/2)
{
//获得最近的左上角的点 坐标减去边界除方格宽度
int col =(x-MARGIN)/BLOCK_SIZE;//行
int row =(y-MARGIN)/BLOCK_SIZE;//列
int leftTopPosX=MARGIN+BLOCK_SIZE*col;
int leftTopPosY=MARGIN+BLOCK_SIZE*row;
//根据距离算出合适的点击位置,点击位置四周四个点,根据距离最近的
clickPosRow=-1;//行初始化
clickPosCol=-1;
int len=0;//鼠标点击与四个顶点距离
selectPos=false;
//确定一个误差在范围内的点,有且只有一个可以确定下来
//两直角边求斜边len左上角
len=sqrt((x-leftTopPosX)*(x-leftTopPosX)
+(y-leftTopPosY)*(y-leftTopPosY));
if(len<POS_OFFSET)
{
clickPosRow=row;
clickPosCol=col;
//判断棋盘有没有棋子,没有就下,标志位改变
if(game->gameMapVec[clickPosRow][clickPosCol]==0)
{
selectPos=true;
}
}
//len 右上角距离
len=sqrt( (