www.pudn.com > goodchessGame.zip > GameController.cpp


// GameController.cpp : implementation file 
// 
 
#include "StdAfx.h" 
#include "GenerationRandomNumbers.h" 
#include "GameController.h" 
#include "FiveInOneDoc.h" 
#include "FiveInOne.h" 
#include "ClientSocket.h" 
#include "WaitDialog.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
const int nMessageID = WM_USER + 342; 
///////////////////////////////////////////////////////////////////////////// 
// CGameController 
 
//IMPLEMENT_DYNCREATE(CGameController, CView) 
IMPLEMENT_DYNAMIC(CGameController, CView) 
 
int CGameController::itimer = 0; 
 
CGameController::CGameController() : m_Dlg(FIVEINONE_APP->m_OptionsDlg) 
{ 
	m_nProgressCounter = 0; 
	m_HDrag = FIVEINONE_APP->LoadCursor(IDC_DRAG); 
	m_HSelection = FIVEINONE_APP->LoadCursor(IDC_SELECTION); 
	m_PrevCursor = FIVEINONE_APP->LoadCursor(IDC_ARROW); 
	m_bPlay = FALSE; 
	m_nTotalNumberOfPlayers = 0; 
	m_pTotalCards = NULL; 
	m_nNumOfDecks = 0; 
	m_bSelection = FALSE; 
	m_DraggedCardIndex = -1; 
	m_bDragging = FALSE; 
	m_nGameType = UNDETERMINED; 
	m_Size = CSize(0,0); 
	m_OriginalPoint = CPoint(0,0); 
	m_pFloorDlg = NULL; 
	m_bAnimating = FALSE; 
 
	m_PlayerID = 0; 
	m_pStartingPoints = NULL; 
	m_pXConstants = NULL; 
 
	m_BackgroundBitmap.LoadBitmap(Background); 
	m_BackgroundBrush.CreatePatternBrush(&m_BackgroundBitmap); 
	 
} 
 
CGameController::~CGameController() 
{ 
	::CleanUp(); 
	m_BackgroundBrush.DeleteObject(); 
	m_BackgroundBitmap.DeleteObject(); 
 
	delete [] m_pStartingPoints; 
	m_pStartingPoints = NULL; 
	delete [] m_pXConstants; 
	m_pXConstants = NULL; 
} 
 
void CGameController::SetPlayerID(int id) 
{ 
	m_PlayerID = id; 
} 
 
int CGameController::GetPlayerID() 
{ 
	return m_PlayerID; 
} 
 
void CGameController::CleanUp() 
{ 
	m_nProgressCounter = 0; 
	m_bPlay = FALSE; 
	m_bDragging = FALSE; 
	m_bSelection = FALSE; 
} 
 
BEGIN_MESSAGE_MAP(CGameController, CView) 
	//{{AFX_MSG_MAP(CGameController) 
	//}}AFX_MSG_MAP 
	ON_COMMAND(ID_FILE_DEAL, OnFileDeal) 
	ON_UPDATE_COMMAND_UI(ID_FILE_DEAL, OnUpdateFileDeal) 
	ON_COMMAND(ID_FILE_DECK, OnFileDeck) 
	ON_UPDATE_COMMAND_UI(ID_FILE_DECK, OnUpdateFileDeck) 
	ON_WM_SETCURSOR() 
	ON_WM_ERASEBKGND() 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CGameController drawing 
 
void CGameController::OnDraw(CDC* pDC) 
{ 
	CDocument* pDoc = GetDocument(); 
	// TODO: add draw code here 
} 
 
BOOL CGameController::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CGameController diagnostics 
 
