标题:100 行代码撸了一个 2048 的小游戏
取消只看楼主
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
结帖率:95.65%
已结贴  问题点数:20 回复次数:7 
100 行代码撸了一个 2048 的小游戏
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

#define GAME_SIZE  4

static void left(int *data)
{
    int i, j, f;
    int row = GAME_SIZE;
    while (row--) {
        for (j=0,f=0,i=0; i<GAME_SIZE; i++) {
            if (data[i]) {
                if (!f && j>0 && data[j-1] == data[i]) {
                    data[j-1]+= data[i]; f = 1;
                } else {
                    data[j++] = data[i]; f = 0;
                }
            }
        }
        while (j < GAME_SIZE) data[j++] = 0;
        data += GAME_SIZE;
    }
}

static void right(int *data)
{
    int i, j, f;
    int row = GAME_SIZE;
    while (row--) {
        for (j=GAME_SIZE-1,f=0,i=GAME_SIZE-1; i>=0; i--) {
            if (data[i]) {
                if (!f && j<GAME_SIZE-1 && data[j+1] == data[i]) {
                    data[j+1]+= data[i]; f = 1;
                } else {
                    data[j--] = data[i]; f = 0;
                }
            }
        }
        while (j >= 0) data[j--] = 0;
        data += GAME_SIZE;
    }
}

static void up(int *data)
{
    int i, j, f;
    int col = GAME_SIZE;
    while (col--) {
        for (j=0,f=0,i=0; i<GAME_SIZE; i++) {
            if (data[i*GAME_SIZE]) {
                if (!f && j>0 && data[(j-1)*GAME_SIZE] == data[i*GAME_SIZE]) {
                    data[(j-1)*GAME_SIZE]+= data[i*GAME_SIZE]; f = 1;
                } else {
                    data[(j++)*GAME_SIZE] = data[i*GAME_SIZE]; f = 0;
                }
            }
        }
        while (j < GAME_SIZE) data[(j++)*GAME_SIZE] = 0;
        data++;
    }
}

static void down(int *data)
{
    int i, j, f;
    int col = GAME_SIZE;
    while (col--) {
        for (j=GAME_SIZE-1,f=0,i=GAME_SIZE-1; i>=0; i--) {
            if (data[i*GAME_SIZE]) {
                if (!f && j<GAME_SIZE-1 && data[(j+1)*GAME_SIZE] == data[i*GAME_SIZE]) {
                    data[(j+1)*GAME_SIZE]+= data[i*GAME_SIZE]; f = 1;
                } else {
                    data[(j--)*GAME_SIZE] = data[i*GAME_SIZE]; f = 0;
                }
            }
        }
        while (j >= 0) data[(j--)*GAME_SIZE] = 0;
        data++;
    }
}

static int next(int *data)
{
    int empidx[GAME_SIZE*GAME_SIZE];
    int empnum = 0;
    int max    = 0;
    int i, j;

    for (j=0,i=0; i<GAME_SIZE*GAME_SIZE; i++) {
        if (data[i] == 0) {
            empidx[j++] = i;
            empnum++;
        }
        max = max > data[i] ? max : data[i];
    }
    if (empnum) {
        data[empidx[rand()%empnum]] = 1;
        return max == 2048 ? 1 : 0;
    }
    else return -1;
}

static void output(int *data)
{
    int i, sum = 0;

    printf("+--------------------+\n\n");
    for (i=1; i<=GAME_SIZE*GAME_SIZE; i++) {
        if (0 || data[i-1]) {
            printf("%4d %s", data[i-1], i%GAME_SIZE ? "" : "\n\n");
        } else {
            printf("%s %s" , "   ."   , i%GAME_SIZE ? "" : "\n\n");
        }
        sum += data[i-1];
    }
    printf("+--------------------+\n\n");
    printf("分数:%d\n\n", sum);
}

int main(void)
{
    int data[GAME_SIZE * GAME_SIZE] = {0};
    int ret = 0;

    next  (data);
    next  (data);
    output(data);

    while (1) {
        int c = getch();
        switch (c) {
        case 'j': left (data); break;
        case 'k': down (data); break;
        case 'l': right(data); break;
        case 'i': up   (data); break;
        case 'q': return 0;
        default : continue;
        }
        ret = next(data);
        output(data);

        if (ret == -1) printf("game over !\n");
        if (ret ==  1) printf("you  win  !\n");
    }
}


+---------------------------------------------------------------+
linux 下 gcc 编译,解决 getch 问题

删掉:
#include <conio.h>

加上:
#include <termio.h>

int getch(void)
{
    struct termios tm, tm_old;
    int fd = 0, ch;

    if (tcgetattr(fd, &tm) < 0) {
        return -1;
    }

    tm_old = tm;
    cfmakeraw(&tm);
    if (tcsetattr(fd, TCSANOW, &tm) < 0) {
        return -1;
    }

    ch = getchar();
    if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {
        return -1;
    }

    return ch;
}


[此贴子已经被作者于2017-9-29 16:10编辑过]

搜索更多相关主题的帖子: void int data while return 
2017-09-16 11:03
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
得分:0 
规则就是 2084 游戏的规则

j - 左
k - 下
l - 右
i - 上

相同数字移动过程中会合并

只有代码,windows 下可以编译通过,linux 下要改改。

2017-09-20 13:36
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
得分:0 
错误信息发来看看
我是用 mingw32 编译的
2017-09-25 19:03
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
得分:0 
回复 12楼 北奔
算法主要就是 left right up down 四个函数
2017-09-27 08:46
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
得分:0 
这四个函数的算法原理是一样的,懂了其中一个就全懂了。
2017-09-27 08:48
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
得分:0 
回复 15楼 iChenwin
linux 下

#include <termio.h>

int getch(void)
{
    struct termios tm, tm_old;
    int fd = 0, ch;

    if (tcgetattr(fd, &tm) < 0) {
        return -1;
    }

    tm_old = tm;
    cfmakeraw(&tm);
    if (tcsetattr(fd, TCSANOW, &tm) < 0) {
        return -1;
    }

    ch = getchar();
    if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {
        return -1;
    }

    return ch;
}

把这个加上


用 ncurses 不太好用,就算要用,也要加初始化的。

main() {
initscr();
.
.
.
endwin();
}

你可以试下
2017-09-29 11:55
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
得分:0 
回复 17楼 iChenwin
的确是有bug的
当然也可以理解为游戏规则如何定义
要改的话也简单
2017-09-29 15:48
RockCarry
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:13
帖 子:662
专家分:58
注 册:2005-8-5
得分:0 
回复 17楼 iChenwin
新加进去的数字,我这边始终设定为 1,这跟真正的2048的规则也是不一样的,要改也很简单。
然后就是output部分,可以想办法搞成彩色的,或者直接上图形界面。
2017-09-29 15:56



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-480740-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.354781 second(s), 8 queries.
Copyright©2004-2025, BCCN.NET, All Rights Reserved