利用MFC编写五子棋程序

时间:2014-08-02 08:48:01
【文件属性】:

文件名称:利用MFC编写五子棋程序

文件大小:461KB

文件格式:RAR

更新时间:2014-08-02 08:48:01

MFC 五子棋

// Chess.cpp: implementation of the CChess class. ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "五子棋.h" #include "Chess.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CChess::CChess() { memset(m_board,0,sizeof(m_board)); m_turn=1; //下棋次序 m_flag=0; //输赢标志,1白 2黑 posflag=0; //下子信息数组下标初始值为0 } CChess::~CChess() { } int CChess::PanYing(int nx, int ny) //判断输赢函数 { int count=0; for(int i=-4;i<5;i++) //判断水平行还是否连成五个子,只要够了5个就返回1,否则返回0. { if(m_board[ny][nx+i]==m_turn) {count++;if(count==5) return m_turn;} else count=0; } count=0; for(i=-4;i<5;i++) //判断竖行是否连成五个子 { if(m_board[ny+i][nx]==m_turn) {count++;if(count==5) return m_turn;} else count=0; } count=0; for(i=-4;i<5;i++) //从左上到右下是否连成五个子 { if(m_board[ny+i][nx+i]==m_turn) {count++;if(count==5) return m_turn;} else count=0; } count=0; for(i=-4;i<5;i++) //从右上到右下是否连成五个子 { if(m_board[ny+i][nx-i]==m_turn) {count++;if(count==5) return m_turn;} else count=0; } count=0; return 0; } void CChess::DrawQp() //画棋盘 { dc->BitBlt(0,0,446,446,qp,0,0,SRCCOPY); //BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop ); //x,y为目的矩形左上角的坐标。nWidth, nHeight为图形的宽高,pSrcDC为资源位图或添加矩形的名字 //xSrc,ySrc为资源位图左上角的坐标。dwRop 光栅处理位图和资源图的结合的方法 //SRCCOPY:Copies the source bitmap to the destination bitmap } void CChess::DrawQz(int nx,int ny,int type) //画棋子 { if(type==0) { if(m_turn==1){dc->Ellipse(nx*29+7,ny*29+7,nx*29+34,ny*29+34); //BOOL Ellipse( int x1, int y1, int x2, int y2 ); //x1,y1为椭圆范围内矩形的左上角坐标,x2,y2为椭圆范围内矩形的右下角坐标 posinfo[posflag].x=nx; posinfo[posflag].y=ny; posinfo[posflag].flag=m_turn; posflag++;} else { CBrush *brush; CBrush brush1(RGB(0,0,0)); // RGB(nRedValue, nGreenValue, nBlueValue) brush=dc->SelectObject(&brush1); dc->Ellipse(nx*29+7,ny*29+7,nx*29+34,ny*29+34); posinfo[posflag].x=nx; posinfo[posflag].y=ny; posinfo[posflag].flag=m_turn; posflag++; dc->SelectObject(brush); } } else if(type==1) { dc->Ellipse(nx*29+7,ny*29+7,nx*29+34,ny*29+34); posinfo[posflag].x=nx; posinfo[posflag].y=ny; posinfo[posflag].flag=m_turn; posflag++; } else { CBrush *brush; CBrush brush1(RGB(0,0,0)); brush=dc->SelectObject(&brush1); dc->Ellipse(nx*29+7,ny*29+7,nx*29+34,ny*29+34); posinfo[posflag].x=nx; posinfo[posflag].y=ny; posinfo[posflag].flag=m_turn; posflag++; dc->SelectObject(brush); } } bool CChess::DownZi(int nx, int ny,int type,HWND hwnd) //下子函数,外不调用此函数 { int x,y; if(nx<0||nx>14||ny<0||ny>14) //先判断下子是否正确 { MessageBox(hwnd,"不正确的下子位置!", NULL,MB_OK); return false; } if(CChess::m_flag!=0)//已分出胜负 { if(m_flag==1){MessageBox(hwnd,"白棋获胜!", NULL,MB_OK);return true;} else{MessageBox(hwnd,"黑棋获胜!", NULL,MB_OK);return true;} } if(m_board[ny][nx]==0) { if(type==2)//人人对战 { m_board[ny][nx]=m_turn; DrawQz(nx,ny); m_flag=PanYing(nx,ny); m_turn=(m_turn==1?2:1); if(m_flag==1){MessageBox(hwnd,"白棋获胜!", NULL,MB_OK);return true;} if(m_flag==2){MessageBox(hwnd,"黑棋获胜!", NULL,MB_OK);return true;} return true; } else //人机对战 { m_board[ny][nx]=m_turn; DrawQz(nx,ny); m_flag=PanYing(nx,ny); m_turn=(m_turn==1?2:1); if(m_flag==1){MessageBox(hwnd,"白棋获胜!", NULL,MB_OK);return true;} if(m_flag==2){MessageBox(hwnd,"黑棋获胜!", NULL,MB_OK);return true;} CChess::AiGo(x,y); m_board[y][x]=m_turn; DrawQz(x,y); m_flag=PanYing(x,y); m_turn=(m_turn==1?2:1); if(m_flag==1){MessageBox(hwnd,"白棋获胜!", NULL,MB_OK);return true;} if(m_flag==2){MessageBox(hwnd,"黑棋获胜!", NULL,MB_OK);return true;} return true; } } return false; } void CChess::ReDraw() //从画函数 { DrawQp(); for(int i=0;i<15;i++) for(int j=0;j<15;j++) { if(m_board[i][j]==1){DrawQz(j,i,1);} if(m_board[i][j]==2){DrawQz(j,i,2);} } } void CChess::NewGame(int type) //新游戏 { memset(m_board,0,sizeof(m_board)); m_flag=0; m_turn=1; posflag=0; if(type==0){m_board[7][7]=1;m_turn=2; posinfo[posflag].x=7;posinfo[posflag].y=7;posinfo[posflag].flag=2; posflag++;} ReDraw(); } void CChess::SetDc(CDC* tqp, CDC *qz) //设置绘图 { qp=tqp; dc=qz; } void CChess::AiGo(int& t, int &h) // { int qiju[2][15][15][8][2]={0}; /* 棋型数组*/ int k,i,j,q,b=0,a=1,d,y1=0,y2=0,x1=0,x2=0; int a1[15][15]={0},a2[15][15]={0}; /****************为双方填写棋型表************/ for(k=0;k<2;k++) //k代表两方对弈者,k=0为白棋,k=1为黑棋。 for(i=0;i<15;i++) for(j=0;j<15;j++) { if(m_board[i][j]==0) //空位 { for(q=0;q<8;q++) //与空位相邻的八个方向上的位置 { if(k==0) d=1; //d=1代表一方 else d=2; //d=2代表另一方 if(q==1&&i>=0&&j>=0) //q=1 { for(;i-a>=0&&j-a>=0;) { if(m_board[i-a][j-a]==d){b++;a++;continue;} else break; } qiju[k][i][j][q][0]=b;b=0; if(m_board[i-a][j-a]==0&&j-a>=0&&i-a>=0){qiju[k][i][j][q][1]=1;a=1;} else {qiju[k][i][j][q][1]=0;a=1;} } if(q==2&&i>=0) //q=2 { for(;i-a>=0;) { if(m_board[i-a][j]==d){b++;a++;continue;} else break; } qiju[k][i][j][q][0]=b;b=0; if(m_board[i-a][j]==0&&i-a>=0){qiju[k][i][j][q][1]=1;a=1;} else {qiju[k][i][j][q][1]=0;a=1;} } if(q==3&&i>=0&&j<15) // q=3 { for(;i-a>=0&&j+a<15;) { if(m_board[i-a][j+a]==d){b++;a++;continue;} else break; } qiju[k][i][j][q][0]=b;b=0; if(m_board[i-a][j+a]==0&&i-a>=0&&j+a<15){qiju[k][i][j][q][1]=1;a=1;} else {qiju[k][i][j][q][1]=0;a=1;} } if(q==4&&j<15) //q=4 { for(;j+a<15;) { if(m_board[i][j+a]==d){b++;a++;continue;} else break; } qiju[k][i][j][q][0]=b;b=0; if(m_board[i][j+a]==0&&j+a<15){qiju[k][i][j][q][1]=1;a=1;} else {qiju[k][i][j][q][1]=0;a=1;} } if(q==5&&i<15&&j<15) //q=5 { for(;i+a<15&&j+a<15;) { if(m_board[i+a][j+a]==d){b++;a++;continue;} else break; } qiju[k][i][j][q][0]=b;b=0; if(m_board[i+a][j+a]==0&&i+a<15&&j+a<15){qiju[k][i][j][q][1]=1;a=1;} else {qiju[k][i][j][q][1]=0;a=1;} } if(q==6&&i<15) //q=6 { for(;i+a<15;) { if(m_board[i+a][j]==d){b++;a++;continue;} else break; } qiju[k][i][j][q][0]=b;b=0; if(m_board[i+a][j]==0&&i+a<15){qiju[k][i][j][q][1]=1;a=1;} else {qiju[k][i][j][q][1]=0;a=1;} } if(q==7&&j>=0&&i<15) //q=7 { for(;i+a<15&&j-a>=0;) { if(m_board[i+a][j-a]==d){b++;a++;continue;} else break; } qiju[k][i][j][q][0]=b;b=0; if(m_board[i+a][j-a]==0&&i+a<15&&j-a>=0){qiju[k][i][j][q][1]=1;a=1;} else {qiju[k][i][j][q][1]=0;a=1;} } } } } /******************根据评分规则对每一个空格评分***************/ for(k=0;k<2;k++) for(i=0;i<15;i++) for(j=0;j<15;j++) { if(k==0) /*为白棋评分*/ { for(q=0;q<4;q++) { if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==4 &&qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==1) b+=7000; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==3 &&qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==1) b+=301; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==2 &&qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==1) b+=43; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==1 &&qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==1) b+=11; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==4 &&((qiju[k][i][j][q+4][1]==0) ||(qiju[k][i][j][q][1]==0))) b+=7000; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==3 &&((qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==0) ||(qiju[k][i][j][q][1]==0&&qiju[k][i][j][q+4][1]==1))) b+=63; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==2 &&((qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==0) ||(qiju[k][i][j][q][1]==0&&qiju[k][i][j][q+4][1]==1))) b+=6; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==1 &&((qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==0) ||(qiju[k][i][j][q][1]==0&&qiju[k][i][j][q+4][1]==1))) b+=1; } if(b==126||b==189||b==252) b=1500; if(b==106) b=1000; a1[i][j]=b;b=0; } if(k==1) /*为黑棋评分*/ { for(q=0;q<4;q++) { if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==4 &&qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==1) b+=30000; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==3 &&qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==1) b+=1500; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==2 &&qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==1) b+=51; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==1 &&qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==1) b+=16; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==4 &&((qiju[k][i][j][q+4][1]==0) ||(qiju[k][i][j][q][1]==0))) b+=30000; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==3 &&((qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==0) ||(qiju[k][i][j][q][1]==0&&qiju[k][i][j][q+4][1]==1))) b+=71; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==2 &&((qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==0) ||(qiju[k][i][j][q][1]==0&&qiju[k][i][j][q+4][1]==1))) b+=7; if((qiju[k][i][j][q][0]+qiju[k][i][j][q+4][0])==1 &&((qiju[k][i][j][q][1]==1&&qiju[k][i][j][q+4][1]==0) ||(qiju[k][i][j][q][1]==0&&qiju[k][i][j][q+4][1]==1))) b+=2; } if(b==142||b==213||b==284) b=1500; if(b==122) b=1300; a2[i][j]=b;b=0; } } /****************算出分数最高的空位,填写坐标*********************/ for(i=0;i<15;i++) for(j=0;j<15;j++) { if(a1[y1][x1]=a1[y1][x1]) {t=x2;h=y2;} //找出空位分数是最高的 else {t=x1;h=y1;} } void CChess::BackGo() //悔棋 { m_board[posinfo[posflag-1].y][posinfo[posflag-1].x]=0; ReDraw(); }


【文件预览】:
智能五子棋游戏-人机对战-支持悔棋-VC++源代码
----SettingDlg.h(1KB)
----StdAfx.cpp(208B)
----SettingDlg.cpp(998B)
----五子棋Dlg.h(2KB)
----Chess.cpp(10KB)
----五子棋.cpp(2KB)
----五子棋.rc(6KB)
----五子棋.aps(217KB)
----五子棋Dlg.cpp(5KB)
----ReadMe.txt(3KB)
----StdAfx.h(1KB)
----info.h(40B)
----五子棋.h(1KB)
----Chess.h(1KB)
----Resource.h(1KB)
----五子棋.dsp(4KB)
----五子棋.clw(2KB)
----五子棋.dsw(520B)
----res()
--------qp.bmp(196KB)
--------五子棋.rc2(398B)
--------五子棋.ico(1KB)

网友评论

  • 很实用,适合拿来学习研究!推荐下载
  • 不错,电脑可以运行。。。。很有帮助
  • 功能很好,只是悔棋是从下向上进行的,加个数组试试。
  • 对于初学者虽然困难一点,还是挺受用的!
  • 作为学习资料,谢谢分享
  • 代码比较给力,谢谢大神
  • 写得很不错,在悔棋功能上有点bug,正在尝试解决
  • 不错 源代码可用
  • 确实挺实用的!
  • 对我很实用
  • 这个写的非常好,太给力啦
  • 代码很好,注释也很详细,VC6.0正常运行
  • 非常好,可以直接拿过来修改后用,我直接添加进了我的mfc,完美
  • 资源很好,有教育意义
  • 不错 源代码可用。
  • 资源很好,能够编译运行
  • 不错的资源
  • 注释很多比较清晰
  • 资源很好,有教育意义
  • 资源很好,有具体的算法,很好用