2048 源码
之前在面试过程中被问到了2048怎么写。当时思路堵塞。写不出来。
面试结束回来细致想了想,认为也不是非常难,能够实现。
于是乎有了以下的代码。
说下思路:
2048主要能够分为1、随机生成新数2或者4,;2、上下左右移动;3、推断死亡及胜利。
上下左右移动都能够归结到对一行或一列的四个数进行操作,然后进行四次。
filename: my2048.h
void Adjust(int *num); void Add(int* num); void Movedown(); void Moveup(); void Moveleft(); void Moveright(); bool dead(); bool win(int MAX); double random(double start, double end); void generate(); void display (int mark);
filename: my2048.cpp
#include <iostream> #include <ctime> #include "my2048.h" using namespace std; int MAP[4][4]; int mark; //将全部非零元素都移动到左側 void Adjust(int *num) { int i,j; for(i=0;i<3;i++) { if(num[i]==0) { for(j=i+1;j<4;j++) { if(num[j]!=0) { num[i]=num[j]; num[j]=0; break; } } } } } void Add(int* num) { int i; //先将全部非零元素都移动到左側 Adjust(num); //然后再考虑同样元素合并问题 for(i=0;i<3;i++) { if(num[i]==num[i+1]) { num[i]=2*num[i]; num[i+1]=0; mark += num[i]; } } //由于合并过程中可能会出现0元素,故须要又一次将非零元素左移 Adjust(num); } void Movedown() { int j; int num[4]={0}; for(j=0;j<4;j++) { num[0]=MAP[3][j]; num[1]=MAP[2][j]; num[2]=MAP[1][j]; num[3]=MAP[0][j]; Add(num); MAP[3][j]=num[0]; MAP[2][j]=num[1]; MAP[1][j]=num[2]; MAP[0][j]=num[3]; } } void Moveup() { int j; int num[4]={0}; for(j=0;j<4;j++) { num[0]=MAP[0][j]; num[1]=MAP[1][j]; num[2]=MAP[2][j]; num[3]=MAP[3][j]; Add(num); MAP[0][j]=num[0]; MAP[1][j]=num[1]; MAP[2][j]=num[2]; MAP[3][j]=num[3]; } } void Moveleft() { int i; int num[4]={0}; for(i=0;i<4;i++) { num[0]=MAP[i][0]; num[1]=MAP[i][1]; num[2]=MAP[i][2]; num[3]=MAP[i][3]; Add(num); MAP[i][0]=num[0]; MAP[i][1]=num[1]; MAP[i][2]=num[2]; MAP[i][3]=num[3]; } } void Moveright() { int i; int num[4]={0}; for(i=0;i<4;i++) { num[0]=MAP[i][3]; num[1]=MAP[i][2]; num[2]=MAP[i][1]; num[3]=MAP[i][0]; Add(num); MAP[i][3]=num[0]; MAP[i][2]=num[1]; MAP[i][1]=num[2]; MAP[i][0]=num[3]; } } //检測是否已经死亡,主要是检查元素是否跟自己右側和下側元素是否同样,同样表明还没死 bool dead() { int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) if(MAP[i][j]==0) return false; for(i=0;i<3;i++) { for(j=0;j<3;j++) { if(MAP[i][j]==MAP[i][j+1] || MAP[i][j]==MAP[i+1][j]) return false; } } return true; } bool win(int MAX) { int i,j; int temp = 0; for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(MAP[i][j]>temp) temp=MAP[i][j]; } } if(temp==MAX) return true; else return false; } double random(double start, double end) { return start+(end-start)*rand()/(RAND_MAX+ 1.0); //最后范围处于[start,end-1] } //随机生成数字2或者4 void generate() { int i,j; int zero_num = 0; //先统计0的个数 for(i=0;i<4;i++) for(j=0;j<4;j++) if(MAP[i][j]==0) zero_num++; //生成两个随机数:第一个数是位置,第二个是新生成的数(2或者4) int random_num = static_cast<int>(random(0,zero_num)+1.0); //int new_num = static_cast<int>((random(0,2)+1.0)) * 2; //2、4全然随机 int new_num = 0; int new_num_temp = static_cast<int>(random(0,4)+1.0); if(new_num_temp<4) new_num = 2; else new_num = 4; int zero_temp=0; for(i=0;i<4;i++) for(j=0;j<4;j++) if(MAP[i][j]==0) { zero_temp ++; if(zero_temp == random_num) MAP[i][j] = new_num; } } void display (int mark) { printf ("得分:%d\n",mark); printf ("┏━━┳━━┳━━┳━━┓\n"); printf ("┃%4d┃%4d┃%4d┃%4d┃\n",MAP[0][0],MAP[0][1],MAP[0][2],MAP[0][3]); printf ("┣━━╋━━╋━━╋━━┫\n"); printf ("┃%4d┃%4d┃%4d┃%4d┃\n",MAP[1][0],MAP[1][1],MAP[1][2],MAP[1][3]); printf ("┣━━╋━━╋━━╋━━┫\n"); printf ("┃%4d┃%4d┃%4d┃%4d┃\n",MAP[2][0],MAP[2][1],MAP[2][2],MAP[2][3]); printf ("┣━━╋━━╋━━╋━━┫\n"); printf ("┃%4d┃%4d┃%4d┃%4d┃\n",MAP[3][0],MAP[3][1],MAP[3][2],MAP[3][3]); printf ("┗━━┻━━┻━━┻━━┛\n"); } int main() { printf("HOW TO PLAY: \n"); printf("Use a(left),s(down),d(right),w(up) to move the tiles.\n"); printf("When two tiles with the same number touch, they merge into one!\n"); printf("When you merge the number 2048, you win!\n"); //printf("Please input the maxnum you want to achieve!\n"); int MAX=16; //cin>>MAX; srand(static_cast<unsigned>(time(0))); int i,j; char direction; mark = 0; for(i=0;i<3;i++) for(j=0;j<3;j++) MAP[i][j]=0; generate(); display(mark); while(cin>>direction) { switch(direction) { case 'a': Moveleft();break; case 's': Movedown();break; case 'd': Moveright();break; case 'w': Moveup();break; //default :cout<<"direction input wrong!"<<endl;break; } generate(); display(mark); if(dead()) { cout<<"You lose!"<<endl; break; } if(win(MAX)) { cout<<"You win!"<<endl; break; } } return 0; }