www.gusucode.com > VC++三子棋游戏源码(类似五子棋)-源码程序 > VC++三子棋游戏源码(类似五子棋)-源码程序\code\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 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
DWORD WINAPI ProcessRecvMsgThread(LPVOID lpParam)
{
	TRACE("Enter ProcessRecvMsgThread(..) ...\n");

	CGameView *view = (CGameView *)lpParam;
	view->run();

	TRACE("Leave ProcessRecvMsgThread(..) ...\n");

	return 0;
}

//Flash the selecting flag
DWORD WINAPI FlashFlagThread(LPVOID lpParam)
{
	TRACE("Enter FlashFlagThread(..) ...\n");

	CGameView *view = (CGameView *)lpParam;
	view->FlashFlag(-1);	

	TRACE("Leave FlashFlagThread(..) ...\n");

	return 0;
}

//Flash the falg that has been moved to another position
DWORD WINAPI FlashPositionThread(LPVOID lpParam)
{
	TRACE("Enter FlashPositionThread(..) ...\n");

	CGameView *view = (CGameView *)lpParam;
	view->FlashPosition(-1);	
	
	TRACE("Leave FlashPositionThread(..) ...\n");

	return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CGameView

IMPLEMENT_DYNCREATE(CGameView, CView)

CGameView::CGameView()
{
	m_strUserName = "";
	m_strPassword = "";
	m_strServerName = "127.0.0.1";
	m_intPort = SERVER_PORT;

	m_hSocket = INVALID_SOCKET;
	m_bConnectToServer = FALSE;
	m_bReadyToGame = FALSE;
	m_bWaitForGame = FALSE;
	m_bInGame = FALSE;
	m_nTableID = 1;
	m_nPosition = -1;	

	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_bCurSelectingFlag = FALSE;

	//OffLine
	m_bOffLine = TRUE;
	m_bOffLineControl = FALSE;

	m_hRunThread = NULL;
	m_bRunState = FALSE;
}

CGameView::~CGameView()
{
}


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);

	///////
	//Flag Borad
	InitControlData();
	LoadWavRes();
	BuildFlagBoard();
	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)
					{
						OnBtSaveFlagInfo();
					}
					else if(nButtonID == GAME_BUTTONID_2)
					{
						OnBtLoadFlagInfo();
					}
				}
				else if(m_nButtonActionMode == PLAYING)
				{
					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)
					{
						OnBtSaveFlagInfo();
					}
				}
			}

			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_darkColor = COLOR_DARK_GRAY;
		m_selectColor_Yellow = COLOR_YELLOW;
		m_selectColor_Black = COLOR_BLACK;
		m_selectColor_Red = COLOR_RED;

		COLORREF tColorBk = RGB(160, 180, 220);
		m_backGroundBrush.CreateSolidBrush(tColorBk);
			
		m_hHandCursor = LoadCursor(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDC_CURSOR_HAND));	
	}
	
	//Load the flag 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,ProcessRecvMsgThread,(LPVOID)this,0,NULL);	
			m_bRunState = (m_hRunThread != NULL);
			///		

			m_bOffLine = FALSE;
		}
	}
	else	//OffLine
	{
		ShowButtons(OFFLINE);

		m_bOffLine = TRUE;
		m_strFlagInfoList.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::BuildFlagBoard()
{
}

void CGameView::InvalidateGameRect()
{
	CRect	rect;
	memset(&rect, 0, sizeof(CRect));
	this->GetClientRect(&rect);

	int nBottom = m_ptButtonPos[0].y-1;
	rect.bottom = nBottom;
	InvalidateRect(rect);

	memset(&rect, 0, sizeof(CRect));
	this->GetClientRect(&rect);
	rect.top = nBottom;
	rect.right = m_ptButtonPos[0].x-1;
	rect.bottom -= 18;	//18--Status Bar Height	
				
	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_SHOWFLAG),_T("WAVE"));
	m_pWaveShowFlag = 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_pWaveShowFlag)
	{
		FreeResource(m_pWaveShowFlag);		
		m_pWaveShowFlag = NULL;
	}
	if(m_pWaveDie)
	{
		FreeResource(m_pWaveDie);		
		m_pWaveDie = NULL;
	}
}

void CGameView::PlaySoundAction(int iResult)
{
	sndPlaySound(NULL,0);
}

void CGameView::InitTableInfo()
{
}

void CGameView::InitFlagInfo(BOOL bInitAll /*=TRUE*/)
{
}

void CGameView::InitControlData()
{	
	m_iSrcSelectedIndex = -1;
	m_iDestSelectedIndex = -1;
	m_bSelectedSrcFlag = FALSE;
	m_bSelectedDestFlag = FALSE;

	m_iFlashingIndex = -1;
	m_iLastSrcSelectedIndex = -1;
	m_iLastDestSelectedIndex = -1;
	m_bFlashFlagThread = FALSE;
	m_bFlashPositionThread = FALSE;

	m_bGameControlFlag = TRUE;
	m_bControlMoveFlag = FALSE;
//	m_bReadyToGame = FALSE;
	m_bWaitForGame = FALSE;
	//m_bInGame = FALSE;
	m_bPeaceGame = FALSE;

	m_bTakenOrderOnOff = TRUE;
	m_iLeftTime = 1;
	m_bDelayTime = FALSE;

	m_bBlastDie = FALSE;
	m_iBlastStep = 3;

	for(int i=0;i<4;i++) iDelayCount[i] = 0;
}

void CGameView::LoadFlagData(int direction,int flagColor,
								 CString strFlagInfo /* = ""*/)
{
}

/////////////////////////////////////////////////////////////////
void  CGameView::SetPosition()
{
	GetClientRect(&m_rect);
}

void  CGameView::SetBitmap()
{
	BMP_COMMENT.DeleteObject();
	BMP_COMMENT.LoadBitmap(IDB_COMMENT);

	BMP_TRAIN_COM.DeleteObject();
	BMP_TRAIN_COM.LoadBitmap(IDB_TRAIN_COM);	

	/////////////////////////////////////
	///*
	BMP_BLACK_FLAG.DeleteObject();
	BMP_BLACK_FLAG.LoadBitmap(IDB_BLACK_FLAGS);

	BMP_BLUE_FLAG.DeleteObject();
	BMP_BLUE_FLAG.LoadBitmap(IDB_BLUE_FLAGS);

	BMP_GREEN_FLAG.DeleteObject();
	BMP_GREEN_FLAG.LoadBitmap(IDB_GREEN_FLAGS);

	BMP_RED_FLAG.DeleteObject();
	BMP_RED_FLAG.LoadBitmap(IDB_RED_FLAGS);
	//*/

	/*
	BMP_BLACK_FLAG.DeleteObject();
	BMP_BLACK_FLAG.LoadBitmap(IDB_ZI_FLAGS);

	BMP_BLUE_FLAG.DeleteObject();
	BMP_BLUE_FLAG.LoadBitmap(IDB_LAN_FLAGS);

	BMP_GREEN_FLAG.DeleteObject();
	BMP_GREEN_FLAG.LoadBitmap(IDB_LV_FLAGS);

	BMP_RED_FLAG.DeleteObject();
	BMP_RED_FLAG.LoadBitmap(IDB_CENG_FLAGS);
	//*/
	/////////////////////////////////////

	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);

	BMP_BLASTDIE.DeleteObject();
	BMP_BLASTDIE.LoadBitmap(IDB_BLAST_DIE);

	BMP_WATCH_OFFLINE.DeleteObject();
	BMP_WATCH_OFFLINE.LoadBitmap(IDB_WATCH_OFFLINE);
}

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)	//(m_bInGame)
	{
		//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 iStartPosX = iPosX - 4*iOneStep;
	int iStartPosY = iPosY + 7*iOneStep;
	m_ptOrderIcon[0].x = iStartPosX;
	m_ptOrderIcon[0].y = iStartPosY;

	iStartPosX = iPosX - 6*iOneStep;
	iStartPosY = iPosY - 4*iOneStep;
	m_ptOrderIcon[1].x = iStartPosX;
	m_ptOrderIcon[1].y = iStartPosY;
	
	iStartPosX = iPosX + 4*iOneStep;
	iStartPosY = iPosY - 7*iOneStep;
	m_ptOrderIcon[2].x = iStartPosX;
	m_ptOrderIcon[2].y = iStartPosY;
	
	iStartPosX = iPosX + 6*iOneStep;
	iStartPosY = iPosY + 4*iOneStep;
	m_ptOrderIcon[3].x = iStartPosX;
	m_ptOrderIcon[3].y = iStartPosY;
}

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);

			rect.bottom = rect.bottom;
			memDC.FillRect(&rect,&m_backGroundBrush);			

			////////////////////////////////////////////////
			//把要画图的代码放在这里
			DrawBkGround(&memDC);
			DrawChessBoard(&memDC);
			////////////////////////////////////////////////
		
			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 iStartPosX = START_POS_X;
	const int iStartPosY = START_POS_Y;
	const int nBoardWidth = BOARD_WIDTH;
	const int nBoardHeight = BOARD_HEIGHT;
	const COLORREF tColor = m_selectColor_Black;

	int nPosCount = POINT_COUNT/2;
	
	//先画外边框, 中间边框, 内边框
	for(int nIndex = 0; nIndex < nPosCount; nIndex++)
	{
		int nPosX = iStartPosX + (BOARD_BASE_SIZE * nIndex);
		int nPosY = iStartPosY + (BOARD_BASE_SIZE * nIndex);
		int nWidth = nBoardWidth - (BOARD_BASE_SIZE * nIndex * 2);
		int nHeight = nBoardHeight - (BOARD_BASE_SIZE * nIndex * 2);

		int nStep = 0;
		pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, 
						nWidth-nStep*2, nHeight-nStep*2, 
						tColor, tColor);

		nStep = 1;
		pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, 
						nWidth-nStep*2, nHeight-nStep*2, 
						tColor, tColor);
		nStep = 2;
		pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, 
						nWidth-nStep*2, nHeight-nStep*2, 
						tColor, tColor);

		nStep = -1;
		pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, 
						nWidth-nStep*2, nHeight-nStep*2, 
						tColor, tColor);
		nStep = -2;
		pDC->Draw3dRect(nPosX+nStep, nPosY+nStep, 
						nWidth-nStep*2, nHeight-nStep*2, 
						tColor, tColor);
	}

	//再画直连线(顺时针画)
	CPen	tPen;
	tPen.CreatePen(PS_SOLID, 3, tColor);
	CPen*	pOldPen		=(CPen*)pDC->SelectObject(&tPen);
	
	{
		int nDistanceX = BOARD_BASE_SIZE * (nPosCount - 1);
		int nDistanceY = BOARD_BASE_SIZE * (nPosCount - 1);

		int nFromPosX = iStartPosX;
		int nFromPosY = iStartPosY;
		int nToPosX = iStartPosX + nDistanceX;
		int nToPosY = iStartPosY + 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();
}

void CGameView::DrawChessMan(CDC *pDC)
{	
	int iStartPosX = 0;
	int iStartPosY = 0;
	
	CDC memDC;	
	memDC.CreateCompatibleDC(pDC);

	/*
	switch(flagColor) {
	case RED:
		{
			memDC.SelectObject(BMP_RED_FLAG);

			break;
		}
	case GREEN:
		{
			memDC.SelectObject(BMP_GREEN_FLAG);

			break;
		}
	case BLUE:
		{
			memDC.SelectObject(BMP_BLUE_FLAG);

			break;
		}
	case BLACK:
		{
			memDC.SelectObject(BMP_BLACK_FLAG);

			break;
		}
	default:
		{			
		}
	}

	if(!bShowFace) 
	{
		flagValue = BKGND;
	}	

	pDC->StretchBlt(iStartPosX,iStartPosY,FLAG_WIDTH,FLAG_HEIGHT,&memDC,0,FLAG_HEIGHT*flagValue,FLAG_WIDTH,FLAG_HEIGHT,SRCCOPY);
		
	if(intSelected == 1)
	{	
		pDC->Draw3dRect(iStartPosX+1,iStartPosY+1,FLAG_WIDTH-2,FLAG_HEIGHT-2,m_selectColor_Yellow,m_selectColor_Yellow);
		pDC->Draw3dRect(iStartPosX,iStartPosY,FLAG_WIDTH,FLAG_HEIGHT,m_selectColor_Yellow,m_selectColor_Yellow);
		pDC->Draw3dRect(iStartPosX-1,iStartPosY-1,FLAG_WIDTH+2,FLAG_HEIGHT+2,m_selectColor_Yellow,m_selectColor_Yellow);
		pDC->Draw3dRect(iStartPosX-2,iStartPosY-2,FLAG_WIDTH+4,FLAG_HEIGHT+4,m_selectColor_Black,m_selectColor_Black);
		pDC->Draw3dRect(iStartPosX-3,iStartPosY-3,FLAG_WIDTH+6,FLAG_HEIGHT+6,m_selectColor_Black,m_selectColor_Black);
		//pDC->Draw3dRect(iStartPosX-4,iStartPosY-4,FLAG_WIDTH+8,FLAG_HEIGHT+8,m_selectColor_Black,m_selectColor_Black);
	}
	else if(intSelected == 2)
	{
		memDC.SelectObject(BMP_SRCMOVEFLAG);
		//pDC->StretchBlt(iStartPosX,iStartPosY,FLAG_WIDTH+4,FLAG_HEIGHT+4,&memDC,0,0,FLAG_WIDTH+4,FLAG_HEIGHT+4,SRCCOPY);

		//left->right->top->bottom->center
		const int wh = 10;
		int step = (FLAG_WIDTH - wh)/2;
		pDC->StretchBlt(iStartPosX,iStartPosY+step,wh,wh,&memDC,0,wh*0,wh,wh,SRCCOPY);
		pDC->StretchBlt(iStartPosX+(FLAG_WIDTH-wh),iStartPosY+step,wh,wh,&memDC,0,wh*1,wh,wh,SRCCOPY);
		pDC->StretchBlt(iStartPosX+wh,iStartPosY,wh,wh,&memDC,0,wh*2,wh,wh,SRCCOPY);
		pDC->StretchBlt(iStartPosX+wh,iStartPosY+(FLAG_WIDTH-wh),wh,wh,&memDC,0,wh*3,wh,wh,SRCCOPY);
		pDC->StretchBlt(iStartPosX+wh,iStartPosY+wh,wh,wh,&memDC,0,wh*4,wh,wh,SRCCOPY);
	}
	else if(intSelected == 3)	//after moving 
	{		
		pDC->Draw3dRect(iStartPosX+1,iStartPosY+1,FLAG_WIDTH-2,FLAG_HEIGHT-2,m_selectColor_Red,m_selectColor_Red);
		pDC->Draw3dRect(iStartPosX,iStartPosY,FLAG_WIDTH,FLAG_HEIGHT,m_selectColor_Red,m_selectColor_Red);
		pDC->Draw3dRect(iStartPosX-1,iStartPosY-1,FLAG_WIDTH+2,FLAG_HEIGHT+2,m_selectColor_Red,m_selectColor_Red);
		pDC->Draw3dRect(iStartPosX-2,iStartPosY-2,FLAG_WIDTH+4,FLAG_HEIGHT+4,m_selectColor_Black,m_selectColor_Black);
		pDC->Draw3dRect(iStartPosX-3,iStartPosY-3,FLAG_WIDTH+6,FLAG_HEIGHT+6,m_selectColor_Black,m_selectColor_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 iStartPosX = m_ptOrderIcon[order].x;
	int iStartPosY = m_ptOrderIcon[order].y;

	int iWidthHeight = 32;
	int textWidthHeight = 24;
	int iIconOrder = m_bTakenOrderOnOff? 0:1;
	pDC->StretchBlt(iStartPosX,iStartPosY,iWidthHeight,iWidthHeight,&memDC,0,iWidthHeight*iIconOrder,iWidthHeight,iWidthHeight,SRCCOPY);
	
	//Draw the Text(Show Left Time)
	if(!m_bOffLine)
	{
		iStartPosX = iStartPosX + iWidthHeight;
		iStartPosY = iStartPosY ; 
		iWidthHeight = textWidthHeight;
		memDC.SelectObject(BMP_LEFTTIME);
		memDC.SetBkColor(COLOR_BKGND);	
		pDC->StretchBlt(iStartPosX,iStartPosY,iWidthHeight,iWidthHeight,&memDC,0,iWidthHeight*(30-m_iLeftTime),iWidthHeight,iWidthHeight,SRCCOPY);
	}
}

void CGameView::InvalidateFlagRect(CPoint &point)
{
	int left = point.x-3;
	int top = point.y-3;
	int right = left + FLAG_WIDTH + 6;
	int bottom = top + FLAG_WIDTH + 6;
	CRect flagRect(left,top,right,bottom);
	InvalidateRect(flagRect,TRUE);
}

void CGameView::InvalidateFlagRect(int flagIndex)
{
	if(flagIndex == -1)
	{
		InvalidateGameRect();

		return;
	}

	CPoint point(0, 0);
	InvalidateFlagRect(point);
}

int CGameView::GetFlagIndex(CPoint &point)
{
	int retIndex = -1;
	
	for(int index=0;index<TOTAL_POINTS;index++)
	{		
		int left = 0;
		int top = 0;
		int right = left + FLAG_WIDTH;
		int bottom = top + FLAG_HEIGHT;
		CRect flagRect(left,top,right,bottom);

		if(flagRect.PtInRect(point))
		{			
			retIndex = index;		

			break;
		}	
	}	

	return retIndex;
}

int CGameView::GetPositionIndex(CPoint &point)
{
	int retIndex = -1;
	
	for(int index=0;index<TOTAL_POINTS;index++)
	{
		/*
		int posIndex = m_pFlags[index].index;

		int left = m_pFlags[index].point.x;
		int top = m_pFlags[index].point.y;
		*/
		int posIndex = 0;

		int left = 0;
		int top = 0;
		int right = left + FLAG_WIDTH;
		int bottom = top + FLAG_HEIGHT;
		CRect flagRect(left,top,right,bottom);

		if(flagRect.PtInRect(point))
		{			
			retIndex = posIndex;	

			break;
		}	
	}	

	return retIndex;
}

BOOL CGameView::GetPositionIndexList(int index, int *posList)
{
	
	return TRUE;
}

void CGameView::StartStopFlashFlagThread(BOOL bStart)
{
	static HANDLE hThread = NULL;

	if(bStart)
	{
		if(m_bInGame && m_bFlashFlagThread) return;

		hThread = ::CreateThread(NULL,1024,FlashFlagThread,(LPVOID)this,0,NULL);
		m_bFlashFlagThread = (hThread != NULL);
	}
	else
	{
		if(m_bFlashFlagThread && hThread != NULL)
		{			
			m_bFlashFlagThread = FALSE;
			WaitForSingleObject(hThread,INFINITE);
			hThread = NULL;
		}
	}
}

void CGameView::StartStopFlashPositionThread(BOOL bStart)
{
	static HANDLE hThread = NULL;
	if(bStart)
	{
		if(m_bFlashPositionThread) return;
		
		hThread = ::CreateThread(NULL,1024,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::FlashFlag(int flagIndex)
{
	//If it is in war, do not stop the flash thread,
	//else stop it and restart...
	if(flagIndex != -1)
	{
		//Stop the flashing flag action firstly
		
		int flasingFlag = m_iFlashingIndex;

		if(!m_bInGame)
		{
			StartStopFlashFlagThread(FALSE);
			if(flasingFlag != -1)
			{
			}
		}
		
		//The flag is flashing,do this action again will stop flashing		
		if(flasingFlag == flagIndex)
		{
			if(!m_bInGame) 
			{
				if(m_iSrcSelectedIndex != -1)
				{
					m_iSrcSelectedIndex = -1;

					InvalidateGameRect();
				}
			}
		}

		//do the flashing action
		else
		{	
			if(m_bInGame)
			{
				if(flasingFlag != -1)
				{
					InvalidateGameRect();
				}
			}

			m_iFlashingIndex = flagIndex;			
			StartStopFlashFlagThread(TRUE);
		}			
	}

	//Run the thread...
	else 
	{
		while(m_bFlashFlagThread)
		{
			if(m_iFlashingIndex != -1)
			{			
			}
			else break;

			if(!m_bFlashFlagThread) break;
					
			InvalidateGameRect();

			for(int i=0; i<25;i++)
			{
				if(!m_bFlashFlagThread) break;

				Sleep(10);
			}
		}
		
		m_bFlashFlagThread = FALSE;

		if(m_iFlashingIndex != -1)
		{
			InvalidateGameRect();
		}
	}
}

void CGameView::SetFlagSelectedState(int flagIndex,int iState)
{
	if(flagIndex != -1)
	{
		InvalidateFlagRect(flagIndex);
	}
}

void CGameView::SetFlagFaceState(int flagIndex)
{
}

void CGameView::FlashPosition(int posIndex)
{
	//Start the thread...
	if(posIndex != -1)
	{
		int tmpPosIndex = m_iFlashingIndex;
		
		StartStopFlashPositionThread(FALSE);
		if(tmpPosIndex != -1)
		{
			InvalidateFlagRect(tmpPosIndex);
		}

		m_iFlashingIndex = posIndex;
		StartStopFlashPositionThread(TRUE);		
	}

	//Run the thread...
	else
	{
		int iFlashingIndex = m_iFlashingIndex;

		BOOL bFlash = TRUE;
		while(m_bFlashPositionThread)
		{
			if(m_iFlashingIndex == -1) break;

			if(bFlash)
			{
				bFlash = FALSE;
			}
			else
			{
				bFlash = TRUE;
			}

			if(!m_bFlashPositionThread) break;

			InvalidateFlagRect(m_iFlashingIndex);

			for(int i=0;i<31;i++)
			{
				if(!m_bFlashPositionThread) break;

				Sleep(10);
			}
		}

		m_bFlashPositionThread = FALSE;
				
		if(m_iFlashingIndex != -1)
		{			
			InvalidateFlagRect(m_iFlashingIndex);
		}

		if(!m_bInGame)
		{
			//Reset the select falg
			if(m_iSrcSelectedIndex != -1)
			{
				m_iLastSrcSelectedIndex = m_iSrcSelectedIndex;
				InvalidateFlagRect(m_iSrcSelectedIndex);

				m_iSrcSelectedIndex = -1;				
			}

			if(m_iDestSelectedIndex != -1)
			{
				m_iLastDestSelectedIndex = m_iDestSelectedIndex;
				InvalidateFlagRect(m_iDestSelectedIndex);

				m_iDestSelectedIndex = -1;
			}
		}
		else
		{
			//continue the flashing
			if(iFlashingIndex != -1)
			{				
				InvalidateFlagRect(iFlashingIndex);
			}
		}
	}
}

void CGameView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	if(!m_bGameControlFlag) 
	{
		m_bCurSelectingFlag = FALSE;
		return;
	}

	ProcessLButtonDown(point);
	
	CView::OnLButtonDown(nFlags, point);
}

void CGameView::ProcessLButtonDown(CPoint &point)
{
}

void CGameView::GetFlagMovePathInfo(int srcIndex,int destIndex,
										int iPathInfo[],int &iStepCount)
{
}

void CGameView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	return;

	//Has Not connected to server
	if(!m_bConnectToServer)
	{

		return;
	}
	
	CView::OnLButtonUp(nFlags, point);
}

BOOL CGameView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bCurSelectingFlag)
	{
		SetCursor(m_hHandCursor);

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

void CGameView::OnMouseMove(UINT nFlags, CPoint point) 
{	
	if(!m_bGameControlFlag) 
	{
		m_bCurSelectingFlag = FALSE;
		return;
	}

	ProcessMouseMove(point);	
	
	CView::OnMouseMove(nFlags, point);
}

void CGameView::ProcessMouseMove(CPoint &point)
{
}

void CGameView::OnTimer(UINT nIDEvent) 
{
	CView::OnTimer(nIDEvent);
}

int CGameView::CheckValidPosition(int srcIndex,int destIndex)
{
	return 1;
}

int CGameView::GetRelativePosition(int myDirection,int absolutePosition)
{
	if(absolutePosition < myDirection)
	{
		absolutePosition += 4;
	}
	
	return (absolutePosition - myDirection);
}

int CGameView::TranslateFlagIndex(int flagColor,int flagIndex)
{
	int retFlagIndex = flagIndex;

	CPoint point(0,0);
	int centerIndex = 132;
	int centerX = 0;
	int centerY = 0;
	int Cx = centerX - 0;
	int Cy = centerY - 0;
	
	int realColor = GetRelativePosition(0, flagColor);

	if(realColor == 0)	
	{
		return flagIndex;
	}
	else if(realColor == 1)
	{	
		point.x = centerX + Cy;
		point.y = centerY - Cx;
	}
	else if(realColor == 2)
	{		
		point.x = centerX + Cx;
		point.y = centerY + Cy;
	}
	else if(realColor == 3)
	{		
		point.x = centerX - Cy;
		point.y = centerY + Cx;	
	}
	else
	{
		TRACE("Should not come here\n");
	}

	retFlagIndex = GetPositionIndex(point);

//	TRACE("In Index = %d -> Out Index = %d\n",flagIndex,retFlagIndex);

	return retFlagIndex;
}

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()
{
	if(m_bWaitForGame) return;

	m_strRecordHistory = "";

	BOOL bReadyTo = TRUE;

}

void CGameView::OnBtLoadFlagInfo()
{
}

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_bPeaceGame) return;

	///////////////////////////////////////////////
	////////////////////////////////////////////////

	m_bPeaceGame = 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;		

		InitFlagInfo();

		LoadFlagFile(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 strFlagMessage("");
		GetNextFlagInfo(strFlagMessage,pos);

		m_nCurStepCount--;
		if(m_nCurStepCount > 0)
		{
			//Only Get Previous position,will start from the previous positon
			CString strFlagInfo= m_strFlagInfoList.GetPrev(pos);
			////

			//Get the previous step flag info...
			strFlagInfo = "";
			POSITION oldPos = pos;		
			while(pos != NULL)
			{
				oldPos = pos;
				strFlagInfo = m_strFlagInfoList.GetPrev(pos);			
				
				//$MoveFromTo:SrcColor-DestColor:srcIndex-srcValue:destIndex-destValue#
				if(strFlagInfo.Left(1) == "$")
				{
					break;
				}
			}
			//pos == NULL means that it is the first step, need not flash position
			if(pos != NULL && strFlagInfo != "")
			{
			}		
			//////////////////////////////////		
			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 flag info
		KillTimer(nIDEvent);

		LoadFlagFile(g_strFileName);
	}
	else if(nIDEvent == OFFLINE_GETSTEPINFO_TIMER)
	{
		//Get the every time move flag info (from src to dest)
		KillTimer(nIDEvent);

		///*
		CString strFlagMessage("");
		GetNextFlagInfo(strFlagMessage,TRUE);		
	}
	else if(nIDEvent == OFFLINE_MOVESTEP_TIMER)
	{
		//Move Flag Step by Step
		KillTimer(nIDEvent);

		if(m_curMoveFlagPosition != NULL)
		{			
			CString strMoveFlag = m_strMoveFlagList.GetNext(m_curMoveFlagPosition);			
			
			//Will Move Next Step
			SetTimer(nIDEvent,100,NULL);
			////
		}
		else
		{
			m_bOffLineControl = TRUE;
		}
	}
}

void CGameView::OnBtSaveFlagInfo()
{
}

void CGameView::OnDestroy() 
{
	CView::OnDestroy();
	
	// TODO: Add your message handler code here	
	ProcessDisconnect();

	m_bInGame = FALSE;
	m_bReadyToGame = FALSE;
}

void CGameView::ProcessDisconnect(BOOL bManual /*=TRUE*/,
									  CString strComment /* = ""*/)
{
	if(m_hSocket != INVALID_SOCKET)
	{
		closesocket(m_hSocket);
		WSACleanup();

		m_hSocket = INVALID_SOCKET;
	}

	FreeWavRes();

	StartStopFlashFlagThread(FALSE);
	StartStopFlashPositionThread(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_bInGame = FALSE;
	m_bReadyToGame = FALSE;
	m_nTableID = 1;
	m_nPosition = -1;

	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()
{
	return (m_bInGame && (!m_bOffLine));
}

////////////////////////////////////////////////////////////
void CGameView::LoadFlagFile(CString strFlagFile)
{
	BOOL bLoadSuc = TRUE;
	
	if(g_strFileName == "") return;
	strFlagFile = g_strFileName;
		
	ifstream ism(strFlagFile,ios::in|ios::binary);
	if(ism.is_open())
	{
		m_bOffLine = TRUE;
		m_strFlagInfoList.RemoveAll();
		m_curStepPosition = NULL;
		m_moveStepPosition = NULL;
				
		m_nTotalStepCount = 0;
		m_nCurStepCount = 0;

		m_bReadyToGame = FALSE;
		m_bInGame = FALSE;
		KillTimer(TOKEN_ORDER_TIMER);
		m_bCurSelectingFlag = 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_strFlagInfoList.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_strFlagInfoList.GetHeadPosition();	
	m_moveStepPosition = m_curStepPosition;
	

	////Init the flag data(Load flag data,show user...),
	//and set m_curStepPosition, prepare to do move flag...
	CString strFlagMessage("");
	GetNextFlagInfo(strFlagMessage,FALSE);
	if(strFlagMessage != "")
	{
		m_bReadyToGame = TRUE;
		m_bInGame = TRUE;
		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::GetNextFlagInfo(CString &strFlagMessage, BOOL bMoveFlag)
{
	strFlagMessage = "";

	if(m_nCurStepCount != 0 && m_nCurStepCount == m_nTotalStepCount) return;
	
	CString strFlagInfo("#");
	
	if(!bMoveFlag)
	{
		POSITION oldPos = m_curStepPosition;
	
		//Get the header info,will load flag info and show user name
		//And Set m_curStepPosition...
		while(strFlagInfo.Left(1) != "$" && m_curStepPosition != NULL)
		{
			oldPos = m_curStepPosition;

			strFlagInfo = m_strFlagInfoList.GetNext(m_curStepPosition);

			if(strFlagInfo.Left(1) != "$") 
			{
				strFlagMessage += strFlagInfo;
			}
		}
		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_strFlagInfoList.GetNext(pos);
		strFlagMessage += strFirstStepInfo;

		if(pos != NULL)
		{
			do
			{
				oldPos = pos;
				strFlagInfo = m_strFlagInfoList.GetNext(pos);
				
				if(strFlagInfo.Left(1) != "$") 
				{
					strFlagMessage += strFlagInfo;
				}
			}while(strFlagInfo.Left(1) != "$" && pos != NULL);
		}
		m_moveStepPosition = oldPos;
		////
	}

	//Invalidate format
	int len = strFlagMessage.GetLength();
	if(len > MAX_BUFLEN-32 || strFlagMessage.FindOneOf("$#:+\r") == -1)
	{
		strFlagMessage = "";

		if(!bMoveFlag)
		{
			m_strFlagInfoList.RemoveAll();
			m_curStepPosition = NULL;			
		}
	}
	////
}

void CGameView::GetNextFlagInfo(CString &strFlagMessage, POSITION &curPos)
{
	strFlagMessage = "";

	//Get the next step info...
	POSITION pos = curPos;	
	CString strFlagInfo("#");

	CString strFirstStepInfo = m_strFlagInfoList.GetNext(pos);
	strFlagMessage += strFirstStepInfo;

	while(strFlagInfo.Left(1) != "$" && pos != NULL)
	{
		strFlagInfo = m_strFlagInfoList.GetNext(pos);

		if(strFlagInfo.Left(1) != "$") 
		{
			strFlagMessage += strFlagInfo;
		}
	}

	//Invalidate format
	int len = strFlagMessage.GetLength();
	if(len > MAX_BUFLEN-32 || strFlagMessage.FindOneOf("$#:+\r") == -1)
	{
		strFlagMessage = "";
	}
	////
}

////////////////////////////////////////////////////////////