C语言之2048小游戏理解分析

news2024/11/12 13:15:15

目录

游戏程序思维导图:

​编辑

功能介绍:

代码管理:

主函数:

    头文件:


游戏程序思维导图:
功能介绍:

按键W --------------- 向上

按键A --------------- 向左

按键S --------------- 向下

按键D --------------- 向右

按键P --------------- 开始游戏

按键L --------------- 结束游戏

按键其他 ---------- 提示有错

代码管理:

direction_choose.c  包含 1、get_errorInfo函数   获取错误信息并打印
                                        2、get_chooseInfo函数  获取方向选择的信息
                                        3、choose_func函数  (1)判断输入的不同方向输出相应的数组
                                                                           (2)判断输入的不同方向计算的得分
                                                                           (3)判断输入信息,输出相应错误原因
draw_map.c           draw函数          打印函数
game_cg.c            game_cg函数       判断是否通关
game_over.c          game_over函数     判断游戏是否失败
go_down.c     包含 1、go_down_move函数   向下移动函数
                              2、go_down_add函数    向下相加函数
                              3、go_down函数        整合向下移动函数和向下相加函数
go_up.c         包含 1、go_up_move函数   向上移动函数
                              2、go_up_add函数    向上相加函数
                              3、go_up函数        整合向上移动函数和向上相加函数
go_left.c        包含 1、go_left_move函数   向左移动函数
                              2、go_left_add函数    向左相加函数
                              3、go_left函数        整合向左移动函数和向左相加函数
go_right.c      包含 1、go_right_move函数   向右移动函数
                              2、go_right_add函数    向右相加函数
                              3、go_right函数        整合向有移动函数和向右相加函数
init.c               包含 1、CreateNumber函数    随机产生2或者4
                               2、init函数            调用CreateNumber函数在数组中随机0位随机产生2或者4          

主函数:
#include "head.h"

int main()
{
    char mode = 0;

    char start = 0;
    int score = 0;
//lable:
    printf("开始游戏请按 P ,结束游戏请按 L\n");
lable:
    system("stty -icanon"); // 系统函数将缓冲区清空

	start = getchar();
    if(start == 'p')
    {
        choose_func(start,score);
    }      
    else
    {
        get_errorInfo(E_ERROR_STATE);
        goto lable;
    }
    while(game_over() && mode != 'l'&& start == 'p')
    {   
        printf("输入A:向左,D:向右,W:向上,S:向下: \n");
        system("stty -icanon");
	    mode = getchar();
        if(mode =='p')
        {
            mode = 'P';
        }
        score = choose_func(mode,score);
        
    }  
    if(mode=='l')
    {
        printf("游戏结束。\n"); 
    }
    return 0;
}
    头文件:
#ifndef _HEAD_H 
#define _HEAD_H

#include<stdio.h> 
#include <stdlib.h>
#include<math.h>
#include<time.h>
#include<stdbool.h>

#define ROW 4   //定义行
#define COL 4   //定义列
//存储数据的数组
int map[ROW][COL];

void draw(); // 画图函数

int go_left_move(); // 向左移动函数
int go_left_add(int score); // 向左相加函数
int go_left(int score); // 向左函数

int go_right_move(); // 向右移动函数
int go_right_add(int score); // 向右相加函数
int go_right(int score); // 向右函数

int go_up_move(); // 向上移动函数
int go_up_add(int score); // 向上相加函数
int go_up(int score); // 向上函数

int go_down_move(); //向下移动函数
int go_down_add(int score); // 向下相加函数
int go_down(int score); // 向下函数

void init(); // 初始化函数

int choose_func(char mode,int score); // 选择方向移动函数

bool game_over(); // 游戏结束判断函数


enum choose{left = 0,
            right = 1,
            up = 2,
            down = 3,
            start = 4,
            end = 5}; // 定义选择枚举

static char get_choose[] = { 
    [left] = 'a',
    [right] = 'd',
    [down] = 's',
    [up] = 'w',
    [start] = 'p',
    [end] = 'l'
}; // 定义选择枚举选择相应的字符键


enum errorInfo
{
    E_ERROR_INPUT,
    E_ERROR_CSTATE,
    E_ERROR_STATE,
    E_ERROR_NONE
};

static char *error_buf[] = {
    [E_ERROR_INPUT] = "输入错误,请重新输入",
    [E_ERROR_CSTATE] = "已经开始游戏,请重新输入",
    [E_ERROR_STATE] = "开始错误,请按P开始游戏",
    [E_ERROR_NONE] = "未知错误"
};
char *get_errorInfo(enum errorInfo mc_erron);

#endif

详细代码可以自行下载浏览。(突然发现自己下载不了,特此补充)

选择函数
#include <stdio.h>
#include "head.h"
/*
*   函数名  : get_errorInfo
*   功能    : 获取错误信息并输出
*   参数    : enum errorInfo mc_erron  枚举errorInfo数据
*   输出    : 定义的指针数组记录的错误信息
*/
char *get_errorInfo(enum errorInfo mc_erron)
{
    printf("%s\n",error_buf[mc_erron]);
}
​
/*
*   函数名  : get_chooseInfo
*   功能    : 获取方向选择的信息
*   参数    : enum choose ch  枚举choose数据
*/
int get_chooseInfo(enum choose ch)
{
    get_choose[ch];
}
​
/*
*   函数名  : choose_func
*   功能    :  1、判断输入的不同方向输出相应的数组
*               2、判断输入的不同方向计算的得分
*               3、判断输入信息,输出相应错误原因
*   参数    :  1、mode    输入的方向名
*               2、score  需要计算的得分
*   返回值  :   score  计算后的得分情况
*/
int choose_func(char mode,int score)
{
    
    enum choose My_choose = mode;
    switch (get_chooseInfo(My_choose)) // 获取方向信息进行控制
    {
    case 's':
        score = go_down(score);
        draw();
        printf("当前得分%d\n",score);
        break;
    case 'w':
        score = go_up(score);
        draw();
        printf("当前得分得分%d\n",score);
        break;
    case 'd':
        score = go_right(score);
        draw();
        printf("当前得分得分%d\n",score);
        break;
    case 'a':
        score = go_left(score);
        draw();
        printf("当前得分得分%d\n",score);
        break; 
    case 'p':
        printf("游戏开始\n");
        init();  // 游戏初始化函数
        init();  // 游戏初始化函数
        draw();  // 打印函数
        break;
    case 'l':
        printf("游戏结束\n");
        printf("最终得分%d\n",score);
        break;
    case 'P':
        get_errorInfo(E_ERROR_CSTATE); // 获取重复输入错误信息
        break;
    default:
        get_errorInfo(E_ERROR_INPUT); // 获取输入异常错误信息
        break;
    }
 
    return score;
​
}
打印函数
#include <stdio.h>
#include "head.h"
​
/*
*  函数名   : draw  打印函数
*  功能     : 打印2048地图
*  主要步骤 : 打印4*4的二维数组,并在0的位置随机生成一个2或者4
*/
void draw()
{
    printf("\n--------------------------------------------\n");
​
    for(int i = 0; i < ROW; i++) 
    {
        printf("--\t");
        for(int j = 0; j < COL; j++)
        {
            printf("%d\t",map[i][j]);
        }
        printf("--  ");
        printf("\n");
        printf("\n");
        
    }
​
    printf("\n----------------------------------------------\n");
​
}
游戏结束函数
#include "head.h"
​
/*
*  函数名   : game_over
*  功能     : 判断游戏是否结束
*  返回值   : 0 或 1
*/
bool game_over()
{
    for (int i = 0; i < ROW; i++)
    {
        for(int j = 0; j < COL; j++)
        {
            if(map[i][j]==map[i][j+1]&&j!=3)
            {
                return true;
            }
            if(map[i][j]==map[i+1][j]&&i!=3)
            {
                return true;
            }
        }
    }
    printf("game_over !!\n");  
    return false;
    
}
向左函数
#include "head.h"
​
/*
*  函数名   : go_left_move
*  功能     : 向左移动
*/
int go_left_move()
{
    for(int i = 0; i < ROW; i++)
    {
        int k = 0;
        for(int j = 0; j < COL; j++)
        {
            if(map[i][j]==0)
            {
                k++;
            }
            if(map[i][j]!=0&&j!=0&&k>0)
            {
                map[i][j-k]=map[i][j];
                map[i][j]=0;
                
            }
        }
    }
}
​
/*
*  函数名   : go_left_add
*  功能     : 向左相加
*  参数     : score  计算向左相加得分
*  返回值   : score  返回计算后得分
*/
int go_left_add(int score)
{
    for(int i = 0; i < ROW; i++)
    {
        int k = 0;
        for(int j = 0; j < COL; j++)
        {
            if(map[i][j]==map[i][j+1]&&j!=3)
            {
                score += map[i][j]*2;
                map[i][j]+=map[i][j+1];
                map[i][j+1]=0;
            }
        }
    }
    return score;
}
​
/*
*  函数名   : go_left
*  功能     : 1、调用向左移动函数和向下相加函数
*              2、得到向左后得分
*              3、初始化获得一个随机值
*  参数     : score  需要计算的得分
*  返回值   : score  返回计算后得分
*/
int go_left(int score)
{
    go_left_move();
    score = go_left_add(score);
    go_left_move();
    init();
    return score;
}
向右函数
#include "head.h"
​
/*
*  函数名   : go_right_move
*  功能     : 向右移动
*/
int go_right_move()
{
    for(int i = 0; i < ROW; i++)
    {
        int k = 0;
        for(int j = COL-1; j >= 0; j--)
        {
            if(map[i][j] == 0)
            {
                k++;
            }
            if(map[i][j] != 0 && j != (COL-1) && k > 0)
            {
                map[i][j+k]=map[i][j];
                map[i][j]=0;
                
            }
        }
    }
}
​
/*
*  函数名   : go_right_add
*  功能     : 向右相加
*  参数     : score  计算向右相加得分
*  返回值   : score  返回计算后得分
*/
int go_right_add(int score)
{
    for(int i = 0; i < ROW; i++)
    {
        for(int j = COL-1; j >= 0; j--)
        {
            if(map[i][j]==map[i][j-1])
            {
                score += map[i][j]*2;
                map[i][j]+=map[i][j-1];
                map[i][j-1]=0;
            }
        }
    }
    return score;
}
​
/*
*  函数名   : go_right
*  功能     : 1、调用向右移动函数和向下相加函数
*              2、得到向右后得分
*              3、初始化获得一个随机值
*  参数     : score  需要计算的得分
*  返回值   : score  返回计算后得分
*/
int go_right(int score)
{
    go_right_move();
    score = go_right_add(score);
    go_right_move();
    init();
    return score;
}
向上函数
#include "head.h"
​
/*
*  函数名   : go_up_move
*  功能     : 向上移动
*/
int go_up_move()
{
    for(int i = 0; i < COL; i++)
    {
        int k = 0;
        for(int j = 0; j < ROW; j++)
        {
            if(map[j][i]==0)
            {
                k++;
            }
            if(map[j][i]!=0&&j!=0&&k>0)
            {
                map[j-k][i]=map[j][i];
                map[j][i]=0;
                
            }
        }
    }
}
​
/*
*  函数名   : go_up_add
*  功能     : 向上相加
*  参数     : score  计算向上相加得分
*  返回值   : score  返回计算后得分
*/
int go_up_add(int score)
{
    for(int i = 0; i < COL; i++)
    {
        for(int j = 0; j < ROW; j++)
        {
            if(map[j][i]==map[j+1][i]&&j!=3)
            {
                score += map[j][i]*2;
                map[j][i]+=map[j+1][i];
                map[j+1][i]=0;
            }
        }
    }
    return score;
}
​
/*
*  函数名   : go_up
*  功能     : 1、调用向上移动函数和向下相加函数
*              2、得到向上后得分
*              3、初始化获得一个随机值
*  参数     : score  需要计算的得分
*  返回值   : score  返回计算后得分
*/
int go_up(int score)
{
    go_up_move();
    score = go_up_add(score);
    go_up_move();
    init();
    return score;
}
向下函数
#include "head.h"
​
/*
*  函数名   : go_down_move
*  功能     : 向下移动
*/
int go_down_move()
{
    for(int i = 0; i < COL; i++)
    {
        int k = 0;
        for(int j = ROW-1; j >= 0; j--)
        {
            if(map[j][i] == 0)
            {
                k++;
            }
            if(map[j][i] != 0 && j != (ROW-1) && k > 0)
            {
                map[j+k][i]=map[j][i];
                map[j][i]=0;
                
            }
        }
    }
}
​
/*
*  函数名   : go_down_add
*  功能     : 向下相加
*  参数     : score  计算向下相加得分
*  返回值   : score  返回计算后得分
*/
int go_down_add(int score)
{
    for(int i = 0; i < COL; i++)
    {
        for(int j = ROW-1; j >= 0; j--)
        {
            if(map[j][i]==map[j-1][i])
            {
                score += map[j][i]*2;
                map[j][i]+=map[j-1][i];
                map[j-1][i]=0;
            }
        }
    }
    return score;
}
​
/*
*  函数名   : go_down
*  功能     : 1、调用向下移动函数和向下相加函数
*              2、得到向下后得分
*              3、初始化获得一个随机值
*  参数     : score  需要计算的得分
*  返回值   : score  返回计算后得分
*/
int go_down(int score)
{
    go_down_move();
    score = go_down_add(score);
    go_down_move();
    init();
    return score;
}
​
初始化函数
#include "head.h"
#define ROW 4   //行
#define COL 4   //列
​
//存储数据的数组
int map[ROW][COL];
​
//随机产生2或者4
int CreateNumber()
{
    if(rand() % 10 != 0)
    {
        return 2;
    }
    else
    {
        return 4;
    }
​
}
​
//初始化函数
void init()
{
    srand(time(NULL));  //设置随机种子
    // 随机产生一个数,并且放到数组里面去 
    for(int i = 0; i < 2; i++)
    {
        int r = rand() % ROW;
        int c = rand() % COL;   //随机产生一个数2或者4,2的概率更大
        if(map[r][c]==0)
        {
            map[r][c] = CreateNumber();
            i++; //只有正确生成了数字,i才会++
        }
        
    }
​
}

