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

📄 ffview.cpp

📁 利用Visual c++编程思想方法实现五子棋游戏的程序设计整个过程
💻 CPP
📖 第 1 页 / 共 2 页
字号:

void CFfView::DestroyListenSocket()
{
	if(m_pListenSocket)
	{
		delete m_pListenSocket;
		m_pListenSocket = NULL;
	}
}

BOOL CFfView::IsWin(int x, int y)
{
	int xMin=max(0, x - 4);//x最近4个棋子坐标的最小值
	int xMax=min(DIVISIONS - 1, x + 4);//最大值
	int yMin=max(0, y - 4);//y的最小值
	int yMax=min(DIVISIONS - 1, y + 4);//最大值

	int i, j, p, q, sum1, sum2, sum3, sum4;

	for(j=xMin; j<=xMax-4; j++)
	{//判断横坐标是否已有4个棋子连续
		for(i=j, sum1=0; i<j+5; i++)
			if(m_nCoords[i][y]==m_nCoords[x][y])
				sum1++;

		if(sum1==5)
			return TRUE;
	}

	for(i=yMin; i<=yMax-4; i++)
	{//判断纵坐标是否已有4个棋子连续
		for(j=i, sum2=0; j<i+5; j++)
			if(m_nCoords[x][j]==m_nCoords[x][y])
				sum2++;
					

		if(sum2==5)
			return TRUE;
	}

	for(i=x, j=y; i>xMin && j>yMin; i--, j--);
	for(; i<=xMax-4 && j<=yMax-4; i++, j++)
	{//判断上半部分是否已有4个棋子连续
		for(sum3=0, p=i, q=j; p<i+5; p++, q++)
			if(m_nCoords[p][q]==m_nCoords[x][y])
				sum3++;

		if(sum3==5)
			return TRUE;
	}

	for(i=x, j=y; i>xMin && j<yMax; i--, j++);
	for(; i<=xMax-4 && j>=yMin+4; i++, j--)
	{//下半部分是否已有4个棋子连续
		for(sum4=0, p=i, q=j; p<i+5; p++, q--)
			if(m_nCoords[p][q]==m_nCoords[x][y])
				sum4++;

		if(sum4==5)
			return TRUE;
	}
	return FALSE;
}

void CFfView::OneStep(int x, int y)
{//重画新走的一步棋
	CRect invalidOldRect((m_ptLastStep.x + 1) * CELLSIZE - CELLSIZE / 2,
						 (m_ptLastStep.y + 1) * CELLSIZE - CELLSIZE / 2,
						 (m_ptLastStep.x + 1) * CELLSIZE + CELLSIZE / 2,
						 (m_ptLastStep.y + 1) * CELLSIZE + CELLSIZE / 2);

	InvalidateRect(&invalidOldRect, FALSE);

	m_ptLastStep.x = x;//新走棋的坐标
	m_ptLastStep.y = y;
	m_nCoords[x][y] = -m_nColor;//棋子颜色
				
	PlaySound(_T("down.wav"), NULL, SND_FILENAME | SND_ASYNC);
	CRect invalidRect((x + 1) * CELLSIZE - CELLSIZE / 2,
					  (y + 1) * CELLSIZE - CELLSIZE / 2,
					  (x + 1) * CELLSIZE + CELLSIZE / 2,
					  (y + 1) * CELLSIZE + CELLSIZE / 2);
	InvalidateRect(&invalidRect, FALSE);
}

void CFfView::OnPaint() 
{//绘制设备上下文
	CPaintDC dc(this); 
	
	CBitmap bitmap;
	bitmap.LoadBitmap (IDB_BKWOOD);

	CDC dcMem;//创建DC
	dcMem.CreateCompatibleDC(&dc);
	CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);

	CRect rect(0, 0, 0, 0);
	GetClientRect(&rect);

	dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcMem,
				  0, 0, 640, 640, SRCCOPY);

	for(int i = 1; i <= DIVISIONS; i++)
	{
		dc.MoveTo(CELLSIZE, i * CELLSIZE);//移到鼠标指定的点上
		dc.LineTo(DIVISIONS * CELLSIZE, i * CELLSIZE);//从指定点画线到目前的点
		dc.MoveTo(i * CELLSIZE, CELLSIZE);
		dc.LineTo(i * CELLSIZE, DIVISIONS * CELLSIZE);
	}

	dc.SelectStockObject(BLACK_BRUSH);

	int nRadius = 4;
	dc.Ellipse(CELLSIZE + CELLSIZE * 3 - nRadius,
			   CELLSIZE + CELLSIZE * 3 - nRadius,
			   CELLSIZE + CELLSIZE * 3 + nRadius,
			   CELLSIZE + CELLSIZE * 3 + nRadius);

	dc.Ellipse(CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) - nRadius,
			   CELLSIZE + CELLSIZE * 3 - nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) + nRadius,
			   CELLSIZE + CELLSIZE * 3 + nRadius);
	
	dc.Ellipse(CELLSIZE + CELLSIZE * (DIVISIONS / 2) - nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS / 2) - nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS / 2) + nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS / 2) + nRadius);
	
	dc.Ellipse(CELLSIZE + CELLSIZE * 3 - nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) - nRadius,
			   CELLSIZE + CELLSIZE * 3 + nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) + nRadius);
	
	dc.Ellipse(CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) - nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) - nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) + nRadius,
			   CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) + nRadius);
  //绘制五个关键点
	dc.SelectStockObject(NULL_BRUSH);

	CPen pen(PS_SOLID, 4, RGB(0, 0, 0));
	CPen* pOldPen = dc.SelectObject(&pen);

	CRect rectFrame(CELLSIZE, CELLSIZE, DIVISIONS * CELLSIZE + 2, DIVISIONS * CELLSIZE + 2);
	rectFrame.InflateRect(5, 5);
	dc.Rectangle(&rectFrame);

	dc.SelectObject(pOldPen);
	dc.SelectObject(pOldBitmap);
//绘制边框
	DrawPieces();
	// Do not call CView::OnPaint() for painting messages
}

BOOL CFfView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
	if(nHitTest == HTCLIENT && m_bLinked && m_bInGame)
	{
		if((m_bMyTurn && (m_nColor == 1)) ||
			(!m_bMyTurn && (m_nColor == -1)))
			::SetCursor(AfxGetApp()->LoadCursor(IDC_BLACK));
		else
			::SetCursor(AfxGetApp()->LoadCursor(IDC_WHITE));
		
		return TRUE;
	}

	return CView::OnSetCursor(pWnd, nHitTest, message);
}

void CFfView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	PlayBGMusic(_T("bgmusic.mid"));
	CView::OnTimer(nIDEvent);
}

void CFfView::PlayBGMusic(LPCSTR FileName)
{
	m_midi.Open(FileName);
	m_midi.Play();
}

void CFfView::OnActionDislink() 
{
	// TODO: Add your command handler code here
	int result = AfxMessageBox(_T("Are you sure you want to disconnect?"),
								MB_YESNO);
	if(result == IDYES)
	{
		int buf[3] = {DISCONNECT, 0, 0};
		m_pClientSocket->Send(buf, 3 * sizeof(int));
		m_bLinked = FALSE;
		m_bInGame = FALSE;
		DestroyClientSocket();
		m_bFlag = TRUE;
		ResetCoords();
		GetParent()->SetWindowText(_T("Ygj - Ready"));
	}
}

void CFfView::OnActionLink() 
{
	// TODO: Add your command handler code here
	CLinkDialog dlg;

	if(dlg.DoModal() == IDOK)
	{
		GetParent()->SetWindowText(_T("Ygj - Waiting for reply"));
		CreateClientSocket(dlg.m_strAddress);
	}
}

void CFfView::OnActionNew() 
{
	// TODO: Add your command handler code here
	int buf[3] = {NEWGAME, 0, 0};
	if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
	{
		AfxMessageBox(_T("Connection interrupted!\n"
						"Cannot connect to your partner."));
		m_bLinked = FALSE;
		DestroyClientSocket();
		GetParent()->SetWindowText(_T("Ygj - Ready"));
		return;
	}
	GetParent()->SetWindowText(_T("Ygj - Waiting for reply"));
}

void CFfView::OnActionSurrender() 
{//强制退出
	// TODO: Add your command handler code here
	int result = AfxMessageBox(_T("Are you sure you want to surrender?"),
								MB_YESNO);
	if(result == IDYES)
	{
		m_bMyTurn = FALSE;
		m_bInGame = FALSE;
		int buf[3] = {SURRENDER, 0, 0};
		if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
		{
			AfxMessageBox(_T("Connection interrupted!\n"
							"Cannot connect to your partner."));
			m_bLinked = FALSE;
			m_bInGame = FALSE;
			DestroyClientSocket();
			GetParent()->SetWindowText(_T("Ygj - Ready"));
			return;
		}
		GetParent()->SetWindowText(_T("Ygj - Game over"));
	}
}

void CFfView::OnMusicMusic() 
{
	// TODO: Add your command handler code here
	m_bMusicOn = !m_bMusicOn;
	if(m_bMusicOn)
	{
		PlayBGMusic(_T("bgmusic.mid"));
		SetTimer(ID_TIMER, m_midi.GetMidiLen() + 500, NULL);
	}
	else
	{
		KillTimer(ID_TIMER);
		PlayBGMusic(NULL);
	}
}

void CFfView::OnUpdateMusicMusic(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_bMusicOn);
}

void CFfView::OnUpdateActionDislink(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bLinked);
}

void CFfView::OnUpdateActionLink(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(!m_bLinked);
}

void CFfView::OnUpdateActionNew(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bLinked && !m_bInGame);
}

void CFfView::OnUpdateActionSurrender(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bLinked && m_bInGame);	
}

void CFfView::OnLButtonDown(UINT nFlags, CPoint point) 
{//获得棋子的具体位置信息
	// TODO: Add your message handler code here and/or call default
	if(m_bLinked && m_bMyTurn)
	{//判断是否连接并轮到当前机器走棋
		int x = (point.x - CELLSIZE / 2) / CELLSIZE;
		int y = (point.y - CELLSIZE / 2) / CELLSIZE;//具体位置信息
		if(x >= 0 && x < DIVISIONS && y >= 0 && y < DIVISIONS)
		{//判断按键是否在棋盘内部
			if(m_nCoords[x][y] == 0)
			{	//判断当前位置是否已经有棋子
				CRect invalidOldRect((m_ptLastStep.x + 1) * CELLSIZE - CELLSIZE / 2,
									 (m_ptLastStep.y + 1) * CELLSIZE - CELLSIZE / 2,
									 (m_ptLastStep.x + 1) * CELLSIZE + CELLSIZE / 2,
									 (m_ptLastStep.y + 1) * CELLSIZE + CELLSIZE / 2);

				InvalidateRect(&invalidOldRect, FALSE);

				PlaySound(_T("down.wav"), NULL, SND_FILENAME | SND_ASYNC);
				m_ptLastStep.x = x;
				m_ptLastStep.y = y;
				m_nCoords[x][y] = m_nColor;
				m_bMyTurn = FALSE;
				
				CRect invalidRect((x + 1) * CELLSIZE - CELLSIZE / 2,
								  (y + 1) * CELLSIZE - CELLSIZE / 2,
								  (x + 1) * CELLSIZE + CELLSIZE / 2,
								  (y + 1) * CELLSIZE + CELLSIZE / 2);
                  //当前一步棋子的位置
				InvalidateRect(&invalidRect, FALSE);

				int buf[3] = {0, x, y};
				if(IsWin(x, y))
				{//判断一方是否已经获胜
					if(m_nColor == -1)
					{
						if(m_bOpponentWin)
						{//如果对方获胜
							buf[0] = EVEN;	// even and game over
							m_bInGame = FALSE;
							GetParent()->SetWindowText(_T("Ygj - Game over"));
						}
						else
						{//对方输
							buf[0] = ULOSE;	// white win and game over
							m_bInGame = FALSE;
							GetParent()->SetWindowText(_T("Ygj - Game over"));
						}
					}
					else
					{//对方获胜,等待最后一步
						buf[0] = IWIN;		// black temp win, waiting for white's last step
						GetParent()->SetWindowText(_T("Ygj - Opponent's turn"));
					}
				}
				else
				{//如果没有分出胜负
					if(m_bOpponentWin)
					{
						buf[0] = UWIN;		// I lose and game over
						m_bInGame = FALSE;
						GetParent()->SetWindowText(_T("Ygj - Game over"));
					}
					else
					{//等待对方下棋
						GetParent()->SetWindowText(_T("Ygj - Opponent's turn"));
						buf[0] = COORDS;	// nobody wins, just an ordinary step
					}
				}

				if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
				{//如果属于连接错误
					AfxMessageBox(_T("Connection interrupted!\n"
								"Cannot continue with the game."));
					m_bLinked = FALSE;
					m_bInGame = FALSE;
					DestroyClientSocket();
					GetParent()->SetWindowText(_T("Ygj - Ready"));
					return;
				}
				// show game result messagebox if gameover
				if(buf[0] == EVEN)
				{
					AfxMessageBox(_T("Even game!"));
				}
				else if(buf[0] == ULOSE)
				{
					AfxMessageBox(_T("Congratulations!\n"
									"You won this game."));
				}
				else if(buf[0] == UWIN)
				{
					AfxMessageBox(_T("Sorry!\n"
									"You lost this game."));
				}
			}
		}
		else
		{
			::MessageBeep(MB_ICONEXCLAMATION);
		}
	}
	CView::OnLButtonDown(nFlags, point);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -