美文网首页
案例:五子棋

案例:五子棋

作者: jdzhangxin | 来源:发表于2018-09-11 13:53 被阅读104次

    需求

    基于wxWidgets实现一个五子棋游戏

    功能

    1. 显示一个19*19线组成的围棋棋盘。
    2. 棋子只能落在线的交点上。
    3. 黑白子交替下棋。
    4. 当黑子或者白子连续五个子组成一条直线,则为胜利。

    参考代码

    #include <wx/wx.h>
    #include <cstdlib>
    #include <cmath>
     
    using namespace std;
     
    // 面板类
    class TestPanel:public wxPanel{
        enum ChessType{
            NO_CHESS,
            BLACK_CHESS,
            WHITE_CHESS
        };
    public:
        TestPanel(wxFrame* parent):wxPanel(parent),cell(20),broad(18*cell),curChessType(BLACK_CHESS),pos(-20,-20){
            // 绑定绘制事件
            Bind(wxEVT_PAINT,&TestPanel::OnPaint,this);
            // 绑定鼠标单机事件
            Bind(wxEVT_LEFT_DOWN,&TestPanel::OnLeftDown,this);
            Bind(wxEVT_MOTION,&TestPanel::OnMove,this);
            Clear();
        }
        wxPoint GetBroadPos(wxPoint const& pos){
            wxPoint temp = pos - vec;
            float fx = 1.0*temp.x/cell;
            float fy = 1.0*temp.y/cell;
                // 规则二:必须下在交点
            return wxPoint(round(fx),round(fy));
     
        }
        void Clear(){
            curChessType = BLACK_CHESS;
            pos = wxPoint(-20,-20);
            memset(record,NO_CHESS,19*19*sizeof(ChessType));
            Refresh();
        }
        void OnMove(wxMouseEvent& event){
            pos = event.GetPosition();
            Refresh();
        }
        void OnLeftDown(wxMouseEvent &event){
            wxPoint pos = GetBroadPos(event.GetPosition());
            // 规则一:必须下在棋盘上
            if(pos.x >= 0 && pos.x <=18 && pos.y >= 0 && pos.y <= 18){
                // 规则三:必须下在没有棋子的地方
                if(record[pos.x][pos.y] == NO_CHESS){
                     record[pos.x][pos.y] = curChessType;
                   // 规则四:黑白子交替下
                   curChessType = (curChessType == WHITE_CHESS?BLACK_CHESS:WHITE_CHESS);
                   Refresh();// 刷新
                }
            }
            if(Success(pos.x,pos.y)){
                if(curChessType == BLACK_CHESS){
                    wxMessageBox(wxT("White Chess Win"));
                }else{
                    wxMessageBox(wxT("Black Chess Win"));
                }
                int answer = wxMessageBox(wxT("Play Again?"),wxT("Tile"),wxYES_NO);
                if(wxYES == answer){
                    Clear();
                }
            }
        }
        bool Success(int x,int y){
            // 横向检测
            int count = 1;
            // 左向
            for(int i=1;i<5;i++){
                if(x-i<0)break;
                if(record[x][y] != record[x-i][y])break;
                count++;
            }
            if(5 == count)return true;
            for(int i=1;i<5;i++){
                if(x+i>18)break;
                if(record[x][y] != record[x+i][y])break;
                count++;
            }
            if(5 <= count)return true;
             
     
            // 纵向检测
            // 左斜向
            //
            return false;
        }
        // 事件处理函数
        void OnPaint(wxPaintEvent &event){
            // 绘制设备上下文
            wxPaintDC dc(this);
     
            wxSize size = GetClientSize();
             
            int left = (size.x - broad)/2;
            int top = (size.y - broad)/2;
            vec = wxPoint(left,top);
            // 行
            for(int i=0;i<19;i++){
                //dc.DrawLine(wxPoint(0,i*cell)+vec,wxPoint(18*cell,i*cell)+vec);
                dc.DrawLine(wxPoint(left,top+i*cell),wxPoint(left+18*cell,top+i*cell));
            }
            for(int i=0;i<19;i++){
                dc.DrawLine(wxPoint(i*cell,0)+vec,wxPoint(i*cell,18*cell)+vec);
            }
             
            for(int i=0;i<19;i++){
                for(int j=0;j<19;j++){
                    if(record[i][j] != 0){
                        DownChess(dc,i,j,record[i][j]);
                    }       
                }
            }
            if(curChessType == WHITE_CHESS){
                dc.SetBrush(*wxWHITE_BRUSH);
            }else{
                dc.SetBrush(*wxBLACK_BRUSH);
            }
            dc.DrawCircle(pos,cell/2);
        }
     
        void DownChess(wxPaintDC& dc,int x,int y,ChessType chessType){
            if(chessType == WHITE_CHESS){
                dc.SetBrush(*wxWHITE_BRUSH);
            }else{
                dc.SetBrush(*wxBLACK_BRUSH);
            }
            // dc.SetBrush(chessType == WHITE_CHESS?*wxWHITE_BRUSH:*wxBLACK_BRUSH);
            dc.DrawCircle(wxPoint(x*cell,y*cell)+vec,cell/2);
        }
    private:
        wxPoint pos;
        const int cell;
        const int broad;
        wxPoint vec;
        ChessType record[19][19];
        ChessType curChessType;
    };
     
    // 框架类
    class TestFrame:public wxFrame{
    public:
        TestFrame(wxString const&title):wxFrame(NULL,wxID_ANY,title){
            // 创建面板对象
            wxPanel* pPanel = new TestPanel(this);
        }
    };
     
    // 应用程序类
    class FrameApp:public wxApp{
        // 重写初始化函数
        bool OnInit(){
            // 创建框架
            wxFrame* pFrame = new TestFrame(wxT("MyFrame"));
            // 显示框架
            pFrame->Show(true);
            return true;
        }
    };
     
    IMPLEMENT_APP(FrameApp); // 应用程序实例化
    

    相关文章

      网友评论

          本文标题:案例:五子棋

          本文链接:https://www.haomeiwen.com/subject/xaqugftx.html