新西兰服务器

怎么用C语言完整实现2048游戏


怎么用C语言完整实现2048游戏

发布时间:2021-11-21 10:10:51 来源:高防服务器网 阅读:65 作者:小新 栏目:开发技术

这篇文章主要介绍怎么用C语言完整实现2048游戏,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

    一、游戏思路

    1、程序开始时出现菜单,让玩家选择开始游戏或者退出游戏。

    2、玩家选择开始游戏后,出现棋盘,通过方向键选择移动的方向。

    3、移动后会将所有方块向该方向移动直至补全空格,同样数字的方块合并成它们的和,还会生成一个随机位置的2或4。

    4、当出现“2048”时,游戏胜利;当棋盘满且无法消除时,游戏失败。

    二、游戏框架

    1.菜单界面

    菜单

    void menu()  {  	printf("**************************n");  	printf("*****按 1 开 始 游 戏*****n");  	printf("*****按 0 退 出 游 戏*****n");  	printf("**************************n");  }

    菜单的选择

    int main()  {  	int input = 0;  	do  	{  		menu();  		printf("请选择:");  		scanf("%d", &input);  		switch (input)  		{  		case 1:  			game2048();     			break;  		case 0:  			printf("退出游戏,客官常来玩呀~)n");  			break;  		default:  			printf("给你一次重新选择的机会n");  			break;  		}  	} while (input);  	return 0;  }

    实际效果

    菜单我觉得还是挺顺眼的,就是有点丑,毕竟是初学者就不要要求太高了。

    2.游戏主体

    1.初始化界面:

    生成一个4行4列的数组(此处的行数和列数已在头文件中用#define宏定义)。

    并且打印出来。

    void DisplayBoard(int board[ROW][COL],int row, int col)  {      int i = 0;      int j = 0;      for (int j = 0; j < COL; j++)          printf("+-----");      printf("+n");      for (int i = 0; i < ROW; i++)      {          for (int j= 0; j < COL; j++)          {              printf("|");              if (board[i][j]!=0)                  printf("%5d", board[i][j]);                 else                  printf("     ");             }          printf("|n");          for (int j = 0; j < COL; j++)          {              printf("+-----");          }          printf("+n");      }      }

    效果如下:

    方吗?方就对了,方就是个好界面!

    2.随机生成初始数字

    游戏的界面我们现在已经有了,接下来要做的就是加入两个随机位置的”2"。

    void get_num(int board[ROW][COL])  {  	int x, y;  	x = rand() % ROW;  	y = rand() % COL;	  	board[x][y] = 2;//一开始随机的数为2  	x = rand() % ROW;  	y = rand() % COL;  	while (board[x][y] == 2)       {  		x = rand() % ROW;  		y = rand() % COL;  	}  	board[x][y] = 2;      system("cls"); //清屏,美观界面  	return;  }

    (这里照例还是使用了时间戳获取随机数的方法)

    可以看到每一次出现的两个位置都是随机的。

    3.实现移动

    这里我们以向上为例,我们要实现移动,以及判定两个方块数字相同就合并成为它们的和,并且当合并后存在空格时继续向上移动。

    简单来说,就是 移动 → 合并 → 再次移动补空。其他三个方向也是一样的道理,只需要改变其中的数值便可实现。

    void up(int board[ROW][COL])  {  	int i = 0;   	int j = 0;  	int x = 0;  	int y = 0;  	for (i = 0; i < ROW; i++)  	{  		//移动  		j = 0;  		y = 0;  		while (j < COL-1 && y < COL-1 )  		{  			if (board[j][i] == 0)   			{  				for (x = j; x < ROW-1; x++)  					board[x][i] = board[x + 1][i];  				board[ROW-1][i] = 0;	  				y++;  			}  			else  				j++;   		}  		//合并  		for (j = 0; j < COL-1; j++)  			if (board[j][i] == board[j + 1][i] && board[j][i] != 0)   			{											   				board[j][i] = board[j][i] * 2; //和  				board[j + 1][i] = 0;		  			}  		//再次移动补空  		j = 0;  		y = 0;  		while (j < COL - 1 && y < COL - 1)  		{  			if (board[j][i] == 0)    			{  				for (x = j; x < ROW - 1; x++)  					board[x][i] = board[x + 1][i];  				board[ROW - 1][i] = 0;  				y++;  			}  			else  				j++;  		}  	}  }
    4.增加新数字

    每次移动会在随机位置出现一个新的数字,可能是2,可能是4。

    通过查询网上资料得知,随机到2的概率约为 9/10,随机到4的概率约为 1/10。

    void put_num(int board[ROW][COL])  {  	int x = 0;  	int y = 0;   	int z = 0;	  	x = rand() % ROW;  	y = rand() % COL;  	while (board[x][y] !=0)  	{  		x = rand() % ROW;  		y = rand() % COL;  	}  	z = rand() % 10;   	if (z<9)	  		board[x][y] = 2;	  	else	  		board[x][y] = 4;	  	return;  }
    5.判定胜负

    当出现2048时胜利,当格子满了且无法消除时失败。

    int is_fail(int board[ROW][COL])  {  	int i = 0;   	int j = 0;  	for (i = 0; i < ROW; i++)  	{  		for (j = 0; j < COL; j++)  		{  			if (board[i][j] == 0)  				return 0;  			if (i > 0)  			{  				if (board[i - 1][j] == board[i][j])  					return 0;  			}  			if (j > 0)  			{  				if (board[i][j - 1] == board[i][j])  					return 0;  			}  		}  	}  	return 1;  }     int is_win(int board[ROW][COL])  {	  	int i = 0;  	int j = 0;  	int num = 0;  	for (i = 0; i < ROW; i++)  		for (j = 0; j < COL; j++)  		{  			if (board[i][j] > num)  				num = board[i][j];  		}  	if (num >= 2048)  		return 1;  	else  		return 0;  }
    6.游戏函数

    将上述代码结合起来

    void game2048()  {  	int board[ROW][COL] = { {0} };  	int control = 0;  	DisplayBoard(board);   	init_num(board);  	system("cls"); //清屏,美观界面  	DisplayBoard(board);  	while ((control = _getch()) != 0x1b)  	{   		switch (control)  		{  		case 0xe0:  			switch (control = getch())  			{  			    case 72:   				    up(board);  				    break;  			    case 80:   			    	down(board);  			    	break;  			    case 75:   			    	left(board);  				    break;  		    	case 77:    		    		right(board);  				    break;  		    	default:  			    	break;  			}  			  		system("cls");  		DisplayBoard(board);  		if (is_win(board) == 1)  		{  			printf("恭喜你赢了!");		      		}  		if (is_fail(board) == 1)  		{  			printf("哈哈哈哈哈哈哈好菜n");  		}  		}  	}	  }

    三、游戏运行

    已知目前游戏存在bug,当格子满了的时候假定一个方向可以消除,另一个方向不可以消除,按了那个不可以消除的方向的话,就会无法操作了,鉴于本人目前初学者并未能够想到很好的解决方法。若有大佬有好的方法也可指点一下。

    我太菜了玩了好久都玩不到2048,最高只有512,1024还是舍友打出来的。

    更新:修复了bug

    先判断数组是否相同再选择是否添加新的随机位置的数字。

    在此感谢各位帮助我测试的朋友,无论成功与否,当然特别感谢提供了这张图片的朋友。

    四、所有代码

    game2048.h

    #pragma once     #include <stdio.h>  #include <time.h>  #include <stdlib.h>  #include <windows.h>  #include<conio.h>     #define ROW 4  #define COL 4  const int copy[ROW][COL];     //初始化并打印游戏界面  void DisplayBoard(int board[ROW][COL]);  //开局随机生成两个2  void init_num(int board[ROW][COL]);  //在移动后随机放置数字2或4  void put_num(int board[ROW][COL]);  //移动  void up(int board[ROW][COL]);  void down(int board[ROW][COL]);  void left(int board[ROW][COL]);  void right(int board[ROW][COL]);  //判定胜负  int is_win(int board[ROW][COL]);  int is_fail(int board[ROW][COL]);

    game2048.c

    #define _CRT_SECURE_NO_WARNINGS 1  #include "game2048.h"     void DisplayBoard(int board[ROW][COL])  {      int i = 0;      int j = 0;      printf("tip:*方向键控制方块移动*ESC键返回菜单*n");      for (int j = 0; j < COL; j++)          printf("+-----");      printf("+n");      for (int i = 0; i < ROW; i++)      {          for (int j= 0; j < COL; j++)          {              printf("|");              if (board[i][j]!=0)                  printf("%5d", board[i][j]);                 else                  printf("     ");          }          printf("|n");          for (int j = 0; j < COL; j++)          {              printf("+-----");          }          printf("+n");      }      }     void init_num(int board[ROW][COL])  {  	int x, y;  	x = rand() % ROW;  	y = rand() % COL;	  	board[x][y] = 2;//随机在一个位置生成2  	x = rand() % ROW;  	y = rand() % COL;  	while (board[x][y] == 2)       {  		x = rand() % ROW;  		y = rand() % COL;  	}  	board[x][y] = 2;   	return;  }     void put_num(int board[ROW][COL])  {  	int x = 0;  	int y = 0;   	int z = 0;	  	x = rand() % ROW;  	y = rand() % COL;  	while (board[x][y] !=0)  	{  		x = rand() % ROW;  		y = rand() % COL;  	}  	z = rand() % 10;  	if (z<9)	  		board[x][y] = 2;	  	else	  		board[x][y] = 4;	  	return;  }  				  void up(int board[ROW][COL])  {  	int i = 0;   	int j = 0;  	int x = 0;  	int y = 0;  	for (i = 0; i < ROW; i++)  	{  		//移动  		j = 0;  		y = 0;  		while (j < COL-1 && y < COL-1 )  		{  			if (board[j][i] == 0)   			{  				for (x = j; x < ROW-1; x++)  					board[x][i] = board[x + 1][i];  				board[ROW-1][i] = 0;	  				y++;  			}  			else  				j++;   		}  		//合并  		for (j = 0; j < COL-1; j++)  			if (board[j][i] == board[j + 1][i] && board[j][i] != 0)   			{											   				board[j][i] = board[j][i] * 2;  				board[j + 1][i] = 0;		  			}  		//再次移动补空  		j = 0;  		y = 0;  		while (j < COL - 1 && y < COL - 1)  		{  			if (board[j][i] == 0)  			{  				for (x = j; x < ROW - 1; x++)  					board[x][i] = board[x + 1][i];  				board[ROW - 1][i] = 0;  				y++;  			}  			else  				j++;  		}  	}  	if (contrast(board) == 0)  		put_num(board);  	else  		return;  }     void down(int board[ROW][COL])  {  	int i = 0;  	int j = 0;  	int x = 0;  	int y = 0;  	for (i = 0; i < ROW; i++)  	{  		j = COL-1;  		y = 0;  		while (j > 0 && y < COL-1)  		{  			if (board[j][i] == 0)  			{  				for (x = j; x > 0; x--)  					board[x][i] = board[x - 1][i];  				board[0][i] = 0;  				y++;  			}  			else   				j--;  		}  		for (j = COL-1; j > 0; j--)  			if (board[j][i] == board[j - 1][i] && board[j][i] != 0)  			{  				board[j][i] = board[j][i] * 2;  				board[j - 1][i] = 0;			  			}  		j = COL - 1;  		y = 0;  		while (j > 0 && y < COL - 1)  		{  			if (board[j][i] == 0)  			{  				for (x = j; x > 0; x--)  					board[x][i] = board[x - 1][i];  				board[0][i] = 0;  				y++;  			}  			else  				j--;  		}  	}  	if (contrast(board) == 0)  		put_num(board);  	else  		return;  }  			  void left(int board[ROW][COL])  {  	int i = 0;  	int j = 0;  	int x = 0;  	int y = 0;  	for (i = 0; i < ROW; i++)  	{  		j = 0;   		y = 0;  		while (j < 3 && y < 3 )  		{  			if (board[i][j] == 0)  			{  				for (x = j; x < ROW-1; x++)  					board[i][x] = board[i][x + 1];  				board[i][COL-1] = 0;  				y++;  			}  			else  				j++;  		}  		for (j = 0; j < 3; j++)  			if (board[i][j] == board[i][j + 1] && board[i][j] != 0)  			{  				board[i][j] = board[i][j] * 2;  				board[i][j + 1] = 0;  			}  		j = 0;   		y = 0;  		while (j < 3 && y < 3)  		{  			if (board[i][j] == 0)  			{  				for (x = j; x < ROW - 1; x++)  					board[i][x] = board[i][x + 1];  				board[i][COL - 1] = 0;  				y++;  			}  			else  				j++;  		}  	}  	if (contrast(board) == 0)  		put_num(board);  	else  		return;  }     void right(int board[ROW][COL])  {  	int i = 0;  	int j = 0;  	int x = 0;  	int y = 0;  	for (i = 0; i < 4; i++)  	{  		j = COL-1;  		y = 0;  		while (j>0 && y < COL-1)  		{  			if (board[i][j] == 0)  			{  				for (x = j; x > 0; x--)  					board[i][x] = board[i][x - 1];  				board[i][0] = 0;  				y++;  			}  			else j--;  		}  		for (j = 3; j > 0; j--)  			if (board[i][j] == board[i][j - 1] && board[i][j] != 0)  			{  				board[i][j] = board[i][j] * 2;  				board[i][j - 1] = 0;  			}  		j = COL - 1;  		y = 0;  		while (j > 0 && y < COL - 1)  		{  			if (board[i][j] == 0)  			{  				for (x = j; x > 0; x--)  					board[i][x] = board[i][x - 1];  				board[i][0] = 0;  				y++;  			}  			else j--;  		}  	}  	if (contrast(board) == 0)  		put_num(board);  	else  		return;  }     int is_fail(int board[ROW][COL])  {  	int i = 0;   	int j = 0;  	for (i = 0; i < ROW; i++)  	{  		for (j = 0; j < COL; j++)  		{  			if (board[i][j] == 0)  				return 0;  			if (i > 0)  			{  				if (board[i - 1][j] == board[i][j])  					return 0;  			}  			if (j > 0)  			{  				if (board[i][j - 1] == board[i][j])  					return 0;  			}  		}  	}  	return 1;  }     int is_win(int board[ROW][COL])  {	  	int i = 0;  	int j = 0;  	int num = 0;  	for (i = 0; i < ROW; i++)  		for (j = 0; j < COL; j++)  		{  			if (board[i][j] > num)  				num = board[i][j];  		}  	if (num >= 2048)  		return 1;  	else  		return 0;  }     void copyboard(int board[ROW][COL],int copy[ROW][COL])  {  	int i = 0;  	int j = 0;  	for (i = 0; i < ROW; i++)  		for (j = 0; j < COL; j++)  			copy[i][j] = board[i][j];  }     int contrast(int board[ROW][COL])  {  	int i = 0;  	int j = 0;  	for (i = 0; i < 4; i++)  		for (j = 0; j < 4; j++)  			if (copy[i][j] != board[i][j])  				return 0;  	return 1;  }

    test.c

    #define _CRT_SECURE_NO_WARNINGS 1  #include "game2048.h"      void menu()  {  	printf("**************************n");  	printf("*****按 1 开 始 游 戏*****n");  	printf("*****按 0 退 出 游 戏*****n");  	printf("**************************n");  }     void game2048()  {  	int board[ROW][COL] = { {0} };  	int control = 0;  	DisplayBoard(board);   	init_num(board);  	system("cls"); //清屏,美观界面  	DisplayBoard(board);  	while ((control = _getch()) != 0x1b)  	{   		switch (control)  		{  		case 0xe0:  			switch (control = getch())  			{  			    case 72:   					copyboard(board, copy);  				    up(board);  				    break;  			    case 80:   					copyboard(board, copy);  			    	down(board);  			    	break;  			    case 75:   					copyboard(board, copy);  			    	left(board);  				    break;  		    	case 77:    					copyboard(board, copy);  		    		right(board);  				    break;  		    	default:  			    	break;  			}  			  		system("cls");  		DisplayBoard(board);  		if (is_win(board) == 1)  		{  			printf("恭喜你赢了!n");  		}  		if (is_fail(board) == 1)  		{  			printf("哈哈哈哈哈哈哈好菜n");  		}  		}  	}	  }     int main()  {  	int input = 0;  	srand((unsigned int)time(NULL));	  	do  	{	menu();  	    printf("请选择:");  	    scanf("%d", &input);  		switch (input)  		{  		    case 1:  			    game2048();     			    break;  		    case 0:  		    	printf("退出游戏,客官常来玩呀~)n");  		    	break;  		    default:  			    printf("给你一次重新选择的机会n");  		    	break;  		}  	} while (input);  	return 0;  }

    以上是“怎么用C语言完整实现2048游戏”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注高防服务器网行业资讯频道!

    [微信提示:高防服务器能助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

    [图文来源于网络,不代表本站立场,如有侵权,请联系高防服务器网删除]
    [