希望每天都可以进步!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1946060.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科技云报道:算网筑基AI注智,中国联通如何讲出AI时代的“新故事”?

科技云报道原创。 AI从未停止进化&#xff0c;也从未停止给人类带来惊喜。 从ChatGPT代表的文生文、Dall-E代表的文生图&#xff0c;到Sora代表的文生视频&#xff0c;Suno为代表的文生音乐&#xff0c;生成式AI的“暴力美学”持续突破内容生产的天花板&#xff0c;大模型技术…

【黑马java基础】特殊文件,日志

目录 特殊文件&#xff1a;Properties属性文件特点、作用使用Properties读取属性文件里的键值对数据使用properties把键值对数据写到属性文件中去案例 特殊文件&#xff1a;XML文件概述读取XML文件中的数据把数据写出到XML文件中去补充知识&#xff1a;约束XML文件的编写[了解]…

打卡第21天------二叉树

我现在每天都是在与时间赛跑&#xff0c;分秒必争&#xff0c;不想浪费一点我自己的时间。 希望通过算法训练营可以把我自己的逻辑思维建立起来&#xff0c;把自己的算法能力给提上去。 一、修剪二叉搜索树 题目链接&#xff1a;669. 修剪二叉搜索树 题目描述&#xff1a; 给…

最优化原理(笔记)

内积是线性代数运算的一个结果&#xff0c;一行*一列。 内积的性质&#xff01; 什么是范数&#xff1f;&#xff1f;&#xff1f; 对称矩阵&#xff1a;关于主对角线对称&#xff01; 正定对称矩阵&#xff1a; 二阶导是正定的&#xff0c;f(x)就是严格的凸函数&#xff01;&a…

element的el-autocomplete带输入建议搜索+搜索匹配文字高亮显示

element的el-autocomplete带输入建议搜索搜索匹配文字高亮显示 直接上代码 // vue代码块 添加插槽<el-autocompleteclearableplaceholder"请输入关键词进行搜索"input"searchInput"v-model"searchInputData":fetch-suggestions"queryS…

Android APP 音视频(02)MediaProjection录屏与MediaCodec编码

说明&#xff1a; 此MediaProjection 录屏和编码实操主要针对Android12.0系统。通过MediaProjection获取屏幕数据&#xff0c;将数据通过mediacodec编码输出H264码流&#xff08;使用ffmpeg播放&#xff09;&#xff0c;存储到sd卡上。 1 MediaProjection录屏与编码简介 这里…

【测开能力提升-Javascript】JavaScript运算符流程结构

1. 递增递减运算符 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script>// 前置递增运算符var age10age //类似于ageage1&#xff0c; 先加1后返回值alert(age)// 后置…

