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

📄 fiveplusgamemodel.cpp

📁 该程序功能:用JAVa实现的彩色五珠棋小游戏
💻 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 + -