博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言实现2048游戏
阅读量:2242 次
发布时间:2019-05-09

本文共 6504 字,大约阅读时间需要 21 分钟。

文章目录

2048游戏在很长一段时间内是一款很火的小游戏。
游戏要求:

  • 最开始两个随机数
  • 每次生成一个随机数2或者4,生成4的概率是1/10
  • 键盘上下左右键控制游戏的走向
  • 当出现2048数字时,玩家获胜

打印界面

//打印	void GamePrint(int row, int col)	{		printf("SCORE = %d", score);		SetCurPos(0, 2);		int i = 0;		for (i = 0; i < row; i++)		{			for (int k = 0; k < 4; k++)			{				printf(" ");				for (int j = 0; j < 4; j++)				{					printf("-");				}			}			printf("\n");			for (int k = 0; k < 4; k++)			{				printf("|");				if (arr[i][k])				{					printf("%4d", arr[i][k]);				}				else				{					for (int j = 0; j < 4; j++)					{						printf(" ");					}				}				}			printf("|\n");			if (i == row - 1)			{				for (int k = 0; k < 4; k++)				{					printf(" ");					for (int j = 0; j < 4; j++)					{						printf("-");					}				}				printf("\n");			}		}		SetCurPos(0, 12);		printf("上下左右表示方向\n");	}

生成随机数

要求生成4的概率为1/10,

生成一个10以内的数字(或者将生成的数字对10取余)
     判断其是否为4
        如果是4就生成4,
        如果不是4,就生成2

void RandNum(int row, int col) //生成随机数	{		int x = 0;		int y = 0;		do		{			x = rand() % 4;			y = rand() % 4;		} while (arr[x][y]);		arr[x][y] = (rand() % 10 ? 2 : 4);	}

是否获胜

int IfWin(int row, int col)	{		for (int i = 0; i < row; i++)		{			for (int j = 0; j < col; j++)			{				if (arr[i][j] == 2048)				{					return 1; //表示赢了				}				if (arr[i][j] == 0)				{					return 0; //表示继续游戏				}			}		}		return -1;//输了	}

移动

移动这部分就是这个游戏的核心。

以右移为例,我们把二维数组抽象成一个4*4的方块,值为0的是空方块,其余的是数字方块。我们只抽取出来一行来做实例(其余行就可以通过循环以同样的方式来做)。一行就可以用一个一维数组来表示b[j]运用两个下标来遍历这个以为数组,k,j;j永远在k的后面,k表示当前比较项,j表示下一个不为0的元素;可以分为以下三种情况:
移动: b[k] == 0;b[j]之前的全是空格子,就要让b[j]移动到b[k]的位置处,然后K++,继续向后走
在这里插入图片描述
合并: b[k] == b[j];就要让b[k] = 2 * b[k] ;然后k++
在这里插入图片描述
碰撞: b[k] != b[j];此时就要分两种情况:
          k + 1 != j;表示两者没有靠在一起,b[k+1] = b[j]; b[j] = 0; k++;
          k + 1 == j;表示两者原本就靠在一起,不用管
在这里插入图片描述

int j = 1;	int k = 0;	for (; j < 4; j++) 	{  		//找出k第一个不为0的块,之后分为三种情况		if (b[j] > 0) 		{			//移动			 if (b[k] == 0) 			{ 				b[k] = b[j];	            b[j] = 0;			}			 //合并			else if (b[k] == b[j])			{				b[k] = 2 * b[k];				b[j] = 0;				k = k + 1;			}			 //碰撞			else			{ 				b[k + 1] = b[j];				if (j != k + 1) 				{ 					b[j] = 0;				}				k = k + 1;			}		}	}

游戏代码:

#include 
#include
#include
#include
#include
#define ROW 4 #define COL 4 //定义全局变量的好处:在函数之间不用传参 // 缺点:只能完成一次游戏,要想继续玩就必须将数组重置为全0; int arr[ROW][COL] = { 0 }; int score = 0; //设置光标的句柄,通俗的说,就是设置光标的位置 void SetCurPos(int x, int y) { HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); COORD coord = { x, y }; SetConsoleCursorPosition(hStdOutput, coord); } //隐藏光标 void ViewInit(int width, int height) { HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO info; GetConsoleCursorInfo(hStdOutput, &info); info.bVisible = 0; SetConsoleCursorInfo(hStdOutput, &info); } //打印 void GamePrint(int row, int col) { printf("SCORE = %d", score); SetCurPos(0, 2); int i = 0; for (i = 0; i < row; i++) { for (int k = 0; k < 4; k++) { printf(" "); for (int j = 0; j < 4; j++) { printf("-"); } } printf("\n"); for (int k = 0; k < 4; k++) { printf("|"); if (arr[i][k]) { printf("%4d", arr[i][k]); } else { for (int j = 0; j < 4; j++) { printf(" "); } } } printf("|\n"); if (i == row - 1) { for (int k = 0; k < 4; k++) { printf(" "); for (int j = 0; j < 4; j++) { printf("-"); } } printf("\n"); } } SetCurPos(0, 12); printf("上下左右表示方向\n"); } //生成随机数 void RandNum(int row, int col) //生成随机数 { int x = 0; int y = 0; do { x = rand() % 4; y = rand() % 4; } while (arr[x][y]); arr[x][y] = (rand() % 10 ? 2 : 4); } //判断是否获胜 int IfWin(int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (arr[i][j] == 2048) { return 1; //表示赢了 } if (arr[i][j] == 0) { return 0; //表示继续游戏 } } } return -1;//输了 } //向左移 void MoveLeft() { for (int i = 0; i < ROW; i++) { int j = 1; int k = 0; for (; j < 4; j++) { if (arr[i][j] > 0) { if (arr[i][k] == 0) { arr[i][k] = arr[i][j]; arr[i][j] = 0; } else if(arr[i][k] == arr[i][j]) { arr[i][k] = 2 * arr[i][k]; score += arr[i][k]; arr[i][j] = 0; k++; } else { arr[i][++k] = arr[i][j]; if (j != k) { arr[i][j] = 0; } } } } } } //向右移 void MoveRight() { for (int i = 0; i < ROW; i++) { int j = 2; int k = 3; for (; j >= 0; j--) { if (arr[i][j] > 0) { if (arr[i][k] == 0) { arr[i][k] = arr[i][j]; arr[i][j] = 0; } else if (arr[i][k] == arr[i][j]) { arr[i][k] = 2 * arr[i][k]; score += arr[i][k]; arr[i][j] = 0; k--; } else { arr[i][--k] = arr[i][j]; if (j != k) { arr[i][j] = 0; } } } } } } //向上移 void MoveUp() { for (int j = 0; j < COL; j++) { int i = 1; int k = 0; for (; i < 4; i++) { if (arr[i][j] > 0) { if (arr[k][j] == arr[i][j]) { score += arr[k++][j] *= 2; arr[i][j] = 0; } else if (arr[k][j] == 0) { arr[k][j] = arr[i][j]; arr[i][j] = 0; } else { arr[++k][j] = arr[i][j]; if (i != k) { arr[i][j] = 0; } } } } } } //向下移 void MoveDown() { for (int j = 0; j < COL; j++) { int i = 2; int k = 3; for (; i >= 0; i--) { if (arr[i][j] > 0) { if (arr[k][j] == 0) { arr[k][j] = arr[i][j]; arr[i][j] = 0; } else if (arr[k][j] == arr[i][j]) { arr[k][j] = 2 * arr[k][j]; score += arr[k][j]; arr[i][j] = 0; k--; } else { arr[--k][j] = arr[i][j]; if (i != k) { arr[i][j] = 0; } } } } } } //游戏继续 void GameContinue() { //为了判断在键盘上按下的哪个键 int ch1 = 0; int ch2 = 0; while (1) { if (ch1 = _getch()) { ch2 = _getch(); if (ch2 == 72) { MoveUp(); break; } if (ch2 == 80) { MoveDown(); break; } if (ch2 == 75) { MoveLeft(); break; } if (ch2 == 77) { MoveRight(); break; } } } } void game() { srand((unsigned int)time(NULL)); ViewInit(20, 10); RandNum(ROW, COL); RandNum(ROW, COL); GamePrint(ROW, COL); while (1) { if (IfWin(ROW, COL) == 1) { printf("YOU WIN!\n"); return; } else if (IfWin(ROW, COL) == -1) { printf("GAME OVER\n"); return; } else { GameContinue(); system("cls"); RandNum(ROW, COL); GamePrint(ROW, COL); } } } int main() { game(); system("pause"); return 0; }
你可能感兴趣的文章
【Java】【28】提高List的removeAll方法的效率
查看>>
【JS】【31】读取json文件
查看>>
OpenSSL源代码学习[转]
查看>>
google app api相关(商用)
查看>>
linux放音乐cd
查看>>
GridView+存储过程实现'真分页'
查看>>
flask_migrate
查看>>
解决activemq多消费者并发处理
查看>>
UDP连接和TCP连接的异同
查看>>
hibernate 时间段查询
查看>>
java操作cookie 实现两周内自动登录
查看>>
Tomcat 7优化前及优化后的性能对比
查看>>
Java Guava中的函数式编程讲解
查看>>
Eclipse Memory Analyzer 使用技巧
查看>>
tomcat连接超时
查看>>
谈谈编程思想
查看>>
iOS MapKit导航及地理转码辅助类
查看>>
检测iOS的网络可用性并打开网络设置
查看>>
简单封装FMDB操作sqlite的模板
查看>>
iOS开发中Instruments的用法
查看>>