【数据结构 | 哈希表】一文了解哈希表(散列表)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【SQL语句大全(MySQL)】

SQL语法 添加删除修改查询基本查询条件查询分组函数/聚合函数分组查询排序分页查询&#xff08;限制查询&#xff09;多表查询连接查询根据年代分类连接查询根据连接方式分类1、内连接2、左外连接3、右外连接 多张表连接的语法格式 嵌套查询 SQL语句书写顺序 添加 INSERT INTO…

什么是STP环路保护

在运行生成树协议的网络中&#xff0c;根端口和其他阻塞端口状态是依靠不断接收来自上游设备的BPDU维持。当由于链路拥塞或者单向链路故障导致这些端口收不到来自上游交换设备的BPDU时&#xff0c;设备会重新选择根端口。原先的根端口会转变为指定端口&#xff0c;而原先的阻塞…

2019年9月全国英语等级考试第三级笔试真题

2019年9月全国英语等级考试第三级笔试真题

vue3.0学习笔记(三)——计算属性、监听器、ref属性、组件通信

1. computed 函数 定义计算属性&#xff1a; computed 函数&#xff0c;是用来定义计算属性的&#xff0c;计算属性不能修改。 计算属性应该是只读的&#xff0c;特殊情况可以配置 get set 核心步骤&#xff1a; 导入 computed 函数 执行函数 在回调参数中 return 基于响应…

尚品汇-sku存入Redis缓存(二十三)

目录&#xff1a; &#xff08;1&#xff09;分布式锁改造获取sku信息 &#xff08;2&#xff09;使用Redisson 分布式锁 AOP实现缓存 &#xff08;3&#xff09;定义缓存aop注解 &#xff08;1&#xff09;分布式锁改造获取sku信息 前面学习了本地锁的弊端&#xff0c;…

Springboot validated JSR303校验

1.导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency> 2.测试类 package com.jmj.gulimall.product.testC;import lombok.Data;import javax.val…

《0基础》学习Python——第二十讲__网络爬虫/<3>

一、用post请求爬取网页 同样与上一节课的get强求的内容差不多&#xff0c;即将requests.get(url,headershead)代码更换成requests.post(url,headershead),其余的即打印获取的内容&#xff0c;如果content-typejson类型的&#xff0c;打印上述代码的请求&#xff0c;则用一个命…

argon主题调整日记

前言 argon主题是一款由solstice23开发的一款简洁美观的WordPress主题&#xff0c;在使用过程中也发现了几个可以优化的点&#xff0c;在查阅主题文档无果后对其进行以下几点修改。 1、使用子主题 为了避免修改源文件而引起主题更新后修改丢失的问题&#xff0c;还是尽量使用子…

一个C++模板工厂的编译问题的解决。针对第三方库的构造函数以及追加了的对象构造函数。牵扯到重载、特化等

一窥模板的替换和匹配方式&#xff1a;偏特化的参数比泛化版本的还要多&#xff1a;判断是不是std::pair&#xff1c;,&#xff1e;。_stdpair模板参数太多-CSDN博客 简介 在一个项目里&#xff0c;调用了第三封的库&#xff0c;这个库里面有个类用的很多&#xff0c;而且其构…

Mindspore框架循环神经网络RNN模型实现情感分类|(六)模型加载和推理(情感分类模型资源下载)

Mindspore框架循环神经网络RNN模型实现情感分类 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;一&#xff09;IMDB影评数据集准备 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;二&#xff09;预训练词向量 Mindspore框架循环神经网络RNN模型实现…

【Vue实战教程】之 Vue Router 路由详解

Vue Router路由 1 路由基础 1.1 什么是路由 用Vue.js创建的项目是单页面应用&#xff0c;如果想要在项目中模拟出来类似于页面跳转的效果&#xff0c;就要使用路由。其实&#xff0c;我们不能只从字面的意思来理解路由&#xff0c;从字面上来看&#xff0c;很容易把路由联想…

CV13_混淆矩阵、F1分数和ROC曲线

1.1 混淆矩阵Confusion Matrix 混淆矩阵&#xff08;Confusion Matrix&#xff09;是机器学习和统计学中用于描述监督学习算法性能的特定表格布局。它是一种特定类型的误差矩阵&#xff0c;可以非常直观地表示分类模型在测试数据集上的预测结果与实际结果之间的对比。 混淆矩…