// 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();
}