棋类对战小游戏(VS2012 MFC基于对话框)

本文介绍了一款名为“二打一棋”的游戏开发过程,包括需求分析、设计思路、操作步骤等内容。游戏实现了移动棋子、吃掉棋子等功能,并详细展示了如何使用MFC环境进行开发。

1需求分析

二打一棋用户需要的功能如下:

1)移动棋子:玩家通过鼠标点击能够实现棋子的移动,同时保证每次只能移动一格,且只能移动到未被占领的格子上。

2)吃掉棋子:同一条线上的己方两个棋子可以吃掉对方的一个棋子,让对方棋子消失。

3)棋子闪烁:点击己方棋子,棋子闪烁,同时保证己方回合内点击对方棋子,对方棋子不闪烁。

4)重新开始:游戏重新开始。

5)黑棋先行:黑棋优先移动。

6)红棋先行:红棋优先移动。

7)退出游戏:退出二打一棋。

2设计思路

2.1总体思路

根据游戏需求,需要利用MFC环境定义一个对话框类,提供程序的初始界面,其中包括重新开始按钮、黑棋先行按钮、红棋先行按钮、退出游戏按钮钮。同时游戏用户对棋盘的相关操作还要通过TVSODlg类来实现。

2.2面向对象技术的应用

项目中主要的类:TVSODlg

TVSODlg类:实现棋盘画面绘制,对棋子进行操作等相关作用。

继承:系统中的对话框基类CDialogEx

成员变量和成员函数如下:

void Hoxiaoyuan(inti,int j) :绘制/红色小圆

void Hexiaoyuan(inti,int j) :绘制黑色小圆

void dayuan(int i,int j):绘制大圆

void youxiao(CPoint q) :确定点击的有效位置

void beijing(CDC* pDC) :绘制棋盘背景

void qizhi() :初始棋子放置

void tiaojian(int i,intj) :棋子消失(胜负)条件判断

int pointvalue[7][6] :点初始值为0,红棋标记为1,黑棋标记为2

CPoint q :保存点信息

int p,n,c,d p=1,黑棋移动,p=2,红棋移动;n=0点未被选定,n=1,点已选定,cd标记选定的点

int pblack,pred :保存红棋和黑棋个数,初始个数均为6

int k :判断棋子是否需要初始化     int i,j

CBitmap beijingtu :插入背景图

afx_msg void OnLButtonDown(UINTnFlags, CPoint point) :鼠标左键点击

afx_msg voidOnTimer(UINT_PTR nIDEvent) :计时器函数

afx_msg void OnBnClickedButton1():重新开始

afx_msg voidOnBnClickedButton2() :黑棋先行

afx_msg voidOnBnClickedButton3() :红棋先行

afx_msg voidOnBnClickedButton4() :退出游戏

3操作步骤

新建基于对话框的MFC应用程序项目TVSO

3.1二打一棋对话框设计

从控件列表中选择按钮控件放于对话框上,修改按钮控件的属性,设计结果如下。

3.2棋盘绘制

通过调用绘图相关函数画出如下所示棋盘界面:相关函数代码在beijing(pDC)中实现。

3.3棋子初始化绘制

⑴用二维数组将图中相关点的信息保存POINT pointt[7][6]

⑵通过调用绘图相关函数画出下图所示棋子界面,并对相关点做标记:相关代码在void CTVSODlg ::qizhi()

3.4鼠标左击

⑴为TVSODlg类添加消息处理函数OnLButtonDown

OnLButtonDown函数中,需调用以下函数:

youxiao(CPoint q):确定点击的有效位置

dayuan(c,d):绘制大圆

Hexiaoyuan(i,j);:绘制黑色小圆

Hoxiaoyuan(i,j):绘制红色小圆

tiaojian(i,j):胜负条件判断

hongheiqi():右上角红黑棋显示

⑶棋子移动的原理:即是绘制新圆覆盖掉原来的圆,同时修改相关标记。

 

3.5棋子闪烁

⑴为TVSODlg类添加消息处理函数OnTimer

⑵在绘制棋子函数中添加SetTimer函数。

3.6添加背景图

⑴将.bmp图片文件放置在项目res文件夹下。

⑵在资源视图中导入.bmp格式图片文件。


⑶为其添加相关函数代码,该函数代码在void CTVSODlg::OnPaint()函数中。

3.7在对话框中显示相关内容。

如果要显示背景、棋子、背景图等,则需要在void CTVSODlg::OnPaint()函数中调用。

4运行效果

5源码

5.1对话框内容显示

该函数添加在void CTVSODlg::OnPaint()函数的else之中。

CPaintDC dc(this);    

CDC DC;                            //定义并创建一个内存设备环境

DC.CreateCompatibleDC(&dc);//创建兼容性DC 

DC.SelectObject(&beijingtu);//调用函数显示图片

dc.StretchBlt(0,0,800,800,&DC,0,0,800,800,SRCCOPY);

      

CDC *pDC=GetDC();

beijing(pDC);

ReleaseDC(pDC);

qizhi();

             

for(i=0;i<7;i++)//重新绘制

{

       for(j=0;j<6;j++)

       {

              if(pointvalue[i][j]==1)Hoxiaoyuan(i,j);

              elseif(pointvalue[i][j]==2) Hexiaoyuan(i,j);

       }

}

5.2左击鼠标响应相关函数

voidCTVSODlg::OnLButtonDown(UINT nFlags, CPoint point)

{

       i=-1;j=-1;

       q=point;

       youxiao(q);

       if(p==1)//黑棋移动

       {

              if(pointvalue[i][j]==2)

              { c=i;d=j;n=1;}//n=1时,表示选定该点   获取ij的值

              else if(pointvalue[i][j]==0&&n==1)

              {

                     if(abs(i-c)==1&&j==d||abs(j-d)==1&&i==c)//判断能够移动,则执行

                     {

                            pointvalue[c][d]=0;

                            pointvalue[i][j]=2;

                            dayuan(c,d);

                            Hexiaoyuan(i,j); //黑棋时

                            tiaojian(i,j);

                            p=2;n=0;c=-1;d=-1; hongheiqi();

                     }

              }

       }

       else if(p==2)

       {

              if(pointvalue[i][j]==1){c=i;d=j;n=1;}

              else if(pointvalue[i][j]==0&&n==1)

              {

                     if(abs(i-c)==1&&j==d||abs(j-d)==1&&i==c)//判断能够移动,则执行

                     {

                            pointvalue[c][d]=0;

                            pointvalue[i][j]=1;//红棋的值

                            dayuan(c,d);

                            Hoxiaoyuan(i,j);

                            tiaojian(i,j);

                            p=1;n=0;c=-1;d=-1; hongheiqi();

                     }

              }

       }

       CDialogEx::OnLButtonDown(nFlags, point);

}

 

 

5.3绘制圆相关函数

voidCTVSODlg::Hoxiaoyuan(int i,int j)  //绘制红色小圆

{

       CDC *pDC=GetDC();

       CPen redbian(PS_SOLID,3,RGB(255,0,0));

       pDC->SelectObject(redbian);

       CBrush red(RGB(255,0,0));

       pDC->SelectObject(red);

       pDC->Ellipse(pointt[i][j].x-10,pointt[i][j].y-10,pointt[i][j].x+10,pointt[i][j].y+10);

       ReleaseDC(pDC);

}

voidCTVSODlg::Hexiaoyuan(int i,int j)//绘制黑色小圆

{

       CDC *pDC=GetDC();

       CPen redbian(PS_SOLID,3,RGB(0,0,0));

       pDC->SelectObject(redbian);

       CBrush black(RGB(0,0,0));

       pDC->SelectObject(black);

       pDC->Ellipse(pointt[i][j].x-10,pointt[i][j].y-10,pointt[i][j].x+10,pointt[i][j].y+10);

       ReleaseDC(pDC);

}

voidCTVSODlg::dayuan(int i,int j)  //绘制大圆

