⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gobangplayer.cpp

📁 用C++环境编写的五子棋小游戏
💻 CPP
字号:
//gobangPlayer.cpp

#include "gobangPlayer.h"
#include "chessboard.h"
#include <cctype>
chessboard gobangPlayer::m_chessboard;
unsigned int gobangPlayer::count=0;
// static 类型, 独立初始化
gobangPlayer::gobangPlayer() 
{
    m_chessmanColor=black;
    m_Move=point(0,0);
}

gobangPlayer::~gobangPlayer()
{
}

void gobangPlayer::setChessmanColor( states color)
{
    m_chessmanColor=color;
}

void gobangPlayer::setMove(char x, char y)
{
    isdigit(x) ? m_Move.x=x-'0'-1 : m_Move.x=toupper(x)-'A'+9;
    isdigit(y) ? m_Move.y=y-'0'-1 : m_Move.y=toupper(y)-'A'+9;
}
//   要是char x 为'0'-'9', x-'0'返回字符相对应的int 类型的数字, 因为在ASCII码表中
//    连续排列, C\C++中数组坐标从0开始, 所以要减1.
//    不是'0'-'9',要是输入合法,就一定是字母, 先返回对应的大写值,这样就可以同时
//   支持大小写输入 减去'A',因为'A'就代表10,再考虑数组从0开始, 
//    应该是 toupper(x)-'A'+10-1 就是toupper(x)-'A'+9



void gobangPlayer::getMove(char &x, char &y)
{
    m_Move.x<9 ? x=('1'+m_Move.x) : x=('A'+m_Move.x-9);
    m_Move.y<9 ? y=('1'+m_Move.y) : y=('A'+m_Move.y-9);
}
//   上面对应的逆过程    

bool gobangPlayer::checkMove()
{
    bool result=true;
    
    if( m_Move.x<0 || m_Move.x>size )
        result=false;
    if( m_Move.y<0 || m_Move.y>size )
        result=false;
    // 输入的棋步不在棋盘上
    if( m_chessboard.getGridState(m_Move)!=blank )
        result=false;
   //    虽然在棋盘上,不过棋盘上已经有了棋子     

    if( result==true )
        m_chessboard.setGridState(m_Move,m_chessmanColor);
    //    要是输入的棋步合法,就更改棋盘的状态,表示在上面下棋子
  
    return result;
}

void gobangPlayer::autoMove()
{
    m_chessboard.updateMarks(m_chessmanColor);
    m_chessboard.getMaxGridMark(m_Move);
    m_chessboard.setGridState(m_Move,m_chessmanColor);
   //    电脑自动下棋: 先更新整个棋盘的格子的分数,找到分数最高的,
    //                  接着在上面下子
    
}

bool gobangPlayer::isWin()
{
    int count=0;
    int i,j,k;
    for( k=1; k<=8; k++ )    // 有八个方向需要扫描
                            // 上, 下, 右, 左, 左斜下, 右斜上, 右斜下, 左斜上
                             
    {
        i=m_Move.x;        
        j=m_Move.y;        //   取得刚下棋步的坐标, 因为是不是胜利, 总是和刚下的棋
                        //   有关
                         
        if( k%2==1)
            count=0;    
        //    扫描的时候要考虑向左,和向右的情况, 比如向左知道有2个相同
       //    向右又有两个相同的棋子, 向左向有在同一直线上,加上
        //   刚下的, 就有五个棋子, 5子连线就胜了.
        //    count是用来表示同一直线上相连棋子的数目的, count==4时,就赢了
       //    刚才已经说过, 假如先向左扫描, 得到相连棋子的数目, 再向右扫描时,
        //    在左边的棋子还会起作用, 因为他们是在同一直线上的
        //    跟着,扫描另外一条直线的时候, count就应该重新为0, 比如说, 横的直线
        //    不会影响竖的直线. 一条直线扫描两次. 所以k%2==1, count=0
        //
        while( 1 )
        {
            switch( k )
            {
            case 1:        i++; break;            //    向上     
            case 2:        i--; break;            //    向下     
            case 3:        j++; break;            //    向右     
            case 4:        j--; break;            //    向左     
            case 5:        i--; j--; break;        //   左斜上     
            case 6:        i++; j++; break;        //    右斜下    
            case 7:        i++; j--; break;        //    左斜上     
            case 8:        i--; j++; break;
            }
           //   case 语句的顺序不能顺便掉转, 一定要保证同一直线连续扫描两次    
            if( i>=0 && i<size && j>=0 && j<size )
            {
                if( m_chessboard.getGridState(point(i,j))==m_chessmanColor )
                    count++;
                else break;
            }
            else break;        
           //    已经超出棋盘范围, 跳出while循环,扫描下一个方向     
            if( count==4 )
                return true;    // count==4, 就表示胜利     
        }
    }
    return false;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -