C语言2048C实现

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <strsafe.h>

//函数返还
#define FALSE 0
#define OK 1
//操作输入
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
//游戏数据
#define SIZE 4
#define HIDE 0
#define TOWER 0

typedef int status;
typedef int Map_2048;
typedef struct Sentry
{
    Map_2048 *TravelSentry;
    Map_2048 *CheckSentry;
} SentryDouble; //哨兵工具包

static void _SetPos(int x, int y); //移动光标到X、Y位置
static void HidePos();             //隐藏光标

static status GAME_PLAY();                                                                                             //游戏启动
static status GAME_DataShow();                                                                                         //打印游戏数据
static status GAME_DataInitialize();                                                                                   //图案初始化
static status GAME_DataCreate();                                                                                       //随机生成的2
static status GAME_DataDeal(int Player_Input);                                                                         //根据输入处理已有数据
static status GAME_XDataDeal(int Player_Input);                                                                        //行处理
static status GAME_YDataDeal(int Player_Input);                                                                        //列处理
static status GAME_XPartDataDeal(int Player_Input, SentryDouble *Sentry, int i);                                       //行部分处理
static status GAME_YPartDataDeal(int Player_Input, SentryDouble *Sentry, int i);                                       //列部分处理
static status SentryInitialize(int Player_Input, SentryDouble *Sentry, int i);                                         //根据Player_Input推进哨兵进入下一阶段
static status CheckSentryDeal(int Player_Input, SentryDouble *Sentry);                                                 // CheckSentry运行
static status DataMerge(SentryDouble *Sentry);                                                                         //数据合并
static status RangeSentryDeal(int Player_Input, SentryDouble Sentry);                                                  //通过RangeSentry查询CheckSentry——TravelSentry之间是否全零
static status DataReorganize(int Player_Input);                                                                        //数据整理
static status GAME_DataTowerDeal();                                                                                    //数据查满
static status GAME_OverJudge();                                                                                        //结束查询
static status GAME_OverPartJudge(int Player_Input, Map_2048 DataSumTemp, Map_2048 DataSum, Map_2048 Over[][SIZE + 1]); //四方向判断
static status Node_Beautiy(int i, int j, int color);                                                                   //节点美化
Map_2048 Map[SIZE + 1][SIZE + 1] = {HIDE};                                                                             //游戏地图初始化,Map[0][]与Map[][0],用于判断行列是否已满

void main()
{

    GAME_PLAY();
    getchar();
}

static status GAME_DataInitialize()
{
    for (int i = 0; i < 2; i++)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 51);
        _SetPos(0, i * 13);
        printf("■■■■■■■■■■■■■■");
        for (int j = 0; j < 14; j++)
        {
            _SetPos(i * 26, j);
            printf("■");
        }
    }
    return OK;
}

static status GAME_OverPartJudge(int Player_Input, Map_2048 DataSumTemp, Map_2048 DataSum, Map_2048 Over[][SIZE + 1])
{
    DataSum = 0;
    GAME_DataDeal(Player_Input);
    GAME_DataCreate();
    for (int i = 1; i <= SIZE; i++)
        for (int j = 1; j <= SIZE; j++)
        {
            if (Over[i][j] != Map[i][j])
            {
                for (int w = 0; w <= SIZE; w++)
                    for (int r = 0; r <= SIZE; r++)
                    {
                        Map[w][r] = Over[w][r];
                    }
                return FALSE;
            }
        }
    return OK;
}

static status GAME_OverJudge()
{
    if (Map[TOWER][TOWER])
    {
        Map_2048 Over[SIZE + 1][SIZE + 1];
        Map_2048 DataSumTemp, DataSum;
        for (int i = 0; i <= SIZE; i++)
            for (int j = 0; j <= SIZE; j++)
            {
                DataSumTemp += Map[i][j];
                Over[i][j] = Map[i][j];
            }
        DataSumTemp -= 9;
        if (!GAME_OverPartJudge(UP, DataSumTemp, DataSum, Over))
            return 2;
        if (!GAME_OverPartJudge(DOWN, DataSumTemp, DataSum, Over))
            return 2;
        if (!GAME_OverPartJudge(LEFT, DataSumTemp, DataSum, Over))
            return 2;
        if (!GAME_OverPartJudge(RIGHT, DataSumTemp, DataSum, Over))
            return 2;
        return OK;
    }
    else
        return FALSE;
}

static void _SetPos(int x, int y)
{
    COORD position;
    HANDLE handle;
    position.X = x;
    position.Y = y;
    handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(handle, position);
}

static void HidePos()
{
    CONSOLE_CURSOR_INFO cursor_info = {1, FALSE};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

static status GAME_DataCreate()
{
    int x, y;
    int Weight;
    Weight = rand() % 10;
    srand(time(NULL));
    if (Map[TOWER][TOWER])
        return FALSE;
    while (1)
    {
        x = rand() % SIZE + 1;
        y = rand() % SIZE + 1;
        if (!Map[x][y])
            if (Weight)
            {
                Map[x][y] = 2;
                break;
            }
            else
            {
                Map[x][y] = 4;
                break;
            }
    }

    return OK;
}

static status GAME_YDataDeal(int Player_Input)
{
    SentryDouble Sentry;
    for (int i = 1; i <= SIZE; i++)
        GAME_YPartDataDeal(Player_Input, &Sentry, i);
    return OK;
}

static status GAME_XDataDeal(int Player_Input)
{
    SentryDouble Sentry;
    for (int i = 1; i <= SIZE; i++)
        GAME_XPartDataDeal(Player_Input, &Sentry, i);
    return OK;
}

static status GAME_DataDeal(int Player_Input)
{
    switch (Player_Input)
    {
    case UP:
    case DOWN:
        GAME_YDataDeal(Player_Input);
        break;
    case LEFT:
    case RIGHT:
        GAME_XDataDeal(Player_Input);
        break;
    default:
        break;
    }
    return OK;
}

static status CheckSentryDeal(int Player_Input, SentryDouble *Sentry)
{

    switch (Player_Input)
    {
    case UP:
        Sentry->CheckSentry = Sentry->CheckSentry + SIZE + 1;
        break;
    case DOWN:
        Sentry->CheckSentry = Sentry->CheckSentry - (SIZE + 1);
        break;
    case LEFT:
        Sentry->CheckSentry = Sentry->CheckSentry + 1;
        break;
    case RIGHT:
        Sentry->CheckSentry = Sentry->CheckSentry - 1;
        break;
    default:
        break;
    }
    if ((*Sentry->CheckSentry == *Sentry->TravelSentry) && (*Sentry->CheckSentry != 0))
        if (RangeSentryDeal(Player_Input, *Sentry) && *Sentry->TravelSentry != 2048)
        {
            DataMerge(Sentry);
            return OK;
        }
    return FALSE;
}

static status RangeSentryDeal(int Player_Input, SentryDouble Sentry)
{
    int I;
    int Sew; //缀
    Map_2048 *RangeSentry;
    switch (Player_Input)
    {
    case UP:
    case LEFT:
        Sew = Player_Input == UP ? (SIZE + 1) : 1;
        I = (Sentry.CheckSentry - Sentry.TravelSentry) / Sew;
        RangeSentry = Sentry.TravelSentry;
        while (I--)
        {
            RangeSentry = RangeSentry + Sew;
            if (*RangeSentry != 0 && *RangeSentry != *Sentry.TravelSentry)
                return FALSE;
        }
        break;
    case DOWN:
    case RIGHT:
        Sew = Player_Input == DOWN ? (SIZE + 1) : 1;
        I = (Sentry.TravelSentry - Sentry.CheckSentry) / Sew;
        RangeSentry = Sentry.CheckSentry;
        while (I--)
        {
            RangeSentry = RangeSentry + Sew;
            if (*RangeSentry != 0 && *RangeSentry != *Sentry.CheckSentry)
                return FALSE;
        }
        break;
    default:
        break;
    }
    return OK;
}

static status SentryInitialize(int Player_Input, SentryDouble *Sentry, int i)
{
    switch (Player_Input)
    {
    case UP:
        Sentry->TravelSentry = Sentry->CheckSentry = &Map[1][i];
        break;
    case LEFT:
        Sentry->TravelSentry = Sentry->CheckSentry = &Map[i][1];
        break;
    case DOWN:
        Sentry->TravelSentry = Sentry->CheckSentry = &Map[SIZE][SIZE - i + 1];
        break;
    case RIGHT:
        Sentry->TravelSentry = Sentry->CheckSentry = &Map[SIZE - i + 1][SIZE];
        break;
    default:
        break;
    }
    return OK;
}

static status GAME_XPartDataDeal(int Player_Input, SentryDouble *Sentry, int i)
{
    SentryInitialize(Player_Input, Sentry, i); //哨兵初始化

    Map_2048 *ExSentry;
    ExSentry = (Player_Input == LEFT ? (&Map[i][SIZE]) : (&Map[SIZE - i + 1][1])); //塔
    int Sew = Player_Input == LEFT ? 1 : -1;                                       //缀

    while ((*Sentry->TravelSentry == 0) && (Sentry->TravelSentry != ExSentry)) //排除零
        Sentry->CheckSentry = Sentry->TravelSentry = Sentry->TravelSentry + Sew;
    

    while (Sentry->TravelSentry != ExSentry)
    {
        Sentry->CheckSentry = Sentry->TravelSentry;
        while (Sentry->CheckSentry != ExSentry)
        {
            CheckSentryDeal(Player_Input, Sentry);
        }
        Sentry->TravelSentry = Sentry->TravelSentry + Sew;
    }
    return OK;
}

static status GAME_YPartDataDeal(int Player_Input, SentryDouble *Sentry, int i)
{
    SentryInitialize(Player_Input, Sentry, i); //哨兵初始化
    Map_2048 *ExSentry;

    ExSentry = (Player_Input == UP ? &Map[SIZE][i] : &Map[1][SIZE - i + 1]); //塔
    int Sew = (Player_Input == UP ? (SIZE + 1) : -(SIZE + 1));               //缀

    while ((*Sentry->TravelSentry == 0) && (Sentry->TravelSentry != ExSentry)) //排除零
        Sentry->CheckSentry = Sentry->TravelSentry = Sentry->TravelSentry + Sew;
    while (Sentry->TravelSentry != ExSentry)
    {
        Sentry->CheckSentry = Sentry->TravelSentry;
        while (Sentry->CheckSentry != ExSentry)
            CheckSentryDeal(Player_Input, Sentry);
        Sentry->TravelSentry = Sentry->TravelSentry + Sew;
    }
    return OK;
}

static status DataMerge(SentryDouble *Sentry)
{
    *Sentry->TravelSentry = (*Sentry->TravelSentry) * 2;
    *Sentry->CheckSentry = HIDE;
    return OK;
}

static status DataReorganize(int Player_Input)
{
    SentryDouble Sentry;
    Map_2048 *ExSentry; //塔
    int Sew;            //缀
    for (int i = 1; i <= SIZE; i++)
    {
        if (Player_Input == LEFT || Player_Input == RIGHT)
        {
            ExSentry = (Player_Input == LEFT ? &Map[i][SIZE] : &Map[SIZE - i + 1][1]); //塔
            Sew = (Player_Input == LEFT ? 1 : -1);                                     //缀
        }
        else if (Player_Input == UP || Player_Input == DOWN)
        {
            ExSentry = (Player_Input == UP ? &Map[SIZE][i] : &Map[1][SIZE - i + 1]); //塔
            Sew = (Player_Input == UP ? SIZE + 1 : -(SIZE + 1));                     //缀
        }
        SentryInitialize(Player_Input, &Sentry, i);
        while (Sentry.TravelSentry != ExSentry)
        {
            if (*Sentry.TravelSentry == 0)
            {
                Sentry.CheckSentry = Sentry.TravelSentry;
                while (Sentry.CheckSentry != ExSentry)
                {
                    Sentry.CheckSentry = Sentry.CheckSentry + Sew;
                    if (*Sentry.CheckSentry != 0)
                    {
                        *Sentry.TravelSentry = *Sentry.CheckSentry;
                        *Sentry.CheckSentry = 0;
                        break;
                    }
                }
            }
            Sentry.TravelSentry = Sentry.TravelSentry + Sew;
        }
    }
    return OK;
}

static status Node_Beautiy(int i, int j, int color)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
    for (int w = 1; w <= 3; w++)
    {
        _SetPos(2 + 6 * i, w + 3 * j);
        w == 2 ? printf("%4d  ", Map[j + 1][i + 1]) : printf("      ");
    }
    return OK;
}