{

       CDC *pDC=GetDC();

       CPen whitebian(PS_SOLID,1,RGB(255,255,255));

       pDC->SelectObject(whitebian);

       pDC->Ellipse(pointt[i][j].x-20,pointt[i][j].y-20,pointt[i][j].x+20,pointt[i][j].y+20);

       ReleaseDC(pDC);

}

5.4右上角红黑棋显示

voidCTVSODlg::hongheiqi()//右上角红黑棋显示

{

       CDC *pDC=GetDC();

       if(p==1)

       {

              CPen redbian(PS_DASH,3,RGB(0,0,0));

              pDC->SelectObject(redbian);

              CBrush black(RGB(0,0,0));

              pDC->SelectObject(black);

              pDC->Ellipse(350-10,30-10,350+10,30+10);

       }

       else if(p==2)

       {

              CPen redbian(PS_DASH,3,RGB(255,0,0));

              pDC->SelectObject(redbian);

              CBrush red(RGB(255,0,0));

              pDC->SelectObject(red);

              pDC->Ellipse(350-10,30-10,350+10,30+10);

       }

       ReleaseDC(pDC);

}

5.5有效点判断函数

voidCTVSODlg::youxiao(CPoint q)

{

       for(i=1;i<=5;i++)

       {

              for(j=1;j<=4;j++)

              {

if(q.x>=pointt[i][j].x-20&&q.x<=pointt[i][j].x+20&&q.y>=pointt[i][j].y-20&&q.y<=pointt[i][j].y+20)

{m=1;break;}//设置点有效位置

              }

              if(m==1){m=0;break;}

       }

}

5.6棋盘背景绘制函数

voidCTVSODlg::beijing(CDC* pDC)  //背景绘制

{

       for(j=100;j<=500;j=j+100)

       {pDC->MoveTo(100,j); pDC->LineTo(400,j);}

       for(i=100;i<=400;i=i+100)

       {pDC->MoveTo(i,100); pDC->LineTo(i,500);}  

for(i=1;i<6;i++)

       {

for(j=1;j<5;j++)

                     dayuan(i,j);//绘制背景圆

       }

}

 

 

5.7初始棋子绘制函数

void CTVSODlg::qizhi()//初始棋子绘制

{

       SetTimer(1,1000,NULL);

       if(k==0)

       {

              for(i=0;i<7;i++)    //点初始值为0,红棋标记为1,黑棋标记为2

              {for(j=0;j<6;j++)  pointvalue[i][j]=0;}

              //初始化棋盘(红棋)

              for(j=1;j<=4;j++){Hoxiaoyuan(1,j);pointvalue[1][j]=1;}

              Hoxiaoyuan(2,1); pointvalue[2][1]=1;

              Hoxiaoyuan(2,4); pointvalue[2][4]=1;

              //初始化棋盘(黑棋)

for(j=1;j<=4;j++){Hexiaoyuan(5,j);pointvalue[5][j]=2;}

              Hexiaoyuan(4,1); pointvalue[4][1]=2;

              Hexiaoyuan(4,4); pointvalue[4][4]=2;

              k=1;

       }

}

5.8棋子消失及胜负判断函数

voidCTVSODlg::tiaojian(int i,int j)//棋子消失(胜负)条件判断

