五子棋大战

本文介绍了五子棋游戏的实现过程,包括数据模型的设计、棋盘绘制、模糊标记技术的应用,以及重点讲解了AI算法的实现。AI通过评估棋子八个方向的得分,选取最优策略进行下棋。
摘要由CSDN通过智能技术生成

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( (x-(leftTopPosX+BLOCK_SIZE)) *(x-(leftTopPosX+BLOCK_SIZE))
                      +(y-
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值