⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fchesvw.cpp

📁 一个用c ++写的 2人五子棋源码小程序
💻 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 + -