#ifdef _DEBUG 
void CGameController::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CGameController::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CFiveInOneDoc* CGameController::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFiveInOneDoc))); 
	return (CFiveInOneDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CGameController message handlers 
void CGameController::Begin() 
{ 
	m_pFloorDlg = new CFloorDialog(this); 
	m_pFloorDlg->ShowWindow(SW_SHOW); 
	m_pFloorDlg->UpdateWindow(); 
} 
 
void CGameController::GenerationOfRandomNumbers() 
{ 
	m_pTotalCards = ArrayTotalCardsFill(m_nNumOfDecks); 
} 
 
void CGameController::DeckInitialization() 
{ 
	m_Deck.InitializationAndDrawing(this, m_nNumOfDecks, m_pTotalCards);	 
} 
 
void CGameController::FloorInitialization() 
{ 
	m_Floor.Initialization(); 
} 
 
void CGameController::OnFileDeal() 
{ 
	// TODO: Add your command handler code here 
} 
 
void CGameController::OnUpdateFileDeal(CCmdUI *pCmdUI) 
{ 
	// TODO: Add your command update UI handler code here 
} 
 
void CGameController::OnFileDeck() 
{ 
	// TODO: Add your command handler code here 
 
	FIVEINONE_APP->m_ImageDialog.DoModal(); 
} 
 
void CGameController::OnUpdateFileDeck(CCmdUI *pCmdUI) 
{ 
	// TODO: Add your command update UI handler code here 
} 
 
//IMPLEMENT_DYNCREATE(CSingleCompGameController, CGameController) 
IMPLEMENT_DYNAMIC(CSingleCompGameController, CGameController) 
 
BEGIN_MESSAGE_MAP(CSingleCompGameController, CGameController) 
 
END_MESSAGE_MAP() 
 
void CSingleCompGameController::Begin() 
{ 
	CGameController::Begin(); 
} 
 
void CSingleCompGameController::OnDraw(CDC *pDC) 
{ 
} 
 
//IMPLEMENT_DYNCREATE(CNetworkGameController, CGameController) 
IMPLEMENT_DYNAMIC(CNetworkGameController, CGameController) 
 
BEGIN_MESSAGE_MAP(CNetworkGameController, CGameController) 
	ON_MESSAGE(nMessageID, OnSocketMessage) 
END_MESSAGE_MAP() 
 
void CNetworkGameController::Begin() 
{ 
	CGameController::Begin(); 
 
	SetHost(m_Dlg.m_IsHost); 
	CWaitDialog waitDlg(this); 
	if(IsHost()) 
	{ 
		m_pListeningSocket = new CListeningSocket(GetSafeHwnd()); 
		m_pListeningSocket->Listen(9876); 
		m_pListeningSocket->StartThread(); 
		while(WaitForSingleObject(m_pListeningSocket->m_hAllConnectedEvent, 0) != WAIT_OBJECT_0) 
		{ 
			int ret = waitDlg.DoModal(); 
			if(ret == IDCANCEL) 
			{ 
				AfxGetMainWnd()->PostMessage(WM_CLOSE, 0, 0); 
				break; 
			} 
		} 
		DataPacket dp; 
		dp.pkt.nBitmapIndex = 0; 
		strcpy(dp.pkt.sData,"Checking game type"); 
		dp.pkt.sGameType = m_nGameType; 
		strcpy(dp.pkt.sPlayerName, m_Dlg.m_strPlayerName); 
		dp.pkt.sService = CHKGAME; 
		Send(dp, sizeof(PACKET)); 
	} 
	else 
	{ 
		m_pFiveInOneSocket = new CFiveInOneSocket(GetSafeHwnd()); 
		m_pFiveInOneSocket->Connect(m_Dlg.m_strServerComputeName); 
		m_pFiveInOneSocket->StartThread(); 
	} 
} 
 
void CNetworkGameController::Send(DataPacket &dp, int nLen) 
{ 
	// TODO: Add your command handler code here 
	DataPacket ldp = dp; 
	if(IsHost()) 
	{ 
        WaitForSingleObject(m_pListeningSocket->m_hSentEvent, INFINITE); 
		POSITION pos = m_pListeningSocket->m_ConnectionList.GetHeadPosition(); 
		while(pos != NULL) 
		{ 
			CClientSocket *pSocket = (CClientSocket*)m_pListeningSocket->m_ConnectionList.GetNext(pos); 
			pSocket->Write(ldp.pktStr, nLen); 
			pSocket->m_bSentReady = FALSE; 
		} 
		ResetEvent(m_pListeningSocket->m_hSentEvent); 
	} 
	else 
	{ 
		WaitForSingleObject(m_pFiveInOneSocket->m_hSentEvent, INFINITE); 
		m_pFiveInOneSocket->Write(ldp.pktStr, nLen); 
		ResetEvent(m_pFiveInOneSocket->m_hSentEvent); 
	} 
} 
 
void CNetworkGameController::ProcessMessage(DataPacket &dp) 
{ 
	switch(dp.pkt.sService) 
	{ 
	case CHKGAME: 
		{ 
			if(IsHost()) 
			{ 
				static bool bGameMismatch = FALSE; 
 
				if(strcmp(dp.pkt.sData, "Game type mismatch") == 0) 
				{ 
					static int x = 0; 
					bGameMismatch = TRUE; 
					DataPacket dp; 
					dp.pkt.nBitmapIndex = 0; 
					strcpy(dp.pkt.sData,"Game type mismatch"); 
					dp.pkt.sGameType = m_nGameType; 
					strcpy(dp.pkt.sPlayerName, m_Dlg.m_strPlayerName); 
					dp.pkt.sService = CHKGAME; 
					Send(dp, sizeof(PACKET)); 
 
					if(x == 0) 
					{ 
						x++; 
                        AfxMessageBox("Game type mismatch. The application will now terminate", MB_OK);		 
						AfxGetMainWnd()->PostMessage(WM_CLOSE, 0, 0); 
					}					 
				} 
				else 
				{ 
					CString name = dp.pkt.sPlayerName; 
					m_NameList.AddHead(name); 
					if(m_NameList.GetCount() >= m_Dlg.m_nNumOfPlayers+1) 
					{ 
						if(CheckNames(m_NameList) && !bGameMismatch) 
						{ 
                            DataPacket lpd; 
							lpd.pkt.nBitmapIndex = 0; 
							strcpy(lpd.pkt.sData, "Checking names"); 
							lpd.pkt.sGameType = m_nGameType; 
							strcpy(lpd.pkt.sPlayerName, m_Dlg.m_strPlayerName); 
							lpd.pkt.sService = CHKNAMES; 
							Send(lpd, sizeof(PACKET)); 
							AfxMessageBox("Two or more players have duplicate names. The application will now terminate", MB_OK); 
							AfxGetMainWnd()->PostMessage(WM_CLOSE, 0, 0); 
						} 
						else 
							CreationOfPlayers(); 
					} 
				} 
			} 
			else 
			{ 
				if(dp.pkt.sGameType != m_nGameType)  
				{ 
					DataPacket ldp; 
					ldp.pkt.nBitmapIndex = 0; 
					strcpy(ldp.pkt.sData, "Game type mismatch"); 
					ldp.pkt.sGameType = m_nGameType; 
					strcpy(ldp.pkt.sPlayerName, m_Dlg.m_strPlayerName); 
					ldp.pkt.sService = CHKGAME; 
					Send(ldp, sizeof(PACKET)); 
					AfxMessageBox("Game type mismatch. The application will now terminate", MB_OK); 
					AfxGetMainWnd()->PostMessage(WM_CLOSE, 0, 0); 
				} 
				else 
				{ 
					DataPacket ldp; 
					ldp.pkt.nBitmapIndex = 0; 
					strcpy(ldp.pkt.sData, "Checking game type"); 
					ldp.pkt.sGameType = m_nGameType; 
					strcpy(ldp.pkt.sPlayerName, m_Dlg.m_strPlayerName); 
					ldp.pkt.sService = CHKGAME; 
					Send(ldp, sizeof(PACKET)); 
				} 
					 
 
				if(strcmp(dp.pkt.sData, "Game type mismatch") == 0) 
				{ 
					AfxMessageBox("Game type mismatch. The application will now terminate", MB_OK); 
					AfxGetMainWnd()->PostMessage(WM_CLOSE, 0, 0); 
				} 
			} 
		} 
		break; 
	case CHKNAMES: 
		{ 
			if(IsHost()) 
			{ 
				;; 
			} 
			else 
			{ 
				AfxMessageBox("Two or more players have duplicate names. The application will now terminate", MB_OK); 
				AfxGetMainWnd()->PostMessage(WM_CLOSE, 0, 0); 
			} 
		} 
		break; 
	case READYTODEALAGAIN: 
		{ 
			if(IsHost()) 
			{ 
				static int counter = 0; 
				counter++; 
				if(counter >= m_nTotalNumberOfPlayers - 1) 
				{ 
					m_bReadyToDeal = TRUE; 
					counter = 0; 
				} 
			} 
		} 
		break; 
	} 
} 
 
void CNetworkGameController::OnDraw(CDC *pDC) 
{ 
} 
 
BOOL CNetworkGameController::IsHost() 
{ 
	return m_bIsHost; 
} 
 
void CNetworkGameController::SetHost(BOOL bIsHost) 
{ 
	m_bIsHost = bIsHost; 
} 
 
HRESULT CNetworkGameController::OnSocketMessage(WPARAM wParam, LPARAM lParam) 
{ 
	DataPacket dp; 
	int nLen = sizeof(PACKET); 
	int nSocketMessageVal = (int)wParam; 
	int nSocketID = (int)lParam; 
	if(IsHost()) 
	{ 
        if(nSocketMessageVal == CListeningSocket::kCanBeRead) 
		{ 
			POSITION pos = m_pListeningSocket->m_ConnectionList.GetHeadPosition(); 
			while(pos != NULL) 
			{ 
				CClientSocket *pSocket = (CClientSocket*)m_pListeningSocket->m_ConnectionList.GetNext(pos); 
				if(pSocket->m_SocketID == nSocketID) 
				{ 
					if(pSocket->Read(dp.pktStr, nLen)) 
					{ 
						m_pFloorDlg->AddMessage(dp); 
						ProcessMessage(dp); 
					} 
					ResetEvent(pSocket->m_hReadEvent); 
				} 
			} 
		} 
	} 
	else 
	{ 
		if(nSocketMessageVal == CFiveInOneSocket::kCanBeRead) 
		{ 
			if(m_pFiveInOneSocket->Read(dp.pktStr, nLen)) 
			{ 
				m_pFloorDlg->AddMessage(dp); 
				ProcessMessage(dp); 
			} 
			ResetEvent(m_pFiveInOneSocket->m_hReadEvent); 
		} 
	} 
	return 0; 
} 
 
BOOL CNetworkGameController::CheckNames(CStringList &rList) 
{ 
	rList.AddHead(m_Dlg.m_strPlayerName); 
 
	int counter = 0; 
	POSITION pos1 = rList.GetHeadPosition(); 
 
	while (pos1 != NULL) 
	{ 
		CString & strFirst = rList.GetNext(pos1); 
 
		POSITION pos2 = rList.GetHeadPosition(); 
 
		while (pos2 != NULL) 
		{ 
			CString & strNext = rList.GetNext(pos2); 
 
			if(strFirst == strNext) 
				counter++; 
		} 
	} 
	 
	if(counter > rList.GetCount()) 
		return TRUE; 
	else 
		return FALSE; 
 
	return FALSE; 
} 
 
void CGameController::OnInitialUpdate() 
{ 
	CView::OnInitialUpdate(); 
 
	// TODO: Add your specialized code here and/or call the base class 
} 
 
BOOL CGameController::Timer(CTypedPtrList *pPlayerList) 
{ 
	int cnt = (pPlayerList->GetHead())->m_CardArray.GetUpperBound(); 
	POSITION pos = pPlayerList->GetHeadPosition(); 
	while (pos != NULL) 
	{ 
		CPlayer *pPlayer = pPlayerList->GetNext(pos); 
		int MaxCards = pPlayer->m_CardArray.GetUpperBound(); 
		if(itimer <= MaxCards) 
			pPlayer->m_CardArray[itimer]->ShowWindow(SW_SHOW); 
		 
		if(itimer > cnt) 
		{ 
			m_bPlay = TRUE; 
			m_bAnimating = FALSE; 
			return FALSE; 
		} 
			 
		MSG msg; 
		while (::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE|PM_QS_PAINT)) 
		{ 
			if (!AfxGetApp()->PumpMessage())  
			{ 
				::PostQuitMessage(0); 
				break; 
			} 
		} 
	} 
	++itimer; 
	 
	return TRUE; 
} 
 
BOOL CGameController::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{ 
	// TODO: Add your message handler code here and/or call default 
 
	if(m_bSelection) 
	{ 
		SetCursor(m_HSelection); 
		return TRUE; 
	} 
	else if(m_bDragging) 
	{ 
		SetCursor(m_HDrag); 
		return TRUE; 
	} 
	 
	return CView::OnSetCursor(pWnd, nHitTest, message); 
} 
 
BOOL CGameController::OnEraseBkgnd(CDC* pDC) 
{ 
	// TODO: Add your message handler code here and/or call default 
 
	CRect ClientRect; 
	GetClientRect(&ClientRect); 
	pDC->FillRect(&ClientRect, &m_BackgroundBrush); 
	 
	return TRUE; 
	 
	//return CView::OnEraseBkgnd(pDC); 
}