当前位置: 首页 > 工具软件 > 2048.cpp > 使用案例 >

c++2048小游戏编写

吕森
2023-12-01

一.序言

     最近编写了一个小游戏,叫作2048,用到了面向对象的知识。

二.头文件与准备

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
const int N=4; //边长

导入3个头文件,用N表示地图边长。

三.类

class game {
	// Private section
	public:
		// Public Declarations
		void Initializing(string T){
			title=T;
			score=0;
			Max_s=0;
			sum_s=0;
			for(int i=1;i<=N;i++)
				for(int j=1;j<=N;j++)
					Map[i][j]=0;
		}
		void Hide(){//用于隐藏控制台光标 
			HANDLE				hOut;
			CONSOLE_CURSOR_INFO	curInfo;
			hOut=GetStdHandle(STD_OUTPUT_HANDLE); 
			curInfo.dwSize=1;
			curInfo.bVisible=0;
			SetConsoleCursorInfo(hOut,&curInfo);
		}
		void paint(){
			int s=5*N+1-title.size()+4;
			for(int i=1;i<=s/2;i++) cout<<' ';
			cout<<title;
			for(int i=1;i<=s/2;i++) cout<<' ';
			cout<<endl;
			cout<<"sorce: "<<score<<" Producer: David"<<endl;
			cout<<"  ";
			for(int i=1;i<=N*5+1;i++) cout<<'-';
			cout<<endl;
			for(int i=1;i<=N;i++){
				cout<<"  ";
				cout<<'|';
				for(int j=1;j<=N;j++){
					if(Map[i][j]){
						cout<<setw(4)<<Map[i][j];
						cout<<'|'; 
					}else{
						cout<<"    |"; 
					}
				}
				cout<<endl;
				cout<<"  ";
				for(int i=1;i<=N*5+1;i++) cout<<'-';
				cout<<endl;
			}
		}
		bool over(){
			for(int i=1;i<=N;i++){
				for(int j=1;j<=N;j++){
					if(Map[i][j]==Map[i-1][j]||Map[i][j]==Map[i][j-1]||Map[i][j]==Map[i][j+1]||Map[i][j]==Map[i+1][j])
						return 0;
				}
			}
			return 1;
		}
		void Generated(){
			srand(time(0));
			int x=rand()%N+1,y=rand()%N+1;
			while(Map[x][y]!=0){
				x=rand()%N+1,y=rand()%N+1;
			}
			Map[x][y]=2;
		}
		void up(){
			for(int i=1;i<=N;i++){
				for(int j=N;j>=1;j--){
					if(Map[i][j]!=0){
						for(int k=i;k>=1;k--){
							if(!Map[k][j]){
								Map[k][j]=Map[k+1][j];
								Map[k+1][j]=0;
								continue;
							}
							if(Map[k][j]==Map[k+1][j]){
								Map[k][j]*=2;
								score+=Map[k][j];
								Max_s=max(Max_s,Map[k][j]);
								sum_s--;
								Map[k+1][j]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void down(){
			for(int i=N;i>=1;i--){
				for(int j=1;j<=N;j++){
					if(Map[i][j]!=0){
						for(int k=i;k<=N;k++){
							if(!Map[k][j]){
								Map[k][j]=Map[k-1][j];
								Map[k-1][j]=0;
								continue;
							}
							if(Map[k][j]==Map[k-1][j]){
								Map[k][j]*=2;
								score+=Map[k][j];
								Max_s=max(Max_s,Map[k][j]);
								sum_s--;
								Map[k-1][j]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void left(){ 
			for(int i=1;i<=N;i++){
				for(int j=1;j<=N;j++){
					if(Map[i][j]!=0){
						for(int k=j;k>=1;k--){
							if(!Map[i][k]){
								Map[i][k]=Map[i][k+1];
								Map[i][k+1]=0;
								continue;
							}
							if(Map[i][k]==Map[i][k+1]){
								Map[i][k]*=2;
								score+=Map[i][k];
								Max_s=max(Max_s,Map[i][k]);
								sum_s--;
								Map[i][k+1]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void right(){
			for(int i=1;i<=N;i++){
				for(int j=N;j>=1;j--){
					if(Map[i][j]!=0){
						for(int k=j;k<=N;k++){
							if(!Map[i][k]){
								Map[i][k]=Map[i][k-1];
								Map[i][k-1]=0;
								continue;
							}
							if(Map[i][k]==Map[i][k-1]){
								Map[i][k]*=2;
								score+=Map[i][k];
								Max_s=max(Max_s,Map[i][k]);
								sum_s--;
								Map[i][k-1]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}		
		void test(){
			int key=getch();
			key=getch();
			if(key==72) up();
			if(key==80) down();
			if(key==75) left();
			if(key==77) right();
		}
		void run(){
			system("title 2048小游戏"); //设置窗口名称 
			Hide(); 
			while(1){
				if(sum_s==N*N&&over()){
					cout<<"You lose! You got"<<score<<"point.";
					system("pause");
					return;
				}
				if(Max_s==2048){
					cout<<"You winner!";
					system("pause");
					return;
				}
				paint();
				test();
				system("cls");
			}
		} 
	protected:
		// Protected Declarations
		int Map[N+2][N+2];  //地图 
		string title; //游戏名字 
		int score; //分数
		int Max_s; //场上最高方块(_s:方块)
		int sum_s; //一共的方块总数 
};

3.1 类变量

	protected:
		// Protected Declarations
		int Map[N+2][N+2];  //地图 
		string title; //游戏名字 
		int score; //分数
		int Max_s; //场上最高方块(_s:方块)
		int sum_s; //一共的方块总数 
  1. Map数组表示地图
  2. sum_s用于判断输
  3. Max_s表示判断赢

3.2 初始化

		void Initializing(string T){
			title=T;
			score=0;
			Max_s=0;
			sum_s=0;
			for(int i=1;i<=N;i++)
				for(int j=1;j<=N;j++)
					Map[i][j]=0;
		}

        初始化各项数值,传进标题。

3.3 隐藏光标

		void Hide(){//用于隐藏控制台光标 
			HANDLE				hOut;
			CONSOLE_CURSOR_INFO	curInfo;
			hOut=GetStdHandle(STD_OUTPUT_HANDLE); 
			curInfo.dwSize=1;
			curInfo.bVisible=0;
			SetConsoleCursorInfo(hOut,&curInfo);
		}

        为了加强游戏体验,所以把光标隐藏一下。

3.4 打印地图

		void paint(){
			int s=5*N+1-title.size()+4;
			for(int i=1;i<=s/2;i++) cout<<' ';
			cout<<title;
			for(int i=1;i<=s/2;i++) cout<<' ';
			cout<<endl;
			cout<<"sorce: "<<score<<" Producer: David"<<endl;
			cout<<"  ";
			for(int i=1;i<=N*5+1;i++) cout<<'-';
			cout<<endl;
			for(int i=1;i<=N;i++){
				cout<<"  ";
				cout<<'|';
				for(int j=1;j<=N;j++){
					if(Map[i][j]){
						cout<<setw(4)<<Map[i][j];
						cout<<'|'; 
					}else{
						cout<<"    |"; 
					}
				}
				cout<<endl;
				cout<<"  ";
				for(int i=1;i<=N*5+1;i++) cout<<'-';
				cout<<endl;
			}
		}

        所有边长使用N,动态打印。

3.5 判断结束

		bool over(){
			for(int i=1;i<=N;i++){
				for(int j=1;j<=N;j++){
					if(Map[i][j]==Map[i-1][j]||Map[i][j]==Map[i][j-1]||Map[i][j]==Map[i][j+1]||Map[i][j]==Map[i+1][j])
						return 0;
				}
			}
			return 1;
		}

        完整的判断在run()函数中。

3.6 随机产生数字

		void Generated(){
			srand(time(0));
			int x=rand()%N+1,y=rand()%N+1;
			while(Map[x][y]!=0){
				x=rand()%N+1,y=rand()%N+1;
			}
			Map[x][y]=2;
		}

        利用随机数,产生新数字。

3.7 处理按键

		void up(){
			for(int i=1;i<=N;i++){
				for(int j=N;j>=1;j--){
					if(Map[i][j]!=0){
						for(int k=i;k>=1;k--){
							if(!Map[k][j]){
								Map[k][j]=Map[k+1][j];
								Map[k+1][j]=0;
								continue;
							}
							if(Map[k][j]==Map[k+1][j]){
								Map[k][j]*=2;
								score+=Map[k][j];
								Max_s=max(Max_s,Map[k][j]);
								sum_s--;
								Map[k+1][j]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void down(){
			for(int i=N;i>=1;i--){
				for(int j=1;j<=N;j++){
					if(Map[i][j]!=0){
						for(int k=i;k<=N;k++){
							if(!Map[k][j]){
								Map[k][j]=Map[k-1][j];
								Map[k-1][j]=0;
								continue;
							}
							if(Map[k][j]==Map[k-1][j]){
								Map[k][j]*=2;
								score+=Map[k][j];
								Max_s=max(Max_s,Map[k][j]);
								sum_s--;
								Map[k-1][j]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void left(){ 
			for(int i=1;i<=N;i++){
				for(int j=1;j<=N;j++){
					if(Map[i][j]!=0){
						for(int k=j;k>=1;k--){
							if(!Map[i][k]){
								Map[i][k]=Map[i][k+1];
								Map[i][k+1]=0;
								continue;
							}
							if(Map[i][k]==Map[i][k+1]){
								Map[i][k]*=2;
								score+=Map[i][k];
								Max_s=max(Max_s,Map[i][k]);
								sum_s--;
								Map[i][k+1]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void right(){
			for(int i=1;i<=N;i++){
				for(int j=N;j>=1;j--){
					if(Map[i][j]!=0){
						for(int k=j;k<=N;k++){
							if(!Map[i][k]){
								Map[i][k]=Map[i][k-1];
								Map[i][k-1]=0;
								continue;
							}
							if(Map[i][k]==Map[i][k-1]){
								Map[i][k]*=2;
								score+=Map[i][k];
								Max_s=max(Max_s,Map[i][k]);
								sum_s--;
								Map[i][k-1]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}	

        记得一共四种情况。

3.8 检测按键

		void test(){
			int key=getch();
			key=getch();
			if(key==72) up();
			if(key==80) down();
			if(key==75) left();
			if(key==77) right();
		}

        用到了getch()函数检测按键。

3.9 运行函数

		void run(){
			system("title 2048小游戏"); //设置窗口名称 
			Hide(); 
			while(1){
				if(sum_s==N*N&&over()){
					cout<<"You lose! You got"<<score<<"point.";
					system("pause");
					return;
				}
				if(Max_s==2048){
					cout<<"You winner!";
					system("pause");
					return;
				}
				paint();
				test();
				system("cls");
			}
		}

        调用各种函数,这个函数是类的核心。

四.主函数

int main(){
	game s;
	s.Initializing("2048 games");
	s.run(); 
	return 0;
}

        这里比较简单,只是调用函数。

五.全代码

        全部代码,一共只有两百多行。

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
const int N=4; //边长
/*
上: 72
下: 80
左: 75
右: 77 
*/
class game {
	// Private section
	public:
		// Public Declarations
		void Initializing(string T){
			title=T;
			score=0;
			Max_s=0;
			sum_s=0;
			for(int i=1;i<=N;i++)
				for(int j=1;j<=N;j++)
					Map[i][j]=0;
		}
		void Hide(){//用于隐藏控制台光标 
			HANDLE				hOut;
			CONSOLE_CURSOR_INFO	curInfo;
			hOut=GetStdHandle(STD_OUTPUT_HANDLE); 
			curInfo.dwSize=1;
			curInfo.bVisible=0;
			SetConsoleCursorInfo(hOut,&curInfo);
		}
		void paint(){
			int s=5*N+1-title.size()+4;
			for(int i=1;i<=s/2;i++) cout<<' ';
			cout<<title;
			for(int i=1;i<=s/2;i++) cout<<' ';
			cout<<endl;
			cout<<"sorce: "<<score<<" Producer: David"<<endl;
			cout<<"  ";
			for(int i=1;i<=N*5+1;i++) cout<<'-';
			cout<<endl;
			for(int i=1;i<=N;i++){
				cout<<"  ";
				cout<<'|';
				for(int j=1;j<=N;j++){
					if(Map[i][j]){
						cout<<setw(4)<<Map[i][j];
						cout<<'|'; 
					}else{
						cout<<"    |"; 
					}
				}
				cout<<endl;
				cout<<"  ";
				for(int i=1;i<=N*5+1;i++) cout<<'-';
				cout<<endl;
			}
		}
		bool over(){
			for(int i=1;i<=N;i++){
				for(int j=1;j<=N;j++){
					if(Map[i][j]==Map[i-1][j]||Map[i][j]==Map[i][j-1]||Map[i][j]==Map[i][j+1]||Map[i][j]==Map[i+1][j])
						return 0;
				}
			}
			return 1;
		}
		void Generated(){
			srand(time(0));
			int x=rand()%N+1,y=rand()%N+1;
			while(Map[x][y]!=0){
				x=rand()%N+1,y=rand()%N+1;
			}
			Map[x][y]=2;
		}
		void up(){
			for(int i=1;i<=N;i++){
				for(int j=N;j>=1;j--){
					if(Map[i][j]!=0){
						for(int k=i;k>=1;k--){
							if(!Map[k][j]){
								Map[k][j]=Map[k+1][j];
								Map[k+1][j]=0;
								continue;
							}
							if(Map[k][j]==Map[k+1][j]){
								Map[k][j]*=2;
								score+=Map[k][j];
								Max_s=max(Max_s,Map[k][j]);
								sum_s--;
								Map[k+1][j]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void down(){
			for(int i=N;i>=1;i--){
				for(int j=1;j<=N;j++){
					if(Map[i][j]!=0){
						for(int k=i;k<=N;k++){
							if(!Map[k][j]){
								Map[k][j]=Map[k-1][j];
								Map[k-1][j]=0;
								continue;
							}
							if(Map[k][j]==Map[k-1][j]){
								Map[k][j]*=2;
								score+=Map[k][j];
								Max_s=max(Max_s,Map[k][j]);
								sum_s--;
								Map[k-1][j]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void left(){ 
			for(int i=1;i<=N;i++){
				for(int j=1;j<=N;j++){
					if(Map[i][j]!=0){
						for(int k=j;k>=1;k--){
							if(!Map[i][k]){
								Map[i][k]=Map[i][k+1];
								Map[i][k+1]=0;
								continue;
							}
							if(Map[i][k]==Map[i][k+1]){
								Map[i][k]*=2;
								score+=Map[i][k];
								Max_s=max(Max_s,Map[i][k]);
								sum_s--;
								Map[i][k+1]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}
		void right(){
			for(int i=1;i<=N;i++){
				for(int j=N;j>=1;j--){
					if(Map[i][j]!=0){
						for(int k=j;k<=N;k++){
							if(!Map[i][k]){
								Map[i][k]=Map[i][k-1];
								Map[i][k-1]=0;
								continue;
							}
							if(Map[i][k]==Map[i][k-1]){
								Map[i][k]*=2;
								score+=Map[i][k];
								Max_s=max(Max_s,Map[i][k]);
								sum_s--;
								Map[i][k-1]=0;
								break;
							}
						}
					}
				}
			}
			if(sum_s!=N*N){
				sum_s++;
				Generated();
			}
		}		
		void test(){
			int key=getch();
			key=getch();
			if(key==72) up();
			if(key==80) down();
			if(key==75) left();
			if(key==77) right();
		}
		void run(){
			system("title 2048小游戏"); //设置窗口名称 
			Hide(); 
			while(1){
				if(sum_s==N*N&&over()){
					cout<<"You lose! You got"<<score<<"point.";
					system("pause");
					return;
				}
				if(Max_s==2048){
					cout<<"You winner!";
					system("pause");
					return;
				}
				paint();
				test();
				system("cls");
			}
		} 
	protected:
		// Protected Declarations
		int Map[N+2][N+2];  //地图 
		string title; //游戏名字 
		int score; //分数
		int Max_s; //场上最高方块(_s:方块)
		int sum_s; //一共的方块总数 
};
int main(){
	game s;
	s.Initializing("2048 games");
	s.run(); 
	return 0;
}

        再送个小技巧:如果想改游戏边长,就改一下第五行的常量N就可以了。

 类似资料: