在一次面试过程中上机写出2048时间2个小时,但是没有写出来,后来工作的时候利用闲时自己写的供大家分享,发现其实2个小时是不够的。
当然还有一些头文件的包含等内容放在了basehead.h中此处省略
先把类结构贴出来
#pragma once
#include "BaseHead.h"
class CGame
{
public:
friend ostream& operator<<(ostream &out, CGame game);
public:
CGame(void);
~CGame(void);
public:
void init();
void ZeroData();
int randoms(int nRange = 0);
POINT getpos();
bool isFull();
bool isOver();
void run();
bool getDirectory();
void step();
bool DirectoryEnable();
void PosEnable();
void posUp();
void posDown();
void posLeft();
void posRight();
void DataEnable();
void DataUp();
void DataDown();
void DataRight();
void DataLeft();
bool IsEnable(int (*temp)[4]);/*bool IsEnable(int temp[4][4]); bool Isable(int temp[][4])*/
bool IsEnable(int *temp);
private:
bool operator==(CGame game);
operator int*();
private:
int _Data[ROW][COL];
POINT _ptNew;
TypeDirectory _type;
};
在编写过程中思路:
1.基本程序框架(略)
2.算法,4中不同方向移动过程中的怎样的算法能够保证所有的相等的数据都能合并在一起并且没有间隔
3.规则,怎样保证下一次的有效性,怎样保证程序over,怎样保证程序成功
算法说明:个人发现在4*4的空间中,需要来回两个循环可以保证所有的数据都合并但是还需要调整位置
规则说明:由于在算法的基础上,所以在判断是否产生移动不能够在通过函数的返回值类判断,需要先保存原来的数据成员然后跟移动后的数据对比,发生移动即为产生移动,在数据满的情况下,需要判断当前所有的数据是否还能够往某一个方向移动,同样在移动之前需要先保存最开始的数据,,当发现无法再进行移动之后程序over,当在其中有一个数据超过2048即为游戏完成
下面是程序的实现代码
#include "Game.h"
CGame::CGame(void)
{
}
CGame::~CGame(void)
{
}
ostream& operator<<(ostream &out, CGame game)
{
game.run();
return out;
}
void CGame::init()
{
ZeroData();
_ptNew = getpos();
_Data[_ptNew.x][_ptNew.y]=2;
_ptNew = getpos();
_Data[_ptNew.x ][_ptNew.y]=2;
}
void CGame::ZeroData()
{
for(int nrom = 0; ROW > nrom; nrom++)
{
for(int ncol = 0; COL > ncol; ncol++)
{
_Data[nrom][ncol] = 0;
}
}
}
int CGame::randoms(int nRange)
{
if(0 == nRange)
{
return rand();
}
else
{
int nres = 0;
do
{
nres = rand();
}
while(nRange <= nres);
return nres;
}
}
POINT CGame::getpos()
{
POINT pt;
do
{
pt.x = randoms(ROW);
pt.y = randoms(COL);
}
while(_Data[pt.x][pt.y]);
return pt;
}
bool CGame::isFull()
{
bool bflage = true;
for(int i = 0; ROW > i; i++)
{
for(int j = 0; COL > j; j++)
{
if(0 == _Data[i][j])
{
bflage = false;
break;
}
else
{
if(2048 == _Data[i][j])
{
printf("game is win \n");
}
}
}
}
return bflage;
}
bool CGame::isOver()
{
CGame game = *this;//save
bool bflage = false;
CGame gametemp = *this;
DataUp();
posUp();
bflage |= (*this == gametemp);
gametemp = *this;
if(!bflage)
{
run();
printf("up bflage is %d\n",bflage);
DataDown();
posDown();
bflage |= (*this == gametemp);
}
gametemp = *this;
if(!bflage)
{
run();
printf("down bflage is %d\n",bflage);
DataLeft();
posLeft();
bflage |= (*this == gametemp);
}
gametemp = (*this);
if(!bflage)
{
run();
printf("left bflage is %d\n",bflage);
DataRight();
posRight();
bflage |= (*this == gametemp);
}
if(!bflage)
{
run();
printf(" down bflage is %d\n",bflage);
}
*this = game;//reserver
return bflage;
}
void CGame::run()
{
for(int nrow = 0; ROW > nrow; nrow++)
{
string sdata;
for(int ncol = 0; COL > ncol; ncol++)
{
int ncount = 0;
int nres = _Data[nrow][ncol]/10;
while(0 < nres)
{
nres /= 10;
ncount++;
}
int ntemp = _Data[nrow][ncol];
if(ntemp)
{
printf("%d",ntemp);
for(int i = 0; ROW - ncount > i; i++)
{
printf("%s"," ");
}
}
else
{
printf("%s","0 ");
}
}
printf("\n");
}
printf("\n");
}
bool CGame::getDirectory()
{
char ch;
while(1)
{
ch = getch();
switch(ch)
{
case 'a':
case 'A':
_type = LEFT_DIRE;
break;
case 'w':
case 'W':
_type = UP_DIRE;
break;
case 's':
case 'S':
_type = DOWN_DIRE;
break;
case 'd':
case 'D':
_type = RIGHT_DIRE;
break;
default:
_type = NULL_DIRE;
break;
}
if((_type == LEFT_DIRE) || (RIGHT_DIRE == _type) || (UP_DIRE == _type) || (DOWN_DIRE == _type))
{
break;
}
continue;
}
return true;
}
void CGame::step()
{
system("cls");
if(!DirectoryEnable())
{
return;
}
_ptNew = getpos();
_Data[_ptNew.x][_ptNew.y] = 2;
run();
if(isFull() && !isOver())
{
printf("game is over\n");
}
}
bool CGame::DirectoryEnable()
{
bool bflage = false;
int nTemp[4][4];
for(int i = 0 ; ROW > i; i++)
{
for(int j = 0 ; COL > j; j++)
{
nTemp[i][j] = _Data[i][j];
}
}
CGame game = *this;
game.run();
DataEnable();
PosEnable();
/*return IsEnable(nTemp);*/
return *this == game;
}
bool CGame::IsEnable(int (*temp)[4])
{
bool bflage = false;
for(int i = 0; ROW > i; i++)
{
for(int j = 0; COL > j; j++)
{
if(temp[i][j] != _Data[i][j])
{
bflage |= true;
break;
}
}
}
return bflage;
}
bool CGame::IsEnable(int *temp)
{
bool bflage = false;
for(int i = 0; ROW > i; i++)
{
for(int j =0; COL > j; j++)
{
if(_Data[i][j] != temp[j])
{
bflage |= true;
break;
}
}
temp += 4;
}
return bflage;
}
bool CGame::operator==(CGame game)
{
bool bfalge = false;
if(this != &game)
{
bfalge |= IsEnable(game);
}
return bfalge;
}
CGame::operator int*()
{
return &_Data[0][0];
}
void CGame::PosEnable()
{
switch(_type)
{
case UP_DIRE:
posUp();
printf("上\n");
break;
case DOWN_DIRE:
posDown();
printf("下\n");
break;
case LEFT_DIRE:
posLeft();
printf("左\n");
break;
case RIGHT_DIRE:
posRight();
printf("右\n");
break;
default:
break;
}
}
void CGame::posUp()
{
for(int j = 0; COL > j; j++)
{
int k = ROW - 1;
for(int i = 0; ROW > i; i++)
{
if(0 == _Data[i][j])
{
k = i;
break;
}
}
for(int i = k + 1; ROW > i; i++)
{
if(_Data[i][j])
{
_Data[k][j] = _Data[i][j];
_Data[i][j] = 0;
k = i;
}
}
}
}
void CGame::posDown()
{
for(int j = 0; COL > j; j++)
{
int k = 0;
for(int i = ROW - 1; 0 <= i ; i--)
{
if(0 == _Data[i][j])
{
k = i;
break;
}
}
for(int i = k - 1; 0 <= i; i--)
{
if(_Data[i][j])
{
_Data[k][j] = _Data[i][j];
_Data[i][j] = 0;
k = i;
}
}
}
}
void CGame::posLeft()
{
for(int i = 0; ROW > i ; i++)
{
int k = COL - 1;
for(int j = 0; COL > j; j++)
{
if(0 == _Data[i][j])
{
k = j;
break;
}
}
for(int j = k+ 1; COL > j; j++)
{
if(_Data[i][j])
{
_Data[i][k] = _Data[i][j];
_Data[i][j] = 0;
k = j;
}
}
}
}
void CGame::posRight()
{
for(int i = 0; ROW > i; i++)
{
int k = 0;
for(int j = COL - 1; 0 <= j; j--)
{
if(0 == _Data[i][j])
{
k = j;
break;
}
}
for(int j = k - 1; 0 <= j; j--)
{
if(_Data[i][j])
{
_Data[i][k] = _Data[i][j];
_Data[i][j] = 0;
k = j;
}
}
}
}
void CGame::DataEnable()
{
switch(_type)
{
case UP_DIRE:
DataUp();
break;
case DOWN_DIRE:
DataDown();
break;
case LEFT_DIRE:
DataLeft();
break;
case RIGHT_DIRE:
DataRight();
break;
default:
break;
}
}
void CGame::DataUp()
{
for(int j = 0; COL > j; j++)
{
for(int k = 0; ROW -1 > k;k++)
{
if(_Data[k][j])
{
if(_Data[k+1][j])
{
if(_Data[k][j] == _Data[k+1][j])
{
_Data[k+1][j] += _Data[k][j];
_Data[k][j] = 0;
}
}
else
{
_Data[k + 1][j] = _Data[k][j];
_Data[k][j] = 0;
}
}
}
}
for(int j = 0; COL > j ; j++)
{
for(int k = ROW - 1; 1 <= k;k--)
{
if(_Data[k][j])
{
if(_Data[k - 1][j])
{
if(_Data[k][j] == _Data[k - 1][j])
{
_Data[k - 1][j] += _Data[k][j];
_Data[k][j] = 0;
}
}
else
{
_Data[k - 1][j] = _Data[k][j];
_Data[k][j] = 0;
}
}
}
}
}
void CGame::DataDown()
{
for(int j = 0; COL > j ; j++)
{
for(int k = ROW - 1; 1 <= k;k--)
{
if(_Data[k][j])
{
if(_Data[k - 1][j])
{
if(_Data[k][j] == _Data[k - 1][j])
{
_Data[k - 1][j] += _Data[k][j];
_Data[k][j] = 0;
}
}
else
{
_Data[k - 1][j] = _Data[k][j];
_Data[k][j] = 0;
}
}
}
}
for(int j = 0; COL > j; j++)
{
for(int k = 0; ROW -1 > k;k++)
{
if(_Data[k][j])
{
if(_Data[k+1][j])
{
if(_Data[k][j] == _Data[k+1][j])
{
_Data[k+1][j] += _Data[k][j];
_Data[k][j] = 0;
}
}
else
{
_Data[k + 1][j] = _Data[k][j];
_Data[k][j] = 0;
}
}
}
}
}
void CGame::DataRight()
{
for(int i = 0; ROW > i; i++)
{
for(int k = COL - 1; 0 < k; k--)
{
if(_Data[i][k])
{
if(_Data[i][k - 1])
{
if(_Data[i][k - 1] == _Data[i][k])
{
_Data[i][k-1] += _Data[i][k];
_Data[i][k] = 0;
}
}
else
{
_Data[i][k-1] = _Data[i][k];
_Data[i][k] = 0;
}
}
}
}
for(int i =0 ; ROW > i; i++ )
{
for(int k = 0; COL-1 > k; k++)
{
if(_Data[i][k])
{
if(_Data[i][k + 1])
{
if(_Data[i][k+1] == _Data[i][k])
{
_Data[i][k+1] += _Data[i][k];
_Data[i][k] = 0;
}
}
else
{
_Data[i][k + 1] = _Data[i][k];
_Data[i][k] = 0;
}
}
}
}
}
void CGame::DataLeft()
{
for(int i =0; ROW > i; i++)
{
for(int k = 0; COL- 1 > k; k++)
{
if(_Data[i][k])
{
if(_Data[i][k+1])
{
if(_Data[i][k+1] == _Data[i][k])
{
_Data[i][k+1] += _Data[i][k];
_Data[i][k] = 0;
}
}
else
{
_Data[i][k+1] = _Data[i][k];
_Data[i][k] = 0;
}
}
}
}
for(int i= 0; ROW > i; i++)
{
for(int k = COL - 1; 0 < k; k--)
{
if(_Data[i][k])
{
if(_Data[i][k-1])
{
if(_Data[i][k-1] == _Data[i][k])
{
_Data[i][k-1] += _Data[i][k];
_Data[i][k] = 0;
}
}
else
{
_Data[i][k - 1] = _Data[i][k];
_Data[i][k] = 0;
}
}
}
}
}
程序的优化之处:其实数据移动的函数只需要两个即可,因为后面都为进行posenable,所以有两个函数式多余的。。。
运行结果可以自己实现