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

📄 mygame.cpp

📁 这是一个连连看的游戏源程序
💻 CPP
字号:
// MyGame.cpp : implementation file
//

#include "stdafx.h"
#include <afx.h>
#include "Game.h"
#include "MyGame.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyGame

CMyGame::CMyGame()
{
	m_dx = 40 ;				//图标尺寸
	m_dy = 50 ;
	m_yc = 90 ;				//小窗口起始y值
	m_num = -1 ;			//初始无点
	m_ScreenWidth = 772 ;	//772*652窗口尺寸,应从窗口函数读取,未完成
	m_ScreenHeight = 652 ;	
	m_Class = EMPTY ;		//无级别
	m_SortAll = true ;		//true-初始排序,false-重新排序
	m_Pause = false ;		//未暂停
	m_GameOver = false ;	//结束否开关
	
	//随机初始化
	time_t tm ;	
	time(&tm) ;
	srand((int)tm) ;
}

CMyGame::~CMyGame()
{
}

BEGIN_MESSAGE_MAP(CMyGame, CWnd)
	//{{AFX_MSG_MAP(CMyGame)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyGame message handlers

//设置不同级别的初始图尺寸
void CMyGame::SetClass()
{
	m_Score = 0 ;
	m_Layer = 0 ;
	switch( m_Class )
	{
	case EASY :
		m_Xsize = 12 ;
		m_Ysize = 7 ;
		m_Look = 2 ;
		m_Prompt = 4 ;
		break;
	case NORMAL :
		m_Xsize = 14 ;
		m_Ysize = 8 ;
		m_Look = 3 ;
		m_Prompt = 6 ;
		break;
	case HARD :
		m_Xsize = 16 ;
		m_Ysize = 9 ;
		m_Look = 4 ;
		m_Prompt = 8 ;
		break;
	}
	m_GameOver = false ;
	m_xc=(770-m_Xsize*m_dx)/2 ;	//770为窗口宽度,应从窗口读取,现未完成
}

//初始化随机生成图标,使用冒泡排序算法

void CMyGame::ReInitData()
{
	m_SortAll = false ;
	do
	{	InitData() ;
	}while(!TestAll()) ;
	m_SortAll = true ;
}
void CMyGame::InitData()
{
	int i, j; 
	int x[16*9];

	//生成初始序号
	if ( m_SortAll )
	{	m_Count = m_Xsize*m_Ysize/2 ;
		m_Time = 300 ;
	}
	int Count = m_Count*2 ;

	//产生随机数
	GetRand(x, Count) ;

	//按冒泡排序算法将随机数的按序号排序

	//按约定的每图标4个产生初始图
	if ( m_SortAll )
	{	for (i=0; i<m_Xsize; i++)
			for (j=0; j<m_Ysize; j++)
				m_Data[i][j]=x[i*m_Ysize+j]/4+1;	//+1,约定值0表示被消去
	}
	else
	{	int tmpData[16*9] ;

		int k = 0 ;
		for (i=0; i<m_Xsize; i++)
			for (j=0; j<m_Ysize; j++)
				if ( m_Data[i][j] != 0 )
					tmpData[k++] = m_Data[i][j] ;
		k = 0 ;
		for (i=0; i<m_Xsize; i++)
			for (j=0; j<m_Ysize; j++)
				if ( m_Data[i][j] != 0 )
					m_Data[i][j] = tmpData[x[k++]] ;
	}
	//m_Layer = M_UPDOWN2 ;							//m_Layer = M_UPDOWN2 ;测试
	//M_OUT,M_IN
}

//产生一组互不相同的num个随机数[0,num-1]
void CMyGame::GetRand(int x[], int num)
{
	int xx, i, j ;
	for( i=0; i<num; i++)
	{	
		do
		{	xx = rand()%num ;
			for(j = 0 ; (j<i)&&(xx!=x[j]); j++);
		}while(j!=i) ;
		x[i] = xx ;
	}
}

//输入参数:(x,y)点坐标
//功能:判断点(x,y)是否在图形窗口内,并转换和保存相应方格值(xw,yw)
//返回成功标志
BOOL CMyGame::GetPoint(int x, int y)
{
	int xw, yw ;
	BOOL InWindow ;

	InWindow = (x-m_xc>=0)&&(x-m_xc<m_Xsize*m_dx)&&(y-m_yc>=0)&&(y-m_yc<m_Ysize*m_dy) ;
										//判断是否在图形窗口内
	if ( InWindow )
	{
		xw = (x-m_xc)/m_dx ;			//计算方格值
		yw = (y-m_yc)/m_dy ;
		InWindow &=(m_Data[xw][yw]!=0) ;//判断是否为0
	}
	if ( InWindow )
	{
		m_num++ ;
		m_xw[m_num] = xw ;				//保存方格值
		m_yw[m_num] = yw ;
	}
	return InWindow ;
}

//输入参数:k,k1为二点的下标
//功能:判断二点间有无连线
//返回:二点间有连线的布尔值
enum {START,END,MIDDLE} ;

BOOL CMyGame::CheckLine(BOOL IsPrompt, int k, int k1)
{
	int x0, x1, y0, y1, x, y ;
	BOOL TestOk=false ;

	x0 = m_xw[k] ;
	y0 = m_yw[k] ;
	x1 = m_xw[k1] ;
	y1 = m_yw[k1] ;
	//1.判断是否同一图标
	if (m_Data[x0][y0]!=m_Data[x1][y1])	
		return false ;	
	//2.判断一字直线
	if (x0==x1)
	{
		TestOk = CheckLineY(MIDDLE, x0, y0, y1);
		if ((!TestOk)&&(x0==0))
		{
			TestOk = true ;
			SetPoint(IsPrompt, -1, y0) ;
			SetPoint(IsPrompt, -1, y1) ; }
		if ((!TestOk)&&(x0==m_Xsize-1))
		{
			TestOk = true ;
			SetPoint(IsPrompt, m_Xsize, y0) ;
			SetPoint(IsPrompt, m_Xsize, y1) ;  }
	}
	if (y0==y1)
	{
		TestOk = CheckLineX(MIDDLE, x0, x1, y0);
		if ((!TestOk)&&(y0==0))
		{
			TestOk = true ;
			SetPoint(IsPrompt, x0, -1) ;
			SetPoint(IsPrompt, x1, -1) ; }
		if ((!TestOk)&&(y0==m_Ysize-1))
		{
			TestOk = true ;
			SetPoint(IsPrompt, x0, m_Ysize) ;
			SetPoint(IsPrompt, x1, m_Ysize) ;  }
	}
	//3.判断L字连线
	if (!TestOk)	
		if(TestOk = CheckLineX(START, x0, x1, y0)&&CheckLineY(MIDDLE, x1, y0, y1))
			SetPoint(IsPrompt, x1, y0) ;
	if (!TestOk)
		if(TestOk = CheckLineY(START, x0, y0, y1)&&CheckLineX(MIDDLE, x0, x1, y1))
			SetPoint(IsPrompt, x0, y1);
	//4.判断连线
	for(x=x0+1;((x==m_Xsize)||((x<m_Xsize)&&(m_Data[x][y0]==0)))&&(!TestOk);x++)
		if (TestOk = CheckLineY(START,x, y0, y1)&&CheckLineX(MIDDLE, x, x1, y1))
		{	SetPoint(IsPrompt, x, y0) ;
			SetPoint(IsPrompt, x, y1) ; }
	for(x=x0-1;((x==-1)||((x>=-1)&&(m_Data[x][y0]==0)))&&(!TestOk);x--)
		if (TestOk = CheckLineY(START, x, y0, y1)&&CheckLineX(MIDDLE, x, x1, y1))
		{	SetPoint(IsPrompt, x, y0) ;
			SetPoint(IsPrompt, x, y1) ; }
	for(y=y0+1;((y==m_Ysize)||((y<m_Ysize)&&(m_Data[x0][y]==0)))&&(!TestOk);y++)
		if (TestOk = CheckLineX(START,x0, x1, y)&&CheckLineY(MIDDLE,x1, y, y1))
		{	SetPoint(IsPrompt, x0, y) ;
			SetPoint(IsPrompt, x1, y) ; }
	for(y=y0-1;((y==-1)||((y>=0)&&(m_Data[x0][y]==0)))&&(!TestOk);y--)
		if (TestOk = CheckLineX(START,x0, x1, y)&&CheckLineY(MIDDLE,x1, y, y1))
		{	SetPoint(IsPrompt, x0, y) ;
			SetPoint(IsPrompt, x1, y) ; }
	if (TestOk&&(!IsPrompt))
		m_Data[x0][y0] = m_Data[x1][y1] = 0 ;
	return TestOk ;
}

