【C语言】2048小游戏【附源码】

2024-04-06 18:44
文章标签 语言 源码 小游戏 2048

本文主要是介绍【C语言】2048小游戏【附源码】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998

一、游戏描述:

        2048是一款数字益智类游戏,玩家需要使用键盘控制数字方块的移动,合并相同数字的方块,最终达到数字方块上出现“2048”的目标。

        每次移动操作,所有数字方块会朝着指定方向同时滑动,并在靠近边界或其他数字方块时停止。如果两个相邻的数字方块数字相同,则它们会合并成一个方块,数字值为原先相同方块的数字值相加。

 

二、效果展示

c661ac348297482ea142d8baa7a78410.png

 

三、代码讲解:

        实现了一个2048游戏的基本功能,包括初始化游戏界面、移动方块、放置新数字以及判定胜负等功能:

  1. DisplayBoard(int board[ROW][COL]):初始化并打印游戏界面。这个函数用于显示游戏的当前状态,包括棋盘上的数字和空格。

  2. init_num(int board[ROW][COL]):在游戏开始时随机生成两个数字2。这个函数用于初始化游戏棋盘,给棋盘上的两个随机位置赋值为2。

  3. put_num(int board[ROW][COL]):在每次移动后随机放置一个数字2或4。这个函数用于在每次玩家移动后,在空白的位置随机生成一个数字2或4。

  4. up(int board[ROW][COL])down(int board[ROW][COL])left(int board[ROW][COL])right(int board[ROW][COL]):分别实现了向上、向下、向左、向右移动的功能。这些函数用于处理玩家的移动操作,更新棋盘上的数字位置。

  5. is_win(int board[ROW][COL]):判断是否获胜。这个函数用于检查游戏是否达到了2048,如果有一个位置的值为2048,则游戏获胜。

  6. is_fail(int board[ROW][COL]):判断是否失败。这个函数用于检查游戏是否失败,即所有位置都被填满且无法进行有效的移动操作。

 

#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]);

显示2048游戏的棋盘界面

        

  1. 打印横向的分隔线,使用"+"和"-"来表示。
  2. 遍历每个格子,如果格子上有数字,则打印该数字并确保宽度为5个字符,右对齐;如果格子上没有数字,则打印5个空格。
  3. 在每行末尾打印"|"
  4. 再次打印横向的分隔线,使用"+"和"-"来表示。
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]);elseprintf("     ");}printf("|\n");for (int j = 0; j < COL; j++){printf("+-----");}printf("+\n");}
}

 

初始化游戏棋盘:

        

  1. 生成一个随机的行索引 x 和列索引 y,确保它们在棋盘范围内。
  2. 在随机选择的位置 (x, y) 上放置一个数字2。
  3. 再次生成一个随机的行索引 x 和列索引 y,确保它们与第一个位置不重复。
  4. 在新的随机选择的位置 (x, y) 上放置另一个数字2。
void init_num(int board[ROW][COL])
{int x, y;x = rand() % ROW;y = rand() % COL;board[x][y] = 2;//随机在一个位置生成2x = rand() % ROW;y = rand() % COL;while (board[x][y] == 2){x = rand() % ROW;y = rand() % COL;}board[x][y] = 2;return;
}

空白位置随机放置一个数字:

  1. 生成一个随机的行索引 x 和列索引 y,确保它们在棋盘范围内。
  2. 如果在选择的位置 (x, y) 上已经有数字,则继续随机选择位置,直到找到一个空白位置。
  3. 生成一个随机数 z,范围为0到9之间的整数。
  4. 如果 z 小于9,则在当前空白位置 (x, y) 放置数字2;如果 z 等于9,则放置数字4。
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;elseboard[x][y] = 4;return;
}

简单的 2048 游戏的移动和合并操作

        上下左右四个方向的移动操作:up、down、left、right

每个函数都按照相应的方向进行移动并合并相同的数字。

在每个函数中,首先进行移动操作,然后进行合并操作,再次进行移动操作,并最后检查游戏是否可以继续进行(通过contrast(board)函数判断)。如果游戏可以继续,则调用put_num(board)函数来生成新的数字;否则直接返回。

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++;}elsej++;}//合并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++;}elsej++;}}if (contrast(board) == 0)put_num(board);elsereturn;
}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++;}elsej--;}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++;}elsej--;}}if (contrast(board) == 0)put_num(board);elsereturn;
}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++;}elsej++;}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++;}elsej++;}}if (contrast(board) == 0)put_num(board);elsereturn;
}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);elsereturn;
}

 

判断在 2048 游戏中是否无法继续移动

  1. 游戏板上还有空格(值为0),即游戏可以继续;
  2. 相邻的方块(上下或左右相邻)有相同的值,即游戏可以继续合并。

如果以上任意情况成立,函数将返回0,表示游戏可以继续;否则,如果所有方块都被填满且没有相邻方块的值相同,函数将返回1,表示游戏无法继续移动,游戏结束。

 

 

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;
}

检查在2048游戏中是否获胜

该函数遍历整个游戏板,找到其中的最大值。如果最大值达到或超过2048,函数将返回1,表示玩家已经获胜;否则返回0,表示游戏尚未获胜。

在2048游戏中,玩家的目标是通过合并方块使得其中一个方块的值达到2048。一旦某个方块的值达到2048,玩家就获胜了。

这个函数的作用是在每一步移动后检查游戏是否已经达到了获胜条件。如果返回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;elsereturn 0;
}

        copyboard 函数的作用是将一个二维数组 board 中的元素复制到另一个二维数组 copy 中。通常在编程中,这样的函数用于保存一个数组的副本,以便后续的比较或者其他操作而不影响原始数组。

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];
}

菜单功能:

void menu()
{printf("**************************\n");printf("**************************\n");printf("**************************\n");printf("*****按 1 开 始 游 戏*****\n");printf("*****按 0 退 出 游 戏*****\n");printf("**************************\n");printf("**************************\n");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;
}

完整代码:

        Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game2048.h"void menu()
{printf("**************************\n");printf("**************************\n");printf("**************************\n");printf("*****按 1 开 始 游 戏*****\n");printf("*****按 0 退 出 游 戏*****\n");printf("**************************\n");printf("**************************\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;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#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]);elseprintf("     ");}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;//随机在一个位置生成2x = 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;elseboard[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++;}elsej++;}//合并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++;}elsej++;}}if (contrast(board) == 0)put_num(board);elsereturn;
}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++;}elsej--;}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++;}elsej--;}}if (contrast(board) == 0)put_num(board);elsereturn;
}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++;}elsej++;}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++;}elsej++;}}if (contrast(board) == 0)put_num(board);elsereturn;
}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);elsereturn;
}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;elsereturn 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;
}

 

 

这篇关于【C语言】2048小游戏【附源码】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/880559

相关文章

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

C语言实现两个变量值交换的三种方式

《C语言实现两个变量值交换的三种方式》两个变量值的交换是编程中最常见的问题之一,以下将介绍三种变量的交换方式,其中第一种方式是最常用也是最实用的,后两种方式一般只在特殊限制下使用,需要的朋友可以参考下... 目录1.使用临时变量(推荐)2.相加和相减的方式(值较大时可能丢失数据)3.按位异或运算1.使用临时

使用C语言实现交换整数的奇数位和偶数位

《使用C语言实现交换整数的奇数位和偶数位》在C语言中,要交换一个整数的二进制位中的奇数位和偶数位,重点需要理解位操作,当我们谈论二进制位的奇数位和偶数位时,我们是指从右到左数的位置,本文给大家介绍了使... 目录一、问题描述二、解决思路三、函数实现四、宏实现五、总结一、问题描述使用C语言代码实现:将一个整

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

Go语言中最便捷的http请求包resty的使用详解

《Go语言中最便捷的http请求包resty的使用详解》go语言虽然自身就有net/http包,但是说实话用起来没那么好用,resty包是go语言中一个非常受欢迎的http请求处理包,下面我们一起来学... 目录安装一、一个简单的get二、带查询参数三、设置请求头、body四、设置表单数据五、处理响应六、超

C语言中的浮点数存储详解

《C语言中的浮点数存储详解》:本文主要介绍C语言中的浮点数存储详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、首先明确一个概念2、接下来,讲解C语言中浮点型数存储的规则2.1、可以将上述公式分为两部分来看2.2、问:十进制小数0.5该如何存储?2.3 浮点

基于Python实现多语言朗读与单词选择测验

《基于Python实现多语言朗读与单词选择测验》在数字化教育日益普及的今天,开发一款能够支持多语言朗读和单词选择测验的程序,对于语言学习者来说无疑是一个巨大的福音,下面我们就来用Python实现一个这... 目录一、项目概述二、环境准备三、实现朗读功能四、实现单词选择测验五、创建图形用户界面六、运行程序七、