c++实现简陋版2048(控制台)

无聊的时候想尝试写一下小游戏,发现2048看起来是最容易的(无积分)
主要的点:

getch():头文件:conio.h;一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车
system(“cls”): 头文件:stdlib.h;是在C语言程序中,调用系统命令cls完成清屏操作。
以及win的句柄什么的,没怎么学,过段时间仔细看看win32的API

具体逻辑:(代码整洁之道还没有看,变量命名和逻辑比较混乱)

void logicW()
{
 for(int i=0;i<xy;++i)
 {
  int wasd[xy]={0};
  int hold=0;
  int temp=0;
  for(int j=0;j<xy;++j)//把一行(列)的非零数字拉到一个数组里
  {
   if(gameNum[j][i])
   {
    wasd[hold++]=gameNum[j][i];
    gameNum[j][i]=0;
   }
  }
  for(int xoy=1;xoy<hold;++xoy)//检测是否存在相邻的数字相等,相等则相加
  {
   if(wasd[xoy]==wasd[xoy-1])
   {
    wasd[xoy-1]+=wasd[xoy];
    wasd[xoy]=0;
   }
  }
  for(int xoy=0;xoy<hold;++xoy)//把处理过的数值填充进去
  {
   if(wasd[xoy])
   {
    gameNum[temp++][i]=wasd[xoy];
   }
  }
 }
}

以下是完整代码:(没精简优化,估计也不会)

#include<iostream>
#include<windows.h>
#include<conio.h>
#include<ctime>
#define xy 4
using namespace std;
void console() {
 //win的句柄,用于调整控制台
 SetConsoleTitle("2048 Bate 1.1   by LDAx");
 HANDLE hand;
 COORD size = {80, 25};
 hand=GetStdHandle(STD_OUTPUT_HANDLE);
 SMALL_RECT rt = {0,0,45,30};
 SetConsoleWindowInfo(hand,true,&rt);
 SetConsoleScreenBufferSize(hand, size);
}
void blueprint() {
 //不放循环直接打吧
 cout<<endl;
 cout<<"      ****     ****         *      ****  "<<endl;
 cout<<"     *    *   *    *      * *     *    * "<<endl;
 cout<<"        *     *    *    *   *      ****  "<<endl;
 cout<<"      *       *    *   * * ** *   *    * "<<endl;
 cout<<"     ******    ****         *      ****  "<<endl;
 cout<<endl;
 cout<<"   **************************************"<<endl;
 cout<<"   **************************************"<<endl;
 cout<<endl;
}
int gameNum[xy][xy]= {0};
//打印数
void pN(int xN,int yN) {
 if(gameNum[xN][yN]) {
  printf("%4d ",gameNum[xN][yN]);
 } else {
  cout<<"     ";
 }
}
//打印图,有时间改成循环的
void gameprint() {
 cout<<"      -------------------------------   "<<endl;
 cout<<"     |       |       |       |       |  "<<endl;
 cout<<"     | ";
 pN(0,0);
 cout<<" | ";
 pN(0,1);
 cout<<" | ";
 pN(0,2);
 cout<<" | ";
 pN(0,3);
 cout<<" |  "<<endl;
 cout<<"     |       |       |       |       |  "<<endl;
 cout<<"      -------------------------------   "<<endl;
 cout<<"     |       |       |       |       |  "<<endl;
 cout<<"     | ";
 pN(1,0);
 cout<<" | ";
 pN(1,1);
 cout<<" | ";
 pN(1,2);
 cout<<" | ";
 pN(1,3);
 cout<<" |  "<<endl;
 cout<<"     |       |       |       |       |  "<<endl;
 cout<<"      -------------------------------   "<<endl;
 cout<<"     |       |       |       |       |  "<<endl;
 cout<<"     | ";
 pN(2,0);
 cout<<" | ";
 pN(2,1);
 cout<<" | ";
 pN(2,2);
 cout<<" | ";
 pN(2,3);
 cout<<" |  "<<endl;
 cout<<"     |       |       |       |       |  "<<endl;
 cout<<"      -------------------------------   "<<endl;
 cout<<"     |       |       |       |       |  "<<endl;
 cout<<"     | ";
 pN(3,0);
 cout<<" | ";
 pN(3,1);
 cout<<" | ";
 pN(3,2);
 cout<<" | ";
 pN(3,3);
 cout<<" |  "<<endl;
 cout<<"     |       |       |       |       |  "<<endl;
 cout<<"      -------------------------------   "<<endl;
}
//清零
void newGame() {
// for(int i=0;i<xy;++i)
// {
//  for(int j=0;j<xy;++j)
//  {
//   gameNum[i][j]=0;
//  }
// }
 memset(gameNum,0,sizeof(int)*xy*xy);
}

//结束判定
bool gameover() {
 for(int i=0; i<xy; ++i) {
  for(int j=0; j<xy; ++j) {
   if(!gameNum[i][j]) {
    return false;
   }
  }
 }
 cout<<"   ***********  GAME OVER  *************"<<endl;
 cout<<"   *******  press R to new game  *******"<<endl;
 char r;
 do {
  r=getch();
 } while(r!='r'&&r!='R');
 newGame();
 return true;
}

//新数字判定
void newNum() {
 srand((int)time(0));//取时间做种子,这个东西还挺耗时的,别放循环里
 int xT,yT;
 do {
  xT=rand()%xy;
  yT=rand()%xy;
 } while(gameNum[xT][yT]);
 gameNum[xT][yT]=(rand()%2+1)*2;
}

//WASD的逻辑,考虑四个整合成一个
void logicW() {
 for(int i=0; i<xy; ++i) {
  int wasd[xy]= {0};
  int hold=0;
  int temp=0;
  for(int j=0; j<xy; ++j) {
   if(gameNum[j][i]) {
    wasd[hold++]=gameNum[j][i];
    gameNum[j][i]=0;
   }
  }
  for(int xoy=1; xoy<hold; ++xoy) {
   if(wasd[xoy]==wasd[xoy-1]) {
    wasd[xoy-1]+=wasd[xoy];
    wasd[xoy]=0;
   }
  }
  for(int xoy=0; xoy<hold; ++xoy) {
   if(wasd[xoy]) {
    gameNum[temp++][i]=wasd[xoy];
   }
  }
 }
}
void logicS() {
 for(int i=0; i<xy; ++i) {
  int wasd[xy]= {0};
  int hold=0;
  int temp=xy-1;
  for(int j=0; j<xy; ++j) {
   if(gameNum[j][i]) {
    wasd[hold++]=gameNum[j][i];
    gameNum[j][i]=0;
   }
  }
  for(int xoy=hold-2; xoy>=0; --xoy) {
   if(wasd[xoy]==wasd[xoy+1]) {
    wasd[xoy+1]+=wasd[xoy];
    wasd[xoy]=0;
   }
  }
  for(int xoy=hold-1; xoy>=0; --xoy) {
   if(wasd[xoy]) {
    gameNum[temp--][i]=wasd[xoy];
   }
  }
 }
}
void logicA() {
 for(int i=0; i<xy; ++i) {
  int wasd[xy]= {0};
  int hold=0;
  int temp=0;
  for(int j=0; j<xy; ++j) {
   if(gameNum[i][j]) {
    wasd[hold++]=gameNum[i][j];
    gameNum[i][j]=0;
   }
  }
  for(int xoy=1; xoy<hold; ++xoy) {
   if(wasd[xoy]==wasd[xoy-1]) {
    wasd[xoy-1]+=wasd[xoy];
    wasd[xoy]=0;
   }
  }
  for(int xoy=0; xoy<hold; ++xoy) {
   if(wasd[xoy]) {
    gameNum[i][temp++]=wasd[xoy];
   }
  }
 }
}
void logicD() {
 for(int i=0; i<xy; ++i) {
  int wasd[xy]= {0};
  int hold=0;
  int temp=xy-1;
  for(int j=0; j<xy; ++j) {
   if(gameNum[i][j]) {
    wasd[hold++]=gameNum[i][j];
    gameNum[i][j]=0;
   }
  }
  for(int xoy=hold-2; xoy>=0; --xoy) {
   if(wasd[xoy]==wasd[xoy+1]) {
    wasd[xoy+1]+=wasd[xoy];
    wasd[xoy]=0;
   }
  }
  for(int xoy=hold-1; xoy>=0; --xoy) {
   if(wasd[xoy]) {
    gameNum[i][temp--]=wasd[xoy];
   }
  }
 }
}
void logic(char key)
{
	switch (key){
		case 'r':
		case 'R':
			newGame();
			break;
		case 'w':
		case 'W':
			logicW();
			break;
		case 'a':
		case 'A':
			logicA();
			break;
		case 's':
		case 'S':
			logicS();
			break;
		case 'd':
		case 'D':
			logicD();
			break;
		default :
			key=getch();
			logic(key);
	}
}

int main() {
 console();
 blueprint();
 gameprint();
 while(1) {
  char key;
  key=getch(); //实时读取key
  logic(key);
  gameover();
  newNum();
  system("cls");
  blueprint();
  gameprint();
 }
}

大概效果:
在这里插入图片描述

发布了1 篇原创文章 · 获赞 1 · 访问量 90

猜你喜欢

转载自blog.csdn.net/qq_31028197/article/details/105743505
今日推荐