//测试X向连线
BOOL CMyGame::CheckLineX(int flag, int x0, int x1, int y)
{
	BOOL Ok=true ;
	int x ;
	
	if ((y==-1)||(y==m_Ysize)) return true ;
	if ( x0 < x1 )
		for(x=x0+(flag!=END);(x<=x1-(flag!=START))&&Ok;x++) 
			Ok = (m_Data[x][y]==0) ;
	else
		for(x=x0-(flag!=END);(x>=x1+(flag!=START))&&Ok;x--) 
			Ok = (m_Data[x][y]==0) ;
	return Ok ;
}

//测试Y向连线
BOOL CMyGame::CheckLineY(int flag, int x, int y0, int y1)
{
	BOOL Ok=true ;
	int y ;

	if ((x==-1)||(x==m_Xsize)) return true ;
	if ( y0 < y1 )
		for(y=y0+(flag!=END);(y<=y1-(flag!=START))&&Ok;y++) 
			Ok = (m_Data[x][y]==0) ;
	else
		for(y=y0-(flag!=END);(y>=y1+(flag!=START))&&Ok;y--) 
			Ok = (m_Data[x][y]==0) ;
	return Ok ;
}

//测试全图有无连线
BOOL CMyGame::TestAll()
{
	int k, num ;
	BOOL TestOk = false ;

	num = m_num ;
	for(k = 1 ; (k <= (m_Xsize*m_Ysize)/4)&&(!TestOk); k++)
	{
		FindValue(k) ;
		TestOk = TestGraph() ;
	}
	m_num = num ;
	return TestOk ;
}

//搜索编号为no的图标,存放在(m_xw[4],m_yw[4])中
void CMyGame::FindValue(int no)
{
	int i, j ;
	BOOL TestOk = false ;

	m_num = -1 ;
	for (i=0; i<m_Xsize; i++)
	{
		for (j=0; j<m_Ysize; j++)
		   if (m_Data[i][j]==no)
		   {
			   m_num++ ;
			   m_xw[m_num] = i ;
			   m_yw[m_num] = j ;
		   }
	}
}

//测试当前图有无连线
BOOL CMyGame::TestGraph()
{
	int k, k1 ;
	BOOL TestOk = false ;

	if (m_num==-1) return false ;
	k = m_num+1 ;
	do
	{
		k1 = --k ;
		do
		{
			TestOk = CheckLine(true, k, --k1) ;
		}while((k1>0)&&(!TestOk));
	}while((k>1)&&(!TestOk)) ;
	if ( TestOk )
	{
		m_xw[0] = m_xw[k1] ;
		m_yw[0] = m_yw[k1] ;
		m_xw[1] = m_xw[k] ;
		m_yw[1] = m_yw[k] ;
		m_num = 1 ;
	}
	return TestOk ;
}

//转换图标(xw,yw)的中心坐标(x,y)
void CMyGame::TranToXYCenter(int *x, int *y, int k)
{
	*x = m_xc+m_xw[k]*m_dx+m_dx/2 ;
	*y = m_yc+m_yw[k]*m_dy+m_dy/2 ;
}

//保存点(xw,yw)到(m_xw[],m_yw[])中
void CMyGame::SetPoint(BOOL IsPrompt, int x, int y)
{
	if (!IsPrompt)
	{
		m_num++;
		m_xw[m_num]=x ; 
		m_yw[m_num]=y ; }
}

//转换(xw,yw)的图标角点坐标(x,y)
void CMyGame::TranToXY(int *x, int *y, int xw, int yw)
{
	*x = m_xc+xw*m_dx ;
	*y = m_yc+yw*m_dy ;
}

/***************移动图形2004.11.10-11.12***************/

void CMyGame::MoveGraph()
{
	switch( m_Layer )
	{
	case M_NO :			//不变化
	case M_OUT :		//向外扩散,未完成
	case M_IN :			//向内集中,未完成
		break ;
	case M_DOWN:		//向下
		MoveToDown2(ALL) ;
		break ;
	case M_LEFT:		//向左
		MoveToLeft2(ALL) ;
		break ;
	case M_UP:			//向上
		MoveToUp2(ALL) ;
		break ;
	case M_RIGHT:		//向右
		MoveToRight2(ALL) ;
		break ;
	case M_UPDOWN :		//上下分离
		switch((m_yw[0]>=m_Ysize/2)+2*(m_yw[1]>=m_Ysize/2))
		{
		case 0 :		//HALF0-HALF0
			MoveToUp2(HALF0) ;
			break ;
		case 1 :		//HALF1-HALF0
			MoveToDown(m_xw[0], m_yw[0], HALF1) ;
			MoveToUp(m_xw[1], m_yw[1], HALF0) ;
			break ;
		case 2 :		//HALF0-HALF1
			MoveToUp(m_xw[0], m_yw[0], HALF0) ;
			MoveToDown(m_xw[1], m_yw[1], HALF1) ;
			break ;
		case 3 :		//HALF1-HALF1
			MoveToDown2(HALF1) ;
			break ;
		}
		break ;
	case M_LEFTRIGHT :	//左右分离
		switch((m_xw[0]>=m_Xsize/2)+2*(m_xw[1]>=m_Xsize/2))
		{
		case 0 :		//HALF0-HALF0
			MoveToLeft2(HALF0) ;
			break ;
		case 1 :		//HALF1-HALF0
			MoveToRight(m_xw[0], m_yw[0], HALF1) ;
			MoveToLeft(m_xw[1], m_yw[1], HALF0) ;
			break ;
		case 2 :		//HALF0-HALF1
			MoveToLeft(m_xw[0], m_yw[0], HALF0) ;
			MoveToRight(m_xw[1], m_yw[1], HALF1) ;
			break ;
		case 3 :		//HALF1-HALF1
			MoveToRight2(HALF1) ;
			break ;
		}
		break ;
	case M_UPDOWN1 :	//上下集中 
		switch((m_yw[0]>=m_Ysize/2)+2*(m_yw[1]>=m_Ysize/2))
		{
		case 0 :		//HALF0-HALF0
			MoveToDown2(HALF0) ;
			break ;
		case 1 :		//HALF1-HALF0
			MoveToUp(m_xw[0], m_yw[0], HALF1) ;
			MoveToDown(m_xw[1], m_yw[1], HALF0) ;
			break ;
		case 2 :		//HALF0-HALF1
			MoveToDown(m_xw[0], m_yw[0], HALF0) ;
			MoveToUp(m_xw[1], m_yw[1], HALF1) ;
			break ;
		case 3 :		//HALF1-HALF1
			MoveToUp2(HALF1) ;
			break ;
		}
		break ;	
	case M_LEFTRIGHT1 :	//左右集中
		switch((m_xw[0]>=m_Xsize/2)+2*(m_xw[1]>=m_Xsize/2))
		{
		case 0 :		//HALF0-HALF0
			MoveToRight2(HALF0) ;
			break ;
		case 1 :		//HALF1-HALF0
			MoveToLeft(m_xw[0], m_yw[0], HALF1) ;
			MoveToRight(m_xw[1], m_yw[1], HALF0) ;
			break ;
		case 2 :		//HALF0-HALF1
			MoveToRight(m_xw[0], m_yw[0], HALF0) ;
			MoveToLeft(m_xw[1], m_yw[1], HALF1) ;
			break ;
		case 3 :		//HALF1-HALF1
			MoveToLeft2(HALF1) ;
			break ;
		}
		break ;
	case M_LEFTRIGHT2 :	//上左下右
		switch((m_yw[0]>=m_Ysize/2)+2*(m_yw[1]>=m_Ysize/2))
		{
		case 0 :		//HALF0-HALF0
			MoveToLeft2(ALL) ;
			break ;
		case 1 :		//HALF1-HALF0
			MoveToRight(m_xw[0], m_yw[0], ALL) ;
			MoveToLeft(m_xw[1], m_yw[1], ALL) ;
			break ;
		case 2 :		//HALF0-HALF1
			MoveToLeft(m_xw[0], m_yw[0], ALL) ;
			MoveToRight(m_xw[1], m_yw[1], ALL) ;
			break ;
		case 3 :		//HALF1-HALF1
			MoveToRight2(ALL) ;
			break ;
		}
		break ;
	case M_UPDOWN2 :	//左下右上
		switch((m_xw[0]>=m_Xsize/2)+2*(m_xw[1]>=m_Xsize/2))
		{
		case 0 :		//HALF0-HALF0
			MoveToDown2(ALL) ;
			break ;
		case 1 :		//HALF1-HALF0
			MoveToUp(m_xw[0], m_yw[0], ALL) ;
			MoveToDown(m_xw[1], m_yw[1], ALL) ;
			break ;
		case 2 :		//HALF0-HALF1
			MoveToDown(m_xw[0], m_yw[0], ALL) ;
			MoveToUp(m_xw[1], m_yw[1], ALL) ;
			break ;
		case 3 :		//HALF1-HALF1
			MoveToUp2(ALL) ;
			break ;
		}
		break ;	
	}
}

//上移子程序
//AreaFlag:ALL-全区,HALF0-上半区,HALF1-下半区
void CMyGame::MoveToUp(int xw, int yw, int AreaFlag)
{
	int yw1;

	switch( AreaFlag )
	{
	case ALL :
	case HALF1 :	
		yw1 = m_Ysize ;
		break ;
	case HALF0 :
		yw1 = m_Ysize/2 ;
		break ;
	}
	for (; yw<yw1-1; yw++)
		m_Data[xw][yw] = m_Data[xw][yw+1] ;
	m_Data[xw][yw] = 0 ;
}

//下移子程序
//AreaFlag:ALL-全区,HALF0-上半区,HALF1-下半区
void CMyGame::MoveToDown(int xw, int yw, int AreaFlag)
{
	int yw1;
	switch( AreaFlag )
	{
	case ALL :
	case HALF0 :
		yw1 = 0 ;
		break ;
	case HALF1 :
		yw1 = m_Ysize/2 ;
		break ;
	}
	for (; yw>yw1; yw--)
		m_Data[xw][yw] = m_Data[xw][yw-1] ;
	m_Data[xw][yw] = 0 ;
}

//左移子程序
//AreaFlag:ALL-全区,HALF0-左半区,HALF1-右半区
void CMyGame::MoveToLeft(int xw, int yw, int AreaFlag)
{
	int xw1;

	switch( AreaFlag )
	{
	case ALL :
	case HALF1 :
		xw1 = m_Xsize ;
		break ;
	case HALF0 :
		xw1 = m_Xsize/2 ;
		break ;
	}
	for (; xw<xw1-1; xw++)
		m_Data[xw][yw] = m_Data[xw+1][yw] ;
	m_Data[xw][yw] = 0 ;
}

//右移子程序
//AreaFlag:ALL-全区,HALF0-左半区,HALF1-右半区
void CMyGame::MoveToRight(int xw, int yw, int AreaFlag)
{
	int xw1;

	switch( AreaFlag )
	{
	case ALL :
	case HALF0 :
		xw1 = 0 ;
		break ;
	case HALF1 :
		xw1 = m_Xsize/2 ;
		break ;
	}
	for (; xw>xw1; xw--)
		m_Data[xw][yw] = m_Data[xw-1][yw] ;
	m_Data[xw][yw] = 0 ;
}

