马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 Stubborn 于 2021-5-12 18:01 编辑
C语言,2048游戏文字版,流程逻辑思路,代码详解(中)
上一篇已经实现了大部分的绘制函数,这部分开始实现游戏的逻辑函数
⑤bool GeneratingRandomNumbers(struct Game *);大致逻辑是,随机生成2或者4,都是1/2的概率,然后随机生成一个索引,在数据列表中为0的位置跟新
- bool GeneratingRandomNumbers(struct Game *data){
- /**Generate a random number and place it in a random position where the data parameter is not 0。
- *If the modification is successful, return true; otherwise, return false。
- */
- srand(time(NULL));
- short value = ((const short []){2, 4})[randint(2)];
- size_t randomIndex = (size_t) randint(data->length);
- data->score += value;
- data->move += 1;
- for (size_t rightIndex = randomIndex; rightIndex < data->length; ++rightIndex)
- {
- if (data->arr[rightIndex]==0)
- {
- data->arr[rightIndex] = value;
- return true;
- }
- }
- for (size_t leftIndex = randomIndex; leftIndex > 0; --leftIndex)
- {
- if (data->arr[leftIndex]==0)
- {
- data->arr[leftIndex] = value;
- return true;
- }
- }
- return false;
- }
复制代码
好了,写到这里,开始回顾一下,实现的什么功能,以及程序的运行流程。
1.程序运行,展示一个欢迎界面,并提供输入选择。
2.输入对应的选择会有对应的界面
3.选择开始游戏后,生成一个随机数,并且打印出游戏界面。
那么接下来,我们就应该编写监听键盘的输入的函数,并实现⑥数字的移动以及合并选择。
首先是监听键盘的输入的函数bool JudgmentInput(int, struct Game *);
根据对应的键盘操作,调用不同的移动函数,当游戏可以发生移动,或者合并的时候,返回一个true。否则返回一个false。
其次当操作成功之后,在生成一个随机数,操作失败检测下当前游戏是不是可以结束,即当前游戏不能发生移动,合并的情况。
不管成功或者失败,都看下有没有到胜利条件,看下合成的数字有没有到2048。然后再次绘制游戏界面,跟新游戏状态。
函数bool JudgmentInput(int, struct Game *); 实现的逻辑是:
当键盘发生了上下左右的操作,调用对应的移动合并操作。
如果移动合并操作失败,或者发生其他的操作,检查游戏是不是结束,或者胜利。
再次打印游戏界面
- bool JudgmentInput(int key, struct Game *data){
- bool flag = false;
- switch (key) { ////LEFT = 75, UP = 72, RIGHT = 77, DOWN = 80, Esc=27
- case 72:
- flag = MoveUp(data);
- break;
- case 80:
- flag = MoveDown(data);
- break;
- case 75:
- flag = MoveLeft(data);
- break;
- case 77:
- flag = MoveRight(data);
- break;
- case 27:
- exit(0);
- }
- if (flag){
- GeneratingRandomNumbers(data);
- } else {
- DrawLoser(data);
- }
- DrawWin(*data);
- DrawTheGameBox(*data);
- return flag;
- }
复制代码
在void StartGame()函数里面死循环,监听键盘操作
- void StartGame(){
- /**Start the game, run the logic of the game
- * */
- bool True = true;
- struct Game data= {16, {0}, 0, 0, 0, time(NULL)};
- struct Game *p = &data;
- GeneratingRandomNumbers(p);
- DrawTheGameBox(data);
- // 监听键盘
- while (True)
- {
- while (kbhit())
- {
- JudgmentInput(getch(), p);
- }
- }
- }
复制代码
现在开始实现⑥部分的数字合并部分,也是整个游戏的逻辑核心。首先看图。
首先看左侧,游戏往上移动。2048游戏的逻辑是什么?
数字向上移动,如果相邻的两个各自数字一样,则合并成一个新数字。
所以我们实现的逻辑是什么?具体如何实现?
我们需要实现数字移动,以及数字的合并。
怎么移动数字,一个最基本的逻辑 ,当遍历到数值为0的时候,那么表明这个位置可以被填充的,0下方的数字都可以移动。用编程表达就是这两个位置可以交换
- arr[index] = arr[index-4];
- arr[index-4] = 0;
复制代码
注意,因为我这里使用的是一维数组,表达方式不一样。实际看个人的数据进行表达。一定要注意数组的越界,我们应该遍历到第三层就停止遍历。
当我们整个遍历一次后,会发生什么?可以移动的数字,全部往上移动了一层。那么我们重复这个步骤,那么就可以全部进行移动
怎么进行数字的合并。和移动数字的逻辑差不多,当遍历数组的时候,发现当前遍历的索引index 和 index + 4 值一样,即上下两个值一样,就可以进行合并。用编程表达就是这两个位置发生改变:
- arr[index] *= 2;
- arr[index-4] = 0;
复制代码
合并之后,又会出现 0 的空位,此时我们再次调用移动函数,进行移动即可完成一次的移动操作
|