www.gusucode.com > VC++三子棋游戏源码(类似五子棋)-源码程序 > VC++三子棋游戏源码(类似五子棋)-源码程序\code\Client\GameView.cpp
//Download by http://www.NewXing.com // GameView.cpp : implementation file // #include "stdafx.h" #include "SanQi.h" #include "GameView.h" #include "MainFrm.h" ////////////////////////////////////////// #include "lock.h" ////////////////////////////////////////// #define WINSOCK_VERSION 0x0101 const int WM_SOCKET_EVENT=WM_USER+103; const int MAX_BUFLEN = 1024; const int RECVMSG_BUFFER = MAX_BUFLEN*4; #define SERVER_PORT 6666 //服务器端口 //////////////////////////////////////////// #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// extern CString g_strFileName; #define INIT_CHESSINFO_TIMER 7000 #define TOKEN_ORDER_TIMER 7001 #define BLAST_DIE_TIMER 7010 //ExitGame #define EXIT_GAME_TIMER 7501 //OffLine #define OFFLINE_TIMER 8010 #define OFFLINE_LOADFILE_TIMER (OFFLINE_TIMER+1) #define OFFLINE_GETSTEPINFO_TIMER (OFFLINE_TIMER+2) #define OFFLINE_MOVESTEP_TIMER (OFFLINE_TIMER+3) ///////////////////////////////////////////////////////////////////////////// //Process Recv Message Thread UINT CGameView::ProcessRecvMsgThread(LPVOID lpParam) { TRACE("Enter ProcessRecvMsgThread(..) ...\n"); CGameView *view = (CGameView *)lpParam; view->run(); TRACE("Leave ProcessRecvMsgThread(..) ...\n"); return 0; } //Flash the selecting Chess UINT CGameView::FlashChessThread(LPVOID lpParam) { TRACE("Enter FlashChessThread(..) ...\n"); CGameView *view = (CGameView *)lpParam; view->FlashChess(INVALID_INDEX); TRACE("Leave FlashChessThread(..) ...\n"); return 0; } //Flash the falg that has been moved to another position UINT CGameView::FlashPositionThread(LPVOID lpParam) { TRACE("Enter FlashPositionThread(..) ...\n"); CGameView *view = (CGameView *)lpParam; view->FlashPosition(INVALID_INDEX); TRACE("Leave FlashPositionThread(..) ...\n"); return 0; } ///////////////////////////////////////////////////////////////////////////// // CGameView IMPLEMENT_DYNCREATE(CGameView, CView) CGameView::CGameView() { m_pChessInfo = NULL; m_strUserName = ""; m_strPassword = ""; m_strServerName = "127.0.0.1"; m_intPort = SERVER_PORT; m_hSocket = INVALID_SOCKET; m_bConnectToServer = FALSE; m_nTableID = 1; m_nPosition = INVALID_INDEX; InitControlData(); m_strRecordHistory = ""; //Sound m_pWaveSelect = NULL; m_pWaveComeIn = NULL; m_pWaveMineOK = NULL; m_pWaveReadyTo = NULL; m_pWaveMove = NULL; m_pWaveNoMove = NULL; m_pWaveEat = NULL; m_pWaveBeEat = NULL; m_pWaveEqual = NULL; m_pWaveDie = NULL; /// for(int i=0;i<4;i++) { m_ptOrderIcon[i].x = -100; m_ptOrderIcon[i].y = -100; } // m_nLastPreSelIndex = INVALID_INDEX; m_bPreSelChess = FALSE; m_nMyColor = NO_COLOR; m_nCurColor = RED; //OffLine m_bOffLine = TRUE; m_bOffLineControl = FALSE; m_hRunThread = NULL; m_bRunState = FALSE; } CGameView::~CGameView() { if( NULL != m_pChessInfo ) { delete m_pChessInfo; m_pChessInfo = NULL; } } BEGIN_MESSAGE_MAP(CGameView, CView) //{{AFX_MSG_MAP(CGameView) ON_WM_CREATE() ON_WM_SIZE() ON_WM_ERASEBKGND() ON_WM_MOUSEMOVE() ON_WM_SETCURSOR() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_TIMER() ON_WM_DESTROY() //}}AFX_MSG_MAP //Socket Event... ON_MESSAGE(WM_SOCKET_EVENT, OnSocketEvent) // END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CGameView drawing void CGameView::OnDraw(CDC* pDC) { CDocument* pDoc = GetDocument(); // TODO: add draw code here } ///////////////////////////////////////////////////////////////////////////// // CGameView diagnostics #ifdef _DEBUG void CGameView::AssertValid() const { CView::AssertValid(); } void CGameView::Dump(CDumpContext& dc) const { CView::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CGameView message handlers int CGameView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; m_statusBarDlg.Create(this); /////// //Chess Borad InitControlData(); LoadWavRes(); BuildChessBoard(); InitButtonPosition(); m_nButtonActionMode = OFFLINE; InitOrderIconPosition(); /////// return 0; } BOOL CGameView::OnEraseBkgnd(CDC* pDC) { DrawAll(pDC); return TRUE; } void CGameView::SetWindowTitle() { //SetWindowText CString strTmpText = g_strFileName; strTmpText.MakeReverse(); strTmpText = strTmpText.SpanExcluding("\\"); strTmpText.MakeReverse(); CString strWindowText(""); strWindowText.Format("[Game4War -- %s] -- Load file: < %s >, Total steps: ( %d ) --> %d",m_strUserName,strTmpText,m_nTotalStepCount,m_nCurStepCount); ::SetWindowText(AfxGetMainWnd()->m_hWnd,strWindowText); } LRESULT CGameView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_COMMAND: { if(HIWORD(wParam) == BN_CLICKED) { int nButtonID = LOWORD(wParam); if(m_nButtonActionMode == INGAMES)//0,1,2 { if(nButtonID == GAME_BUTTONID_0) { OnBtStartGame(); } else if(nButtonID == GAME_BUTTONID_1) { OnBtSaveChessInfo(); } else if(nButtonID == GAME_BUTTONID_2) { OnBtLoadChessInfo(); } } else if(m_nButtonActionMode == PLAYING_MOVE) { if(nButtonID == GAME_BUTTONID_1) { OnBtImpetratePeace(); } else if(nButtonID == GAME_BUTTONID_2) { OnBtSurrender(); } } else { if(nButtonID == GAME_BUTTONID_0) { OnBtOpenFile(); } else if(nButtonID == GAME_BUTTONID_1) { OnBtPreviousStep(); } else if(nButtonID == GAME_BUTTONID_2) { OnBtNextStep(); } else if(nButtonID == GAME_BUTTONID_3) { OnBtSaveChessInfo(); } } } break; } default: { break; } } return CView::WindowProc(message, wParam, lParam); } BOOL CGameView::PreTranslateMessage(MSG* pMsg) { //Only for OffLine... if(!m_bOffLine) return FALSE; if(pMsg->message == WM_KEYDOWN) { switch(pMsg->wParam) { case VK_LEFT: { OnBtPreviousStep(); break; } case VK_RIGHT: { OnBtNextStep(); break; } } } return CView::PreTranslateMessage(pMsg); } void CGameView::OnInitialUpdate() { CView::OnInitialUpdate(); // TODO: Add your specialized code here and/or call the base class { SetPosition(); SetBitmap(); SetTextFont(); m_tColor_Dark = COLOR_DARK_GRAY; m_tColor_Yellow = COLOR_YELLOW; m_tColor_Black = COLOR_BLACK; m_tColor_Red = COLOR_RED; COLORREF tColorBk = RGB(160, 180, 220); m_tBkBrush.CreateSolidBrush(tColorBk); m_hHandCursor = LoadCursor(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDC_CURSOR_HAND)); } //Will Init All Chess Information SetTimer(INIT_CHESSINFO_TIMER, 50, NULL); //Load the Chess info SetTimer(OFFLINE_LOADFILE_TIMER,5,NULL); /////////////////////////////////////////////////////////////// //CommandLine:Server-Port:UserName:TableID-Position# CString strCommandLine = GetCommandLine(); // strCommandLine = "CommandLine|127.0.0.1-6770|younggle|6-1"; CString strServerName("127.0.0.1"); int nPort = 0; if(strCommandLine.Find("|") != -1) //OnLine { if(Connect(strServerName,nPort)) { CString strComment(""); strComment.Format("Connect Server [%s:%d] successfully!",strServerName,nPort); //Create ProcessRecvMsgThread(..) .... m_hRunThread = ::CreateThread(NULL,1024, (LPTHREAD_START_ROUTINE)CGameView::ProcessRecvMsgThread, (LPVOID)this,0,NULL); m_bRunState = (m_hRunThread != NULL); /// m_bOffLine = FALSE; } } else //OffLine { ShowButtons(OFFLINE); m_bOffLine = TRUE; m_strChessInfoList.RemoveAll(); m_curStepPosition = NULL; m_moveStepPosition = NULL; m_nTotalStepCount = 0; m_nCurStepCount = 0; } /////////////////////////////////////////////////////////////// } void CGameView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here if(GetSafeHwnd() == NULL) return; CRect rect,oldRect; GetClientRect(&rect); if(rect.right-rect.left < 700 || rect.right-rect.left > 850) { ::SendMessage(::AfxGetMainWnd()->m_hWnd,WM_SIZE,(WPARAM)cx,(LPARAM)cy); ::SendMessage(::AfxGetMainWnd()->m_hWnd,WM_PAINT,0,0); } CWnd* pWnd =&m_statusBarDlg; SAFE_CHECKWND(pWnd) { RECT rect,rt; memset(&rect, 0, sizeof(RECT)); this->GetClientRect(&rect); pWnd->GetClientRect(&rt); rect.top =rect.bottom - 18; //18--Status Bar Height pWnd->MoveWindow(&rect); m_statusBarDlg.SetStatus(" Ready"); } } void CGameView::BuildChessBoard() { } void CGameView::InvalidateGameRect() { if( NULL == m_pChessInfo ) return; CHESS_STRUCT *pFirstChessInfo = &m_pChessInfo[0]; CHESS_STRUCT *pLastChessInfo = &m_pChessInfo[TOTAL_POINTS - 1]; int nDistance = 5; CRect rect; rect.left = pFirstChessInfo->point.x - nDistance; rect.right = pLastChessInfo->point.x + CHESS_WIDTH + nDistance; rect.top = pFirstChessInfo->point.y - nDistance; rect.bottom = pLastChessInfo->point.y + CHESS_HEIGHT + nDistance; InvalidateRect(rect); } void CGameView::InvalidateOrderIconRect() { int iWidthHeight = 32; for(int d=0;d<4;d++) { CRect rect; memset(&rect, 0, sizeof(CRect)); this->GetClientRect(&rect); rect.left = m_ptOrderIcon[d].x; rect.top = m_ptOrderIcon[d].y; rect.right = rect.left + 2*iWidthHeight; rect.bottom = rect.top + 2*iWidthHeight; InvalidateRect(&rect); } } void CGameView::LoadWavRes() { if(m_pWaveSelect != NULL) return; HMODULE hmod = AfxGetResourceHandle(); HRSRC hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_SELECT),_T("WAVE")); m_pWaveSelect = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_COMEIN),_T("WAVE")); m_pWaveComeIn = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_MINEOK),_T("WAVE")); m_pWaveMineOK = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_READYTO),_T("WAVE")); m_pWaveReadyTo = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_TAKEDOWN),_T("WAVE")); m_pWaveTakeDown = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_MOVE),_T("WAVE")); m_pWaveMove = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_NOMOVE),_T("WAVE")); m_pWaveNoMove = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_EAT),_T("WAVE")); m_pWaveEat = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_BEEAT),_T("WAVE")); m_pWaveBeEat = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_EQUAL),_T("WAVE")); m_pWaveEqual = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_SHOWCHESS),_T("WAVE")); m_pWaveShowChess = LoadResource(hmod,hSndResource); hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE_DIE),_T("WAVE")); m_pWaveDie = LoadResource(hmod,hSndResource); } void CGameView::FreeWavRes() { if(m_pWaveSelect) { FreeResource(m_pWaveSelect); m_pWaveSelect = NULL; } if(m_pWaveMove) { FreeResource(m_pWaveMove); m_pWaveMove = NULL; } if(m_pWaveNoMove) { FreeResource(m_pWaveNoMove); m_pWaveNoMove = NULL; } if(m_pWaveEat) { FreeResource(m_pWaveEat); m_pWaveEat = NULL; } if(m_pWaveBeEat) { FreeResource(m_pWaveBeEat); m_pWaveBeEat = NULL; } if(m_pWaveEqual) { FreeResource(m_pWaveEqual); m_pWaveEqual = NULL; } if(m_pWaveShowChess) { FreeResource(m_pWaveShowChess); m_pWaveShowChess = NULL; } if(m_pWaveDie) { FreeResource(m_pWaveDie); m_pWaveDie = NULL; } } void CGameView::PlaySoundAction(int iResult) { sndPlaySound(NULL,0); } void CGameView::InitTableInfo() { } void CGameView::InitChessInfo() { /*// 00 ○━01━02━○━04━05━○ ┃\│ │ ┃ │ │/┃ 07─○━09━○━11━○─13 ┃ ┃\│ ┃ │/┃ ┃ 14─15─○━○━○─19─20 ┃ ┃ ┃ ┃ ┃ ┃ ○━○━○ 24 ○━○━○ ┃ ┃ ┃ ┃ ┃ ┃ 28─29─○━○━○─33─34 ┃ ┃/│ ┃ │\┃ ┃ 35─○━37━○━39━○─41 ┃/│ │ ┃ │ │\┃ ○━43━44━○━46━47━○ 48 //*/ //// const int nBoardWidth = BOARD_WIDTH; const int nBoardHeight = BOARD_HEIGHT; const int nChessWidth = CHESS_WIDTH; const int nChessHeight = CHESS_HEIGHT; CRect rect; GetClientRect(&rect); int nCenterX = (rect.left + rect.right)/2; int nCenterY = (rect.top + rect.bottom)/2; const int nStartPosX = nCenterX - nBoardWidth/2; const int nStartPosY = nCenterY - nBoardHeight/2; const int nBoardBaseSize = BOARD_BASE_SIZE; //// //// if( NULL != m_pChessInfo ) { delete m_pChessInfo; m_pChessInfo = NULL; } int nChessCount = TOTAL_POINTS; m_pChessInfo = new CHESS_STRUCT[nChessCount]; const int nBasePoints = BASE_POINTS; const int nLinePoints = (nBasePoints * 2) + 1; int nPosArray[nLinePoints][nLinePoints]; for(int i = 0; i < nLinePoints; i++) { for(int j=0; j < nLinePoints; j++) { nPosArray[i][j] = i*nLinePoints + j; } } int nIndex = 0; for(i = 0; i < nLinePoints; i++) { for(int j=0; j < nLinePoints; j++) { m_pChessInfo[nIndex].nIndex = nIndex; m_pChessInfo[nIndex].point = INVLID_POS; m_pChessInfo[nIndex].bRealPos = FALSE; m_pChessInfo[nIndex].tColor = NO_COLOR; m_pChessInfo[nIndex].tValue = NO_CHESS; m_pChessInfo[nIndex].nSelMode = NO_SELECTED; m_pChessInfo[nIndex].bFlashOn = FALSE; int nValue = nPosArray[i][j]; if( ( (i == j) || (i == nLinePoints/2) || (j == nLinePoints/2) || ((i+j) == (nLinePoints-1)) ) && (nValue != nLinePoints*nLinePoints/2) ) { int nX = (nStartPosX + nBoardBaseSize * j) - nChessWidth/2; int nY = (nStartPosY + nBoardBaseSize * i) - nChessHeight/2; m_pChessInfo[nIndex].point = CPoint(nX, nY); m_pChessInfo[nIndex].bRealPos = TRUE; } nIndex++; } } InvalidateGameRect(); //// } void CGameView::InitControlData() { m_nSrcSelIndex = INVALID_INDEX; m_nLastSrcSelIndex = INVALID_INDEX; m_bSelSrcChess = FALSE; m_nDestSelIndex = INVALID_INDEX; m_nLastDestSelIndex = INVALID_INDEX; m_bSelDestChess = FALSE; m_nFlashingIndex = INVALID_INDEX; m_bFlashChessThread = FALSE; m_bFlashPositionThread = FALSE; m_tGameStatus = OFFLINE; m_bCanMoveChess = TRUE; m_bPeaceAction = FALSE; m_bTakenOrderOnOff = TRUE; m_nLeftTime = 1; m_bDelayTime = FALSE; for(int i=0;i<4;i++) { nDelayCount[i] = 0; } } void CGameView::LoadChessData(int direction,int ChessColor, CString strChessInfo /* = ""*/) { } ///////////////////////////////////////////////////////////////// void CGameView::SetPosition() { } void CGameView::SetBitmap() { BMP_COMMENT.DeleteObject(); BMP_COMMENT.LoadBitmap(IDB_COMMENT); ///////////////////////////////////// ///* BMP_RED_CHESS.DeleteObject(); BMP_RED_CHESS.LoadBitmap(IDB_RED_CHESS); BMP_BLUE_CHESS.DeleteObject(); BMP_BLUE_CHESS.LoadBitmap(IDB_BLUE_CHESS); //*/ BMP_SRCMOVEFLAG.DeleteObject(); BMP_SRCMOVEFLAG.LoadBitmap(IDB_SRCMOVEFLAG); BMP_TOKENORDER.DeleteObject(); BMP_TOKENORDER.LoadBitmap(IDB_TOKEN_ORDER); BMP_LEFTTIME.DeleteObject(); BMP_LEFTTIME.LoadBitmap(IDB_LEFT_TIME); } void CGameView::SetTextFont() { LOGFONT lf; memset(&lf,0,sizeof(LOGFONT)); lf.lfHeight=16; lf.lfWeight=14; m_textFont.CreateFontIndirect(&lf); } void CGameView::TransparentBlt(CDC * pDestDc, int x, int y, int w, int h, CBitmap * pBmp, int sx, int sy, COLORREF crTransparent) { CDC memDC, maskDC, tempDC; maskDC.CreateCompatibleDC(pDestDc); CBitmap maskBitmap; //add these to store return of SelectObject() calls CBitmap* pOldMemBmp = NULL; CBitmap* pOldMaskBmp = NULL; memDC.CreateCompatibleDC(pDestDc); tempDC.CreateCompatibleDC(pDestDc); CBitmap bmpImage; bmpImage.CreateCompatibleBitmap( pDestDc, w, h); pOldMemBmp = memDC.SelectObject( &bmpImage ); CBitmap * oldBmp = tempDC.SelectObject(pBmp); memDC.BitBlt( 0,0,w, h, &tempDC, sx, sy, SRCCOPY ); // Create monochrome bitmap for the mask maskBitmap.CreateBitmap(w, h, 1, 1, NULL); pOldMaskBmp = maskDC.SelectObject( &maskBitmap ); memDC.SetBkColor(crTransparent); // Create the mask from the memory DC maskDC.BitBlt(0, 0, w, h, &memDC, 0, 0, SRCCOPY); memDC.SetBkColor(RGB(0,0,0)); memDC.SetTextColor(RGB(255,255,255)); memDC.BitBlt(0, 0, w, h, &maskDC, 0, 0, SRCAND); // Set the foreground to black. See comment above. pDestDc->SetBkColor(RGB(255,255,255)); pDestDc->SetTextColor(RGB(0,0,0)); pDestDc->BitBlt(x, y, w, h, &maskDC, 0, 0, SRCAND); // Combine the foreground with the background pDestDc->BitBlt(x, y, w, h, &memDC, 0, 0, SRCPAINT); tempDC.SelectObject(oldBmp); if (pOldMaskBmp) maskDC.SelectObject( pOldMaskBmp ); if (pOldMemBmp) memDC.SelectObject( pOldMemBmp ); } void CGameView::InitButtonPosition() { int iWidth = BUTTON_WIDTH; int iHeight = BUTTON_HEIGHT; int iOneStep = 0; int iX = 0; int iY = 0; for(int i=0;i<4;i++) { int startX = iX + 3*iOneStep + iWidth/2; int startY = iY + 6*iOneStep + (iHeight + 5)*i - iHeight; m_ptButtonPos[i].x = startX; m_ptButtonPos[i].y = startY; } /////////////////////////// RECT rect; memset(&rect, 0, sizeof(RECT)); for(i=0; i<4;i++) { rect.left = m_ptButtonPos[i].x; rect.right = rect.left + BUTTON_WIDTH; rect.top = m_ptButtonPos[i].y; rect.bottom = rect.top + BUTTON_HEIGHT; m_btGameButtons[i].Create("三棋游戏", WS_VISIBLE|WS_CHILD|WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, rect, this, GAME_BUTTONID_0+i); //Set Button property m_btGameButtons[i].SetFlat(FALSE); m_btGameButtons[i].SetColor(CButtonST::BTNST_COLOR_FG_IN, RGB(255,0,0)); m_btGameButtons[i].SetColor(CButtonST::BTNST_COLOR_FG_OUT, RGB(255,0,0)); m_btGameButtons[i].ShowWindow(SW_HIDE); m_btGameButtons[i].EnableWindow(FALSE); m_btGameButtons[i].SetWindowText(""); } ////////////////////////////// } void CGameView::ShowButtons(GAMESTATUS nMode) { m_nButtonActionMode = nMode; int color = (int)(0xffffffff - 10L); COLORREF rgb = RGB(255, 255, 255); if(m_bOffLine) { m_nButtonActionMode = OFFLINE; //0,1,2,3 //m_btGameButtons[0].SetWindowText("打开文件"); m_btGameButtons[0].SetBitmaps(IDB_OPENFILE,rgb,color); m_btGameButtons[0].ShowWindow(SW_SHOW); m_btGameButtons[0].EnableWindow(TRUE); //m_btGameButtons[1].SetWindowText(" 上一步 "); m_btGameButtons[1].SetBitmaps(IDB_PREVSTEP,rgb,color); m_btGameButtons[1].ShowWindow(SW_SHOW); m_btGameButtons[1].EnableWindow(FALSE); //m_btGameButtons[2].SetWindowText(" 下一步 "); m_btGameButtons[2].SetBitmaps(IDB_NEXTSTEP,rgb,color); m_btGameButtons[2].ShowWindow(SW_SHOW); m_btGameButtons[2].EnableWindow(FALSE); //m_btGameButtons[3].SetWindowText("保存棋谱"); m_btGameButtons[3].SetBitmaps(IDB_SAVEINFOS,rgb,color); m_btGameButtons[3].ShowWindow(SW_SHOW); m_btGameButtons[3].EnableWindow(FALSE); } else if(nMode == PLAYING_MOVE) //(In Game) { //1,2 //m_btGameButtons[1].SetWindowText("祈求和平"); m_btGameButtons[1].SetBitmaps(IDB_HOPEPEACE,rgb,color); m_btGameButtons[1].ShowWindow(SW_SHOW); m_btGameButtons[1].EnableWindow(TRUE); //m_btGameButtons[2].SetWindowText("缴械投降"); m_btGameButtons[2].SetBitmaps(IDB_SURRENDER,rgb,color); m_btGameButtons[2].ShowWindow(SW_SHOW); m_btGameButtons[2].EnableWindow(TRUE); } else if(nMode == READY) //(m_bWaitForGame) { for(int i=0; i<4;i++) { m_btGameButtons[i].ShowWindow(SW_HIDE); m_btGameButtons[i].EnableWindow(FALSE); } } else if(nMode == INGAMES) //(m_bReadyToGame) { //0,1,2 //m_btGameButtons[0].SetWindowText("大军出征"); m_btGameButtons[0].SetBitmaps(IDB_STARTGAME,rgb,color); m_btGameButtons[0].ShowWindow(SW_SHOW); m_btGameButtons[0].EnableWindow(TRUE); //m_btGameButtons[1].SetWindowText("保存阵图"); m_btGameButtons[1].SetBitmaps(IDB_SAVEINFO,rgb,color); m_btGameButtons[1].ShowWindow(SW_SHOW); m_btGameButtons[1].EnableWindow(TRUE); //m_btGameButtons[2].SetWindowText("载入阵图"); m_btGameButtons[2].SetBitmaps(IDB_LOADINFO,rgb,color); m_btGameButtons[2].ShowWindow(SW_SHOW); m_btGameButtons[2].EnableWindow(TRUE); } } void CGameView::InitOrderIconPosition() { int iOneStep = 0; int iPosX = 0; int iPosY = 0; int nStartPosX = iPosX - 4*iOneStep; int nStartPosY = iPosY + 7*iOneStep; m_ptOrderIcon[0].x = nStartPosX; m_ptOrderIcon[0].y = nStartPosY; nStartPosX = iPosX - 6*iOneStep; nStartPosY = iPosY - 4*iOneStep; m_ptOrderIcon[1].x = nStartPosX; m_ptOrderIcon[1].y = nStartPosY; nStartPosX = iPosX + 4*iOneStep; nStartPosY = iPosY - 7*iOneStep; m_ptOrderIcon[2].x = nStartPosX; m_ptOrderIcon[2].y = nStartPosY; nStartPosX = iPosX + 6*iOneStep; nStartPosY = iPosY + 4*iOneStep; m_ptOrderIcon[3].x = nStartPosX; m_ptOrderIcon[3].y = nStartPosY; } void CGameView::DrawAll(CDC *pDC) { CDC memDC; CBitmap bitmap; CBitmap* pOldBitmap; if( memDC.CreateCompatibleDC(pDC) ) { CRect rect; GetClientRect(&rect); if(bitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom)) { pOldBitmap = memDC.SelectObject(&bitmap); const int nBoardWidth = BOARD_WIDTH; const int nBoardHeight = BOARD_HEIGHT; rect.bottom = rect.bottom; memDC.FillRect(&rect,&m_tBkBrush); //////////////////////////////////////////////// //把要画图的代码放在这里 DrawBkGround(&memDC); DrawChessBoard(&memDC); DrawAllChessMan(&memDC, m_pChessInfo); //////////////////////////////////////////////// pDC->BitBlt(rect.left, rect.top, rect.right, rect.bottom, &memDC, 0, 0, SRCCOPY); memDC.SelectObject( pOldBitmap ); bitmap.DeleteObject(); memDC.DeleteDC(); ReleaseDC(&memDC); } } } void CGameView::DrawBkGround(CDC *pDC) { } void CGameView::DrawChessBoard(CDC *pDC) { //画棋盘 //// const int nBoardWidth = BOARD_WIDTH; const int nBoardHeight = BOARD_HEIGHT; const int nBoardBaseSize = BOARD_BASE_SIZE; CRect rect; GetClientRect(&rect); int nCenterX = (rect.left + rect.right)/2; int nCenterY = (rect.top + rect.bottom)/2; const int nStartPosX = nCenterX - nBoardWidth/2; const int nStartPosY = nCenterY - nBoardHeight/2; //// const COLORREF tRectColor = RGB(32, 32, 32); const COLORREF tLineColor = RGB(240, 240, 240); int nBaseCount = BASE_POINTS; //画外边框, 中间边框, 内边框 for(int nIndex = 0; nIndex < nBaseCount; nIndex++) { int nPosX = nStartPosX + (nBoardBaseSize * nIndex); int nPosY = nStartPosY + (nBoardBaseSize * nIndex); int nWidth = nBoardWidth - (nBoardBaseSize * nIndex * 2); int nHeight = nBoardHeight - (nBoardBaseSize * nIndex * 2); int nStep = 0; pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, nWidth-nStep*2, nHeight-nStep*2, tLineColor, tLineColor); nStep = 1; pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, nWidth-nStep*2, nHeight-nStep*2, tRectColor, tRectColor); nStep = 2; pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, nWidth-nStep*2, nHeight-nStep*2, tRectColor, tRectColor); nStep = -1; pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, nWidth-nStep*2, nHeight-nStep*2, tRectColor, tRectColor); nStep = -2; pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, nWidth-nStep*2, nHeight-nStep*2, tRectColor, tRectColor); } //画直连线(顺时针画) { CPen tPen; tPen.CreatePen(PS_SOLID, 3, tRectColor); CPen* pOldPen =(CPen*)pDC->SelectObject(&tPen); int nDistanceX = nBoardBaseSize * (nBaseCount - 1); int nDistanceY = nBoardBaseSize * (nBaseCount - 1); int nFromPosX = nStartPosX; int nFromPosY = nStartPosY; int nToPosX = nStartPosX + nDistanceX; int nToPosY = nStartPosY + nDistanceY; pDC->MoveTo(nFromPosX, nFromPosY); pDC->LineTo(nToPosX, nToPosY); pDC->MoveTo(nFromPosX+nBoardWidth/2, nFromPosY); pDC->LineTo(nToPosX+nDistanceX/2, nToPosY); pDC->MoveTo(nFromPosX+nBoardWidth, nFromPosY); pDC->LineTo(nToPosX+nDistanceX, nToPosY); pDC->MoveTo(nFromPosX+nBoardWidth, nFromPosY+nBoardHeight/2); pDC->LineTo(nToPosX+nDistanceX, nToPosY+nDistanceX/2); pDC->MoveTo(nFromPosX+nBoardWidth, nFromPosY+nBoardHeight); pDC->LineTo(nToPosX+nDistanceX, nToPosY+nDistanceX); pDC->MoveTo(nFromPosX+nBoardWidth/2, nFromPosY+nBoardHeight); pDC->LineTo(nToPosX+nDistanceX/2, nToPosY+nDistanceX); pDC->MoveTo(nFromPosX, nFromPosY+nBoardHeight); pDC->LineTo(nToPosX, nToPosY+nDistanceX); pDC->MoveTo(nFromPosX, nFromPosY+nBoardHeight/2); pDC->LineTo(nToPosX, nToPosY+nDistanceX/2); pDC->SelectObject(pOldPen); tPen.DeleteObject(); } { CPen tPen; tPen.CreatePen(PS_SOLID, 1, tLineColor); CPen* pOldPen =(CPen*)pDC->SelectObject(&tPen); int nDistanceX = nBoardBaseSize * (nBaseCount - 1); int nDistanceY = nBoardBaseSize * (nBaseCount - 1); int nFromPosX = nStartPosX; int nFromPosY = nStartPosY; int nToPosX = nStartPosX + nDistanceX; int nToPosY = nStartPosY + nDistanceY; int nOffSet = 2; pDC->MoveTo(nFromPosX+nOffSet, nFromPosY+nOffSet); pDC->LineTo(nToPosX-nOffSet, nToPosY-nOffSet); pDC->MoveTo(nFromPosX+nBoardWidth/2, nFromPosY+nOffSet); pDC->LineTo(nToPosX+nDistanceX/2, nToPosY-nOffSet); pDC->MoveTo(nFromPosX+nBoardWidth-nOffSet, nFromPosY+nOffSet); pDC->LineTo(nToPosX+nDistanceX, nToPosY); pDC->MoveTo(nFromPosX+nBoardWidth-nOffSet, nFromPosY+nBoardHeight/2); pDC->LineTo(nToPosX+nDistanceX+nOffSet, nToPosY+nDistanceX/2); pDC->MoveTo(nFromPosX+nBoardWidth-nOffSet, nFromPosY+nBoardHeight-nOffSet); pDC->LineTo(nToPosX+nDistanceX, nToPosY+nDistanceX); pDC->MoveTo(nFromPosX+nBoardWidth/2, nFromPosY+nBoardHeight-nOffSet); pDC->LineTo(nToPosX+nDistanceX/2, nToPosY+nDistanceX); pDC->MoveTo(nFromPosX+nOffSet, nFromPosY+nBoardHeight-nOffSet); pDC->LineTo(nToPosX, nToPosY+nDistanceX); pDC->MoveTo(nFromPosX+nOffSet, nFromPosY+nBoardHeight/2); pDC->LineTo(nToPosX-nOffSet, nToPosY+nDistanceX/2); pDC->SelectObject(pOldPen); tPen.DeleteObject(); } } void CGameView::DrawAllChessMan(CDC *pDC, void *pChessInfo) { if( NULL == pChessInfo ) return; CHESS_STRUCT *ptChessInfo = (CHESS_STRUCT *)pChessInfo; int nChessCount = TOTAL_POINTS; for(int nIndex = 0; nIndex < nChessCount; nIndex++) { CHESS_STRUCT *pInfo = &ptChessInfo[nIndex]; BOOL bRealPos = pInfo->bRealPos; if( !bRealPos ) continue; BOOL bFlashOn = pInfo->bFlashOn; if( bFlashOn ) continue; DrawChessMan(pDC, pInfo); } } void CGameView::DrawChessMan(CDC *pDC, void *pChessInfo) { if( NULL == pChessInfo ) return; CHESS_STRUCT *ptChessInfo = (CHESS_STRUCT *)pChessInfo; int nStartPosX = ptChessInfo->point.x; int nStartPosY = ptChessInfo->point.y; CHESS_COLOR tColor = ptChessInfo->tColor; CHESS_VALUE tValue = ptChessInfo->tValue; int nSelMode = ptChessInfo->nSelMode; CDC memDC; memDC.CreateCompatibleDC(pDC); switch(tColor) { case RED: { memDC.SelectObject(BMP_RED_CHESS); break; } case BLUE: { memDC.SelectObject(BMP_BLUE_CHESS); break; } default: { } } pDC->StretchBlt(nStartPosX, nStartPosY, CHESS_WIDTH, CHESS_HEIGHT, &memDC, 0, CHESS_HEIGHT*tValue, CHESS_WIDTH, CHESS_HEIGHT,SRCCOPY); if(nSelMode == PRE_SELECTED) { //pDC->Draw3dRect(nStartPosX+1,nStartPosY+1,CHESS_WIDTH-2,CHESS_HEIGHT-2,m_tColor_Yellow,m_tColor_Yellow); pDC->Draw3dRect(nStartPosX,nStartPosY,CHESS_WIDTH,CHESS_HEIGHT,m_tColor_Black,m_tColor_Black); pDC->Draw3dRect(nStartPosX-1,nStartPosY-1,CHESS_WIDTH+2,CHESS_HEIGHT+2,m_tColor_Yellow,m_tColor_Yellow); pDC->Draw3dRect(nStartPosX-2,nStartPosY-2,CHESS_WIDTH+4,CHESS_HEIGHT+4,m_tColor_Black,m_tColor_Black); //pDC->Draw3dRect(nStartPosX-3,nStartPosY-3,CHESS_WIDTH+6,CHESS_HEIGHT+6,m_tColor_Black,m_tColor_Black); } else if(nSelMode == SRC_SELECTED) { memDC.SelectObject(BMP_SRCMOVEFLAG); //left->right->top->bottom->center const int wh = 10; int step = (CHESS_WIDTH - wh)/2; pDC->StretchBlt(nStartPosX,nStartPosY+step,wh,wh,&memDC,0,wh*0,wh,wh,SRCCOPY); pDC->StretchBlt(nStartPosX+(CHESS_WIDTH-wh),nStartPosY+step,wh,wh,&memDC,0,wh*1,wh,wh,SRCCOPY); pDC->StretchBlt(nStartPosX+wh,nStartPosY,wh,wh,&memDC,0,wh*2,wh,wh,SRCCOPY); pDC->StretchBlt(nStartPosX+wh,nStartPosY+(CHESS_WIDTH-wh),wh,wh,&memDC,0,wh*3,wh,wh,SRCCOPY); pDC->StretchBlt(nStartPosX+wh,nStartPosY+wh,wh,wh,&memDC,0,wh*4,wh,wh,SRCCOPY); } else if(nSelMode == DEST_SELECTED) //after moving { pDC->Draw3dRect(nStartPosX+1,nStartPosY+1,CHESS_WIDTH-2,CHESS_HEIGHT-2,m_tColor_Red,m_tColor_Red); pDC->Draw3dRect(nStartPosX,nStartPosY,CHESS_WIDTH,CHESS_HEIGHT,m_tColor_Red,m_tColor_Red); pDC->Draw3dRect(nStartPosX-1,nStartPosY-1,CHESS_WIDTH+2,CHESS_HEIGHT+2,m_tColor_Red,m_tColor_Red); pDC->Draw3dRect(nStartPosX-2,nStartPosY-2,CHESS_WIDTH+4,CHESS_HEIGHT+4,m_tColor_Black,m_tColor_Black); pDC->Draw3dRect(nStartPosX-3,nStartPosY-3,CHESS_WIDTH+6,CHESS_HEIGHT+6,m_tColor_Black,m_tColor_Black); } } void CGameView::DrawUserInfo(CDC *pDC) { int iOneStep = 0; int iWidthHeight = 32; for(int ii=0;ii<4;ii++) { int iX = 0; int iY = 0; CString strUserName = m_userInfo[ii].userName; if(ii == 0) { iX = iX - 4*iOneStep; iY = iY + 7*iOneStep; } else if(ii == 1) { iX = iX - 6*iOneStep; iY = iY - 4*iOneStep; } else if(ii == 2) { iX = iX + 4*iOneStep; iY = iY - 7*iOneStep; } else if(ii == 3) { iX = iX + 6*iOneStep; iY = iY + 3*iOneStep - iWidthHeight; } pDC->SetBkColor(COLOR_BKGND); pDC->TextOut(iX,iY,strUserName); } } void CGameView::DrawOrderIcon(CDC *pDC) { CDC memDC; memDC.CreateCompatibleDC(pDC); memDC.SelectObject(BMP_TOKENORDER); memDC.SetBkColor(COLOR_BKGND); int curOrder = 0; int myOrder = 2; int order = GetRelativePosition(myOrder,curOrder); int nStartPosX = m_ptOrderIcon[order].x; int nStartPosY = m_ptOrderIcon[order].y; int iWidthHeight = 32; int textWidthHeight = 24; int iIconOrder = m_bTakenOrderOnOff? 0:1; pDC->StretchBlt(nStartPosX,nStartPosY,iWidthHeight,iWidthHeight,&memDC,0,iWidthHeight*iIconOrder,iWidthHeight,iWidthHeight,SRCCOPY); //Draw the Text(Show Left Time) if(!m_bOffLine) { nStartPosX = nStartPosX + iWidthHeight; nStartPosY = nStartPosY ; iWidthHeight = textWidthHeight; memDC.SelectObject(BMP_LEFTTIME); memDC.SetBkColor(COLOR_BKGND); pDC->StretchBlt(nStartPosX,nStartPosY,iWidthHeight,iWidthHeight,&memDC,0,iWidthHeight*(30-m_nLeftTime),iWidthHeight,iWidthHeight,SRCCOPY); } } void CGameView::InvalidateChessRect(CPoint &point) { int nDistance = CHESS_WIDTH/8; int left = point.x - nDistance; int top = point.y - nDistance; int right = left + CHESS_WIDTH + nDistance * 2; int bottom = top + CHESS_HEIGHT + nDistance * 2; CRect rect(left,top,right,bottom); InvalidateRect(rect,TRUE); } void CGameView::InvalidateChessRect(int nChessIndex) { if(nChessIndex == INVALID_INDEX) { InvalidateGameRect(); return; } else { int nX = m_pChessInfo[nChessIndex].point.x; int nY = m_pChessInfo[nChessIndex].point.y; CPoint point(nX, nY); InvalidateChessRect(point); } } int CGameView::GetChessIndex(CPoint &point) { int retIndex = INVALID_INDEX; if( NULL == m_pChessInfo ) return retIndex; for(int nIndex = 0; nIndex < TOTAL_POINTS; nIndex++) { int left = m_pChessInfo[nIndex].point.x; int top = m_pChessInfo[nIndex].point.y; int right = left + CHESS_WIDTH; int bottom = top + CHESS_HEIGHT; CRect ChessRect(left,top,right,bottom); if(ChessRect.PtInRect(point)) { retIndex = nIndex; break; } } return retIndex; } int CGameView::GetPositionIndex(CPoint &point) { int retIndex = INVALID_INDEX; for(int index=0;index<TOTAL_POINTS;index++) { int posIndex = m_pChessInfo[index].nIndex; int left = m_pChessInfo[index].point.x; int top = m_pChessInfo[index].point.y; int right = left + CHESS_WIDTH; int bottom = top + CHESS_HEIGHT; CRect ChessRect(left,top,right,bottom); if(ChessRect.PtInRect(point)) { retIndex = posIndex; break; } } return retIndex; } BOOL CGameView::GetPositionIndexList(int index, int *posList) { return TRUE; } void CGameView::FlashChessAction(BOOL bFlashOn) { static HANDLE hThread = NULL; if(bFlashOn) { if(IsInGame() && m_bFlashChessThread) return; hThread = ::CreateThread(NULL,1024, (LPTHREAD_START_ROUTINE)CGameView::FlashChessThread, (LPVOID)this,0,NULL); m_bFlashChessThread = (hThread != NULL); } else { if(m_bFlashChessThread && hThread != NULL) { m_bFlashChessThread = FALSE; WaitForSingleObject(hThread,INFINITE); hThread = NULL; } } } void CGameView::FlashPositionAction(BOOL bFlashOn) { static HANDLE hThread = NULL; if(bFlashOn) { if(m_bFlashPositionThread) return; hThread = ::CreateThread(NULL,1024, (LPTHREAD_START_ROUTINE)CGameView::FlashPositionThread, (LPVOID)this,0,NULL); m_bFlashPositionThread = (hThread != NULL); } else { if(m_bFlashPositionThread && hThread != NULL) { m_bFlashPositionThread = FALSE; WaitForSingleObject(hThread,INFINITE); hThread = NULL; } } } void CGameView::FlashChess(int nChessIndex) { //If it is in war, do not stop the flash thread, //else stop it and restart... int nFlasingIndex = m_nFlashingIndex; int nSrcSelIndex = m_nSrcSelIndex; if(nChessIndex != INVALID_INDEX) { //Stop the flashing Chess action firstly if(!IsInGame()) { FlashChessAction(FALSE); if(nFlasingIndex != INVALID_INDEX) { m_pChessInfo[nFlasingIndex].bFlashOn = FALSE; } } //The Chess is flashing,do this action again will stop flashing if(nFlasingIndex == nChessIndex) { if(!IsInGame()) { if(nSrcSelIndex != INVALID_INDEX) { m_pChessInfo[nSrcSelIndex].nSelMode = NO_SELECTED; InvalidateChessRect(nSrcSelIndex); m_nSrcSelIndex = INVALID_INDEX; m_bSelSrcChess = FALSE; m_nLastPreSelIndex = INVALID_INDEX; } } } //do the flashing action else { if(IsInGame()) { if(nFlasingIndex != INVALID_INDEX) { m_pChessInfo[nFlasingIndex].bFlashOn = FALSE; InvalidateChessRect(nFlasingIndex); } } m_nFlashingIndex = nChessIndex; //Set the flashing chess index FlashChessAction(TRUE); } } //Run the thread... else { while(m_bFlashChessThread) { if(nFlasingIndex != INVALID_INDEX) { BOOL bFlashOn = m_pChessInfo[nFlasingIndex].bFlashOn; m_pChessInfo[nFlasingIndex].bFlashOn = !bFlashOn; m_pChessInfo[nFlasingIndex].nSelMode = NO_SELECTED; } else break; if(!m_bFlashChessThread) break; InvalidateChessRect(nFlasingIndex); for(int nCount = 0; nCount < 15; nCount++) { if(!m_bFlashChessThread) break; Sleep(10); } } m_bFlashChessThread = FALSE; //stop the flashing if(nFlasingIndex != INVALID_INDEX) { m_pChessInfo[nFlasingIndex].bFlashOn = FALSE; m_pChessInfo[nFlasingIndex].nSelMode = NO_SELECTED; InvalidateChessRect(nFlasingIndex); m_nFlashingIndex = INVALID_INDEX; } } } void CGameView::SetChessState(int nChessIndex,int nState) { if(nChessIndex != INVALID_INDEX) { m_pChessInfo[nChessIndex].nSelMode = (SELECTED_MODE)nState; InvalidateChessRect(nChessIndex); } } void CGameView::FlashPosition(int nPosIndex) { int nFlashingIndex = m_nFlashingIndex; //Start the thread... if(nPosIndex != INVALID_INDEX) { FlashPositionAction(FALSE); if(nFlashingIndex != INVALID_INDEX) { InvalidateChessRect(nFlashingIndex); } m_nFlashingIndex = nPosIndex; FlashPositionAction(TRUE); } //Run the thread... else { BOOL bFlash = TRUE; while(m_bFlashPositionThread) { if(nFlashingIndex == INVALID_INDEX) break; if(bFlash) { bFlash = FALSE; } else { bFlash = TRUE; } if(!m_bFlashPositionThread) break; InvalidateChessRect(nFlashingIndex); for(int i=0;i<31;i++) { if(!m_bFlashPositionThread) break; Sleep(10); } } m_bFlashPositionThread = FALSE; if(nFlashingIndex != INVALID_INDEX) { InvalidateChessRect(nFlashingIndex); } if(!IsInGame()) { //Reset the source and the destination flashing position int nSrcSelIndex = m_nSrcSelIndex; int nDestSelIndex = m_nDestSelIndex; if(nSrcSelIndex != INVALID_INDEX) { m_nLastSrcSelIndex = nSrcSelIndex; InvalidateChessRect(nSrcSelIndex); m_nSrcSelIndex = INVALID_INDEX; } if(nDestSelIndex != INVALID_INDEX) { m_nLastDestSelIndex = nDestSelIndex; InvalidateChessRect(nDestSelIndex); m_nDestSelIndex = INVALID_INDEX; } } else { //continue the flashing if(nFlashingIndex != INVALID_INDEX) { InvalidateChessRect(nFlashingIndex); } } } } void CGameView::OnLButtonDown(UINT nChesss, CPoint point) { if(!m_bCanMoveChess) { m_bPreSelChess = FALSE; return; } ProcessLButtonDown(point); if( !m_bSelSrcChess ) //If not selected, check selected or not { ProcessMouseMove(point); } CView::OnLButtonDown(nChesss, point); } void CGameView::ProcessLButtonDown(CPoint &point) { int nChessIndex = GetChessIndex(point); if(INVALID_INDEX == nChessIndex) { } else { CHESS_VALUE tValue = m_pChessInfo[nChessIndex].tValue; CHESS_COLOR tColor = m_pChessInfo[nChessIndex].tColor; if( NO_CHESS != tValue ) //Here is a Chess { m_nSrcSelIndex = nChessIndex; m_bSelSrcChess = TRUE; FlashChess(nChessIndex); return; } else { CHESS_COLOR tCurColor = (CHESS_COLOR)m_nCurColor; m_pChessInfo[nChessIndex].tValue = NORMAL_CHESS; m_pChessInfo[nChessIndex].tColor = tCurColor; if( RED == (CHESS_COLOR)tCurColor ) m_nCurColor = BLUE; else if( BLUE == (CHESS_COLOR)tCurColor ) m_nCurColor = RED; else {} InvalidateChessRect(nChessIndex); } } } void CGameView::GetChessMovePathInfo(int srcIndex,int destIndex, int iPathInfo[],int &iStepCount) { } void CGameView::OnLButtonUp(UINT nChesss, CPoint point) { return; //Has Not connected to server if(!m_bConnectToServer) { return; } CView::OnLButtonUp(nChesss, point); } BOOL CGameView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default if(m_bPreSelChess) { SetCursor(m_hHandCursor); return TRUE; } return CView::OnSetCursor(pWnd, nHitTest, message); } void CGameView::OnMouseMove(UINT nChesss, CPoint point) { //CString strMousePos(""); //strMousePos.Format("三旗游戏 -- Mouse Move: (%d, %d)", point.x, point.y); //::SetWindowText(AfxGetMainWnd()->m_hWnd,strMousePos); if(!m_bCanMoveChess) { m_bPreSelChess = FALSE; return; } ProcessMouseMove(point); CView::OnMouseMove(nChesss, point); } void CGameView::ProcessMouseMove(CPoint &point) { int nChessIndex = GetChessIndex(point); int nLastPreSelIndex = m_nLastPreSelIndex; if(INVALID_INDEX == nChessIndex) //Not Selected { if(INVALID_INDEX != nLastPreSelIndex) //Refresh Last Selected { SetChessState(nLastPreSelIndex, NO_SELECTED); } m_bPreSelChess = FALSE; } else { if( nLastPreSelIndex == nChessIndex ) //The Same Selection, do nothing { return; } if(nLastPreSelIndex != nChessIndex) //The different selection, { //refresh the last selected SetChessState(nLastPreSelIndex, NO_SELECTED); } if(nLastPreSelIndex == m_nLastSrcSelIndex) { SetChessState(nLastPreSelIndex, SRC_SELECTED); } else if(nLastPreSelIndex == m_nLastDestSelIndex) { SetChessState(nLastPreSelIndex, DEST_SELECTED); } m_bPreSelChess = TRUE; SetCursor(m_hHandCursor); SetChessState(nChessIndex, PRE_SELECTED); InvalidateChessRect(nChessIndex); } m_nLastPreSelIndex = nChessIndex; //Set the mouse last selected } void CGameView::OnTimer(UINT nIDEvent) { if( nIDEvent == INIT_CHESSINFO_TIMER ) { KillTimer(nIDEvent); InitChessInfo(); } CView::OnTimer(nIDEvent); } int CGameView::CheckValidPosition(int nSrcIndex, int nDestIndex) { return 1; } int CGameView::GetRelativePosition(int nMyDirection,int nAbsDirection) { if(nAbsDirection < nMyDirection) { nAbsDirection += MAX_DIRECTION; } return (nAbsDirection - nMyDirection); } int CGameView::TranslateChessIndex(int nChessIndex, int nChessColor) { int nRetChessIndex = nChessIndex; int nMyColor = m_nMyColor; if(nChessColor == nMyColor) //It is my side { nRetChessIndex = nChessIndex; } else { nRetChessIndex = (TOTAL_POINTS - 1) - nChessIndex; } return nRetChessIndex; } BOOL CGameView::IsCallSan(int nChessIndex, int nChessColor) { if( (INVALID_INDEX == nChessIndex) || (NO_COLOR == nChessColor) ) return FALSE; const int nLinePoints = LINE_POINTS; int nColIndex = nChessIndex/nLinePoints; int nRowIndex = nChessIndex - (nColIndex * nLinePoints); return FALSE; } BOOL CGameView::Connect(CString strServerName,int intPort) { WSADATA wsaData; if(WSAStartup(WINSOCK_VERSION,&wsaData)) { MessageBox("Could not load Windows Sockets DLL.",NULL,MB_OK); return FALSE; } CString strIPAddress = strServerName; struct hostent *hp = NULL; if(isalpha( int(strServerName.GetAt(0)) )) { // server address is a name hp = gethostbyname(strIPAddress); if(hp == NULL) { ReportWinsockErr("Cannot resolve the Address!!"); return FALSE; } else { struct in_addr *ip = (struct in_addr *) hp->h_addr_list[0]; strIPAddress.Format("%d.%d.%d.%d", ip->S_un.S_un_b.s_b1, ip->S_un.S_un_b.s_b2, ip->S_un.S_un_b.s_b3, ip->S_un.S_un_b.s_b4); } } /* else { // Convert nnn.nnn address to a usable one DWORD dwAddr = inet_addr(strIPAddress); hp = gethostbyaddr((char *)&dwAddr,4,AF_INET); } */ /* SOCKADDR_IN server; memset(&server,0,sizeof(server)); memcpy(&(server.sin_addr),hp->h_addr,hp->h_length); server.sin_family = hp->h_addrtype; server.sin_port = htons(intPort); ///*/ SOCKADDR_IN server; memset(&server,0,sizeof(server)); server.sin_addr.s_addr = inet_addr(strIPAddress); server.sin_family = AF_INET; server.sin_port = htons(intPort); ////// m_hSocket=socket(PF_INET,SOCK_STREAM,0); if(m_hSocket == SOCKET_ERROR) { ReportWinsockErr("Create Socket error!!"); return FALSE; } int nConnect=connect(m_hSocket,(LPSOCKADDR)&server,sizeof(server)); if(nConnect == SOCKET_ERROR) { ReportWinsockErr("Connect failed! Maybe the Server does not exist."); return FALSE; } else { //MessageBox("Successfully connected Server!!",NULL,MB_OK); } int iErrorCode=WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_EVENT,FD_READ|FD_CLOSE); if(iErrorCode==SOCKET_ERROR) { MessageBox("WSAAsyncSelect failed on socket",NULL,MB_OK); return FALSE; } return TRUE; } void CGameView::ReportWinsockErr(CString strErrorMsg) { CString strTextOut(""); strTextOut.Format("\nWinsock error %d: %s\n\n", WSAGetLastError(), strErrorMsg); MessageBeep(MB_ICONSTOP); MessageBox(strTextOut, AfxGetAppName(), MB_OK|MB_ICONSTOP); return; } BOOL CGameView::Send(CString strMessage) { if(m_hSocket == INVALID_SOCKET) { CWaitCursor wait; if(!Connect(m_strServerName,m_intPort)) return FALSE; wait.Restore(); } int nCharSend = send(m_hSocket,strMessage,strMessage.GetLength(),0); if(nCharSend==SOCKET_ERROR) { TRACE("Error occurred during send!!"); return FALSE; } TRACE("Send Message ---> %s\n",strMessage); return TRUE; } //WM_SOCKET_EVENT LRESULT CGameView::OnSocketEvent(WPARAM wParam,LPARAM lParam) { return 0; } void CGameView::run() { while(m_bRunState) { Sleep(0); if(/**/ m_hRunThread) { SuspendThread(m_hRunThread); } if(!m_bRunState) break; /////Copy the message from a list... //process the recv msg.... /////// } } void CGameView::OnBtStartGame() { m_strRecordHistory = ""; BOOL bReadyTo = TRUE; } void CGameView::OnBtLoadChessInfo() { } void CGameView::CodeData(CString &strData,int nCode) { //-1: CONVERT_TXT_TO_MSG //1 CONVERT_MSG_TO_TXT int nMagicNumber = 32; int nKeyNumber = nMagicNumber*nCode; //Convert User Name char *szData = strData.GetBuffer(0); strData.ReleaseBuffer(); int len = strlen(szData); for(int i=0; i<len; i++) { if(szData[i] != '\n') { szData[i] = szData[i] + nKeyNumber; } } } void CGameView::OnBtImpetratePeace() { if(m_bPeaceAction) return; /////////////////////////////////////////////// //////////////////////////////////////////////// m_bPeaceAction = TRUE; } void CGameView::OnBtSurrender() { int result = MessageBox("Do you really want to Do that?","Kill yourself??",MB_YESNO|MB_ICONQUESTION|MB_ICONEXCLAMATION); if(result == IDYES) { /////////////////////////////////////////////// //////////////////////////////////////////////// } } void CGameView::OnBtOpenFile() { CFileDialog dlg(TRUE,NULL,NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_FILEMUSTEXIST, //"War Files (*.war)|*.war|All Files (*.*)|*.*||"); "War Files (*.war)|*.war||"); if(dlg.DoModal() == IDOK) { CWaitCursor wait; CString strPathName = dlg.GetPathName(); g_strFileName = strPathName; InitChessInfo(); LoadChessFile(g_strFileName); InvalidateGameRect(); wait.Restore(); } } void CGameView::OnBtPreviousStep() { if(m_nCurStepCount == 0 || m_curStepPosition == NULL) { m_btGameButtons[1].EnableWindow(m_nCurStepCount != 0); return; } if(m_bOffLineControl) { m_btGameButtons[1].EnableWindow(m_nCurStepCount != 0); m_btGameButtons[2].EnableWindow(TRUE); ////////////////////////////////// m_moveStepPosition = m_curStepPosition; POSITION pos = m_moveStepPosition; CString strChessMessage(""); GetNextChessInfo(strChessMessage,pos); m_nCurStepCount--; if(m_nCurStepCount > 0) { //Only Get Previous position,will start from the previous positon CString strChessInfo= m_strChessInfoList.GetPrev(pos); //// //Get the previous step Chess info... strChessInfo = ""; POSITION oldPos = pos; while(pos != NULL) { oldPos = pos; strChessInfo = m_strChessInfoList.GetPrev(pos); //$MoveFromTo:SrcColor-DestColor:srcIndex-srcValue:destIndex-destValue# if(strChessInfo.Left(1) == "$") { break; } } //pos == NULL means that it is the first step, need not flash position if(pos != NULL && strChessInfo != "") { } ////////////////////////////////// if(pos != NULL) { m_curStepPosition = oldPos; } } SetWindowTitle(); //// InvalidateGameRect(); } } void CGameView::OnBtNextStep() { if(m_nCurStepCount == m_nTotalStepCount || m_curStepPosition == NULL) { m_btGameButtons[2].EnableWindow(m_nCurStepCount != m_nTotalStepCount); return; } if(m_bOffLineControl) { m_bOffLineControl = FALSE; m_btGameButtons[1].EnableWindow(TRUE); m_btGameButtons[2].EnableWindow(m_nCurStepCount != m_nTotalStepCount); SetTimer(OFFLINE_GETSTEPINFO_TIMER,0,NULL); } } void CGameView::ProcessBtNextStep(int nIDEvent) { if(nIDEvent == OFFLINE_LOADFILE_TIMER) { //Init the Chess info KillTimer(nIDEvent); LoadChessFile(g_strFileName); } else if(nIDEvent == OFFLINE_GETSTEPINFO_TIMER) { //Get the every time move Chess info (from src to dest) KillTimer(nIDEvent); ///* CString strChessMessage(""); GetNextChessInfo(strChessMessage,TRUE); } else if(nIDEvent == OFFLINE_MOVESTEP_TIMER) { //Move Chess Step by Step KillTimer(nIDEvent); if(m_curMoveChessPosition != NULL) { CString strMoveChess = m_strMoveChessList.GetNext(m_curMoveChessPosition); //Will Move Next Step SetTimer(nIDEvent,100,NULL); //// } else { m_bOffLineControl = TRUE; } } } void CGameView::OnBtSaveChessInfo() { } void CGameView::OnDestroy() { CView::OnDestroy(); // TODO: Add your message handler code here ProcessDisconnect(); m_tGameStatus = OFFLINE; } void CGameView::ProcessDisconnect(BOOL bManual /*=TRUE*/, CString strComment /* = ""*/) { if(m_hSocket != INVALID_SOCKET) { closesocket(m_hSocket); WSACleanup(); m_hSocket = INVALID_SOCKET; } FreeWavRes(); FlashChessAction(FALSE); FlashPositionAction(FALSE); if(m_hRunThread != NULL) { if(bManual) { m_bRunState = FALSE; ResumeThread(m_hRunThread); WaitForSingleObject(m_hRunThread,INFINITE); CloseHandle(m_hRunThread); } else { TerminateThread(m_hRunThread,0); } m_hRunThread = NULL; } if(!bManual) //Server Shut Down { MessageBox(strComment,"Warning",MB_OK|MB_ICONSTOP); } InitControlData(); m_bConnectToServer = FALSE; m_tGameStatus = OFFLINE; m_nTableID = 1; m_nPosition = INVALID_INDEX; InvalidateGameRect(); ShowButtons(READY); //SetWindowText CString strText(""); strText.Format("[Game3Chess] -- [---]"); ::SetWindowText(AfxGetMainWnd()->m_hWnd,strText); // CWnd* pMainWnd =::AfxGetMainWnd(); if(NULL != pMainWnd && ::IsWindow(pMainWnd->GetSafeHwnd())) { pMainWnd->PostMessage(WM_CLOSE, 0, 0); } } BOOL CGameView::IsInGame() { //In Game -> TRUE BOOL bInGame = ( (m_tGameStatus == PLAYING_PRE) || (m_tGameStatus == PLAYING_MOVE) ); bInGame &= (!m_bOffLine); return bInGame; } //////////////////////////////////////////////////////////// void CGameView::LoadChessFile(CString strChessFile) { BOOL bLoadSuc = TRUE; if(g_strFileName == "") return; strChessFile = g_strFileName; ifstream ism(strChessFile,ios::in|ios::binary); if(ism.is_open()) { m_bOffLine = TRUE; m_strChessInfoList.RemoveAll(); m_curStepPosition = NULL; m_moveStepPosition = NULL; m_nTotalStepCount = 0; m_nCurStepCount = 0; m_tGameStatus = OFFLINE; KillTimer(TOKEN_ORDER_TIMER); m_bPreSelChess = FALSE; InitControlData(); const int iDataLen = 256; char szDataBuf[iDataLen]; while(!ism.eof()) { ism.getline(szDataBuf,iDataLen); int len = strlen(szDataBuf); //// CString strData = (CString)szDataBuf; CodeData(strData,1); //// if(len > 4 && strData.Right(1) == "#") { m_strChessInfoList.AddTail(strData); if(strData.Left(1) == "$") m_nTotalStepCount++; } else if(strData == "") { bLoadSuc = TRUE; continue; } else { bLoadSuc = FALSE; break; } } ism.close(); } else { bLoadSuc = FALSE; MessageBox("The file can not be opened.Maybe the file does not exist!","Warning",MB_OK|MB_ICONSTOP); return; } if(!bLoadSuc) { m_bOffLine = FALSE; MessageBox("The file can not be loaded.Maybe the file type is not right!","Warning",MB_OK|MB_ICONSTOP); return; } m_curStepPosition = m_strChessInfoList.GetHeadPosition(); m_moveStepPosition = m_curStepPosition; ////Init the Chess data(Load Chess data,show user...), //and set m_curStepPosition, prepare to do move Chess... CString strChessMessage(""); GetNextChessInfo(strChessMessage,FALSE); if(strChessMessage != "") { m_tGameStatus = PLAYING_MOVE; m_bOffLineControl = TRUE; InvalidateGameRect(); SetWindowTitle(); //Set the Order(flash the order icon) m_bTakenOrderOnOff = TRUE; SetTimer(TOKEN_ORDER_TIMER,1000,NULL); InvalidateGameRect(); //// m_btGameButtons[1].EnableWindow(m_nCurStepCount != 0); m_btGameButtons[2].EnableWindow(m_nCurStepCount != m_nTotalStepCount); m_btGameButtons[3].EnableWindow(TRUE); } //////// } void CGameView::GetNextChessInfo(CString &strChessMessage, BOOL bMoveChess) { strChessMessage = ""; if(m_nCurStepCount != 0 && m_nCurStepCount == m_nTotalStepCount) return; CString strChessInfo("#"); if(!bMoveChess) { POSITION oldPos = m_curStepPosition; //Get the header info,will load Chess info and show user name //And Set m_curStepPosition... while(strChessInfo.Left(1) != "$" && m_curStepPosition != NULL) { oldPos = m_curStepPosition; strChessInfo = m_strChessInfoList.GetNext(m_curStepPosition); if(strChessInfo.Left(1) != "$") { strChessMessage += strChessInfo; } } m_curStepPosition = oldPos; m_moveStepPosition = m_curStepPosition; } else { //Get the next step info... m_curStepPosition = m_moveStepPosition; POSITION pos = m_curStepPosition; POSITION oldPos = pos; CString strFirstStepInfo = m_strChessInfoList.GetNext(pos); strChessMessage += strFirstStepInfo; if(pos != NULL) { do { oldPos = pos; strChessInfo = m_strChessInfoList.GetNext(pos); if(strChessInfo.Left(1) != "$") { strChessMessage += strChessInfo; } }while(strChessInfo.Left(1) != "$" && pos != NULL); } m_moveStepPosition = oldPos; //// } //Invalidate format int len = strChessMessage.GetLength(); if(len > MAX_BUFLEN-32 || strChessMessage.FindOneOf("$#:+\r") == -1) { strChessMessage = ""; if(!bMoveChess) { m_strChessInfoList.RemoveAll(); m_curStepPosition = NULL; } } //// } void CGameView::GetNextChessInfo(CString &strChessMessage, POSITION &curPos) { strChessMessage = ""; //Get the next step info... POSITION pos = curPos; CString strChessInfo("#"); CString strFirstStepInfo = m_strChessInfoList.GetNext(pos); strChessMessage += strFirstStepInfo; while(strChessInfo.Left(1) != "$" && pos != NULL) { strChessInfo = m_strChessInfoList.GetNext(pos); if(strChessInfo.Left(1) != "$") { strChessMessage += strChessInfo; } } //Invalidate format int len = strChessMessage.GetLength(); if(len > MAX_BUFLEN-32 || strChessMessage.FindOneOf("$#:+\r") == -1) { strChessMessage = ""; } //// } ////////////////////////////////////////////////////////////