📄 fiveplusgamemodel.cpp
字号:
// FivePlusGameModel.cpp: implementation of the CFivePlusGameModel class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FivePlus.h"
#include "FivePlusGameModel.h"
#include "NameInputDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_SERIAL( CFivePlusGameModel, CObject, 1 )
CFivePlusGameModel::CFivePlusGameModel()
{
Initialize();
m_nCommon = 37;
m_nAny = 14;
m_nCrack = 7;
this->m_nMoveInterval = 40;
this->m_nShowInterval = 20;
this->m_nSelectInterval = 20;
int nXProportion[GRID_NUM_HOR];
for ( int i = 0; i < GRID_NUM_HOR; i++ ){
nXProportion[i] = 1;
}
m_rndXCoord.SetProperty(GRID_NUM_HOR, nXProportion);
m_rndXCoord.Initialize();
int nYProportion[GRID_NUM_VER];
for ( i = 0; i < GRID_NUM_VER; i++ ){
nYProportion[i] = 1;
}
m_rndYCoord.SetProperty(GRID_NUM_VER, nYProportion);
m_rndYCoord.Initialize();
for ( i = 0; i < 3; i++ ){
m_currentGrid[i] = NOTHING;
}
m_offSet[0].cx = 0;
m_offSet[0].cy = 1;
m_offSet[1].cx = 1;
m_offSet[1].cy = 0;
m_offSet[2].cx = 0;
m_offSet[2].cy = -1;
m_offSet[3].cx = -1;
m_offSet[3].cy = 0;
CFivePlusApp* theApp = (CFivePlusApp*)::AfxGetApp();
m_nExtraScore = 50;
CFile file;
BOOL result = file.Open(
theApp->m_szWorkPath + "\\score3.dat",
CFile::modeRead);
if ( result ){
CArchive ar(&file, CArchive::load);
Serialize(ar);
ar.Close();
file.Close();
}
//初始化随机种子比例,7色比例为37,自由壶为14,炸弹为7
this->ResetRandom();
m_rndBalls.Initialize();
}
CFivePlusGameModel::~CFivePlusGameModel()
{
CFivePlusApp* theApp = (CFivePlusApp*)::AfxGetApp();
CFile file(theApp->m_szWorkPath + "\\score3.dat",
CFile::modeCreate|CFile::modeWrite);
CArchive ar(&file, CArchive::store);
Serialize(ar);
ar.Close();
file.Close();
}
BOOL CFivePlusGameModel::NewGame()
{
if ( m_scoreModel.CanUpBoard(m_nScore) ){
CNameInputDlg dlg;
int result = dlg.DoModal();
if ( result ){
CScoreRecord* score = new CScoreRecord;
score->m_szName = dlg.m_szName;
score->m_nScore = m_nScore;
m_scoreModel.UpBoard(score);
}
}
Initialize();
NextBalls();
NextStep();
return TRUE;
}
BOOL CFivePlusGameModel::NextStep()
{
if ( FillPanel() ){
NextBalls();
return TRUE;
}else{
return FALSE;
}
}
BOOL CFivePlusGameModel::FillPanel()
{
m_lstInvalidPoint.RemoveAll();
float percent = (float)CountOccupy()/(float)(GRID_NUM_HOR*GRID_NUM_VER);
int num = 3;
if ( percent > 0.6f )
num = 2;
for ( int i = 0; i < num; i++ ){
if (!this->FillGrid(m_currentGrid[i]))
return FALSE;
}
for ( i = 0; i < this->m_nExtraChessman; i++){
if (!this->FillGrid(m_rndBalls.NextRandomInt() + 1))
return FALSE;
}
this->m_nExtraChessman = 0;
return TRUE;
}
BOOL CFivePlusGameModel::NextBalls()
{
for ( int i = 0; i < 3; i++ ){
m_currentGrid[i] = m_rndBalls.NextRandomInt() + 1;
}
return TRUE;
}
BOOL CFivePlusGameModel::IsFill()
{
for ( int i = 0; i < GRID_NUM_HOR; i++ ){
for ( int j = 0; j < GRID_NUM_VER; j++ ){
if ( m_grid[i][j] == NOTHING ){
return FALSE;
}
}
}
return TRUE;
}
BOOL CFivePlusGameModel::Initialize()
{
this->m_nExtraChessman = 0;
for ( int i = 0; i < GRID_NUM_HOR; i++ ){
for ( int j = 0; j < GRID_NUM_VER; j++ ){
m_grid[i][j] = NOTHING;
}
}
m_bHasSel = FALSE;
m_lstInvalidPoint.RemoveAll();
m_nScore = 0;
return TRUE;
}
int CFivePlusGameModel::ClickPoint(CPoint point)
{
m_lstInvalidPoint.RemoveAll();
if ( m_bHasSel ){
if ( m_grid[point.x][point.y] != NOTHING ){
if ( point == m_ptSel ){
return NO_OPERATION;
}else{
m_lstInvalidPoint.AddTail(m_ptSel);
//m_lstInvalidPoint.AddTail(point);
m_ptSel = point;
return SELECT_CHESSMAN;
}
}else{
return MoveTo(point);
}
}else{
if ( m_grid[point.x][point.y] != NOTHING ){
m_bHasSel = TRUE;
m_ptSel = point;
//m_lstInvalidPoint.AddTail(m_ptSel);
return SELECT_CHESSMAN;
}else{
return NO_OPERATION;
}
}
}
int CFivePlusGameModel::MoveTo(const CPoint point)
{
m_destPoint = point;
if ( CanMoveTo() ){
m_lstInvalidPoint.AddTail(m_ptSel);
m_lstInvalidPoint.AddTail(m_destPoint);
m_grid[m_destPoint.x][m_destPoint.y] = m_grid[m_ptSel.x][m_ptSel.y];
m_grid[m_ptSel.x][m_ptSel.y] = NOTHING;
m_bHasSel = FALSE;
return MOVE_CHESSMAN;
}else{
return NO_OPERATION;
}
}
BOOL CFivePlusGameModel::CanMoveTo()
{
ResetDirection(m_ptSel);
m_lstDeadPoint.RemoveAll();
m_lstPathPoint.RemoveAll();
m_lstPathPoint.AddTail(m_ptSel);
return FindPath();
}
int CFivePlusGameModel::CheckPoint(CPoint point, BOOL bClear)
{
int oldScore = this->m_nScore/m_nExtraScore;
if ( bClear ){
m_lstInvalidPoint.RemoveAll();
}
int result = 0;
result += RightToLeft(point);
int oldStandard = m_nBallStandard;
int result2 = LeftToRight(point);
if ( oldStandard != m_nBallStandard )
result += result2;
result += BottomToTop(point);
oldStandard = m_nBallStandard;
result2 = TopToBottom(point);
if ( oldStandard != m_nBallStandard )
result += result2;
result += RBToLT(point);
oldStandard = m_nBallStandard;
result2 = LTToRB(point);
if ( oldStandard != m_nBallStandard )
result += result2;
result += RTToLB(point);
oldStandard = m_nBallStandard;
result2 = LBToRT(point);
if ( oldStandard != m_nBallStandard )
result += result2;
if ( result ){
if ( !m_lstInvalidPoint.Find(point) ){
m_lstInvalidPoint.AddTail(point);
}
if ( bClear ){
ClearInvalid();
}
}
m_nScore += result;
int newScore = this->m_nScore/m_nExtraScore;
if ( newScore > oldScore )
this->m_nExtraChessman += newScore;
return result;
}
BOOL CFivePlusGameModel::Equal(int firstBall, int secondBall)
{
BOOL result = (secondBall != NOTHING) &&
(firstBall == secondBall ||
firstBall == FREEDOM ||
secondBall == FREEDOM ||
firstBall == CRACKER ||
secondBall == CRACKER);
return result;
}
int CFivePlusGameModel::RightToLeft(const CPoint point)
{
CSize direction(-1, 0);
return DirToDir(point, direction);
}
int CFivePlusGameModel::LeftToRight(const CPoint point)
{
CSize direction(1, 0);
return DirToDir(point, direction);
}
int CFivePlusGameModel::BottomToTop(const CPoint point)
{
CSize direction(0, -1);
return DirToDir(point, direction);
}
int CFivePlusGameModel::TopToBottom(const CPoint point)
{
CSize direction(0, 1);
return DirToDir(point, direction);
}
int CFivePlusGameModel::RBToLT(const CPoint point)
{
CSize direction(-1, -1);
return DirToDir(point, direction);
}
int CFivePlusGameModel::LTToRB(const CPoint point)
{
CSize direction(1, 1);
return DirToDir(point, direction);
}
int CFivePlusGameModel::RTToLB(const CPoint point)
{
CSize direction(-1, 1);
return DirToDir(point, direction);
}
int CFivePlusGameModel::LBToRT(const CPoint point)
{
CSize direction(1, -1);
return DirToDir(point, direction);
}
int CFivePlusGameModel::CheckNewPoint()
{
BOOL result = 0;
CList<CPoint, CPoint&> m_lstTempPoint;
m_lstTempPoint.AddTail(&m_lstInvalidPoint);
m_lstInvalidPoint.RemoveAll();
POSITION pos = m_lstTempPoint.GetHeadPosition();
while ( pos ){
result += CheckPoint(m_lstTempPoint.GetNext(pos), FALSE);
}
if ( result ){
ClearInvalid();
}
return result;
}
BOOL CFivePlusGameModel::ClearInvalid()
{
POSITION pos = m_lstInvalidPoint.GetHeadPosition();
while ( pos ){
CPoint point = m_lstInvalidPoint.GetNext(pos);
m_grid[point.x][point.y] = NOTHING;
}
return TRUE;
}
BOOL CFivePlusGameModel::FindPath()
{
for ( int i = 0; i < 4; i++){
CPoint nextPoint = m_lstPathPoint.GetTail();//m_pptMovePath[m_nPathPoint - 1];
nextPoint.Offset(m_offSet[i]);
if ( nextPoint.x >= 0 && nextPoint.x < GRID_NUM_HOR &&
nextPoint.y >= 0 && nextPoint.y < GRID_NUM_VER &&
m_grid[nextPoint.x][nextPoint.y] == NOTHING &&
!m_lstPathPoint.Find(nextPoint) &&
!m_lstDeadPoint.Find(nextPoint)){
m_lstPathPoint.AddTail(nextPoint);
if ( nextPoint == m_destPoint ){
return TRUE;
}
this->ResetDirection(nextPoint);
return FindPath();
}
}
if ( m_lstPathPoint.GetCount() > 1 ){
CPoint point = m_lstPathPoint.RemoveTail();
if ( !m_lstDeadPoint.Find(point) ){
m_lstDeadPoint.AddTail(point);
}
return FindPath();
}
return FALSE;
}
int CFivePlusGameModel::DirToDir(const CPoint point,
const CSize direction)
{
int count = 1;
int realAdd = 0;
m_nBallStandard = m_grid[point.x][point.y];
BOOL bContainCracker = FALSE;
if ( m_nBallStandard == CRACKER ){
bContainCracker = TRUE;
}
for ( int i = point.x + direction.cx, j = point.y + direction.cy;
i >= 0 && i < GRID_NUM_HOR &&
j >= 0 && j < GRID_NUM_VER;
i += direction.cx, j += direction.cy ){
if ( m_nBallStandard == FREEDOM ||
m_nBallStandard == CRACKER ){
m_nBallStandard = m_grid[i][j];
}
if ( !Equal(m_nBallStandard, m_grid[i][j]) ){
break;
}
if ( m_grid[i][j] == CRACKER ){
bContainCracker = TRUE;
}
CPoint ptCheck(i, j);
if ( !m_lstInvalidPoint.Find(ptCheck) ){
m_lstInvalidPoint.AddTail(ptCheck);
realAdd++;
}
count++;
}
for ( i = point.x - direction.cx, j = point.y - direction.cy;
i >= 0 && i < GRID_NUM_HOR &&
j >= 0 && j < GRID_NUM_VER;
i -= direction.cx, j -= direction.cy ){
if ( m_nBallStandard == FREEDOM ||
m_nBallStandard == CRACKER ){
m_nBallStandard = m_grid[i][j];
}
if ( !Equal(m_nBallStandard, m_grid[i][j]) ){
break;
}
if ( m_grid[i][j] == CRACKER ){
bContainCracker = TRUE;
}
CPoint ptCheck(i, j);
if ( !m_lstInvalidPoint.Find(ptCheck) ){
m_lstInvalidPoint.AddTail(ptCheck);
realAdd++;
}
count++;
}
if ( count >= 5 ){
if ( bContainCracker ){
DeleteAllInvalid(m_nBallStandard);
}
return CalScore(count, direction);
}else{
for ( int i = 0; i < realAdd; i++ ){
m_lstInvalidPoint.RemoveTail();
}
//m_nInvalidNum = m_nInvalidNum - realAdd;
return 0;
}
}
BOOL CFivePlusGameModel::DeleteAllInvalid(int nBall)
{
if ( nBall == FREEDOM ||
nBall == CRACKER ){
return FALSE;
}else{
for ( int i = 0; i < GRID_NUM_HOR; i++){
for ( int j = 0; j < GRID_NUM_VER; j++){
if ( m_grid[i][j] == nBall ){
CPoint point(i, j);
if ( !m_lstInvalidPoint.Find(point) ){
m_lstInvalidPoint.AddTail(point);
}
}
}
}
return TRUE;
}
}
int CFivePlusGameModel::CalScore(int nBallNum, CSize direction)
{
if ( direction.cx != 0 && direction.cy != 0 )
nBallNum++;
int result = 0;
switch(nBallNum){
case 5:
result = 3;
break;
case 6:
result = 5;
break;
case 7:
result = 8;
break;
case 8:
result = 12;
break;
case 9:
result = 17;
break;
}
return result;
}
int CFivePlusGameModel::GetScore()
{
return m_nScore;
}
//DEL void CFivePlusGameModel::FlashMove()
//DEL {
//DEL
//DEL }
void CFivePlusGameModel::ResetDirection(CPoint from)
{
int offX = m_destPoint.x - from.x;
int offY = m_destPoint.y - from.y;
if ( offY == 0 ){//abs(offX) >= abs(offY)
if ( offX >= 0 ){
m_offSet[0].cx = 1;
m_offSet[0].cy = 0;
m_offSet[2].cx = -1;
m_offSet[2].cy = 0;
}else{
m_offSet[0].cx = -1;
m_offSet[0].cy = 0;
m_offSet[2].cx = 1;
m_offSet[2].cy = 0;
}
if ( offY >= 0 ){
m_offSet[1].cx = 0;
m_offSet[1].cy = 1;
m_offSet[3].cx = 0;
m_offSet[3].cy = -1;
}else{
m_offSet[1].cx = 0;
m_offSet[1].cy = -1;
m_offSet[3].cx = 0;
m_offSet[3].cy = 1;
}
}else{
if ( offX >= 0 ){
m_offSet[1].cx = 1;
m_offSet[1].cy = 0;
m_offSet[3].cx = -1;
m_offSet[3].cy = 0;
}else{
m_offSet[1].cx = -1;
m_offSet[1].cy = 0;
m_offSet[3].cx = 1;
m_offSet[3].cy = 0;
}
if ( offY >= 0 ){
m_offSet[0].cx = 0;
m_offSet[0].cy = 1;
m_offSet[2].cx = 0;
m_offSet[2].cy = -1;
}else{
m_offSet[0].cx = 0;
m_offSet[0].cy = -1;
m_offSet[2].cx = 0;
m_offSet[2].cy = 1;
}
}
}
int CFivePlusGameModel::CountOccupy()
{
int result = 0;
for ( int i = 0; i < GRID_NUM_HOR; i++){
for ( int j = 0; j < GRID_NUM_VER; j++){
if ( m_grid[i][j] != NOTHING )
result++;
}
}
return result;
}
BOOL CFivePlusGameModel::FillGrid(int chessman)
{
if ( IsFill() ){
return FALSE;
}
BOOL hasFill = FALSE;
while ( !hasFill ){
int x = m_rndXCoord.NextRandomInt();
int y = m_rndYCoord.NextRandomInt();
if ( m_grid[x][y] == NOTHING ){
m_grid[x][y] = chessman;
CPoint point(x, y);
if ( !m_lstInvalidPoint.Find(point) )
m_lstInvalidPoint.AddTail(point);
hasFill = TRUE;
}
}
return TRUE;
}
void CFivePlusGameModel::Serialize(CArchive &ar)
{
m_scoreModel.Serialize(ar);
if (ar.IsStoring())
{
for ( int i = 0; i < GRID_NUM_HOR; i++ )
{
for ( int j = 0; j < GRID_NUM_VER; j++ )
{
ar << m_grid[i][j];
}
}
ar << m_nScore << m_nExtraChessman;
for ( i = 0; i < 3; i++ )
{
ar << m_currentGrid[i];
}
ar << m_nExtraScore;
ar << this->m_nShowInterval;
ar << this->m_nSelectInterval;
ar << this->m_nMoveInterval;
}
else
{
for ( int i = 0; i < GRID_NUM_HOR; i++ )
{
for ( int j = 0; j < GRID_NUM_VER; j++ )
{
ar >> m_grid[i][j];
}
}
ar >> m_nScore >> m_nExtraChessman;
for ( i = 0; i < 3; i++ )
{
ar >> m_currentGrid[i];
}
ar >> m_nExtraScore;
ar >> this->m_nShowInterval;
ar >> this->m_nSelectInterval;
ar >> this->m_nMoveInterval;
}
}
void CFivePlusGameModel::ResetRandom()
{
int nProportion[CRACKER];
for ( int i = RED; i < FREEDOM; i++ ){
nProportion[i - 1] = m_nCommon;
}
nProportion[FREEDOM - 1] = m_nAny;
nProportion[CRACKER - 1] = m_nCrack;
m_rndBalls.SetProperty(CRACKER, nProportion);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -