需求
基于wxWidgets实现一个五子棋游戏
功能
- 显示一个19*19线组成的围棋棋盘。
- 棋子只能落在线的交点上。
- 黑白子交替下棋。
- 当黑子或者白子连续五个子组成一条直线,则为胜利。
参考代码
#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); // 应用程序实例化
网友评论