⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tttdoc.cpp

📁 API经典入门
💻 CPP
字号:
// tttdoc.cpp : implementation of the CTTTDoc class
//

#include "stdafx.h"
#include "ttt.h"

#include "tttdoc.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTTTDoc

IMPLEMENT_DYNCREATE(CTTTDoc, CDocument)

BEGIN_MESSAGE_MAP(CTTTDoc, CDocument)
	//{{AFX_MSG_MAP(CTTTDoc)
	ON_COMMAND(ID_OPTIONS_HUMANSTART, OnOptionsHumanstart)
	ON_UPDATE_COMMAND_UI(ID_OPTIONS_HUMANSTART, OnUpdateOptionsHumanstart)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTTTDoc construction/destruction

CTTTDoc::CTTTDoc()
{
	// TODO: add one-time construction code here
	m_cWhoGoesFirst = 'X';
	// this is not put in the OnNewDocument function since
	// we may want to dynamically change it.
}

CTTTDoc::~CTTTDoc()
{
}

/////////////////////////////////////////////////////////////////////////////
// CTTTDoc Operations

void CTTTDoc::AnalyzeBoard()
{
	int Sum, I, J; 

	int BestSum = 0;
	int BestI, BestJ;
	
	const int ImminentWin = 2;
	const int ImminentLoss = -2; // for the computer, i.e. for 'O'
	
	InitWinSumIterator();
	while ( NextWinSum(Sum, I, J) )
	{
	
		switch (Sum)
		{
			case 3:
			m_cGameStatus = 'O';
			return;
			
			case -3:
			m_cGameStatus = 'X';
			return;
			
			// keep tract of the best sum coordinates for
			// ImminentWin or ImminentLoss
			case ImminentWin:
			BestSum = Sum;
			BestI = I;
			BestJ = J;
			break;
			
			case ImminentLoss:
			if ( BestSum != ImminentWin )
			{
				BestSum = Sum;
				BestI = I;
				BestJ = J;
			}
			break;
			
			default:
			break;
		}
		
	} // end while

	// Save the imminent win/loss coordinates
	if (abs(BestSum) == 2)
	{
		m_nBestI = BestI;
		m_nBestJ = BestJ;
		return;
	}
	
	
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			// if there are blanks the game's still afoot
			if (m_acBoard[i][j] == ' ')
			{
				m_nBestI = i;
				m_nBestJ = j;
				return;
			}
	
	// if there are no blanks and no wins it's a draw.			
	m_cGameStatus = 'C';
		
}

void CTTTDoc::InitWinSumIterator()
{
	m_nIterator = 0;
}

BOOL CTTTDoc::NextWinSum(int &nSum, int &nBestI, int &nBestJ)
{
	int i, j;

	if (m_nIterator < 0)
		return FALSE;
		// Iterator was not initialized.
		
	// hold the value of the original iterator
	int nPosition = m_nIterator;
	// increment the iterator for the next pass
	m_nIterator++;
	
	nSum = 0;
		
	if (nPosition < BOARD_SIZE)
	{
		// calculate the appropriate horizontal win sum
		
		for (j = 0; j < BOARD_SIZE; j++)
			if (m_acBoard[nPosition][j] == 'X')
				nSum--;
			else if (m_acBoard[nPosition][j] == 'O')
				nSum++;
			else  // m_acBoard[i][j] == ' '
			{
				nBestI = nPosition;
				nBestJ = j;
			}
		
		return TRUE;
	}
	
	if (nPosition < 2*BOARD_SIZE )
	{
		// calculate the appropriate vertical win sum
		
		// translate the iterator into array units
		j = nPosition - BOARD_SIZE;
		
		for (i = 0; i < BOARD_SIZE; i++)
			if (m_acBoard[i][j] == 'X')
				nSum--;
			else if (m_acBoard[i][j] == 'O')
				nSum++;
			else  // m_acBoard[i][j] == ' '
			{
				nBestI = i;
				nBestJ = j;
			}
		
		return TRUE;
	}
	
	int nDiagonalWins = 2; // one for each diagonal
	if (nPosition < 2*BOARD_SIZE + nDiagonalWins)
	{
		// calculate the appropriate diagonal win sum
		
		// translate the iterator into diagonal iteration units
		// n will take on values of 0 & 1
		int n = nPosition - 2*BOARD_SIZE;
		
		for (i = 0; i < BOARD_SIZE; i++) 
		{
			j = n*(2-2*i) + i;
			if (m_acBoard[i][j] == 'X')
				nSum--;
			else if (m_acBoard[i][j] == 'O')
				nSum++;
			else  // m_acBoard[i][i] == ' '
			{
				nBestI = i;
				nBestJ = j;
			}
		}
		
		return TRUE;
	}
	
	return FALSE;
	// m_nIterator went beyond the possible iterations
}

BOOL CTTTDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
    
    // initialize the board with spaces
    memset(m_acBoard[0], ' ', BOARD_SIZE*BOARD_SIZE);

	m_cGameStatus = ' ';
	m_nBestI = BOARD_SIZE/2;
	m_nBestJ = BOARD_SIZE/2;
	m_nIterator = -1;
	
	// if the computer goes first then make a move.
	if (m_cWhoGoesFirst == 'O')
		m_acBoard[1][1] = 'O';

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CTTTDoc serialization

void CTTTDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CTTTDoc diagnostics

#ifdef _DEBUG
void CTTTDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CTTTDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTTTDoc commands

void CTTTDoc::OnOptionsHumanstart()
{
	// TODO: Add your command handler code here
	
	if (m_cWhoGoesFirst == 'X')
		m_cWhoGoesFirst = 'O';
	else
		m_cWhoGoesFirst = 'X';	
	

}

void CTTTDoc::OnUpdateOptionsHumanstart(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetRadio (m_cWhoGoesFirst == 'X');
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -