📄 fchesvw.cpp
字号:
// fchesvw.cpp : implementation of the CFchessView class
//
#include "stdafx.h"
#include "winsock.h"
#include "fchess.h"
#include ".\tcpsock\ts.h"
#include "fchesdoc.h"
#include "messageb.h"
#include "fchesvw.h"
//#include "estdlg.h"
//#include <afxext.h> // MFC extensions
char szYourTurn[10][40]=
{"该你了,加油啊...",
"该你了,这小子挺难对付的...",
"该你了,看来你要认真思考一下了...",
"该你了,这难不倒你的...",
"该你了,你可是天下第一哦...",
"该你了,加油啊...",
"该你了,加油啊...",
"该你了,加油啊...",
"该你了,加油啊...",
"该你了,加油啊..."};
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFchessView
IMPLEMENT_DYNCREATE(CFchessView, CView)
BEGIN_MESSAGE_MAP(CFchessView, CView)
ON_MESSAGE(WSA_READ, OnWSARead)
//{{AFX_MSG_MAP(CFchessView)
ON_COMMAND(ID_GAME_NEW, OnGameNew)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_DESTROY()
ON_COMMAND(ID_FUNCTION_SENDMESSAGETOOTHER, OnFunctionSendMessage)
ON_UPDATE_COMMAND_UI(ID_FUNCTION_SENDMESSAGETOOTHER, OnUpdateFunctionSendMessage)
ON_WM_SETCURSOR()
ON_COMMAND(ID_GAME_QUITCURRENTGAME, OnAbortGame)
ON_UPDATE_COMMAND_UI(ID_GAME_QUITCURRENTGAME, OnUpdateAbortGame)
ON_COMMAND(IDM_BEEP, OnBeep)
ON_UPDATE_COMMAND_UI(IDM_BEEP, OnUpdateBeep)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFchessView construction/destruction
CFchessView::CFchessView()
{
srand(time(NULL));
// TODO: add construction code here
m_fSound=AfxGetApp()->GetProfileInt("config","sound",1);
m_iTotalWin=AfxGetApp()->GetProfileInt("config","tw",0);
m_iTotalLost=AfxGetApp()->GetProfileInt("config","tl",0);
m_fFirstDeside=m_fEst=m_fCanDeside=FALSE;
for(int i=0;i<XVALUE;i++)
for(int j=0;j<YVALUE;j++)
m_bChessArray[i][j]=0;
}
CFchessView::~CFchessView()
{
AfxGetApp()->WriteProfileInt("config","sound",m_fSound);
AfxGetApp()->WriteProfileInt("config","tw",m_iTotalWin);
AfxGetApp()->WriteProfileInt("config","tl",m_iTotalLost);
}
BOOL is_five(int* piF)
{
for(int i=0;i<5;i++)
{
if(piF[i]==0)
return FALSE;
}
return TRUE;
}
BOOL is_six(int* piF)
{
for(int i=0;i<4;i++)
{
if(piF[i]==0)
return FALSE;
}
return TRUE;
}
BOOL CFchessView::IsMatch(const int iX,const int iY)
{//判断是否连续五颗
int fRes[6];
int x,y,i;
memset(fRes,0,sizeof(int)*5);
for(x=iX;x<iX+5 && x<XVALUE;x++)// to right
{
fRes[x-iX]=(m_bChessArray[iX][iY]==m_bChessArray[x][iY])?1:0;
}
if(is_five(fRes))
return TRUE;
memset(fRes,0,sizeof(int)*5);
for(y=iY;y<iY+5 && y<YVALUE;y++)// to down
{
fRes[y-iY]=(m_bChessArray[iX][iY]==m_bChessArray[iX][y])?1:0;
}
if(is_five(fRes))
return TRUE;
memset(fRes,0,sizeof(int)*5);
for(x=iX,y=iY;x>=0 && y<YVALUE && x>iX-5 ;x--,y++)// left down
{
fRes[y-iY]=(m_bChessArray[iX][iY]==m_bChessArray[x][y])?1:0;
}
if(is_five(fRes))
return TRUE;
memset(fRes,0,sizeof(int)*5);
for(x=iX,y=iY;x<XVALUE && y<YVALUE && y<iY+5 ;x++,y++)// right down
{
fRes[x-iX]=(m_bChessArray[iX][iY]==m_bChessArray[x][y])?1:0;
}
if(is_five(fRes))
return TRUE;
return FALSE;
}
BOOL CFchessView::IsMatch2(const int iX,const int iY)
{//判断是否连续四颗
int fRes[6];
int x,y,i;
memset(fRes,0,sizeof(int)*4);
for(x=iX;x<iX+4 && x<XVALUE;x++)// to right
{
fRes[x-iX]=(m_bChessArray[iX][iY]==m_bChessArray[x][iY] )?1:0;
}
if(is_six(fRes))
{
if(iX>0 && m_bChessArray[iX-1][iY]==0 && iX+5<XVALUE && m_bChessArray[iX+4][iY]==0)
return TRUE;
}
memset(fRes,0,sizeof(int)*4);
for(y=iY;y<iY+4 && y<YVALUE;y++)// to down
{
fRes[y-iY]=(m_bChessArray[iX][iY]==m_bChessArray[iX][y])?1:0;
}
if(is_six(fRes))
{
if(iY>0 && m_bChessArray[iX][iY-1]==0 && iY+5<YVALUE && m_bChessArray[iX][iY+4]==0)
return TRUE;
}
memset(fRes,0,sizeof(int)*4);
for(x=iX,y=iY;x>=0 && y<YVALUE && x>iX-4 ;x--,y++)// left down
{
fRes[y-iY]=(m_bChessArray[iX][iY]==m_bChessArray[x][y])?1:0;
}
if(is_six(fRes))
{
if(iX>0 && iY+5<YVALUE && m_bChessArray[iX-1][iY+4]==0
&& iX+5<XVALUE &&iY>0 && m_bChessArray[iX+4][iY-1]==0)
return TRUE;
}
memset(fRes,0,sizeof(int)*4);
for(x=iX,y=iY;x<XVALUE && y<YVALUE && y<iY+4 ;x++,y++)// right down
{
fRes[x-iX]=(m_bChessArray[iX][iY]==m_bChessArray[x][y])?1:0;
}
if(is_six(fRes))
{
if(iX>0 && iY>0&& m_bChessArray[iX-1][iY-1]==0
&& iX+5<XVALUE && iY+5<YVALUE && m_bChessArray[iX+4][iY+4]==0)
return TRUE;
}
return FALSE;
}
BOOL CFchessView::IsWin(int iChessValue)
{
for(int y=0;y<YVALUE;y++)
for(int x=0;x<XVALUE;x++)
{
if(m_bChessArray[x][y]==iChessValue)
if(IsMatch(x,y))
return TRUE;
}
for(int y1=1;y1<YVALUE;y1++)
for(int x1=1;x1<XVALUE;x1++)
{
if(m_bChessArray[x1][y1]==iChessValue)
if(IsMatch2(x1,y1))
return TRUE;
}
return FALSE;
}
BOOL CFchessView::JudgeWin(void)
{
int iCV=(m_tsComm.IsListenSide())?BLACK_CHESS:WHITE_CHESS;
return IsWin(iCV);
}
BOOL CFchessView::JudgeLost(void)
{
int iCV=(!m_tsComm.IsListenSide())?BLACK_CHESS:WHITE_CHESS;
return IsWin(iCV);
}
/////////////////////////////////////////////////////////////////////////////
// CFchessView drawing
void CFchessView::PlayMessage(void)
{
if(m_fSound)
MessageBeep(MB_ICONQUESTION);
}
void CFchessView::DrawBoard(CDC* pDC)
{
CPen penNew(PS_SOLID,1,RGB(0,0,0)),*ppenOld;
ppenOld=pDC->SelectObject(&penNew);
int iX,iY;
iX=iY=XSIZE;
for(int i=0;i<XVALUE;i++)
{//draw |
pDC->MoveTo(XSTART+iX*i,YSTART+0);
pDC->LineTo(XSTART+iX*i,YSTART+iY*(YVALUE-1));
}
for(int j=0;j<YVALUE;j++)
{
pDC->MoveTo(XSTART+0,YSTART+iY*j);
pDC->LineTo(XSTART+iX*(XVALUE-1),YSTART+iY*j);
}
pDC->SelectObject(ppenOld);
}
void CFchessView::DrawChess(CDC* pDC)
{
HICON hiconB=AfxGetApp()->LoadIcon(IDI_BLACK);
HICON hiconW=AfxGetApp()->LoadIcon(IDI_WHITE);
HICON hiconLB=AfxGetApp()->LoadIcon(IDI_LASTB);
HICON hiconLW=AfxGetApp()->LoadIcon(IDI_LASTW);
int iX,iY;
iX=iY=XSIZE;
for(int i=0;i<XVALUE;i++)
for(int j=0;j<YVALUE;j++)
{
switch(m_bChessArray[i][j])
{
case BLACK_CHESS:
pDC->DrawIcon(i*iX,j*iY,hiconB);
if(i==m_CPLast.bX && j==m_CPLast.bY)
pDC->DrawIcon(i*iX,j*iY,hiconLB);
break;
case WHITE_CHESS:
pDC->DrawIcon(i*iX,j*iY,hiconW);
if(i==m_CPLast.bX && j==m_CPLast.bY)
pDC->DrawIcon(i*iX,j*iY,hiconLW);
break;
default:
break;
}
}
}
void CFchessView::DrawCurrent(CDC* pDC)
{
DrawBoard(pDC);
DrawChess(pDC);
}
void CFchessView::OnDraw(CDC* pDC)
{
CFchessDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
DrawCurrent(pDC);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CFchessView diagnostics
#ifdef _DEBUG
void CFchessView::AssertValid() const
{
CView::AssertValid();
}
void CFchessView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CFchessDoc* CFchessView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFchessDoc)));
return (CFchessDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CFchessView message handlers
void CFchessView::OnGameNew()
{
//Sleep(40);
//m_tsComm.Close();
//m_fFirstDeside=m_fEst=m_fCanDeside=FALSE;
for(int i=0;i<XVALUE;i++)
for(int j=0;j<YVALUE;j++)
m_bChessArray[i][j]=0;
if(!m_fEst)
EstNew();
else
{
MakeNew(m_CP);
m_tsComm.Write((LPCSTR)&m_CP,sizeof(m_CP));
}
m_fLastMessage=FALSE;
m_fFirstDeside=FALSE;
m_fCanDeside=(m_tsComm.IsListenSide())?TRUE:FALSE;
Invalidate(TRUE);
}
void CFchessView::AskNew(void)
{
for(int i=0;i<XVALUE;i++)
for(int j=0;j<YVALUE;j++)
m_bChessArray[i][j]=0;
m_fLastMessage=FALSE;
m_fFirstDeside=FALSE;
m_fCanDeside=(m_tsComm.IsListenSide())?TRUE:FALSE;
//AfxMessageBox("New game");
SetMess("New Game !");
m_CPLast.bX=m_CPLast.bY=(BYTE)-1;
Invalidate(TRUE);
}
void CFchessView::EstNew(void)
{
//CEstDlg dlg(&m_tsComm,NULL,0X3000);
m_CPLast.bX=m_CPLast.bY=(BYTE)-1;
if(::EstComm(&m_tsComm,0X3000,NULL)==IDOK)
{
m_tsComm.Established(GetSafeHwnd());
//AfxMessageBox("Let's begin !",MB_OK);
SetMess("Let's Begin !");
m_fEst=TRUE;
m_fLastMessage=FALSE;
m_fFirstDeside=FALSE;
m_fCanDeside=(m_tsComm.IsListenSide())?TRUE:FALSE;
}
}
void CFchessView::SetMess(const char* pszMess)
{
CFrameWnd* pP=GetParentFrame();
CString szMess(pszMess);
CMessageBar* pBar=(CMessageBar*)pP->GetDescendantWindow(IDD_MESSAGEBAR);
if(pBar)
pBar->SetRecv(szMess);
}
void CFchessView::ReadMessage(void)
{
WORD wSize;
m_tsComm.Read((LPSTR)&wSize,sizeof(wSize));
LPSTR lpszRead=new char[wSize+1];
m_tsComm.Read(lpszRead,wSize);
lpszRead[wSize]='\0';
SetMess(lpszRead);
PlayMessage();
delete lpszRead;
}
LONG CFchessView::OnWSARead(UINT uP,LONG lP)
{
ASSERT(m_fEst);
if(WSAGETSELECTERROR(lP)!=0)
return 0L;
if(WSAGETSELECTEVENT(lP)==FD_READ)
{
if(m_fLastMessage)
{
m_fLastMessage=FALSE;
ReadMessage();
return 0L;
}
int iR=m_tsComm.Read((LPSTR)&m_CP,sizeof(m_CP));
if(iR==-1)
return 0L;
if(IsMessage(m_CP))
{
m_fLastMessage=TRUE;
return 0L;
}
if(IsNew(m_CP))
{
AskNew();
return 0L;
}
if(IsAskToQuit(m_CP))
{
m_fFirstDeside=m_fCanDeside=FALSE;
for(int i=0;i<XVALUE;i++)
for(int j=0;j<YVALUE;j++)
m_bChessArray[i][j]=0;
SetMess("Other abort !");
m_fLastMessage=FALSE;
Invalidate(TRUE);
if(m_tsComm.IsListenSide())
m_fCanDeside=TRUE;
}
else
{
ASSERT(IsValid(m_CP));
m_CPLast=m_CP;
m_bChessArray[m_CP.bX][m_CP.bY]=
(m_tsComm.IsListenSide())?
WHITE_CHESS:BLACK_CHESS;
//MessageBeep(MB_ICONQUESTION);
PlayMessage();
SetMess(szYourTurn[rand()%10]);
if(JudgeLost())
{
AskNew();
AfxMessageBox("You Lost !");
m_iTotalLost++;
//SetMess("You Lost !");
}
Invalidate(FALSE);
m_fCanDeside=TRUE;
}
}
else
{
for(int i=0;i<XVALUE;i++)
for(int j=0;j<YVALUE;j++)
m_bChessArray[i][j]=0;
m_tsComm.Close();
if(m_fEst)
SetMess("Connect Lost !");
m_fLastMessage=FALSE;
m_fFirstDeside=m_fEst=m_fCanDeside=FALSE;
Invalidate(TRUE);
}
return 0L;
}
void CFchessView::OnLButtonDown(UINT nFlags, CPoint point)
{
if(m_fEst&&
m_fCanDeside&&
point.x<XSIZE*(XVALUE)&&
point.y<XSIZE*(YVALUE))
{
int iX,iY;
iX=point.x/XSIZE;
iY=point.y/XSIZE;
if(m_bChessArray[iX][iY]==0)
{
m_fFirstDeside=TRUE;
m_CP.bX=iX;
m_CP.bY=iY;
CPoint ptC(iX*XSIZE-3,iY*XSIZE-3);
ClientToScreen(&ptC);
::SetCursorPos(ptC.x+5,ptC.y+5);
CRect rcC(ptC,CSize(XSIZE,XSIZE));
rcC+=CPoint(1,1);
ClipCursor(rcC);
}
}
else
//MessageBeep(MB_ICONQUESTION);
PlayMessage();
CView::OnLButtonDown(nFlags, point);
}
void CFchessView::OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_fEst&&m_fFirstDeside)
{
m_fFirstDeside=FALSE;
m_fCanDeside=FALSE;
m_bChessArray[m_CP.bX][m_CP.bY]=
(m_tsComm.IsListenSide())?
BLACK_CHESS:WHITE_CHESS;
Invalidate(FALSE);
m_tsComm.Write((LPCSTR)&m_CP,sizeof(m_CP));
ClipCursor(NULL);
SetMess("等待对方落棋...");
if(JudgeWin())
{
AskNew();
AfxMessageBox("You Win !");
m_iTotalWin++;
//SetMess("You Win !");
}
}
CView::OnLButtonUp(nFlags, point);
}
void CFchessView::OnRButtonDown(UINT nFlags, CPoint point)
{
if(m_fEst&&m_fFirstDeside)
{
m_fFirstDeside=FALSE;
m_fCanDeside=TRUE;
ClipCursor(NULL);
}
CView::OnRButtonDown(nFlags, point);
}
void CFchessView::OnDestroy()
{
CView::OnDestroy();
if(m_fEst)
{
m_CP.bX=m_CP.bY=0XFF;
m_tsComm.Write((LPCSTR)&m_CP,sizeof(m_CP));
Sleep(40);
m_tsComm.Close();
}
}
void CFchessView::OnFunctionSendMessage()
{
CString szSend;
CFrameWnd* pP=GetParentFrame();
CMessageBar* pBar=(CMessageBar*)pP->GetDescendantWindow(IDD_MESSAGEBAR);
if(pBar)
pBar->GetSend(szSend);
WORD wS=szSend.GetLength();
if(wS)
{
CHESSPOS CP;
SetMessage(CP);
m_tsComm.Write((LPCSTR)&CP,sizeof(CP));
Sleep(1000);
char *pszSend=new char[wS+sizeof(CP)];
memcpy(pszSend,&wS,sizeof(wS));
memcpy(pszSend+sizeof(wS),szSend,wS);
m_tsComm.Write((LPCSTR)pszSend,sizeof(wS)+wS);
delete pszSend;
}
}
void CFchessView::OnUpdateFunctionSendMessage(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_fEst);
}
BOOL CFchessView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(m_fEst&&m_fFirstDeside)
{
SetCursor(AfxGetApp()->LoadCursor(
(m_tsComm.IsListenSide())?
IDC_CHESSB:IDC_CHESSW));
return TRUE;
}
else
return CView::OnSetCursor(pWnd, nHitTest, message);
}
void CFchessView::OnAbortGame()
{
SetQuit(m_CP);
m_tsComm.Write((LPCSTR)&m_CP,sizeof(m_CP));
m_fFirstDeside=m_fCanDeside=FALSE;
for(int i=0;i<XVALUE;i++)
for(int j=0;j<YVALUE;j++)
m_bChessArray[i][j]=0;
SetMess("Abort !");
m_fLastMessage=FALSE;
Invalidate(TRUE);
if(m_tsComm.IsListenSide())
m_fCanDeside=TRUE;
}
void CFchessView::OnUpdateAbortGame(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_fEst);
}
void CFchessView::OnBeep()
{
m_fSound=!m_fSound;
}
void CFchessView::OnUpdateBeep(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_fSound);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -