www.gusucode.com > 网络五子棋,VC++游戏源码源码程序 > 网络五子棋,VC++游戏源码源码程序\code\src\Board.cpp
#include "board.h" #include "Resource.h" #include "ConnectData.h" #include "Rule.h" #include "FiveChessDlg.h" //download by http://www.NewXing.com #define MAX_LEN 256 /*定义最大长度*/ ////////////////////////////////////////////////////////////////////////// // 构造函数,初始化棋盘数据以及图像数据 ////////////////////////////////////////////////////////////////////////// CBoard::CBoard() { // 初始化图像列表 m_iml.Create( 24, 24, ILC_COLOR24 | ILC_MASK, 0, 2 ); // 载入黑、白棋子掩码位图 CBitmap bmpBlack, bmpWhite; bmpBlack.LoadBitmap( IDB_BMP_BLACK ); m_iml.Add( &bmpBlack, 0xff00ff ); bmpWhite.LoadBitmap( IDB_BMP_WHITE ); m_iml.Add( &bmpWhite, 0xff00ff ); } ////////////////////////////////////////////////////////////////////////// // 析构函数 ////////////////////////////////////////////////////////////////////////// CBoard::~CBoard() { } // 消息映射表 BEGIN_MESSAGE_MAP( CBoard, CWnd ) //{{AFX_MSG_MAP(CBoard) ON_WM_PAINT() ON_WM_LBUTTONUP() //}}AFX_MSG_MAP END_MESSAGE_MAP() ////////////////////////////////////////////////////////////////////////// // 处理WM_PAINT消息 ////////////////////////////////////////////////////////////////////////// void CBoard::OnPaint() { CPaintDC dc( this ); CDC MemDC; MemDC.CreateCompatibleDC( &dc ); // 装载棋盘 CBitmap bmp; CPen pen; bmp.LoadBitmap( IDB_BMP_QP ); pen.CreatePen( PS_SOLID, 1, 0xff ); MemDC.SelectObject( &bmp ); MemDC.SelectObject( &pen ); MemDC.SetROP2( R2_NOTXORPEN ); // 根据棋盘数据绘制棋子 int x, y; POINT pt; for ( y = 0; y < 15; y++ ) { for ( x = 0; x < 15; x++ ) { if ( -1 != m_data[x][y] ) { pt.x = 12 + 25 * x; pt.y = 84 + 25 * y; m_iml.Draw( &MemDC, m_data[x][y], pt, ILD_TRANSPARENT ); } } } // 完成绘制 dc.BitBlt( 0, 0, 395, 472, &MemDC,0, 0, SRCCOPY ); } ////////////////////////////////////////////////////////////////////////// // 处理左键弹起消息,为玩家落子之用 ////////////////////////////////////////////////////////////////////////// void CBoard::OnLButtonUp( UINT nFlags, CPoint point ) { MSGSTRUCT msg; CRule rule; CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd(); BYTE buf[MAX_LEN] = {0}; if ( m_bWait) { MessageBeep( MB_OK ); return; } if(pDlg->m_bIsConnect) { int x, y; x = ( point.x - 12 ) / 25; y = ( point.y - 84 ) / 25; // 如果在(0, 0)~(14, 14)范围内,且该坐标没有落子, // 则落子于此,否则发声警告并退出过程 if ( x < 0 || x > 14 || y < 0 || y > 14 || m_data[x][y] != -1 ) { MessageBeep( MB_OK ); return; } else { // 如果位置合法,则落子 SetData( x, y, m_color ); msg.color = m_color; msg.x = x; msg.y = y; } // 开始等待 m_bWait = TRUE; msg.msgType = MSG_PUTSTEP; pDlg->Send(&msg); if(rule.Win(m_color, msg.x, msg.y) == _WIN) {// 胜利 pDlg->MessageBox( _T("恭喜,您获得了胜利!"), _T("胜利"), MB_ICONINFORMATION ); pDlg->SetMenuState(TRUE); } else if(rule.Win(m_color, msg.x, msg.y) == _LOST) {// 出现禁手 pDlg->MessageBox( _T("执黑禁手, 您输了!"), _T("失败"), MB_ICONINFORMATION ); pDlg->SetMenuState(TRUE); } } } ////////////////////////////////////////////////////////////////////////// // 清空棋盘 ////////////////////////////////////////////////////////////////////////// void CBoard::Clear( BOOL bWait ) { int x, y; for ( y = 0; y < 15; y++ ) { for ( x = 0; x < 15; x++ ) { m_data[x][y] = -1; } } // 设置等待标志 m_bWait = bWait; Invalidate(); } ////////////////////////////////////////////////////////////////////////// // 设置玩家颜色 ////////////////////////////////////////////////////////////////////////// void CBoard::SetColor(int color) { m_color = color; } ////////////////////////////////////////////////////////////////////////// // 获取玩家颜色 ////////////////////////////////////////////////////////////////////////// int CBoard::GetColor() const { return m_color; } ////////////////////////////////////////////////////////////////////////// // 设置等待标志 ////////////////////////////////////////////////////////////////////////// void CBoard::SetWait( BOOL bWait ) { m_bOldWait = m_bWait; m_bWait = bWait; } ////////////////////////////////////////////////////////////////////////// // 设置棋盘数据,并绘制棋子 ////////////////////////////////////////////////////////////////////////// void CBoard::SetData( int x, int y, int color ) { m_data[x][y] = color; Draw( x, y, color ); } ////////////////////////////////////////////////////////////////////////// // 在指定棋盘坐标处绘制指定颜色的棋子 ////////////////////////////////////////////////////////////////////////// void CBoard::Draw(int x, int y, int color) { POINT pt; pt.x = 12 + 25 * x; pt.y = 84 + 25 * y; CDC *pDC = GetDC(); CPen pen; pen.CreatePen( PS_SOLID, 1, 0xff ); pDC->SelectObject( &pen ); pDC->SetROP2( R2_NOTXORPEN ); m_iml.Draw( pDC, color, pt, ILD_TRANSPARENT ); ReleaseDC( pDC ); } ////////////////////////////////////////////////////////////////////////// // 接收来自对方的数据 ////////////////////////////////////////////////////////////////////////// void CBoard::Receive() { CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd(); MSGSTRUCT msg; if(pDlg->m_sock.Receive((LPVOID)&msg, sizeof(MSGSTRUCT)) == SOCKET_ERROR) { AfxGetMainWnd()->MessageBox( _T("接收数据时发生错误,请检查您的网络连接。"), _T("错误"), MB_ICONSTOP ); return; } switch(msg.msgType) { case MSG_PUTSTEP: SetData( msg.x, msg.y, msg.color ); Over(msg.x, msg.y); break; case MSG_DRAW: if ( IDYES == GetParent()->MessageBox( _T("对方请求和棋,接受这个请求吗?"), _T("和棋"), MB_ICONQUESTION | MB_YESNO ) ) { // 发送允许和棋消息 MSGSTRUCT msg; msg.msgType = MSG_AGREE_DRAW; pDlg->m_sock.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) ); SetWait( TRUE ); // 使“重玩”菜单生效 pDlg->SetMenuState(TRUE); } else { // 发送拒绝和棋消息 MSGSTRUCT msg; msg.msgType = MSG_REFUSE_DRAW; pDlg->m_sock.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) ); } break; case MSG_AGREE_DRAW: pDlg->MessageBox( _T("看来真是棋逢对手,对方接受了您的和棋请求。"), _T("和棋"), MB_ICONINFORMATION ); // 和棋后,使“重玩”菜单生效 pDlg->SetMenuState(TRUE); break; case MSG_REFUSE_DRAW: pDlg->MessageBox( _T("看来对方很有信心取得胜利,所以拒绝了您的和棋请求。"), _T("和棋"), MB_ICONINFORMATION ); RestoreWait(); pDlg->SetMenuState(FALSE); break; case MSG_EXTERN: break; default: break; } } ////////////////////////////////////////////////////////////////////////// // 和棋操作 ////////////////////////////////////////////////////////////////////////// void CBoard::DrawGame() { CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd(); // 设置等待标志 SetWait( TRUE ); MSGSTRUCT msg; msg.msgType = MSG_DRAW; pDlg->m_sock.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) ); } ////////////////////////////////////////////////////////////////////////// // 处理对方落子后的工作 ////////////////////////////////////////////////////////////////////////// void CBoard::Over(int x, int y) { CRule rule; CFiveChessDlg *pDlg = (CFiveChessDlg *)GetParent(); // 判断对方是否胜利 if ( rule.Win( 1 - m_color, x, y ) == _WIN) { pDlg->MessageBox( _T("您输了,不过不要灰心,失败乃成功之母哦!"), _T("失败"), MB_ICONINFORMATION ); // 如果是网络对战,则生效“重玩” if ( pDlg->m_bIsConnect ) { pDlg->SetMenuState(TRUE); } return; } //判断对方是否出现禁手 else if(rule.Win(1 - m_color, x, y) == _LOST) { pDlg->MessageBox( _T("恭喜您, 对方出现禁手输了!"), _T("胜利"), MB_ICONINFORMATION ); // 如果是网络对战,则生效“重玩” if ( pDlg->m_bIsConnect ) { pDlg->SetMenuState(TRUE); } return; } m_bWait = FALSE; } ////////////////////////////////////////////////////////////////////////// // 重新设置先前的等待标志 ////////////////////////////////////////////////////////////////////////// void CBoard::RestoreWait() { SetWait( m_bOldWait ); }