基于MFC的五子棋应用(二)

基于MFC的五子棋应用(二)

书接上文,上回讲到五子棋MFC界面及资源视图 点这里

这回来讲一讲落子的实现和胜负的判断

判断胜负:

  通过一个over()函数进行实现,落子后判断游戏是否结束,若游戏结束则跳出对话框宣布胜利方,否则变换光标棋子,并转为对方落子

思路:落子位置为中心,检查各个方向上的连续五个棋子是否同色,是则结束并重新开始。五子棋数组赋值为1和-1 相连五子的和的绝对值 = 5则相连

  这里将白子和黑子用1、-1表示最主要的目的是为了实现人机对战时,计算机算法的实现(在这里先埋个伏笔)
  over()函数具体代码如下:
void CWuZiQiView::over(CPoint point)
{
    //获取鼠标指向数组位置
    int x=(point.x-30)/20;
    int y=(point.y-30)/20;
    //计算开始判断的坐标 xx,yy
    int xx,yy;
    if(x<4)
        xx=0;
    else
        xx=x-4;
    if(y<4)
        yy=0;
    else
        yy=y-4;

    int i,j,k;


    //横向判断
    for(i=xx;i<15;i++)
    { 
        k=0;
        for(j=i;j<i+5;j++)
        {
            k=k+wzq[j][y];      
            //五个都是白棋
            if(k==5)
            {
                AfxMessageBox("白棋胜-");
                //
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是基于MFC五子棋存盘读盘实现: 1. 创建MFC工程,将以下代码添加到stdafx.h文件中: ```cpp #include <fstream> using namespace std; #define BLACK 1 #define WHITE 2 const int MAX_LINE = 15; class Chessboard { private: int board[MAX_LINE][MAX_LINE] = { 0 }; // 棋盘,0表示无棋子,1表示黑棋,2表示白棋 int turn = BLACK; // 轮到哪一方下棋,1表示黑棋,2表示白棋 int winner = 0; // 获胜方,0表示未分胜负,1表示黑棋获胜,2表示白棋获胜 public: Chessboard() {} // 判断是否越界 bool checkBound(int x, int y) { return x >= 0 && x < MAX_LINE && y >= 0 && y < MAX_LINE; } // 判断是否可以下棋 bool isLegal(int x, int y) { return checkBound(x, y) && board[x][y] == 0; } // 下棋 bool putChess(int x, int y) { if (!isLegal(x, y)) return false; board[x][y] = turn; turn = 3 - turn; // 切换到对方下棋 return true; } // 判断是否有五子连珠 bool checkWinner(int x, int y) { int dx[4] = { 1, 1, 0, -1 }; int dy[4] = { 0, 1, 1, 1 }; int cnt; for (int k = 0; k < 4; k++) { cnt = 1; for (int i = x + dx[k], j = y + dy[k]; checkBound(i, j) && board[i][j] == board[x][y]; i += dx[k], j += dy[k]) { cnt++; } for (int i = x - dx[k], j = y - dy[k]; checkBound(i, j) && board[i][j] == board[x][y]; i -= dx[k], j -= dy[k]) { cnt++; } if (cnt >= 5) { winner = board[x][y]; return true; } } return false; } // 打印棋盘 void printBoard(CDC* pDC) { pDC->TextOut(20, 20, " "); for (int i = 0; i < MAX_LINE; i++) { CString str; str.Format("%d ", i); pDC->TextOut(20 + i * 20, 20, str); } for (int i = 0; i < MAX_LINE; i++) { CString str; str.Format("%d ", i); pDC->TextOut(20, 40 + i * 20, str); for (int j = 0; j < MAX_LINE; j++) { if (board[i][j] == 0) pDC->TextOut(20 + j * 20, 40 + i * 20, "+ "); else if (board[i][j] == BLACK) pDC->TextOut(20 + j * 20, 40 + i * 20, "X "); else pDC->TextOut(20 + j * 20, 40 + i * 20, "O "); } } } // 存盘 void saveGame(const char* filename) { ofstream fout(filename); fout << turn << endl; fout << winner << endl; for (int i = 0; i < MAX_LINE; i++) { for (int j = 0; j < MAX_LINE; j++) { fout << board[i][j] << " "; } fout << endl; } fout.close(); } // 读盘 bool loadGame(const char* filename) { ifstream fin(filename); if (!fin) return false; fin >> turn >> winner; for (int i = 0; i < MAX_LINE; i++) { for (int j = 0; j < MAX_LINE; j++) { fin >> board[i][j]; } } fin.close(); return true; } }; ``` 2. 在对话框上添加一个按钮和一个编辑框,按钮用于存盘,编辑框用于输入/显示文件名。 3. 在按钮的点击事件中添加以下代码: ```cpp void CMyDlg::OnBnClickedButtonSave() { CString filename; m_editFileName.GetWindowText(filename); if (filename.IsEmpty()) { AfxMessageBox("请输入文件名!"); return; } Chessboard chessboard; chessboard.saveGame(filename); AfxMessageBox("存盘成功!"); } ``` 4. 在对话框的OnInitDialog函数中添加以下代码: ```cpp void CMyDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDIT_FILENAME, m_editFileName); } BOOL CMyDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: 在此添加额外的初始化 m_editFileName.SetWindowText("game.txt"); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } ``` 5. 在对话框上添加一个菜单项,用于读盘,添加以下代码: ```cpp void CMyDlg::OnFileLoad() { CString filename; m_editFileName.GetWindowText(filename); if (filename.IsEmpty()) { AfxMessageBox("请输入文件名!"); return; } Chessboard chessboard; if (chessboard.loadGame(filename)) { m_chessboard = chessboard; m_chessboard.printBoard(GetDC()); AfxMessageBox("读盘成功!"); } else { AfxMessageBox("读盘失败!"); } } ``` 6. 在资源文件中添加菜单项,并在消息映射中添加以下代码: ```cpp BEGIN_MESSAGE_MAP(CMyDlg, CDialogEx) ON_COMMAND(ID_FILE_LOAD, &CMyDlg::OnFileLoad) END_MESSAGE_MAP() ``` 7. 在对话框类中添加一个私有成员变量m_chessboard,用于存储当前的棋盘状态。 ```cpp class CMyDlg : public CDialogEx { private: Chessboard m_chessboard; // ... }; ``` 8. 在对话框的OnPaint函数中添加以下代码: ```cpp void CMyDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 // 不为绘图消息调用 CDialogEx::OnPaint() m_chessboard.printBoard(&dc); } ``` 9. 编译并运行程序,点击存盘按钮可以将当前的棋盘状态存储到文件中,点击读盘菜单项可以从文件中读取之前存储的棋盘状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值