📄 mfctttdoc.cpp
字号:
// mfctttDoc.cpp : implementation of the CMfctttDoc class
//
#include "stdafx.h"
#include "mfcttt.h"
#include "mfctttDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Find lenght of array
#define LENGTH(a) (sizeof(a)/sizeof(a[0]))
// This structure contains the logic for playing
// 0=empty, -1=my piece, 1=opponent piece, 2=don't care
struct TTLogic
{
int state[9];
BOOL lost;
int movex;
int movey;
BOOL win;
} logic[]=
{
{{0,2,2,2,2,2,2,2,2},FALSE,0,0,FALSE}, // opening #1
{{1,2,2,2,0,2,2,2,2},FALSE,1,1,FALSE}, // opening #2
{{1,1,1,2,2,2,2,2,2},TRUE,0,0,FALSE}, // wins x8
{{2,2,2,1,1,1,2,2,2},TRUE,0,0,FALSE},
{{2,2,2,2,2,2,1,1,1},TRUE,0,0,FALSE},
{{1,2,2,1,2,2,1,2,2},TRUE,0,0,FALSE},
{{2,1,2,2,1,2,2,1,2},TRUE,0,0,FALSE},
{{2,2,1,2,2,1,2,2,1},TRUE,0,0,FALSE},
{{1,2,2,2,1,2,2,2,1},TRUE,0,0,FALSE},
{{2,2,1,2,1,2,1,2,2},TRUE,0,0,FALSE},
{{-1,-1,0,2,2,2,2,2,2},FALSE,2,0,TRUE},
{{-1,0,-1,2,2,2,2,2,2},FALSE,1,0,TRUE},
{{-1,2,2,-1,2,2,0,2,2},FALSE,0,2,TRUE},
{{-1,2,2,0,2,2,-1,2,2},FALSE,0,1,TRUE},
{{-1,2,2,2,-1,2,2,2,0},FALSE,2,2,TRUE},
{{-1,2,2,2,0,2,2,2,-1},FALSE,1,1,TRUE},
{{1,-1,2,2,-1,2,2,0,2},FALSE,1,2,TRUE},
{{1,2,-1,2,-1,2,0,2,2},FALSE,0,2,TRUE},
{{1,2,2,-1,-1,0,2,2,2},FALSE,2,1,TRUE},
{{1,2,2,0,-1,-1,2,2,2},FALSE,0,1,TRUE},
{{1,2,0,2,-1,2,-1,2,2},FALSE,2,0,TRUE},
{{1,0,2,2,-1,2,2,-1,2},FALSE,1,0,TRUE},
{{2,2,-1,2,2,-1,2,2,0},FALSE,2,2,TRUE},
{{2,2,-1,2,2,0,2,2,-1},FALSE,2,1,TRUE},
{{2,2,0,2,2,-1,2,2,-1},FALSE,2,0,TRUE},
{{2,2,2,2,2,2,-1,-1,0},FALSE,2,2,TRUE},
{{2,2,2,2,2,2,-1,0,-1},FALSE,1,2,TRUE},
{{2,2,2,2,2,2,0,-1,-1},FALSE,0,2,TRUE},
{{1,1,0,2,2,2,2,2,2},FALSE,2,0,FALSE},
{{1,0,1,2,2,2,2,2,2},FALSE,1,0,FALSE},
{{1,2,2,1,2,2,0,2,2},FALSE,0,2,FALSE},
{{1,2,2,0,2,2,1,2,2},FALSE,0,1,FALSE},
{{2,2,2,1,1,0,2,2,2},FALSE,2,1,FALSE},
{{2,2,2,1,0,1,2,2,2},FALSE,1,1,FALSE},
{{2,2,2,0,1,1,2,2,2},FALSE,0,1,FALSE},
{{2,2,2,2,2,2,1,1,0},FALSE,2,2,FALSE},
{{2,2,2,2,2,2,1,0,1},FALSE,1,2,FALSE},
{{2,2,2,2,2,2,0,1,1},FALSE,0,2,FALSE},
{{2,1,2,2,1,2,2,0,2},FALSE,1,2,FALSE},
{{2,1,2,2,0,2,2,1,2},FALSE,1,1,FALSE},
{{2,0,2,2,1,2,2,1,2},FALSE,1,0,FALSE},
{{2,2,1,2,2,1,2,2,0},FALSE,2,2,FALSE},
{{2,2,1,2,2,0,2,2,1},FALSE,2,1,FALSE},
{{2,2,0,2,2,1,2,2,1},FALSE,2,0,FALSE},
{{2,2,1,2,1,2,0,2,2},FALSE,0,2,FALSE},
{{2,2,1,2,0,2,1,2,2},FALSE,1,1,FALSE},
{{2,2,0,2,1,2,1,2,2},FALSE,2,0,FALSE},
{{1,2,2,2,-1,2,0,1,2},FALSE,0,2,FALSE}
};
/////////////////////////////////////////////////////////////////////////////
// CMfctttDoc
IMPLEMENT_DYNCREATE(CMfctttDoc, CDocument)
BEGIN_MESSAGE_MAP(CMfctttDoc, CDocument)
//{{AFX_MSG_MAP(CMfctttDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMfctttDoc construction/destruction
CMfctttDoc::CMfctttDoc()
{
wins=loss=draw=0;
}
CMfctttDoc::~CMfctttDoc()
{
}
BOOL CMfctttDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// empty board and reset interesting variables
for (int i=0;i<LENGTH(board);i++) board[i]=EMPTY;
turn=0;
lastmove=-1;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMfctttDoc serialization
// Save and Load games
void CMfctttDoc::Serialize(CArchive& ar)
{
int i;
if (ar.IsStoring())
{
for (i=0;i<LENGTH(board);i++) ar<<board[i];
ar<<turn;
ar<<lastmove;
ar<<mylast;
}
else
{
for (i=0;i<LENGTH(board);i++) ar>>board[i];
ar>>turn;
ar>>lastmove;
ar>>mylast;
}
}
/////////////////////////////////////////////////////////////////////////////
// CMfctttDoc diagnostics
#ifdef _DEBUG
void CMfctttDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CMfctttDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMfctttDoc commands
// Access the board array. Notice that SetBoardState
// also sets lastmove for the undo function
int CMfctttDoc::GetBoardState(int x,int y)
{
return board[y*3+x];
}
void CMfctttDoc::SetBoardState(int x,int y,int state)
{
board[lastmove=y*3+x]=state;
}
// Make our move
void CMfctttDoc::Play(void)
{
BOOL l,w;
int x,y;
// Find entry in the logic array
if (!compare(x,y,l,w))
{
// no match -- just move to any empty square
for (int j=0;j<LENGTH(board);j++)
if (board[j]==EMPTY) break;
// no empty square, then draw game!
if (j==LENGTH(board))
{
draw++;
AfxMessageBox("Draw Game");
return;
}
// Fake up x and y for empty square
x=j%3;
y=j/3;
l=w=FALSE;
}
if (l) // Rats, we lost
{
loss++;
AfxMessageBox("You Win!");
return;
}
board[mylast=y*3+x]=O; // Make our move and set undo variable
turn++;
UpdateAllViews(NULL);
if (w)
{
wins++;// We Won!
AfxMessageBox("I Win!");
}
}
// Find entry in logic table that matches current board
BOOL CMfctttDoc::compare(int &x,int &y,BOOL &l,BOOL &w)
{
int i,j;
for (i=0;i<LENGTH(logic);i++)
{
for (j=0;j<LENGTH(board);j++)
{
// ignore don't cares
if (logic[i].state[j]==2) continue;
// if no match, try next line
if (logic[i].state[j]!=board[j]) break;
}
if (j==LENGTH(board)) // complete match!
{
x=logic[i].movex;
y=logic[i].movey;
l=logic[i].lost;
w=logic[i].win;
return TRUE;
}
}
return FALSE;
}
// Single level undo
// If doit is FALSE, then we are only asking
// if undo is possible; otherwise, we want
// the undo to occur
BOOL CMfctttDoc::undo(BOOL doit)
{
if (lastmove==-1) return FALSE;
if (doit)
{
board[lastmove]=EMPTY;
board[mylast]=EMPTY;
lastmove=-1;
UpdateAllViews(NULL);
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -