C语言实现游戏三2048游戏
目录
前言
游戏规则:游戏开始,在4x4的棋盘上随机两个方块出现数字2,通过方向键控制所有方块向同一个方向移动,两个相同数字方块撞在一起之后合并成为他们的和。每次移动,棋盘上还会在一个随机位置增加一个数字2或者数字4,当最终得到一个“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("]", 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
-
-
-
-
-
-
-
-
-
-
-
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
-
-
-
-
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("]", 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
-
-
-
-
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的小游戏。
我不是生活中的主人公,但是我还是想要努力到能够让自己不再留下遗憾,努力到配得上自己喜欢的人。
三天时间,2048,愿不忘初心。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfjhcig
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24