用VC++6.0的控制台实现2048小游戏的程序

 更新时间:2020年4月25日 17:39  点击:1742

首先感谢这位大侠的无私分享,仔细学习这个程序以后收获很多,试着添加一些注释

源程序是从开源中国看到的,原作者是 刘地(sir?)
地址为http://www.oschina.net/code/snippet_593413_46040
geek_monkey于2015年3月5日为拜读该程序,受益匪浅
为了方便自己,以及更多初学者阅读,我试着写了写了注释供参考
我是C语言初学者,如有错误希望指正。轻喷

复制代码 代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
int x[4][4],y[4][4],z=0,o=0;//z表示的是当前矩阵中的非零数字的数量,z为16则说明数字排满了,本局输了
                            //o表示最大数字的值,本例设定的是1024
typedef int row[4];  //row代表具有4个元素的整型数组
row *p=x, *q=y;//P是整型指针数组,有4组,每组有4个元素。p[1]=x[1]=*(x+1)
void show()//显示函数
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            if(p[i][j]==0)
            {
                printf("-     ");//没有放置数字(也就是数字为0时)显示一个小横杠
            }
            else
            {
                printf("%-4d  ",p[i][j]);//显示位宽为4的整数,-表示左对齐
            }
        }
        printf("\n\n");
    }
    printf("\n\n");
}
void over()//将2维数组左右对调
{
    int i,j;
    row *r;
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        {
            q[i][3-j]=p[i][j];
        }
    r=p,p=q,q=r;
}
void left()//将2维数组逆时针转动90°
{
    int i,j;
    row *r;
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        {
            q[3-j][i]=p[i][j];
        }
    r=p,p=q,q=r;
}
void right()//将2维数组顺时针转动90°
{
    int i,j;
    row *r;
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        {
            q[j][3-i]=p[i][j];
        }
    r=p,p=q,q=r;
}
void inc()//此函数的作用是在0数字的位置上随机放置一个2或者4
{
    int i,j,k;
    for(;;)
    {
        k=rand()%16,i=k/4,j=k%4;//这个操作可以保证i,j小于等于4,不会放到二维数组外边
        if(p[i][j]==0)break;//确认p[i][j]是空白的,然后才能放置2或者4
    }
    if(rand()%2) //随机产生2或者4,理论上rand()%2的结果,0,1,几率各占一半
    {
        p[i][j]=4;
    }
    else
    {
        p[i][j]=2;
    }
    z++;
}
void merge(char c)
{
    int i,j,k,t;
    switch(c)//注,这个stitch没有default,也没有给按下右方向键的处理语句。即,按下右方向键,则跳过switch
    {
        case 'H'://检测到按了上方向键
            right();//顺时针转动90度
        break;
        case 'K'://左
            over();//左右对称换
        break;
        case 'P'://下
            left(); //逆90
        break;
    }
    //上边这个switch语句是将矩阵变换,将数字推向上,左或者下的操作转换为推向右的操作。
    //下边这个循环语句的功能是,把每一行的数字都往右边推,数字大小一样则合并。
    for(i=0;i<4;i++)//一行一行地检测
    {
        for(j=k=3;j>=0 && p[i][j]==0;j--);//从第i行的右边开始,向左找非零元素。也就是要让p[i][j]不为0的时候,结束本条for语句
        if(j<0)continue;//经过下边的右推操作,第i行最左边的值也非0,说明此行操作结束,跳出i的for循环,执行i+1行的右推操作
            t=p[i][j],p[i][j]=0,p[i][k]=t;//P[i][j]是P[i][k]左边的一个数。这里的j的值是由上一条语句找出来的,通过t传值保证了这个p[i][k]不为0
            for(j--;j>=0;j--)
            {
                t=p[i][j];
                if(t!=0)//如果p[i][j]不为0,就检测它与右侧的p[i][k]是否为相同
                {
                    p[i][j]=0;
                    if(p[i][k]==t)
                    {
                        z--,p[i][k]+=t;//相同则加倍,同时非0数字的数量减少一个
                        o=(t==512);//t为512代表最大值是1024,此时o==1,游戏以胜利结束
                    }
                    else
                    {
                        k--,p[i][k]=t;//不停则将p[i][j]的值赋给p[i][k],即数据右移动一位
                    }
                }
            }
    }
    switch(c)
    {
        case 'H'://按下,上方向键,矩阵逆时针旋转90°。这个操作与之前那个switch正好相反
            left();
        break;
        case 'K'://左右再次对调
            over();
        break;
        case 'P':
            right();
        break;
    }
    inc();
}
int main()
{
    char a,b;
    srand(time(NULL));
    inc();
    inc();//放置两个初始值
    show();
    while(z<16 && !o)//游戏结束条件,z==16或者o==1
    {
        a=getch();
        if(a==-32)//方向键的第一个字节为-32.char是无符的,这里为什么是-32还没弄明白
        {
            b=getch();
            if(b==72||b==75||b==77||b==80)
            {
                merge(b);
                show();
            }
        }
    }
    if(o)
    {
        printf("congratulations!");
    }
    else
    {
        printf("sorry, you failed!");
    }
    getch();
    return 0;
}
/*
特殊按键是两个字节,第一个字节是表示按的是特殊键的(普通键就一个字节),第 二个字节就是按键的ASCII码,
当按下“普通键”时,它的低8位数存放该字符的ASCII码。
对于特殊键,低8位为0。特殊键包括箭头键、功能键等。高8位字节存放该键的扫描码
#define KEY_LEFT 75   K   左
#define KEY_RIGHT 77  M   右
#define KEY_UP 72     H   上
#define KEY_DOWN 80   P   下
*/

