美文网首页
用C语言实现2048游戏

用C语言实现2048游戏

作者: 小土豆dy | 来源:发表于2019-08-16 20:28 被阅读0次

2048_C_code

用C语言编写的2048

1

要实现我们的 2048 小游戏,需要涉及一些数据结构的知识,以及一些 Linux 的系统调用。此外,为了方便在屏幕上使用字符绘图,我们还需要使用一个文本界面的屏幕绘图库 ncurses ,具体到操作就是在编译的时候需要加上 -lcurses 选项。
安装ncurses库:
sudo apt-get install libncurses5-dev

设计思路

要实现 2048 游戏目前有两个关键点:

  1. 在满足条件情况下消除方块
  2. 允许在游戏主界面(16 宫格)中任意一格输出数据
    其中第二点借助 ncurses 库可以较容易实现,但是第一点要稍微麻烦些。第一点的实现思路是,我们创建一个与游戏地图相同维数的数组矩阵,通过数组矩阵来维护 2048 游戏中每个格子的数据与状态,从而玩家的移动操作都可以映射为对数组矩阵的操作。

基础工作

  1. 引头文件
    编写自己的头文件head.h。
    添加库函数头文件:
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
  1. 创建函数
void draw(); //用于绘制游戏界面
void play(); //游戏运行的逻辑主体
void init(); //初始化函数,用于完成一些必要的初始化操作
void draw_one(int y, int x); //绘制单个数字
void cnt_value(int *new_y, int *new_x);
int game_over(); //结束游戏
int cnt_one(int y, int x);
  1. 编写函数
    创建函数文件head.c。
    添加函数的内容。