{

       if(pointvalue[i][j]==2) //黑棋时

       {

              if(pointvalue[i-1][j]==2)//

              {

                     if(pointvalue[i+1][j]==1&&pointvalue[i+2][j]!=1)

                     {

                            pointvalue[i+1][j]=0;

                            dayuan(i+1,j);

                            pred--;

                     }

                     if(pointvalue[i-2][j]==1&&pointvalue[i-3][j]!=1)

                     {

                            pointvalue[i-2][j]=0;

                            dayuan(i-2,j);

                            pred--;

                     }

              }

              if(pointvalue[i+1][j]==2)//

              {

                     if(pointvalue[i-1][j]==1&&pointvalue[i-2][j]!=1)

                     {

                            pointvalue[i-1][j]=0;

                            dayuan(i-1,j);

                            pred--;

                     }

                     if(pointvalue[i+2][j]==1&&pointvalue[i+3][j]!=1)

                     {

                            pointvalue[i+2][j]=0;

                            dayuan(i+2,j);

                            pred--;

                     }

              }

              if(pointvalue[i][j-1]==2)//

              {

                     if(pointvalue[i][j+1]==1&&pointvalue[i][j+2]!=1)

                     {

                            pointvalue[i][j+1]=0;

                            dayuan(i,j+1);

                            pred--;

                     }

                     if(pointvalue[i][j-2]==1&&pointvalue[i][j-3]!=1)

                     {

                            pointvalue[i][j-2]=0;

                            dayuan(i,j-2);

                            pred--;

                     }

              }

              if(pointvalue[i][j+1]==2)//

              {

                     if(pointvalue[i][j-1]==1&&pointvalue[i][j-2]!=1)

                     {

                            pointvalue[i][j-1]=0;

                            dayuan(i,j-1);

                            pred--;

                     }

                     if(pointvalue[i][j+2]==1&&pointvalue[i][j+3]!=1)

                     {

                            pointvalue[i][j+2]=0;

                            dayuan(i,j+2);

                            pred--;

                     }

              }

              if(pred==0) AfxMessageBox("黑旗获胜");

       }

       else if(pointvalue[i][j]==1)//红棋时

       {

              if(pointvalue[i-1][j]==1)//

              {

                     if(pointvalue[i+1][j]==2&&pointvalue[i+2][j]!=2)

                     {

                            pointvalue[i+1][j]=0;

                            dayuan(i+1,j);

                            pblack--;

                     }

                     if(pointvalue[i-2][j]==2&&pointvalue[i-3][j]!=2)

                     {

                            pointvalue[i-2][j]=0;

                            dayuan(i-2,j);

                            pblack--;

                     }

              }

              if(pointvalue[i+1][j]==1)//

              {

                     if(pointvalue[i-1][j]==2&&pointvalue[i-2][j]!=2)

                     {

                            pointvalue[i-1][j]=0;

                            dayuan(i-1,j);

                            pblack--;

                     }

                     if(pointvalue[i+2][j]==2&&pointvalue[i+3][j]!=2)

                     {

                            pointvalue[i+2][j]=0;

                            dayuan(i+2,j);

                            pblack--;

                     }

              }

              if(pointvalue[i][j-1]==1)//

              {

                     if(pointvalue[i][j+1]==2&&pointvalue[i][j+2]!=2)

                     {

                            pointvalue[i][j+1]=0;

                            dayuan(i,j+1);

                            pblack--;

                     }

                     if(pointvalue[i][j-2]==2&&pointvalue[i][j-3]!=2)

                     {

                            pointvalue[i][j-2]=0;

                            dayuan(i,j-2);

                            pblack--;

                     }

              }

              if(pointvalue[i][j+1]==1)//

              {

                     if(pointvalue[i][j-1]==2&&pointvalue[i][j-2]!=2)

                     {

                            pointvalue[i][j-1]=0;

                            dayuan(i,j-1);

                            pblack--;

                     }

                     if(pointvalue[i][j+2]==2&&pointvalue[i][j+3]!=2)

                     {

                            pointvalue[i][j+2]=0;

                            dayuan(i,j+2);

                            pblack--;

                     }

              }

              if(pblack==0) AfxMessageBox("红旗获胜");

       }

}

5.9计时器函数

voidCTVSODlg::OnTimer(UINT_PTR nIDEvent)

{

       if(pointvalue[i][j]==2&&p==1)

       {

              dayuan(i,j);

              Hexiaoyuan(i,j);

       }

       else if(pointvalue[i][j]==1&&p==2)

       {

              dayuan(i,j);

              Hoxiaoyuan(i,j);

       }

       CDialogEx::OnTimer(nIDEvent);

}

5.10重新开始按钮

voidCTVSODlg::OnBnClickedButton1()

{

       p=1;n=0;

       pblack=6;pred=6;

       k=0;

       OnPaint();

}

5.11黑棋先行按钮

