#include "3_1.h"
#include "3_1Doc.h"
#include "3_1View.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMy3_1View
IMPLEMENT_DYNCREATE(CMy3_1View, CView)
BEGIN_MESSAGE_MAP(CMy3_1View, CView)
//{{AFX_MSG_MAP(CMy3_1View)
ON_WM_LBUTTONUP()
ON_WM_SETCURSOR()
ON_COMMAND(ID_START, OnStart)
ON_COMMAND(ID_PLAYER, OnPlayer)
ON_COMMAND(ID_CPMPUTER, OnCpmputer)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMy3_1View construction/destruction
CMy3_1View::CMy3_1View()
{
// TODO: add construction code here
hcursorblack=AfxGetApp()->LoadCursor(IDC_CURSOR1);
hcursorwhite=AfxGetApp()->LoadCursor(IDC_CURSOR2);
m_bmwhite.LoadBitmap(IDB_WHITE);
m_bmblack.LoadBitmap(IDB_BLACK);
for(int i=0;i<19;i++)
for(int j=0;j<19;j++)
wzq[i][j]=0;
colorwhite=true;
//默認為人對機
vscomputer=1;
}
CMy3_1View::~CMy3_1View()
{
}
BOOL CMy3_1View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMy3_1View drawing
void CMy3_1View::OnDraw(CDC* pDC)
{
CMy3_1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
//畫背景
CBrush mybrush1;
mybrush1.CreateSolidBrush(RGB(192,192,192));
CRect myrect1(0,0,1200,800);
pDC->FillRect(myrect1,&mybrush1);
CBrush mybrush;
mybrush.CreateSolidBrush(RGB(0,0,0));
for(int a=0;a<3;a++)
for(int b=0;b<3;b++)
{
CRect myrect(97+a*120,97+b*120,103+a*120,103+b*120);
pDC->FillRect(myrect,&mybrush);
}
//畫黑框線
CPen mypen;
CPen*myoldPen;
mypen.CreatePen(PS_SOLID,1,RGB(0,0,0));
myoldPen=pDC->SelectObject(&mypen);
for(int i=0;i<19;i++)
{
pDC->MoveTo(40,40+i*20);
pDC->LineTo(400,40+i*20);
pDC->MoveTo(40+i*20,40);
pDC->LineTo(40+i*20,400);
}
CDC Dc;
if(Dc.CreateCompatibleDC(pDC)==FALSE)
AfxMessageBox("Can't create DC");
for(int n=0;n<19;n++)
for(int m=0;m<19;m++)
if(wzq[n][m]==1)
{
Dc.SelectObject(m_bmwhite);
pDC->BitBlt(n*20+32,m*20+32,160,160,&Dc,0,0,SRCCOPY);
}
else if(wzq[n][m]==-1)
{
Dc.SelectObject(m_bmblack);
pDC->BitBlt(n*20+32,m*20+32,160,160,&Dc,0,0,SRCCOPY);
}
}
/////////////////////////////////////////////////////////////////////////////
// CMy3_1View printing
BOOL CMy3_1View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMy3_1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CMy3_1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CMy3_1View diagnostics
#ifdef _DEBUG
void CMy3_1View::AssertValid() const
{
CView::AssertValid();
}
void CMy3_1View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMy3_1Doc* CMy3_1View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy3_1Doc)));
return (CMy3_1Doc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMy3_1View message handlers
void CMy3_1View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDC *pDC=GetDC();
CDC Dc;
if(Dc.CreateCompatibleDC(pDC)==FALSE)
AfxMessageBox("Can't create DC");
//顯示棋子
/////////////////////人對機
if(vscomputer==1)
{
if(point.x>30&&point.x<410&&point.y>30&&point.y<410)
{
int px=(point.x-30)/20;
int py=(point.y-30)/20;
if(colorwhite&&wzq[px][py]==0)
{
Dc.SelectObject(m_bmwhite);
pDC->BitBlt(px*20+32,py*20+32,160,160,&Dc,0,0,SRCCOPY);
wzq[px][py]=1;
over(point);
colorwhite=false;
//保存白棋位置
vspoint=point;
//計算機下棋
computerdown();
}
}
}
//人對人
if(vscomputer==2)
{
if(point.x>30&&point.x<410&&point.y>30&&point.y<410)
{
int px=(point.x-30)/20;
int py=(point.y-30)/20;
if(colorwhite&&wzq[px][py]==0)
{
Dc.SelectObject(m_bmwhite);
pDC->BitBlt(px*20+32,py*20+32,160,160,&Dc,0,0,SRCCOPY);
wzq[px][py]=1;
over(point);
colorwhite=false;
}
else if(wzq[px][py]==0)
{
Dc.SelectObject(m_bmblack);
pDC->BitBlt(px*20+32,py*20+32,160,160,&Dc,0,0,SRCCOPY);
wzq[px][py]=-1;
over(point);
colorwhite=true;
}
}
}
CView::OnLButtonUp(nFlags, point);
}
BOOL CMy3_1View::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
if(nHitTest==HTCLIENT)
{
if(colorwhite)
{
CMainFrame*pFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd;
CStatusBar*pStatus=&pFrm->m_wndStatusBar;
if(pStatus)
{
pStatus->GetStatusBarCtrl().SetIcon(0,AfxGetApp()->LoadIcon(IDI_WHITE));
pStatus->SetPaneText(0,"白棋下");
}
SetCursor(hcursorwhite);
}
else
{
CMainFrame*pFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd;
CStatusBar*pStatus=&pFrm->m_wndStatusBar;
if(pStatus)
{
//顯示圖像
pStatus->GetStatusBarCtrl().SetIcon(0,AfxGetApp()->LoadIcon(IDI_BLACK));
//顯示文字
pStatus->SetPaneText(0,"黑棋下");
}
SetCursor(hcursorblack);
}
return 1;
}
return CView::OnSetCursor(pWnd, nHitTest, message);
}
void CMy3_1View::over(CPoint point)
{
//獲取鼠標指向數組位置
int x=(point.x-30)/20;
int y=(point.y-30)/20;
//開始判斷的坐標
int xx,yy;
if(x<4)
xx=0;
else
xx=x-4;
if(y<4)
yy=0;
else
yy=y-4;
int i,j,a;
//橫向判斷
for(i=xx;i<15;i++)
{
a=0;
for(j=i;j<i+5;j++)
{
a=a+wzq[j][y];
if(a==5)
{
AfxMessageBox("白棋勝!");OnStart();return;
}
if(a==-5)
{
AfxMessageBox("黑棋勝!");OnStart();return;
}
}
}
//豎向判斷
for(i=yy;i<15;i++)
{
a=0;
for(j=i;j<i+5;j++)
{
a=a+wzq[x][j];
if(a==5)
{
AfxMessageBox("白棋勝!");OnStart();return;
}
if(a==-5)
{
AfxMessageBox("黑棋勝!");OnStart();return;
}
}
}
//向右下角
//判斷起點位置
if(x<y)
{
if(xx==0)
yy=y-x;
}
else
{
if(yy==0)
xx=x-y;
}
//參數1時退出循環
int over=0;
do
{
a=0;
for(i=0;i<5;i++)
{
if((xx+i)<19||(yy+i)<19)
{
a=a+wzq[xx+i][yy+i];
if(a==5)
{
AfxMessageBox("白棋勝!");OnStart();return;
}
if(a==-5)
{
AfxMessageBox("黑棋勝!");OnStart();return;
}
}
//到了邊界
else
over=1;
}
xx+=1;
yy+=1;
}while(over==0);
//向左下角
if(y>(18-x))
{
if(x>13)
{
yy=y-(18-x);
xx=18;
}
else
{
yy=y-4;
xx=x+4;
}
}
else
{
if(y<5)
{
xx=x+y;
yy=0;
}
else
{
yy=y-4;
xx=x+4;
}
}
over=0;
do
{
a=0;
for(i=0;i<5;i++)
{
if((xx-i)>=0||(yy+i)<19)
{
a=a+wzq[xx-i][yy+i];
if(a==5)
{
AfxMessageBox("白棋勝!");OnStart();return;
}
if(a==-5)
{
AfxMessageBox("黑棋勝!");OnStart();return;
}
}
//到了邊界
else
over=1;
}
xx-=1;
yy+=1;
}while(over==0);
}
void CMy3_1View::OnStart()
{
// TODO: Add your command handler code here
for(int i=0;i<19;i++)
for(int j=0;j<19;j++)
wzq[i][j]=0;
colorwhite=true;
Invalidate();
}
//黑棋下
void CMy3_1View::putdown(CPoint point)
{
CDC *pDC=GetDC();
CDC Dc;
if(Dc.CreateCompatibleDC(pDC)==FALSE)
AfxMessageBox("Can't create DC");
Dc.SelectObject(m_bmblack);
pDC->BitBlt(point.x*20+32,point.y*20+32,160,160,&Dc,0,0,SRCCOPY);
wzq[point.x][point.y]=-1;
//變數組坐標為棋盤坐標
CPoint overpoint;
overpoint.x=point.x*20+30;
overpoint.y=point.y*20+30;
over(overpoint);
colorwhite=true;
}
//輪到計算機下棋
void CMy3_1View::computerdown()
{
//把各種情形賦值為如下
bpointcan4=(-1,-1);
wpointcan4=(-1,-1);
bpointcan3=(-1,-1);
wpointcan3=(-1,-1);
bpointcan2=(-1,-1);
wpointcan2=(-1,-1);
bpointcan1=(-1,-1);
//搜索最好的落棋點
for(int i=0;i<19;i++)
for(int j=0;j<19;j++)
bestputdown(i,j);
//判斷放在哪裏
//棋多的位置優先
//黑白壹樣多時黑先
if(bpointcan4.x!=-1)
{
putdown(bpointcan4);
return;
}
else if(wpointcan4.x!=-1)
{
putdown(wpointcan4);
return;
}
else if(bpointcan3.x!=-1)
{
putdown(bpointcan3);
return;
}
else if(wpointcan3.x!=-1)
{
putdown(wpointcan3);
return;
}
else if(bpointcan2.x!=-1)
{
putdown(bpointcan2);
return;
}
else if(wpointcan2.x!=-1)
{
putdown(wpointcan2);
return;
}
else
{
putdown(bpointcan1);
return;
}
}
//檢查四個方向,各算出五個棋子的和並賦值
void CMy3_1View::bestputdown(int i,int j)
{
int num[4];
CPoint numbig;
int a,k;
/////////////////////////////// num[0] -->
a=0;
if(i<15)
for(k=0;k<5;k++)
a=a+wzq[i+k][j];
num[0]=abs(a);
////////////////////////////// num[1] "|"
a=0;
if(j<15)
for(k=0;k<5;k++)
a=a+wzq[i][j+k];
num[1]=abs(a);
/////////////////////////////// num[2] "\"
a=0;
if(i<15&&j<15)
for(k=0;k<5;k++)
a=a+wzq[i+k][j+k];
num[2]=abs(a);
////////////////////////////// num[3] "/"
a=0;
if((i>4)&&(j<15))
for(k=0;k<5;k++)
a=a+wzq[i-k][j+k];
num[3]=abs(a);
//比較哪個方向同色棋最多
numbig=maxnum(num[0],num[1],num[2],num[3]);
//在得到最大值和方向上尋找落棋點
switch(numbig.y)
{
case 4:
searchcandown4(i,j,numbig.x);break;
case 3:
searchcandown3(i,j,numbig.x);break;
case 2:
searchcandown2(i,j,numbig.x);break;
default:
searchcandown1(i,j,numbig.x);
}
}
CPoint CMy3_1View::maxnum(int a, int b, int c, int d)
{
//point.x為方向值
//point.y為最大值
CPoint point;
if(a>=b)
{
point.x=0;
point.y=a;
}
else
{
point.x=1;
point.y=b;
}
if(c>point.y)
{
point.x=2;
point.y=c;
}
if(d>point.y)
{
point.x=3;
point.y=d;
}
return point;
}
//有四個同色棋
void CMy3_1View::searchcandown4(int i, int j, int n)
{
// CPoint point;
int k;
///////////////////////////// num[0] "--"
if(n==0)
for(k=0;k<5;k++)
//如果第壹個是空
if(wzq[i][j]==0)
{
//如果下面有白棋
if(wzq[i+1][j]==1)
{
//下面位置可以下棋,已經有四個白棋
wpointcan4.x=i;
wpointcan4.y=j;
break;
}
else
{
//下面位置可以下棋,已經有四個黑棋
bpointcan4.x=i;
bpointcan4.y=j;
break;
}
}
//如果找到下棋位置,壹定能找到!
else if(wzq[i+k][j]==0)
{
//如果第壹個是白棋
if(wzq[j][j]==1)
{
wpointcan4.x=i+k;
wpointcan4.y=j;
break;
}
//否則第壹個是黑棋
else
{
bpointcan4.x=i+k;
bpointcan4.y=j;
break;
}
}
//////////////////////////// num[1] "|"
if(n==1)
for(k=0;k<5;k++)
{
if(wzq[i][j]==0)
if(wzq[i][j+1]==1)
{
wpointcan4.x=i;
wpointcan4.y=j;
break;
}
else
{
bpointcan4.x=i;
bpointcan4.y=j;
break;
}
else if(wzq[i][j+k]==0)
{
if(wzq[i][j]==1)
{
wpointcan4.x=i;
wpointcan4.y=j+k;
break;
}
else
{
bpointcan4.x=i;
bpointcan4.y=j+k;
break;
}
}
}
/////////////////////////////// num[2] "\"
if(n==2)
for(k=0;k<5;k++)
{
if(wzq[i][j]==0)
if(wzq[i+1][j+1]==1)
{
wpointcan4.x=i;
wpointcan4.y=j;
break;
}
else
{
bpointcan4.x=i;
bpointcan4.y=j;
break;
}
else if(wzq[i+k][j+k]==0)
{
if(wzq[i][j]==1)
{
wpointcan4.x=i+k;
wpointcan4.y=j+k;
break;
}
else
{
bpointcan4.x=i+k;
bpointcan4.y=j+k;
break;
}
}
}
////////////////////////////// num[3] "/"
if(n==3)
for(k=0;k<5;k++)
{
if(wzq[i][j]==0)
if(wzq[i-1][j+1]==1)
{
wpointcan4.x=i;
wpointcan4.y=j;
break;
}
else
{
bpointcan4.x=i;
bpointcan4.y=j;
break;
}
else if(wzq[i-k][j+k]==0)
{
if(wzq[i][j]==1)
{
wpointcan4.x=i-k;
wpointcan4.y=j+k;
break;
}
else
{
bpointcan4.x=i-k;
bpointcan4.y=j+k;
break;
}
}
}
}
//最多有三個同色
void CMy3_1View::searchcandown3(int i, int j, int n)
{
int k=0;
///////////////////////////// num[0] "--"
if(n==0)
for(k=0;k<5;k++)
//找到位置
if(wzq[i+k][j]==0)
{
//下壹個是白棋
if(wzq[i+k+1][j]==1)
{
//下面位置可以下棋,已經有三個白棋
wpointcan3.x=i+k;
wpointcan3.y=j;
}
//下壹個是黑棋
else if(wzq[i+k+1][j]==-1)
{
bpointcan3.x=i+k;
bpointcan3.y=j;
}
}
//////////////////////////// num[1] "|"
if(n==1)
for(k=0;k<5;k++)
if(wzq[i][j+k]==0)
{
if(wzq[i][j+k-1]==1)
{
wpointcan3.x=i;
wpointcan3.y=j+k;
}
else if(wzq[i][j+k+1]==-1)
{
bpointcan3.x=i;
bpointcan3.y=j+k;
}
}
/////////////////////////////// num[2] "\"
if(n==2)
for(k=0;k<5;k++)
if(wzq[i+k][j+k]==0)
{
if(wzq[i+k+1][j+k+1]==1)
{
wpointcan3.x=i+k;
wpointcan3.y=j+k;
}
else if(wzq[i+k+1][j+k+1]==-1)
{
bpointcan3.x=i+k;
bpointcan3.y=j+k;
}
}
////////////////////////////// num[3] "/"
if(n==3)
for(k=0;k<5;k++)
if(wzq[i-k][j+k]==0)
{
if(wzq[i-k-1][j+k+1]==1)
{
wpointcan3.x=i-k;
wpointcan3.y=j+k;
}
else if(wzq[i-k-1][j+k+1]==-1)
{
bpointcan3.x=i-k;
bpointcan3.y=j+k;
}
}
}
//最多有兩個同色
void CMy3_1View::searchcandown2(int i, int j, int n)
{
int k=0,m=0,a=0,b=0;
///////////////////////////// num[0] "--"
if(n==0)
{
//判斷有多少個空位置
for(k=0;k<5;k++)
if(wzq[i+k][j]==0)
m+=1;
//如果只有壹個空位置
if(m==1)
for(a=0;a<5;a++)
//找到空位置
if(wzq[i+a][j]==0)
{
//下面兩個棋子值的和
b=wzq[i+a+1][j]+wzq[i+a+2][j];
//都是黑棋
if(b==-2)
{
//下面位置可以下棋,旁邊有兩個黑棋
bpointcan2.x=i+a;
bpointcan2.y=j;
}
//都是白棋
if(b==2)
{
wpointcan2.x=i+a;
wpointcan2.y=j;
}
}
//如果有三個空位置,說明另外兩個同色
if(m==3)
{
for(a=0;a<5;a++)
//如果兩個是黑棋
if(wzq[i+a][j]==-1)
{
for(b=0;b<5;b++)
//如果找到空位置
if(wzq[i+b][j]==0)
{
//下面位置可以下棋,旁邊有兩個黑棋
bpointcan2.x=i+b;
bpointcan2.y=j; break;
}
}
else
//如果兩個是白棋
if(wzq[i+a][j]==1)
{
for(b=0;b<5;b++)
if(wzq[i+b][j]==0)
{
wpointcan2.x=i+b;
wpointcan2.y=j; break;
}
}
}
}
//////////////////////////// num[1] "|"
m=0;
if(n==1)
{
for(k=0;k<5;k++)
if(wzq[i][j+k]==0)
m++;
if(m==1)
for(a=0;a<5;a++)
if(wzq[i][j+a]==0)
{
b=wzq[i][j+a+1]+wzq[i][j+a+2];
if(b==-2)
{
bpointcan2.x=i;
bpointcan2.y=j+a;
}
if(b==2)
{
wpointcan2.x=i;
wpointcan2.y=j+a;
}
}
if(m==3)
{
for(a=0;a<5;a++)
if(wzq[i][j+a]==-1)
{
for(b=0;b<5;b++)
if(wzq[i][j+b]==0)
{
bpointcan2.x=i;
bpointcan2.y=j+b; break;
}
}
else
if(wzq[i][j+a]==1)
{
for(b=0;b<5;b++)
if(wzq[i][j+b]==0)
{
wpointcan2.x=i;
wpointcan2.y=j+b; break;
}
}
}
}
/////////////////////////////// num[2] "\"
m=0;
if(n==2)
{
for(k=0;k<5;k++)
if(wzq[i+k][j+k]==0)
m++;
if(m==1)
for(a=0;a<5;a++)
if(wzq[i+a][j+a]==0)
{
b=wzq[i+a+1][j+a+1]+wzq[i+a+2][j+a+2];
if(b==-2)
{
bpointcan2.x=i+a;
bpointcan2.y=j+a;
}
if(b==2)
{
wpointcan2.x=i+a;
wpointcan2.y=j+a;
}
}
if(m==3)
{
for(a=0;a<5;a++)
if(wzq[i+a][j+a]==-1)
{
for(b=0;b<5;b++)
if(wzq[i+b][j+b]==0)
{
bpointcan2.x=i+b;
bpointcan2.y=j+b; break;
}
}
else
if(wzq[i+a][j+a]==1)
{
for(b=0;b<5;b++)
if(wzq[i+b][j+b]==0)
{
wpointcan2.x=i+b;
wpointcan2.y=j+b; break;
}
}
}
}
////////////////////////////// num[3] "/"
m=0;
if(n==3)
{
for(k=0;k<5;k++)
if(wzq[i-k][j+k]==0)
m++;
if(m==1)
for(a=0;a<5;a++)
if(wzq[i-a][j+a]==0)
{
b=wzq[i-a-1][j+a+1]+wzq[i-a-2][j+a+2];
if(b==-2)
{
bpointcan2.x=i-a;
bpointcan2.y=j+a;
}
if(b==2)
{
wpointcan2.x=i-a;
wpointcan2.y=j+a;
}
}
if(m==3)
{
for(a=0;a<5;a++)
if(wzq[i-a][j+a]==-1)
{
for(b=0;b<5;b++)
if(wzq[i-b][j+b]==0)
{
bpointcan2.x=i-b;
bpointcan2.y=j+b; break;
}
}
else
if(wzq[i-a][j+a]==1)
{
for(b=0;b<5;b++)
if(wzq[i-b][j+b]==0)
{
wpointcan2.x=i-b;
wpointcan2.y=j+b; break;
}
}
}
}
}
//如果五個位置的和是壹
void CMy3_1View::searchcandown1(int i, int j, int n)
{
//計算剛才白棋落棋點
int ii=(vspoint.x-30)/20;
int jj=(vspoint.y-30)/20;
int a;
for(a=0;a<5;a++)
//如果不到邊界
if(ii+a<19)
{
//向右,如果有空位置
if(wzq[ii+a][jj]==0)
{
//在這個位置下黑棋
bpointcan1.x=ii+a;
bpointcan1.y=jj;
return;
}
}
//到了邊界
else
//向左,如果有空位置
if(wzq[ii-1][jj]==0)
{
bpointcan1.x=ii-a;
bpointcan1.y=jj;
return;
}
}
//vscomputer:2表示人對人,1表示人對機
void CMy3_1View::OnPlayer()
{
// TODO: Add your command handler code here
vscomputer=2;
OnStart();
}
void CMy3_1View::OnCpmputer()
{
// TODO: Add your command handler code here
vscomputer=1;
OnStart();
}