📄 mygame.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 + -