C语言游戏2-五子棋(人机对战)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、开始工作
新建工程,选 MFC AppWizard(exe),添上工程名,确定。
选基于对话框,完成,确定。
插入位图 网上的源码一般都是将棋盘和棋子用画图程序画出来,但我不会弄。我的方法是直接贴图。 先插入位图(BMP 格式),以下是我用的位图,当然你也可以用自己的位图:
插入位图流程:
有时会弹出下面这个窗口,这是完全没有问题的: 位图插入后会自动赋予 ID 值,我们可以修改一下:
pDC 是显示图片窗口的句柄
我的画图函数是下面这样的,其中要注意两个函数 BitBlt 和 TransparentBlt,程序后有解释: void CMyDlg::Draw(int x, int y, UINT bitmap, CDC *pDC) {
//装载图片 CBitmap m_bmp; m_bmp.LoadBitmap(bitmap); //创建画布,比如要在窗口显示,则 pDC 为窗口句柄 CDC dc; dc.CreateCompatibleDC(pDC); //将位图选到 dc 中,顺便保存画刷到 pOldbmp //保存画刷、恢复画刷为规范操作,但可以不用 CBitmap *pOldbmp=dc.SelectObject(&m_bmp); //创建 bm,用来获取图片信息,这里是为了获取图片尺寸 BITMAP bm; m_bmp.GetObject(sizeof(BITMAP),&bm); //画图 if(IDB_BOARD==bitmap)//画棋盘
调整一下界面,希望你没有强迫症,可不要在调整上花太多时间了。下面是我做出的效果:
三、下棋
现在要将棋子准确下到各个点上,我用的棋盘,间距为 34,点击鼠标时获取点击坐标 x,y, 然后 x/34,y/34,确定棋子下到了哪个点上。
////////////////////////OnLButtonUp 函数///////////////////////////////////
添加消息处理函数:
我用的消息是 WM_LBUTTONUP,也就是当鼠标左键抬起来的时候,函数响应:
以下是函数代码: void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point) {
// TODO: Add your message handler code here and/or call default if(point.x>0&&point.x<480&&point.y>0&&point.y<480) {
pDC->BitBlt(x,y,bm.bmWidth,bm.bmHeight,&dc,0,0,SRCCOPY); else { //每个图片里有 4X4 个棋子,我只要画出一个就行了
int w=bm.bmWidth/4; int h=bm.bmHeight/4; TransparentBlt(pDC->m_hDC,x,y,w,h,dc.m_hDC,0,0,w,h,RGB(255,255,255)); } dc.SelectObject(pOldbmp);//恢复画刷 } pDC->BitBlt(x,y,bm.bmWidth,bm.bmHeight,&dc,0,0,SRCCOPY);
GetDlgItem(IDCANCEL)->ShowWindow(SW_HIDE);
或者直接在资源窗口中调整对话框:
然后在 OnPaint 函数中加入以下代码画图:
CDC *pDC=GetDC();//获取当前窗口句柄 Draw(13,13,IDB_BOARD,pDC);//画棋盘 //Draw(0,0,IDB_BLACK,pDC);//画黑棋,只是为了查看显示效果
函数弄好后就调用这个函数画图了。
先在 OnInitDialog 函数中加入以下代码,调整对话框大小,并隐藏按钮:
// TODO: Add extra initialization here
MoveWindow(0,0,520,540);//窗口定位
CenterWindow();
//居中窗口
GetDlgItem(IDOK)->ShowWindow(SW_HIDE);
初始化成员变量,在 OnPaint 函数里加入下面代码。画完棋盘的同时,初始化棋盘。 for(int i=0;i<15;i++) for(int j=0;j<15;j++) chess[i][j]=0;
修改 OnLButtonUp 函数中的下棋代码原来是直接用 Draw(x,y,IDB_BLACK,pDC);画棋,现在改成 下面的内容,当点上没有棋时才下棋:
对于扫描,我这里添加一个成员函数 search 用来扫描
代码比较长,注意不要出错了,不然调试很麻烦的。
int CMyDlg::search(int i, int j, int m, int n) {
int tempi,tempj,count=-1; int alive1=0,alive2=0; //第一次扫描 tempi=i;tempj=j; while(tempi>0 && tempi<15 &&
///////////////////////////// search 函数//////////////////////////////////////
那到底怎么判断输赢呢?我采用的是下面这个方法: 申明变量 alive1,alive2,用来判断活棋还是死棋。申明变量 count 用来判断连子的个数。 以横向四子为例,我刚下了第三个棋子。先从第三个棋子位置开始,往右边扫描,如果下的 也是黑棋,则 count++。如果遇到的不是黑棋,判断是不是空地。如果是空地 alive1=1,表 示右边一头是活的。否则 alive=0。然后回到第三子位置,往左边扫描。
功能也是贴图,但图片背景透明:将 dc 中的位图(dc.m_hDC 是 dc 的句柄),截取大小 w,h,
粘贴到 pDC 所指的设备,贴图坐标 x,y,贴图大小为 w,h,如果图片大小不符则拉伸或压缩
图片。最后一项是背景色,可以将图片背景透明化。
使用 TransparentBlt 必须包含头文件和类库,否则编译错误: #include <wingdi.h> #pragma comment (lib,"msimg32.lib")
if(0==chess[i][j]) {
Draw(x,y,IDB_BLACK,pDC); chess[i][j]=1;//下的黑棋,这一点变成 1 } 下棋功能完成了。
四、判断胜负
////////////////////////////iswin 函数/////////////////////////////////////////
五子棋人机对战,AI 很低,做参考用,仅仅为大家提供一下思路。 如果有什么好的建议或发现什么问题,希望能告诉我,我的邮箱是 caoweizhou@ 开发环境:l C++ 6.0 游戏界面:
C 语言游戏 2-五子棋(人机对战)
一、开始工作.....................................................................................................................................2 二、画图............................................................................................................................................. 5 三、下棋............................................................................................................................................. 8 四、判断胜负...................................................................................................................................10 五、人工智能...................................................................................................................................13 六、附加功能...................................................................................................................................17
先添加一个 BOOL 类型的成员函数 iswin(int i, int j),每下一个棋子都通过这个棋子判断是否 赢了。是则返回 TRUE(或 1),否则返回 FALSE(或 0)。默认返回 FALSE。
在 OnLButtonUp 函数中调用 iswin。如果赢了弹出窗口"我赢了,结束战斗!",初始化棋盘: void CMyDlg::OnLButtonUp(UINT nFlags, CPoint point) {
二、画图
///////////////////////////Draw 函数/////////////////////////////////////////
添加成员函数 Draw:
Draw(int x, int y, UINT bitmap, CDC *pDC)
解释一下:
x,y 是画图的坐标
bitmap 是图片 ID,比如我的黑棋图片 ID 就是 IDB_BLACK
// TODO: Add your message handler code here and/or call default if(point.x>0&&point.x<480&&point.y>0&&point.y<480) {
int j=point.x/34; int i=point.y/34; int x=j*34; int y=i*34; CDC *pDC=GetDC();//获取当前设备句柄 if(0==chess[i][j]) {
Draw(x,y,IDB_BLACK,pDC); chess[i][j]=1; } //判断输赢 if(iswin(i,j)) { MessageBox("我赢了,结束战斗!","提示",MB_OK); Invalidate(FALSE); } } CDialog::OnLButtonUp(nFlags, point); } MessageBox 弹出窗口"我赢了,结束战斗!" Invalidate(FALSE)会放出一个 WM_PAINT 消息,间接调用 OnPaint 函数,初始化棋盘。
int j=point.x/34; int i=point.y/34; int x=j*34; int y=i*34; CDC *pDC=GetDC();//获取当前设备句柄 Draw(x,y,IDB_BLACK,pDC); }
CDialog::OnLButtonUp(nFlags, point); } 函数中,point.x,point.y 为点击鼠标时的坐标 现在可以将棋子准确地下到点上了,可是就算点上有已经有棋子了,点鼠标后也会下棋。所 以我们用一个二维数组存储棋盘上的棋子。 添加成员变量:
功能是贴图:将 dc 中的位图,截取大小 bm.bmWidth,bm.bmHeight,粘贴到 pDC 所指的设
备,贴图坐标 x,y。最后一个参数为粘贴方式,我们是直接粘贴,所以是 SRCCOPY
TransparentBlt(pDC->m_hDC,x,y,w,h,dc.m_hDC,0,0,w,h,RGB(255,255,255));
相关文档
最新文档