static status GAME_DataShow()
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            switch (Map[j + 1][i + 1])
            {
            case 2:
                Node_Beautiy(i, j, 191);
                break;
            case 4:
                Node_Beautiy(i, j, 159);
                break;
            case 8:
                Node_Beautiy(i, j, 175);
                break;
            case 16:
                Node_Beautiy(i, j, 223);
                break;
            case 32:
                Node_Beautiy(i, j, 207);
                break;
            case 64:
                Node_Beautiy(i, j, 71);
                break;
            case 128:
                Node_Beautiy(i, j, 143);
                break;
            case 256:
                Node_Beautiy(i, j, 63);
                break;
            case 512:
                Node_Beautiy(i, j, 31);
                break;
            case 1024:
                Node_Beautiy(i, j, 79);
                break;
            case 2048:
                Node_Beautiy(i, j, 78);
                break;
            case 0:
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 255);
                _SetPos(2 + 6 * i, 1 + 3 * j);
                printf("      ");
                _SetPos(2 + 6 * i, 2 + 3 * j);
                printf("      ");
                _SetPos(2 + 6 * i, 3 + 3 * j);
                printf("      ");
                break;
            default:
                break;
            }
        }
    }
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
    return OK;
}

static status GAME_DataTowerDeal()//
{
    int j, i;
    for (i = 1; i <= SIZE; i++)
    {
        for (j = 1; j <= SIZE; j++)
            if (!Map[i][j])
                break;
        if (j == SIZE + 1)
            Map[i][TOWER] = 1;
        else
            Map[i][TOWER] = 0;
    }

    for (i = 1; i <= SIZE; i++)
    {
        for (j = 1; j <= SIZE; j++)
            if (!Map[j][i])
                break;
        if (j == SIZE + 1)
            Map[TOWER][i] = 1;
        else
            Map[TOWER][i] = 0;
    }
    for (i = 1; i <= SIZE; i++)
        if (!Map[i][TOWER] || !Map[TOWER][i])
            break;
    Map[TOWER][TOWER] = (i == SIZE + 1 ? 1 : 0);
    return OK;
}

static status GAME_PLAY()
{
    system("mode con cols=28 lines=17 ");
    char Player_inPut;
    HidePos();
    GAME_DataInitialize();
    int Player_Input, count = 0;
    for (int i = 0; i <= SIZE; i++)
        for (int j = 0; j <= SIZE; j++)
            Map[i][j] = HIDE;
    for (int i = 0; i < 3; i++) //初始化
        GAME_DataCreate();
    GAME_DataShow();
    _SetPos(0, 14);
    printf("                                  ");
    _SetPos(0, 15);
    printf("                                  ");
    while (1)
    {
        HidePos();
        _SetPos(0, 14);
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
        printf("得分:%5d ", count);
        printf("重开:R");
        HidePos();
    InputAgain:
        Player_Input = _getch();
        if (Player_Input == 224)
            Player_Input = _getch();
        else if (Player_Input == (int)'R' || Player_Input == (int)'r')
            main();
        else
            goto InputAgain;

        GAME_DataDeal(Player_Input);
        DataReorganize(Player_Input);
        GAME_DataTowerDeal();
        GAME_DataShow();

        Sleep(100);
        GAME_DataCreate();
        GAME_DataTowerDeal();
        GAME_DataShow();

        if (GAME_OverJudge() == 1)
            break;
        else if (!GAME_OverJudge())
            count++;
        HidePos();
    }
    _SetPos(0, 15);
    printf("游戏结束 ");
    printf("是否再来一次?(Y)/(N)");
Again:
    Player_inPut = getchar();
    if (Player_inPut == 'Y' || Player_inPut == 'y')
        main();
    else if (Player_inPut == 'N' || Player_inPut == 'n')
        return OK;
    else
        goto Again;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值