//二点下移子程序,考虑二点同列
//AreaFlag:ALL-全区,HALF0-上半区,HALF1-下半区
void CMyGame::MoveToDown2(int AreaFlag)
{
	if ((m_xw[0]!=m_xw[1])||((m_xw[0]==m_xw[1])&&(m_yw[0]<m_yw[1])))
	{	MoveToDown(m_xw[0], m_yw[0], AreaFlag) ;
		MoveToDown(m_xw[1], m_yw[1], AreaFlag) ;}
	else
	{	MoveToDown(m_xw[1], m_yw[1], AreaFlag) ;
		MoveToDown(m_xw[0], m_yw[0], AreaFlag) ;}
}

//二点左移子程序,考虑二点同行
//AreaFlag:ALL-全区,HALF0-左半区,HALF1-右半区
void CMyGame::MoveToLeft2(int AreaFlag)
{
	if ((m_yw[0]!=m_yw[1])||((m_yw[0]==m_yw[1])&&(m_xw[0]>m_xw[1])))
	{	MoveToLeft(m_xw[0], m_yw[0], AreaFlag) ;
		MoveToLeft(m_xw[1], m_yw[1], AreaFlag) ;}
	else
	{	MoveToLeft(m_xw[1], m_yw[1], AreaFlag) ;
		MoveToLeft(m_xw[0], m_yw[0], AreaFlag) ;}
}

//二点上移子程序,考虑二点同列
//AreaFlag:ALL-全区,HALF0-上半区,HALF1-下半区	
void CMyGame::MoveToUp2(int AreaFlag)
{
	if ((m_xw[0]!=m_xw[1])||((m_xw[0]==m_xw[1])&&(m_yw[0]>m_yw[1])))
	{	MoveToUp(m_xw[0], m_yw[0], AreaFlag) ;
		MoveToUp(m_xw[1], m_yw[1], AreaFlag) ;}
	else
	{	MoveToUp(m_xw[1], m_yw[1], AreaFlag) ;
		MoveToUp(m_xw[0], m_yw[0], AreaFlag) ;}
}

//二点右移子程序,考虑二点同行
//AreaFlag:ALL-全区,HALF0-左半区,HALF1-右半区
void CMyGame::MoveToRight2(int AreaFlag)
{
	if ((m_yw[0]!=m_yw[1])||((m_yw[0]==m_yw[1])&&(m_xw[0]<m_xw[1])))
	{	MoveToRight(m_xw[0], m_yw[0], AreaFlag) ;
		MoveToRight(m_xw[1], m_yw[1], AreaFlag) ;}
	else
	{	MoveToRight(m_xw[1], m_yw[1], AreaFlag) ;
		MoveToRight(m_xw[0], m_yw[0], AreaFlag) ;}
}

//计算过关奖励
int CMyGame::CompAward()
{
	return((m_Layer+1)*200+m_Time*10+m_Look*50) ;
}

//处理过关
void CMyGame::ProcessNext()
{
	CString str ;
	char *Class[3]={"Easy","Normal","Hard"} ;
	int Award ;
	
	if (m_Layer!=M_OUT)
	{	m_Layer++ ;
		m_Look++ ;
		m_Prompt+=5 ;
		Award = CompAward() ;
		str.Format("过关成功,请进入第%d关!\n剩余时间、生命值和关数依照比例,可以获得%d分。",
			m_Layer+1,Award) ;
		m_Score += Award ;
		AfxMessageBox(str) ; 
		InitData() ;//重新初始化
	}
	else
	{	str.Format("恭喜过关!!您以后可以挑战[%s难度],祝您玩的愉快",Class[m_Class+1]) ;
		AfxMessageBox(str) ; 
	}
}

⌨️ 快捷键说明

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