以上就是本文分享的内容了,希望对大家学习VC++能有所帮助。

[!--infotagslink--]

相关文章

  • SpringMVC文件上传原理及实现过程解析

    这篇文章主要介绍了SpringMVC文件上传原理及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-15
  • C# MVC模式中应该怎样区分应用程序逻辑(Controller层)和业务逻辑(Model层)?

    这篇文章主要介绍了C# MVC模式中应该怎样区分应用程序逻辑(Controller层)和业务逻辑(Model层)?,这也小编做.NET项目时经常思考和让人混乱的一个问题,这篇文章写的挺好,一下清晰了许多,需要的朋友可以参考下...2020-06-25
  • 使用Maven 搭建 Spring MVC 本地部署Tomcat的详细教程

    这篇文章主要介绍了使用Maven 搭建 Spring MVC 本地部署Tomcat,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-16
  • SpringMvc自动装箱及GET请求参数原理解析

    这篇文章主要介绍了SpringMvc自动装箱及GET请求参数原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
  • vc提示unexpected end of file found的原因分析

    这篇文章主要介绍了vc提示unexpected end of file found的原因分析,给出了几点常见错误原因的分析,需要的朋友可以参考下...2020-04-25
  • SpringMvc获取请求头请求体消息过程解析

    这篇文章主要介绍了SpringMvc获取请求头请求体消息过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-17
  • Springmvc ResponseBody响应json数据实现过程

    这篇文章主要介绍了Springmvc ResponseBody响应json数据实现过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-10-26
  • C#创建SQLite控制台应用程序详解

    这篇文章主要为大家详细介绍了C#创建SQLite控制台应用程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • 基于C#后台调用跨域MVC服务及带Cookie验证的实现

    本篇文章介绍了,基于C#后台调用跨域MVC服务及带Cookie验证的实现。需要的朋友参考下...2020-06-25
  • 详解CocosCreator MVC架构

    这篇文章主要介绍了CocosCreator MVC架构,同学们在制作游戏过程中,尽量使用一些架构,会避免很多问题...2021-04-16
  • Spring MVC 处理一个请求的流程

    Spring MVC是Spring系列框架中使用频率最高的部分。不管是Spring Boot还是传统的Spring项目,只要是Web项目都会使用到Spring MVC部分。因此程序员一定要熟练掌握MVC部分。本篇博客简要分析Spring MVC处理一个请求的流程。...2021-02-06
  • 理解javascript中的MVC模式

    这篇文章主要为大家介绍了javascript中的MVC模式,MVC是一种软件架构模式,一般把软件模式分为三部分,本文就针对MVC模式的三部分进行讲解,感兴趣的小伙伴们可以参考一下...2016-02-01
  • 仅30行代码实现Javascript中的MVC

    这篇文章主要介绍了仅30行代码实现Javascript中的MVC的方法,MVC的基础是观察者模式,这是实现model和view同步的关键,想要深入了解的朋友可以参考本文...2016-02-18
  • 使用jQuery.form.js/springmvc框架实现文件上传功能

    这篇文章主要介绍了使用jQuery.form.jsspringmvc框架实现文件上传功能,非常具有参考借鉴价值,感兴趣的朋友一起学习吧...2016-05-14
  • SpringMVC和rabbitmq集成的使用案例

    这篇文章主要介绍了SpringMVC和rabbitmq集成的使用案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-20
  • AngularJS教程之MVC体系结构详解

    本文主要讲解AngularJS MVC体系结构,这里提供详细的教程供大家学习参考,有需要的小伙伴可以参考下...2016-08-24
  • web面试MVC与MVVM区别及Vue为什么不完全遵守MVVM解答

    这篇文章主要介绍了web面试中常问问题,MVC与MVVM区别以及Vue为什么不完全遵守MVVM的难点解答,有需要的朋友可以借鉴参考下,希望能够有所帮助...2021-09-24
  • 一次tomcat源码启动控制台中文乱码的调试过程记录

    平时在使用tomcat做一些服务的时候经常遇到各种乱码问题,下面这篇文章主要给大家介绍了一次tomcat源码启动控制台中文乱码的调试过程,需要的朋友可以参考下...2021-06-01
  • ASP.NET MVC API 接口验证的示例代码

    本篇文章主要介绍了ASP.NET MVC API 接口验证的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2021-09-22
  • SpringMVC中的handlerMappings对象用法

    这篇文章主要介绍了SpringMVC中的handlerMappings对象用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-26