voidCTVSODlg::OnBnClickedButton2()

{

       OnBnClickedButton1();

}

5.12红棋先行按钮

voidCTVSODlg::OnBnClickedButton3()

{

       OnBnClickedButton1();

       p=2;

}

5.13退出游戏按钮

voidCTVSODlg::OnBnClickedButton4()

{

       CTVSODlg::OnCancel();

}



我们把同一标的(昆仑万维,现价 43.20 元,2026-07-31 收盘)交给三套系统,各出一份独立分析: **C 报告(CoordClaw 基于管理学多智能体系统)**——投研级。它由五个角色构成:周婷整合撰写、李静出基本面、王芳出技术面、赵明出风险、陈默做 PM 终审。最终产物是一份 38 项分级风险清单(P0×4 / P1×12 / P2×12 / P3×6 / 尾部×4)、双源交叉验证的财务数据(EM/Sina 差异 <0.01%)、严格的口径纪律,以及一份原样保留的"待核实"清单。结论冷冰冰:高风险,不建议参与。 **D 报告(DeepSeek)**——信息整理级。它把"4+3 AGI 略"、天工 AI、Opera 浏览器、StarMaker 拆得很漂亮,核心财务数据(营收 81.98 亿、归母 -15.93 亿)也没算错。但整篇没有技术面、没有量化风控,更关键的是——它完全没提实控人已减持 75%、质押状态未知、净现金仅 15.19 亿且续航只有 1.26~1.81 年这些要命的负面。这是典型的"选择性呈现"。 **K 报告(Kimi)**——以对比评估的方式呈现。它搭起"数据准确性 / 分析维度 / 结论合理性"的三维框架,把几份材料放在一起对照,给出各自的强弱判定。它的维度意识比 D 报告更自觉,但作为一份独立分析,它对"评估方法本身的信度"交待不足,部分引用的核对也不够彻底。 结果两家的结论高度一致。C 报告(多智能体)被评投研级、居首;D 报告(DeepSeek 自己写的)被评信息整理级、居中;K 报告(Kimi 自己那份)维度较全但核验深度有限,排在两者之间。DeepSeek 的那份评估把 C 给了五星、D 三星、K 四星;Kimi 的那份评估也独立地把最高分给了 C。
问题现象 - 同一张 TF 卡/SD 卡在其他电脑上能正常识别,插到本机却只"响一声",资源管理器里不显示盘符; - 磁盘管理里能看到磁盘,但显示为灰色 / RAW / 无盘符; - 插入 U 盘、读卡器后偶尔能显示,重启或更换卡片后又消失; - 使用 diskpart、mountvol 等命令时系统卡住无响应。 ## 问题根源 经排查,这类问题通常不是 TF 卡损坏,而是 Windows 存储子系统与本机读卡器/驱动之间的兼容性故障,主要包括: 1. **盘符未分配** —— 卷已被系统识别,但没有挂载点,因此资源管理器不显示; 2. **USB 幽灵设备残留** —— 系统里残留 `Disconnected` 状态的 USBSTOR 设备记录,阻塞新设备枚举; 3. **USB 选择性暂停(Selective Suspend)** —— Windows 空闲时给读卡器断电,导致识别不稳定; 4. **automount 被关闭或失效** —— 新插入的卷无法自动分配盘符; 5. **存储堆栈挂起** —— 残留的 diskpart 进程锁死存储服务。 ## 解决方案(一键永久修复) 本项目是一个 **Codex Skill + 一键安装器**,自动完成以下修复: - 启用系统自动挂载(automount enable / scrub) - 清理 Disconnected 幽灵 USB 设备 - 永久禁用 USB 选择性暂停(防读卡器被断电) - 自动为所有无盘符的可移动卷分配盘符 - 注册**开机守护任务**:每次开机自动执行以上修复,彻底告别手动操作 ## 使用方法 ```powershell # 在其他电脑上(Windows 10/11): # 1. 下载本项目 # 2. 右键 install.bat → 以管理员身份运行(或直接双击后点"是")
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值