GIF 2020-11-6 12-57-11.gif

去年年底写的代码,有点意思

一些控制台函数

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;                    //设置控制台用的

void windows_init()
{
    GetConsoleCursorInfo(hOut, &CursorInfo);        //获取控制台光标信息
    CursorInfo.bVisible = false;            //隐藏控制台光标
    SetConsoleCursorInfo(hOut, &CursorInfo);        //设置控制台光标状态

    srand(time(0));
}

void myprint(int y, int x, char colo,char color, const char* p)//
{
    COORD pos = { x,y };
    SetConsoleCursorPosition(hOut, pos);
    SetConsoleTextAttribute(hOut, colo+(color*0x10));
    printf(p);
}
char get_key()                    //获得按键键值
{
    char a;
    if (_kbhit() == 1)            //由于单使用 _getch()会导致程序堵塞,所以用先用_kbhit()获得是否有按键按下
    {
        a = _getch();
        return a;
    }
    return 0;

}

long HAL_GetTick()
{
    return clock();

}

void HAL_Delay(long a)
{
    long b;
    b = HAL_GetTick() + a;
    while (b> HAL_GetTick());

}

主程序

int map[4][4] =   //棋盘
{
    {0,2,4,8,},
    {16,32,64,128,},
    {256,512,1024,2048,},
    {4096,8192,0,0,},
};
int colo_tab[14] =//颜色表
{
    0,
    blue| hig,
    green| hig,
    red|hig,
    yellow|hig,
    lightblue|hig,
    purple|hig,
    white|hig,
    blue,
    green,
    red,
    yellow,
    lightblue,
    purple,

};

int dpow(int d)//计算颜色表中的第几个颜色 
{
    int a;
    if (d == 0)
    {
        return 0;
    }
    for (a = 0; a < 14; a++)
    {
        if (pow(2, a) == d)
        {
            return a;
        }
    }

}


void dis_map()
{
    char y = 0, x = 0;
    int z;
    char buff[7];
    for (y = 0; y < 4; y++)
    {
        for (x = 0; x < 4; x++)
        {
            z = map[y][x];
            sprintf(buff,"% 5d", z);
            myprint((y * 3), x * 5, 0, colo_tab[dpow(z)], "     ");
            myprint((y * 3) + 1, x * 5, 0, colo_tab[dpow(z)], buff);
            myprint((y * 3)+2, x * 5, 0, colo_tab[dpow(z)], "     ");
        }
    }
    for (y = 0; y < 12; y++)
    {
        myprint(y, 20, white, 0, "|");
    }
    myprint(12, 0, white, 0, "---------------------");

}

#define random(x) (rand()%x)//定义随机数范围
int game_mod = 0;           //游戏模式
char ch;                    //按键状态
unsigned int best = 0, score = 0;//分数
char move_jc_buff = 0;        //是否可以移动
void clear_map()                 //清空棋盘
{
    char y, x;
    for (y = 0; y < 4; y++)
    {
        for (x = 0; x < 4; x++)
        {
            map[y][x] = 0;
        }
    }
}
unsigned int move(char dir)        //返回值最高位为1表示可以移动   剩下的位表示移动的分数
{
    char move_flag = 0;            //移动标志
    int y = 0, x = 0, y2, x2;
    unsigned int fs = 0;            //分数

    //一共4个方向
    if (dir == uu)             //向上
    {
        for (x = 0; x < 4; x++)            //从左往右扫描
        {
            for (y = 0; y < 4; y++)        //从上往下扫描
            {
                if (map[y][x] != 0)        //如果扫到不为空
                {
                    y2 = y;             //避免改变y
                    while (((y2 - 1) >= 0))            //扫描这一条  直到碰边                     
                    {
                        if ((map[y2 - 1][x] == 0))     //如果往上的一个位置是空的 
                        {
                            map[y2 - 1][x] = map[y2][x];//把当前的向上移
                            map[y2][x] = 0;                //清空当前
                            move_flag = 1;              //成功移动了
                        }
                        if (map[y2 - 1][x] == map[y2][x])//如果当前与往上一个位置是相等的
                        {
                            map[y2 - 1][x] = map[y2][x] + map[y2 - 1][x];//加起来
                            fs = fs + map[y2 - 1][x];                    //分数加上
                            map[y2][x] = 0;                                //清空当前
                            move_flag = 1;                                //成功移动了
                        }

                        y2 -= 1;                                        //扫描下一格
                    }
                }
            }


        }
    }
    if (dir == dd)
    {
        for (x = 0; x < 4; x++)
        {
            for (y = 3; y >= 0; y--)
            {
                if (map[y][x] != 0)
                {
                    y2 = y;
                    while (((y2 + 1) <= 3))
                    {
                        if ((map[y2 + 1][x] == 0))
                        {
                            map[y2 + 1][x] = map[y2][x];
                            map[y2][x] = 0;
                            move_flag = 1;
                        }
                        if (map[y2 + 1][x] == map[y2][x])
                        {
                            map[y2 + 1][x] = map[y2][x] + map[y2 + 1][x];
                            fs = fs + map[y2 + 1][x];
                            map[y2][x] = 0;
                            move_flag = 1;
                        }

                        y2 += 1;
                    }
                }
            }


        }
    }
    if (dir == ll)
    {
        for (y = 0; y < 4; y++)
        {
            for (x = 0; x < 4; x++)
            {
                if (map[y][x] != 0)
                {
                    x2 = x;
                    while (((x2 - 1) >= 0))
                    {
                        if ((map[y][x2 - 1] == 0))
                        {
                            map[y][x2 - 1] = map[y][x2];
                            map[y][x2] = 0;
                            move_flag = 1;
                        }
                        if (map[y][x2 - 1] == map[y][x2])
                        {
                            map[y][x2 - 1] = map[y][x2] + map[y][x2 - 1];
                            fs = fs + map[y][x2 - 1];
                            map[y][x2] = 0;
                            move_flag = 1;
                        }

                        x2 -= 1;
                    }
                }
            }


        }
    }
    if (dir == rr)
    {
        for (y = 0; y < 4; y++)
        {
            for (x = 3; x >= 0; x--)
            {
                if (map[y][x] != 0)
                {
                    x2 = x;
                    while (((x2 + 1) <= 3))
                    {
                        if ((map[y][x2 + 1] == 0))
                        {
                            map[y][x2 + 1] = map[y][x2];
                            map[y][x2] = 0;
                            move_flag = 1;
                        }
                        if (map[y][x2 + 1] == map[y][x2])
                        {
                            map[y][x2 + 1] = map[y][x2] + map[y][x2 + 1];
                            fs = fs + map[y][x2 + 1];
                            map[y][x2] = 0;
                            move_flag = 1;
                        }

                        x2 += 1;
                    }
                }
            }


        }
    }
    if (move_flag == 1)
    {
        fs |= 0x8000;            //如果移动了把返回值分数的最高位置一
    }
    else
    {
        fs &= ~0x8000;
    }

    return fs;
}

char move_jc()            //检测是否可以移动
{
    char y, x, a, e = 0;
    int map_buff[4][4];
    char move_tab[4] =      //方向表
    {
        uu,
        dd,
        ll,
        rr,
    };
    for (y = 0; y < 4; y++)//先备份当前棋盘
    {
        for (x = 0; x < 4; x++)
        {
            map_buff[y][x] = map[y][x];
        }
    }
    for (a = 0; a < 4; a++)                //检测4个方向
    {
        if (move(move_tab[a]) & 0x8000)//最高位为1移动成功
        {
            e = 1;                        //标记置一
            break;                        //跳出for
        }
    }
    for (y = 0; y < 4; y++)                //还原棋盘
    {
        for (x = 0; x < 4; x++)
        {
            map[y][x] = map_buff[y][x];
        }
    }
    return e;                            //返回结果

}

void rand_dot()                            //随机放一个2
{
    char y, x;
    do
    {
        x = random(4);                    //获得随机数范围0-4
        y = random(4);
    } while (map[y][x]);                    //坐标不合法 再获一次
    map[y][x] = 2;                        //坐标合法 放2
}

int main()
{
    windows_init();
    unsigned int jg;
    char buff[10];
    while (1)
    {
        ch = get_key();                                    //获取键值
        switch (game_mod)
        {
        case 0:
            if (ch == space)                            //如果空格被按下
            {
                clear_map();                            //清空棋盘
                map[2][3] = 2;                            //2默认初始位置
                srand((int)time(0));                    //设置随机数种子
                game_mod = 1;                            //游戏开始
            }
            break;
        case 1:
            move_jc_buff = move_jc();                    //获取是否还能移动
            if (move_jc_buff == 0)                        //如果不能移动游戏结束
            {
                game_mod = 2;                            //游戏结束
            }
            else
            {
                if (ch ==uu|| ch == dd || ch == ll || ch == rr)                            //否则判断是否有按键按下
                {
                    jg = move(ch);                        //获取移动结果
                    if (jg & 0x8000)                    //如果move的返回值最高位为1 成功移动
                    {
                        jg &= ~0x8000;                    //去掉最高位的1
                        score += jg;                    //加给分数
                        rand_dot();                        //随机坐标给一个2

                    }
                }
            }
            break;
        case 2:
            if (ch == space)                            //按下空格
            {
                if (score > best)                        //如果破纪录了
                {
                    best = score;                        //更新最高记录
                }
                score = 0;                                //当前分数清零
                game_mod = 0;                            //回到欢迎界面
            }
            break;
        case 3:

            break;
        default:
            break;
        }
        myprint(13,0,white,0,"2048小游戏,空格开始");
        sprintf(buff, "当前分数:%05d", score);
        myprint(14, 0, white, 0, buff);
        sprintf(buff, "最高分数:%05d", best);
        myprint(15, 0, white, 0, buff);
        myprint(18, 0, white, 0, "吴文峰   2019-12-12");
        dis_map();
    }
    

}

最后修改:2020 年 11 月 06 日
声明:无闻风博客|版权所有,违者必究|如未注明,均为原创| 转载:转载请注明原文链接