#include "head.h"
int a[4][4] = {0};
int empty;
int old_y, old_x;
void draw()
{
    int n, m, x, y;
    char c[4] = {'0', '0', '0', '0'};
    clear();
    for(n=0;n<9;n+=2)
    {
        for(m=0;m<21;m++)
        {
            move(n, m);
            addch('-');
            refresh();
        }
    }
    for(m=0;m<22;m+=5)
    {
        for(n=1;n<8;n++)
        {
            move(n,m);
            addch('|');
            refresh();
        }
    }
    for(y=0;y<4;y++)
    {
        for(x=0;x<4;x++)
        {
            draw_one(y, x);
        }
    }
}
void play()
{
    int x, y, i, new_x, new_y, temp;
    int old_empty, move;
    char ch;

    while(1)
    {
        move = 0;
        old_empty = empty;
        ch = getch();
        switch(ch) {
            case 97:    //左移  a
            case 104:   // h
            case 68:    // 左移方向键
                for(y = 0; y < 4; y++)
                    for(x = 0; x < 4; )
                    {
                        if(a[y][x] == 0)
                        {
                            x++;
                            continue;
                        }
                        else
                        {
                            for(i = x + 1; i < 4; i++)
                            {
                                if(a[y][i] == 0)
                                {
                                    continue;
                                }
                                else
                                {
                                    if(a[y][x] == a[y][i])
                                    {
                                        a[y][x] += a[y][i];
                                        a[y][i] = 0;
                                        empty++;
                                        break;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                            x = i;
                        }
                    }
                for(y = 0; y < 4; y++)
                    for(x = 0; x < 4; x++)
                    {
                        if(a[y][x] == 0)
                        {
                            continue;
                        }
                        else
                        {
                            for(i = x; (i > 0) && (a[y][i-1] == 0); i--)
                            {
                                a[y][i-1] = a[y][i];
                                a[y][i] = 1;
                                move = 1;
                            }
                        }
                    }
                break;
            case 100:   //右移 d
            case 108:   // l
            case 67:    //右移方向键
                for(y = 0; y < 4; y++)
                    for(x = 3; x >= 0; )
                    {
                        if(a[y][x] == 0)
                        {
                            x--;
                            continue;
                        }
                        else
                        {
                            for(i = x - 1; i >= 0; i--)
                            {
                                if(a[y][i] == 0)
                                {
                                    continue;
                                }
                                else if(a[y][x] == a[y][i])
                                {
                                    a[y][x] += a[y][i];
                                    a[y][i] = 0;
                                    empty++;
                                    break;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            x = i;
                        }
                    }
                for(y = 0; y < 4; y++)
                    for(x = 3; x >= 0; x--)
                    {
                        if(a[y][x] == 0)
                        {
                            continue;
                        } else
                        {
                            for(i = x; (i < 3) && (a[y][i+1] == 0); i++)
                            {
                                a[y][i+1] = a[y][i];
                                a[y][i] = 0;
                                move = 1;
                            }
                        }
                    }
                break;
            case 119:   //上移 w
            case 107:   //k
            case 65:    //上移方向键
                for(x = 0; x < 4; x++)
                    for(y = 0; y < 4; )
                    {
                        if(a[y][x] == 0)
                        {
                            y++;
                            continue;
                        }
                        else
                        {
                            for(i = y + 1; i < 4; i++)
                            {
                                if(a[i][x] == 0)
                                {
                                    continue;
                                }
                                else if(a[y][x] == a[i][x])
                                {
                                    a[y][x] += a[i][x];
                                    a[i][x] = 0;
                                    empty++;
                                    break;
                                } else
                                {
                                    break;
                                }
                            }
                            y = i;
                        }
                    }
                for(x = 0; x < 4; x++)
                    for(y = 0; y < 4; y++)
                    {
                        if(a[y][x] == 0)
                        {
                            continue;
                        }
                        else
                        {
                            for(i = y; (i > 0) && (a[i-1][x] == 0); i--)
                            {
                                a[i-1][x] = a[i][x];
                                a[i][x] = 0;
                                move = 1;
                            }
                        }
                    }
                break;
            case 115:   //下移 s
            case 106:   //j
            case 66:    //下移方向键
                for(x = 0; x < 4; x++)
                    for(y = 3; y >= 0; )
                    {
                        if(a[y][x] == 0)
                        {
                            y--;
                            continue;
                        }
                        else
                        {
                            for(i = y - 1; i >= 0; i--)
                            {
                                if(a[i][x] == 0)
                                {
                                    continue;
                                }
                                else if(a[y][x] == a[i][x])
                                {
                                    a[y][x] += a[i][x];
                                    a[i][x] = 0;
                                    empty++;
                                    break;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            y = i;
                        }
                    }
                for(x = 0; x < 4; x++)
                    for(y = 3; y >= 0; y--)
                    {
                        if(a[y][x] == 0)
                        {
                            continue;
                        }
                        else
                        {
                            for(i = y; (i < 3) && (a[i+1][x] == 0); i++)
                            {
                                a[i+1][x] = a[i][x];
                                a[i][x] = 0;
                                move = 1;
                            }
                        }
                    }
                break;
            case 'Q':
            case 'q':
                game_over();
                break;
            default:
                continue;
                break;
        }
        if(empty <= 0)
            game_over();
        if((empty != old_empty) || (move == 1))
        {
            do{
                new_x = rand() % 4;
                new_y = rand() % 4;
            }while(a[new_y][new_x] != 0);

            cnt_value(&new_y, &new_x);

            do {
                temp = rand() % 4;
            }while(temp == 0 || temp == 2);
            a[new_y][new_x] = temp + 1;
            empty--;
        }
        draw();
    }
}
void init()
{
    int x, y;
    initscr();
    cbreak();
    noecho();
    curs_set(0);
    empty = 15;
    srand(time(0));
    x = rand() % 4;
    y = rand() % 4;
    a[y][x] = 2;
    draw();
}
void draw_one(int y, int x)
{
    int i, m, k, j;
    char c[5] = {0x00};
    i = a[y][x];
    m = 0;
    while(i>0)
    {
        j = i %10;
        c[m++] = j + '0';
        i = i / 10;
    }
    m = 0;
    k = (x+1) * 5 - 1;
    while(c[m] != 0x00)
    {
        move(2*y+1, k);
        addch(c[m++]);
        k--;
    }
}
void cnt_value(int *new_y, int *new_x)
{
    int max_x, max_y, x, y, value;
    int max = 0;

    max = cnt_one(*new_y, *new_x);
    for(y = 0; y < 4; y++)
        for(x = 0; x < 4; x++)
        {
            // 如果(y, x)对应的空格为空
            if(!a[y][x])
            {
                // 优先选取周围空格最多的空格展示新数字
                value = cnt_one(y, x);
                if(value > max && old_y != y && old_x != x)
                {
                    // 避免在同一位置反复出现新数字
                    *new_y = y;
                    *new_x = x;
                    old_x = x;
                    old_y = y;
                    break;
                }
            }
        }
}
int game_over()
{
    sleep(1);
    endwin();
    exit(0);
}
int cnt_one(int y, int x)
{
    int value = 0;
    if(y - 1 > 0)
        a[y-1][x] ? 0 : value++;
    if(y + 1 < 4)
        a[y+1][x] ? 0 : value++;
    if(x - 1 >= 0)
        a[y][x-1] ? 0 : value++;
    if(x + 1 < 4)
        a[y][x+1] ? 0 : value++;
    if(y - 1 >= 0 && x - 1 >= 0)
        a[y-1][x-1] ? 0 : value++;
    if(y - 1 >= 0 && x + 1 < 4)
        a[y-1][x+1] ? 0 : value++;
    if(y + 1 < 4 && x - 1 >= 0)
        a[y+1][x-1] ? 0 : value++;
    if(y + 1 < 4 && x + 1 < 4)
        a[y+1][x+1] ? 0 : value++;
    return value;

}
  1. 编写主函数game_2048.c
#include "head.h"
int main()
{
    init();
    play();
    endwin();
    return 0;
}
  1. 编写makefile文件
test:game_2048.o head.o
    gcc game_2048.o head.o -o test -lcurses
game_2048.o:game_2048.c
    gcc -c -Wall game_2048.c -o game_2048.o -lcurses
head.o:head.c
    gcc -c -Wall head.c -o head.o -lcurses

.PHONY:clean
clean:
    rm *.o test

  1. 编译
    make
  2. 结果

2

也可以用Game_2048.c一个文件进行编译

gcc Game_2048.c -o 2048 -lcurses


代码地址:
Github地址
参考:

实验楼->C 语言制作 2048
C 语言制作 2048

相关文章

  • 用C语言实现2048游戏

    2048_C_code 用C语言编写的2048 1 要实现我们的 2048 小游戏,需要涉及一些数据结构的知识,以...

  • C语言实现2048游戏

    原文链接:https://blog.csdn.net/qq_44275213/article/details/10...

  • Android原生控件实现2048游戏-Kotlin版

      一直想写个2048的游戏,并且最近正在学习kotlin中,所以就决定用kotlin语言来实现,游戏拥有多种模式...

  • 用Python实现2048游戏

    今天带大家完成一份终端版2048游戏 2048游戏还是很经典的 首先还是新建一个空白的棋盘 然后是棋盘的显示函数 ...

  • python—手把手教你实现2048小游戏

    相信2048这个游戏对大家来说一定不陌生,下面这篇文章就主要给大家介绍了怎么用Python实现2048小游戏,文中...

  • 微信小程序版2048

    今天代码君教大家做一款2048游戏,用微信小程序来做,话不多说,先上效果图 2048的实现 一、2048.js 二...

  • 用js实现2048小游戏

    笔记仓库:https://github.com/nnngu/LearningNotes 本文永久更新地址 http...

  • 用Python实现小游戏2048

    转自:Python中文网社区论坛 直接上代码吧!

  • C语言编程之2048小游戏

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程...

  • 如何用Axure制作2048小游戏

    2048这款游戏肯定很多人都玩过吧,2048属于一款数字游戏。如果要自己设计2048该如何实现呢?我们都知道,Ax...

网友评论

      本文标题:用C语言实现2048游戏

      本文链接:https://www.haomeiwen.com/subject/hqtcsctx.html