C# · 12月 20, 2021

c++实现2048[牛客网、控制台]

1.前言

刚学完c++基础,找个项目练练手,于是上牛客网找了个2048练练手,文章最后给出源码

2.简介

一次只能合并相邻的两个数字,例如 [2 2 2 2] ,向右合并以后是 [空 空 4 4] ,不是 [空 空 空 8]

每次合并的时候,合并方向优先级高,例如 [空 2 2 2],向右合并以后是 [空 空 2 4],不是 [空 空 4 2]

判断游戏结束

每次合并以后随机新出4的概率10%

3.项目思路

用一个4*4的int数组来储存数据,初始化为0

用户上下左右移的操作可整体简化为3个步骤

1)将非0元素紧凑

2)合并同类项

3)再将非0元素紧凑

4.示例

2

2

8

此时执行上移操作,步骤如下

                                1)紧凑

2

2

8

                               2)上移合并同类项

4

8

                               3)紧凑

4

8

5.bug

因为楼主在随机位置生成随机数的代码如下

//生成随机数

int randomNum(){

int num=rand()%10;

return num>8?4:2;

}

//para num->用户想生成[0,num]间随机数

inline void random(int num){

srand((unsigned int)(time(NULL)));

a=rand()%num;

Sleep(100);

b=rand()%num;

}

//生成1个随机位置并赋值

void randomAddress(){

//随着4*4数组中非0个数增加 可能出现卡顿 带优化

while(map[a][b]!=0){

random(3);

}

int num=randomNum();

map[a][b]=num;

cout<<"row:"<

}

当数组中非0元素个数增多时,在随机位置生成随机数所耗费的时间也不断增加

6.源码

#include

#include

#include

using namespace std;

void print();//打印当前状态

int randomNum();//生成2个随机数(其中一个必为2,另一个 2:4出现的比例=4:1)

void randomAddress();//生成2个随机位置

inline void random(int);//生成随机数[0,num),以便上述2个函数使用

void up();

void down();

void left();

void right();

bool isEnd();//判断游戏是否结束

int map[4][4]={0,};

int a=0,b=0;//两个用来储存随机数的值

void print(){

cout << "************************************************" << endl;

cout << "* " << map[0][0] << " " << map[0][1] << " " << map[0][2] << " " << map[0][3] << " *" << endl;

cout << "************************************************" << endl;

cout << "* " << map[1][0] << " " << map[1][1] << " " << map[1][2] << " " << map[1][3] << " *" << endl;

cout << "************************************************" << endl;

cout << "* " << map[2][0] << " " << map[2][1] << " " << map[2][2] << " " << map[2][3] << " *" << endl;

cout << "************************************************" << endl;

cout << "* " << map[3][0] << " " << map[3][1] << " " << map[3][2] << " " << map[3][3] << " *" << endl;

cout << "************************************************" << endl;

cout << "操作详情:(输入后,按回车键结束)" << endl;

cout << "w : 向上移动 s : 向下移动" << endl;

cout << "a : 向左移动 r : 向右移动" << endl;

cout << "q : 退出" << endl;

}

//para num->用户想生成[0,num]间随机数

inline void random(int num){

srand((unsigned int)(time(NULL)));

a=rand()%num;

Sleep(100);

b=rand()%num;

}

//生成随机数

int randomNum(){

int num=rand()%10;

return num>8?4:2;

}

//判断游戏是否结束 结束条件:1.4×4数组中非0元素已满 2.出现2048

bool isEnd(){

for(int a=0;a<4;a++){

for(int b=0;b<4;b++){

if(map[a][b]==2048)return true;

if(map[a][b]==0)return false;

}

}

return true;

}

//生成1个随机位置并赋值

void randomAddress(){

//随着4*4数组中非0个数增加 可能出现卡顿 带优化

while(map[a][b]!=0){

random(3);

}

int num=randomNum();

map[a][b]=num;

cout<<"row:"<

}

//用户点击上移操作

void up(){

int row,column;

//1.将非0元素上移

for(row=0;row<4;row++){

for(column=0;column<4;column++){

while(row!=0&&map[row][column]!=0&&map[row-1][column]==0){

map[row-1][column]=map[row][column];

map[row][column]=0;

row–;

}

}

}

//2.相同元素合并 循环遍历每一个元素

for(row=1;row<4;row++){

for(column=0;column<4;column++){

if(map[row][column]==0)continue;

else if(map[row][column]!=map[row-1][column]){

continue;

}else{

map[row-1][column]*=2;

map[row][column]=0;

}

}

}

//3.将合并后非0元素上移

for(row=0;row<4;row++){

for(column=0;column<4;column++){

while(row!=0&&map[row][column]!=0&&map[row-1][column]==0){

map[row-1][column]=map[row][column];

map[row][column]=0;

row–;

}

}

}

randomAddress();

}

//用户点击下移操作

void down(){

int row,column;

//1.将非0元素下移

for(row=3;row>=0;row–){

for(column=0;column<4;column++){

while(row!=3&&map[row][column]!=0&&map[row+1][column]==0){

map[row+1][column]=map[row][column];

map[row][column]=0;

row++;

}

}

}

//2.合并同类项

for(row=2;row>=0;row–){

for(column=0;column<4;column++){

if(map[row][column]==0)continue;

else if(map[row][column]!=map[row+1][column]){

continue;

}else{

map[row+1][column]*=2;

map[row][column]=0;

}

}

}

//3.合并后非0

for(row=3;row>=0;row–){

for(column=0;column<4;column++){

while(row!=3&&map[row][column]!=0&&map[row+1][column]==0){

map[row+1][column]=map[row][column];

map[row][column]=0;

row++;

}

}

}

randomAddress();

}

//用户点击左移操作

void left(){

int row,column;

//1.将非0元素左移

for(row=0;row<4;row++){

for(column=0;column<4;column++){

while(column!=0&&map[row][column]!=0&&map[row][column-1]==0){

map[row][column-1]=map[row][column];

map[row][column]=0;

column–;

}

}

}

//2.合并元素

for(row=0;row<4;row++){

for(column=1;column<4;column++){

if(map[row][column]==0)continue;

else if(map[row][column]!=map[row][column-1])continue;

map[row][column]=0;

map[row][column-1]*=2;

}

}

//3.

for(row=0;row<4;row++){

for(column=0;column<4;column++){

while(column!=0&&map[row][column]!=0&&map[row][column-1]==0){

map[row][column-1]=map[row][column];

map[row][column]=0;

column–;

}

}

}

randomAddress();

}

void right(){

int row,column;

//1.

for(row=0;row<4;row++){

for(column=3;column>=0;column–){

while(column!=3&&map[row][column]!=0&&map[row][column+1]==0){

map[row][column+1]=map[row][column];

map[row][column]=0;

column++;

}

}

}

//2.右移合并同类项

for(row=0;row<4;row++){

for(column=2;column>=0;column–){

if(map[row][column]==0||map[row][column]!=map[row][column+1])continue;

else{

map[row][column+1]*=2;

map[row][column]=0;

}

}

}

//3.

for(row=0;row<4;row++){

for(column=3;column>=0;column–){

while(column!=3&&map[row][column]!=0&&map[row][column+1]==0){

map[row][column+1]=map[row][column];

map[row][column]=0;

column++;

}

}

}

randomAddress();

}

int main(){

char control;

//数据初始化

randomAddress();

randomAddress();

print();

while(cin>>control){

switch(control){

case ‘w’:up();break;

case ‘s’:down();break;

case ‘a’:left();break;

case ‘d’:right();break;

case ‘q’:return 0;

}

print();//将移动后元素打印

if(isEnd()){

cout<<"游戏已结束"<<endl;

return 0;

}

}

return 0;

}