www.gusucode.com > VC++写的中国象棋游戏源程序源码程序 > VC++写的中国象棋游戏源程序源码程序\code\chessView.cpp
// chessView.cpp : implementation of the CChessView class // Download by http://www.NewXing.com #include "stdafx.h" #include "chess.h" #include "chessDoc.h" #include "chessView.h" #include "welcome.h" #include "ipaddress.h" #include "blocksocket.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// SIDE g_side = WHITE_SIDE; int g_server; CString g_stringIp; BOOL g_bEnabled = TRUE; CTimeSpan g_time; CEvent g_eventStart; // creates autoreset events BOOL signal = TRUE; CBlockingSocket g_sListen; ULONG g_dwIPServer = 0;//"192.168.100.36"; CString g_stringInfo; volatile UINT g_nPortServer = 0x5000; volatile BOOL g_bListening = TRUE; ///////////////////////////////////////////////////////////////////////////// // CChessView IMPLEMENT_DYNCREATE(CChessView, CView) BEGIN_MESSAGE_MAP(CChessView, CView) //{{AFX_MSG_MAP(CChessView) ON_WM_CREATE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_SHOWWINDOW() ON_WM_TIMER() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) ON_MESSAGE(WM_CONNECTED, OnConnected) ON_MESSAGE(WM_START, OnStart) END_MESSAGE_MAP() #define START_X 30 #define START_Y 30 #define END_X (START_X+480) #define END_Y (START_Y+540)//60*9 ///////////////////////////////////////////////////////////////////////////// // CChessView construction/destruction void CChessView::InitChess() { // m_dibFile.AttachMapFile("d:\\chessbmp.bmp"); m_chessArray1.InitArray(16); m_chessArray2.InitArray(16); CHESSMAN man; char *manarray1[] = {"车", "马", "象", "士", "将", "士", "象", "马", "车",\ "炮", "炮", "兵", "兵", "兵", "兵", "兵"}; char *manarray2[] = {"车", "马", "象", "士", "将", "士", "象", "马", "车",\ "炮", "炮", "卒", "卒", "卒", "卒", "卒"}; man.point.y = START_Y; for(int i=0; i<16; i++) { if(i<9) man.point.x = START_X + i*60; else if(i<11) { if(i == 9) man.point.x = START_X + 60; else man.point.x = START_X + 420; man.point.y = START_Y + 60*2; } else { man.point.x = START_X + (i-11) *60*2; man.point.y = START_Y + 60*3; } strcpy(man.string, manarray1[i]); m_chessArray1.SetChessman(i, man); } man.point.y = END_Y; for(i=0; i<16; i++) { if(i<9) man.point.x = START_X + i*60; else if(i<11) { if(i == 9) man.point.x = START_X + 60; else man.point.x = START_X + 420; man.point.y = END_Y - 60*2; } else { man.point.x = START_X + (i-11) *60*2; man.point.y = END_Y - 60*3; } strcpy(man.string, manarray2[i]); m_chessArray2.SetChessman(i, man); } } CChessView::CChessView(): m_sizeEllipse(50, 50), m_bCaptured(FALSE) { InitChess(); m_iChessmanOp = -1; } CChessView::~CChessView() { } BOOL CChessView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CChessView drawing void CChessView::OnDraw(CDC* pDC) { CChessDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here PaintChessboard(pDC); PaintChessman(pDC); } void CChessView::PaintChessboard(CDC *pDC) { /* BeginWaitCursor(); m_dibFile.UsePalette(pDC); // message handlers, not here CSize sizeFileDib = m_dibFile.GetDimensions(); m_dibFile.Draw(pDC, CPoint(10, 10), sizeFileDib); EndWaitCursor();*/ #define END2_Y END_Y #define END2_X END_X #define MID_Y (60*4+30) CBrush brush(RGB(0, 128, 128)); CRect rect(START_X, START_Y, END2_X, END2_Y); CPen pen(PS_SOLID, 2, RGB(0, 0, 0)); CBrush *pOldBrush = pDC->SelectObject(&brush); CPen *pOldPen = pDC->SelectObject(&pen); pDC->Rectangle(rect); for(int i=1; i<8; i++) { pDC->MoveTo(i*60+START_X, START_Y); pDC->LineTo(i*60+START_X, MID_Y); } for(i=1; i<8; i++) { pDC->MoveTo(i*60+START_X, MID_Y+60); pDC->LineTo(i*60+START_X, END2_Y); } for(i=1; i<5; i++) { pDC->MoveTo(START_X, START_Y+i*60); pDC->LineTo(END2_X, START_Y+i*60); } for(i=0; i<4; i++) { pDC->MoveTo(START_X, MID_Y+60+i*60); pDC->LineTo(END2_X, MID_Y+60+i*60); } pDC->MoveTo(START_X+60*3, START_Y); pDC->LineTo(START_X+60*5, START_Y+60*2); pDC->MoveTo(START_X+60*5, START_Y); pDC->LineTo(START_X+60*3, START_Y+60*2); pDC->MoveTo(START_X+60*3, END2_Y); pDC->LineTo(START_X+60*5, END2_Y-60*2); pDC->MoveTo(START_X+60*5, END2_Y); pDC->LineTo(START_X+60*3, END2_Y-60*2); pDC->SelectObject(pOldBrush); pDC->SelectObject(pOldPen); } void CChessView::SetSide() { if(g_side == RED_SIDE) { CChessArray array(m_chessArray1); m_chessArray1 = m_chessArray2; for(int i=11; i<=15; i++) { char p[] = "兵"; m_chessArray1.SetChessmanValue(i, p); } m_chessArray2 = array; for(i=11; i<=15; i++) { char p2[] = "卒"; m_chessArray2.SetChessmanValue(i, p2); } } } void CChessView::PaintChessman(CDC *pDC) { CFont fontText; fontText.CreateFont(40, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, NULL);//Create仅仅是选择 //(从WnidowsGdi中)一种字体 CFont* pOldFont = (CFont*) pDC->SelectObject(&fontText); CPen pen(PS_SOLID, 2, RGB(255, 0, 0)); CPen* pOldPen = (CPen*) pDC->SelectObject(&pen); CBrush brush(RGB(0, 0, 0)); CBrush *pOldBrush = (CBrush*) pDC->SelectObject(&brush); for(int i=0; i<16; i++) { PCHESSMAN pMan1 = m_chessArray1.GetChessman(i); CRect rect; rect.top = pMan1->point.y-25; rect.left = pMan1->point.x-25; rect.bottom = pMan1->point.y + 25; rect.right = pMan1->point.x + 25; pDC->Ellipse(&rect); pDC->SetTextColor(RGB(255, 0, 0)); pDC->SetBkColor(RGB(0, 0, 0)); pDC->TextOut(pMan1->point.x-17, pMan1->point.y-17, pMan1->string); } CPen pen2(PS_SOLID, 2, RGB(255, 255, 255)); pDC->SelectObject(&pen2); for(i=0; i<16; i++) { PCHESSMAN pMan2 = m_chessArray2.GetChessman(i); CRect rect; rect.top = pMan2->point.y-25; rect.left = pMan2->point.x-25; rect.bottom = pMan2->point.y + 25; rect.right = pMan2->point.x + 25; pDC->Ellipse(&rect); pDC->SetTextColor(RGB(255, 255, 255)); pDC->SetBkColor(RGB(0, 0, 0)); pDC->TextOut(pMan2->point.x-17, pMan2->point.y-17, pMan2->string); } pDC->SelectObject(pOldFont); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); } ///////////////////////////////////////////////////////////////////////////// // CChessView printing BOOL CChessView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CChessView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CChessView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CChessView diagnostics #ifdef _DEBUG void CChessView::AssertValid() const { CView::AssertValid(); } void CChessView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CChessDoc* CChessView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CChessDoc))); return (CChessDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CChessView message handlers int CChessView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; CWelcome dlg; if(dlg.DoModal() == IDCANCEL) ::ExitProcess(0); g_server = !dlg.m_iYes; CIpAddress ip; if(!g_server) { if(ip.DoModal() != IDOK) ::ExitProcess(0); g_side = (SIDE)!ip.m_iRed; } SetSide(); if(g_server) { g_bEnabled = FALSE; StartServer(); } else { if(g_side == RED_SIDE) { g_time = CTimeSpan(0,0, 5, 0); TRACE("g_time:%s", g_time.Format("%M:%S")); g_bEnabled = TRUE; } else g_bEnabled = FALSE; StartClient(); } SetTimer(1, 1000, NULL); SetTimer(2, 500, NULL); // TODO: Add your specialized creation code here return 0; } void CChessView::StartClient() { AfxBeginThread(ClientThreadProc, GetSafeHwnd(), THREAD_PRIORITY_NORMAL); } void CChessView::StartServer() { try { CSockAddr saServer; saServer = CSockAddr(INADDR_ANY, (USHORT) g_nPortServer); g_sListen.Create(); g_sListen.Bind(saServer); g_sListen.Listen();// start listening g_bListening = TRUE; AfxBeginThread(ServerThreadProc, GetSafeHwnd(), THREAD_PRIORITY_NORMAL); } catch(CBlockingSocketException* e) { g_sListen.Cleanup(); LogBlockingSocketException(GetSafeHwnd(), "VIEW:", e); e->Delete(); } } int CChessView::TransChessman(int iCount) { if(iCount <= 8) return 8-iCount; if(iCount == 9) return 10; if(iCount == 10) return 9; if(iCount>=11 && iCount<=15) return 11 + 15 - iCount; return 0; } LRESULT CChessView::OnStart(WPARAM wParam, LPARAM lParam) { CString s((char*)lParam); CPoint point; CSize size(25, 25); int m = s.Find('M'); m_iChessmanOp = TransChessman(atoi(s.Left(m))); int t = s.Find('T'); point.x = atoi(s.Mid(m+1, t-m-1)); point.x = END_X-point.x+START_X; int r = s.Find('\r'); point.y = atoi(s.Mid(t+1, r-t-1)); point.y = END_Y -point.y+START_Y; CClientDC dc(this); OnPrepareDC(&dc); CRgn circle[16]; GetChessmanRgn(circle, (SIDE)g_side); int count; if((count=IsPtInChessman(circle, point)) != -1) { if(g_side == RED_SIDE) { CPoint p1 = m_chessArray1.GetPointOrg(count); p1 -= size; CRect r(p1, m_sizeEllipse); r.InflateRect(2, 2); m_chessArray1.SetChessmanPoint(count, CPoint(-100, -100)); InvalidateRect(r); } else { CPoint p1 = m_chessArray2.GetPointOrg(count); p1 -= size; CRect r(p1, m_sizeEllipse); r.InflateRect(2, 2); m_chessArray2.SetChessmanPoint(count, CPoint(-100, -100)); InvalidateRect(r); } } if(g_side == RED_SIDE) { CPoint point2 = m_chessArray2.GetPointOrg(m_iChessmanOp); m_chessArray2.SetChessmanPoint(m_iChessmanOp, point); point2 -= size; CRect rect(point2, m_sizeEllipse); dc.LPtoDP(rect); rect.InflateRect(2, 2); InvalidateRect(rect, TRUE); point -= size; CRect rect2(point, m_sizeEllipse); dc.LPtoDP(rect2); rect2.InflateRect(2, 2); InvalidateRect(rect2, TRUE); } else { CPoint point2 = m_chessArray1.GetPointOrg(m_iChessmanOp); m_chessArray1.SetChessmanPoint(m_iChessmanOp, point); point2 -= size; CRect rect(point2, m_sizeEllipse); dc.LPtoDP(rect); rect.InflateRect(2, 2); InvalidateRect(rect, TRUE); point -= size; CRect rect2(point, m_sizeEllipse); dc.LPtoDP(rect2); rect2.InflateRect(2, 2); InvalidateRect(rect2, TRUE); } g_time = CTimeSpan(0, 0, 5, 0); g_bEnabled = TRUE; return 0; } LRESULT CChessView::OnConnected(WPARAM wParam, LPARAM lParam) { char *p = strchr((char*)lParam, '1'); if(p) g_side = WHITE_SIDE; else g_side = RED_SIDE; if(g_side == RED_SIDE) g_bEnabled = TRUE; // g_csStatus.Lock(); SetSide(); Invalidate(); return 0; } BOOL CChessView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); } void CChessView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) { // TODO: Add your specialized code here and/or call the base class // m_dibFile.SetSystemPalette(pDC); CView::OnPrepareDC(pDC, pInfo); } void CChessView::GetChessmanRgn(CRgn *rgn, SIDE enumSide) { CRect rectArray[16]; CPoint pointMan; CSize size(25, 25); CClientDC dc(this); OnPrepareDC(&dc); if(enumSide == RED_SIDE) { for(int i=0; i<16; i++) { pointMan = m_chessArray1.GetPointOrg(i) - size; rectArray[i] = CRect(pointMan, m_sizeEllipse); dc.LPtoDP(rectArray[i]); // Now it's in device coordinates (rgn+i)->CreateEllipticRgnIndirect(rectArray[i]); } } else { for(int i=0; i<16; i++) { pointMan = m_chessArray2.GetPointOrg(i) - size; rectArray[i] = CRect(pointMan, m_sizeEllipse); dc.LPtoDP(rectArray[i]); // Now it's in device coordinates (rgn+i)->CreateEllipticRgnIndirect(rectArray[i]); } } } int CChessView::IsPtInChessman(CRgn *rgn, CPoint point) { int count = -1; for(int i=0; i<16; i++) { if((rgn+i)->PtInRegion(point)) { count = i; break; } } return count; } void CChessView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(!g_bEnabled) return; CRgn circle[16]; GetChessmanRgn(circle, g_side); m_iChessman = IsPtInChessman(circle, point); if(m_iChessman!=-1 && (circle+m_iChessman)->PtInRegion(point)) { CClientDC dc(this); OnPrepareDC(&dc); SetCapture(); m_bCaptured = TRUE; CSize size(25, 25); if(g_side == RED_SIDE) { m_pointTopLeft = m_chessArray1.GetPointOrg(m_iChessman)-size; m_pointArray.SetValue(m_chessArray1, m_chessArray2); } else { m_pointTopLeft = m_chessArray2.GetPointOrg(m_iChessman)-size; m_pointArray.SetValue(m_chessArray2, m_chessArray1); } CPoint pointTopLeft(m_pointTopLeft); dc.LPtoDP(&pointTopLeft); m_sizeOffset = point - pointTopLeft; // device coordinates // New mouse cursor is active while mouse is captured ::SetCursor(::LoadCursor(NULL, IDC_CROSS)); } CView::OnLButtonDown(nFlags, point); } void CChessView::MyInvalidate(CPoint point) { CSize size(25, 25); point -= size; CRect rect(point, m_sizeEllipse); rect.InflateRect(2, 2); InvalidateRect(rect); } void CChessView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (m_bCaptured) { ::ReleaseCapture(); m_bCaptured = FALSE; g_bEnabled = FALSE; BOOL flag; CPoint man; if(g_side == RED_SIDE) { man = m_chessArray1.GetPointOrg(m_iChessman); CPoint oldman = man; flag = m_pointArray.IsPointCorrect(m_iChessman, man); m_chessArray1.SetChessmanPoint(m_iChessman, man); MyInvalidate(oldman); MyInvalidate(man); } else { man = m_chessArray2.GetPointOrg(m_iChessman); CPoint oldman = man; flag = m_pointArray.IsPointCorrect(m_iChessman, man); m_chessArray2.SetChessmanPoint(m_iChessman, man); MyInvalidate(oldman); MyInvalidate(man); } if(flag) { CDC *pDC = GetDC(); if(g_side == RED_SIDE) { if(m_iChessmanOp != -1){ CPoint splash = m_chessArray2.GetPointOrg(m_iChessmanOp); m_iChessmanOp = -1; //COLORREF color = pDC->GetPixel(splash.x+23, splash.y); if(!signal) { signal = !signal; MyInvertRgn(pDC, splash);} MyInvalidate(splash);} } else { if(m_iChessmanOp != -1){ CPoint splash = m_chessArray1.GetPointOrg(m_iChessmanOp); m_iChessmanOp = -1; //COLORREF color = pDC->GetPixel(splash.x+23, splash.y); if(!signal) {signal = !signal; MyInvertRgn(pDC, splash);} MyInvalidate(splash);} } g_stringInfo.Format("%d,M%d,T%d\r\n", m_iChessman, man.x, man.y); CRgn circle[16]; GetChessmanRgn(circle, (SIDE)!g_side); int count; if((count=IsPtInChessman(circle, man)) != -1) { CSize size(25, 25); if(g_side == RED_SIDE) { CPoint p1 = m_chessArray2.GetPointOrg(count); p1 -= size; CRect r(p1, m_sizeEllipse); r.InflateRect(2, 2); m_chessArray2.SetChessmanPoint(count, CPoint(-100, -100)); InvalidateRect(r); } else { CPoint p1 = m_chessArray1.GetPointOrg(count); p1 -= size; CRect r(p1, m_sizeEllipse); r.InflateRect(2, 2); m_chessArray1.SetChessmanPoint(count, CPoint(-100, -100)); InvalidateRect(r); } } g_eventStart.SetEvent(); } else g_bEnabled = TRUE; } CView::OnLButtonUp(nFlags, point); } void CChessView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (m_bCaptured) { CClientDC dc(this); OnPrepareDC(&dc); CSize size(25, 25); CRect rectOld(m_pointTopLeft, m_sizeEllipse); m_pointTopLeft = point - m_sizeOffset; dc.DPtoLP(&m_pointTopLeft); if(g_side) m_chessArray1.SetChessmanPoint(m_iChessman, m_pointTopLeft+size); else m_chessArray2.SetChessmanPoint(m_iChessman, m_pointTopLeft+size); dc.LPtoDP(rectOld); rectOld.InflateRect(2, 2); InvalidateRect(rectOld, TRUE); CRect rectNew(m_pointTopLeft, m_sizeEllipse); dc.LPtoDP(rectNew); rectNew.InflateRect(2,2); InvalidateRect(rectNew, TRUE); } CView::OnMouseMove(nFlags, point); } void CChessView::PreSubclassWindow() { // TODO: Add your specialized code here and/or call the base class CView::PreSubclassWindow(); } void CChessView::OnShowWindow(BOOL bShow, UINT nStatus) { CView::OnShowWindow(bShow, nStatus); // TODO: Add your message handler code here } void CChessView::OnTimer(UINT nIDEvent) { if(nIDEvent == 1) { g_time -= CTimeSpan(0, 0, 0, 1); TRACE("g_time:%s", g_time.Format("%M:%S")); } if(nIDEvent == 2) { if(m_iChessmanOp != -1) { CPoint p; CDC *pDC = GetDC(); CSize size(25, 25); signal = !signal; if(g_side == RED_SIDE) { p = m_chessArray2.GetPointOrg(m_iChessmanOp); MyInvertRgn(pDC, p); } else { p = m_chessArray1.GetPointOrg(m_iChessmanOp); MyInvertRgn(pDC, p); } } } CView::OnTimer(nIDEvent); } void CChessView::MyInvertRgn(CDC *pDC, CPoint point) { CSize size(25, 25); point -= size; CRect rect(point, m_sizeEllipse); CRgn c; c.CreateEllipticRgnIndirect(rect); pDC->InvertRgn(&c); }