精华内容
下载资源
问答
  • C++控制台小游戏

    千次阅读 2020-02-12 14:32:25
        使用C++编写一些简单怀旧的小游戏,没有实现其中的玩法之类的,只实现核心功能 运行说明 运行平台是Windows     下载压缩包或者使用git都行,完成后使用clion(其他支持cmake工程的也行,环境需要配置好,...

    游戏入门编程-C++


    简介

        使用C++编写一些简单怀旧的小游戏,没有实现其中的玩法之类的,只实现核心功能

    运行说明

    运行平台是Windows

        下载压缩包或者使用git都行,完成后使用clion(其他支持cmake工程的也行,环境需要配置好,visual studio应该可以),加载工程进行运行即可

    git clone https://github.com/lw1243925457/LearnGameC.git
    

        环境配置可以稍微参考下这个:https://github.com/lw1243925457/LOG/blob/master/profession/program/C%2B%2B/windows%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE.md

    游戏目录

    • 数字雨(电影中的窗口一大堆看不懂的东西,比较酷,就简单模拟一个)
    • 推箱子
    • 贪吃蛇
    • 俄罗斯方块(使用特殊符号容易乱码,也不好处理,就简单使用了*和#,看着有点眼花…)
    • 太空射击(暂无死亡)

    数字雨

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uMWmr08a-1581489036627)(./picture/codeRain.png)]

    推箱子

    • 简介:

      • 简单的推箱子游戏,将所有箱子推到目的地即可
    • 游戏符号标记:

      • 障碍物:#
      • 主角:*
      • 箱子:$
      • 目的地:@
      • 箱子+目的地:!
      • 人物+目的地: R
    • 游戏控制:

      • 上下左右键进行移动控制

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lRMi600Q-1581489036629)(./picture/box.gif)]

    贪吃蛇

    • 简介:

      • 贪吃蛇游戏,吃豆子变长
    • 游戏符号标记:

      • 障碍物:#
      • 蛇头:0
      • 蛇身:o
      • 豆子:*
    • 游戏控制:

      • 上下左右键进行移动控制
      • 空格开始游戏

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I2jqBHdH-1581489036629)(./picture/snake.gif)]

    俄罗斯方块

    • 简介:

      • 俄罗斯方块
    • 游戏符号标记:

      • 障碍物:#
      • 方块:*
    • 游戏控制:

      • 下左右键进行移动控制
      • 空格进行变换

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yu4A0JO9-1581489036630)(./picture/tetris.gif)]

    太空射击

    • 简介:

      • 太空射击,简单的射击类游戏
    • 游戏符号标记:

      • 主角:A
      • 子弹:I
      • 敌机:V
    • 游戏控制:

      • 下左右键进行移动控制
      • 空格进行射击

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SOCoEpLn-1581489036630)(./picture/shot.gif)]

    编写过程中的参考链接

    • C/C++获取系统时间戳,精确到毫秒:https://blog.csdn.net/liyunlong41/article/details/76933575

    • C++写一个限时输入功能,超过时间执行其他操作:https://blog.csdn.net/dulingmo/article/details/81077071

    • CLion 输出遇到乱码解决办法:https://blog.csdn.net/Cbk_XLL/article/details/78752534

    • win10 Clion debug 使用 cmd控制台:https://blog.csdn.net/qq_32767041/article/details/

    • C++ 中的容器类详解:https://blog.csdn.net/tju_fengbo/article/details/81978595

    • C语言 双缓冲控制台防闪屏技术:https://blog.csdn.net/weixinhum/article/details/72179593

    • 控制台双缓冲技术:https://www.cnblogs.com/xdblog/p/4783364.html

    • C程序之修改Windows的控制台大小:https://www.cnblogs.com/iloverain/p/5642588.html

    • C语言/C++程序员大神打造炫酷的黑客帝国数字雨:https://www.jianshu.com/p/4dde809eb039

    • C/C++实现控制台输出不同颜色字体的方法:https://www.jb51.net/article/124054.htm

    • C++更改控制台(SetConsoleTextAttribute)的输出的颜色:https://blog.csdn.net/TweeChalice/article/details/96496625

    • 在平面中,一个点绕任意点旋转θ度后的点的坐标:https://www.cnblogs.com/fengliu-/p/10944151.html

    • 俄罗斯方块的相关算法:https://zhuanlan.zhihu.com/p/32122479

    • 如何在VC 6.0 上输出特殊符号比如一个黑色的实心方块:https://blog.csdn.net/ahuang1900/article/details/8948672

    展开全文
  • C++控制台小游戏及其源代码 数组地图,简单AI,简单特效。
  • 这是一个C++控制台小游戏,你控制一台坦克,需要突破所有的障碍物并找到出口,具有一定的创新性与可玩性,有关卡设置,界面友好。 这个项目运用了类、封装、继承、数组、坐标、键盘控制等知识,有所有源代码,有参考...
  • C++控制台小游戏*67

    2019-05-09 12:58:54
    C++游戏整合‾\large\color{Darkblue}\underline\texttt{C++游戏整合}C++游戏整合​ 更新至68个游戏‾\large\color{Darkblue}\underline\texttt{更新至68个游戏}更新至68个游戏​ 说明: 该游戏整合里的游戏不是我做...

    C++游戏整合\large\color{Darkblue}\underline\texttt{C++游戏整合}

    更新至68个游戏\large\color{Darkblue}\underline\texttt{更新至68个游戏}

    说明:

    该游戏整合里的游戏不是我做的,是我多年搜集出来,方便大家游玩的,全是C++游戏,感兴趣的话,可以加入团队,实时更新哦。

    下载:

    百度网盘 提取码: 9qyq


    腾讯微云


    QQ(贼快)


    csdn


    制作环境:WIN 10 64位

    抵制不良游戏,拒绝盗版游戏。\large\color{orange}\text{抵制不良游戏,拒绝盗版游戏。}
    注意自我保护,谨防受骗上当。\large\color{orange}\text{注意自我保护,谨防受骗上当。}
    适度游戏益脑,沉迷游戏伤身。\large\color{orange}\text{适度游戏益脑,沉迷游戏伤身。}
    合理安排时间,享受健康生活。\large\color{orange}\text{合理安排时间,享受健康生活。}

    制作团队:

    展开全文
  • 我们肯定能想到的是游戏界面的绘制,游戏的键盘控制,游戏逻辑。 游戏逻辑中包括数字的生成,合并,分数计算,以及游戏结束的判断。 棋盘是 4 x 4 的,且只需要显示数字,这可以用一个int数组来表示。

    原创不易,请勿抄袭
    作者联系方式 : QQ:993678929


    0.游戏界面展示

    在这里插入图片描述
    在这里插入图片描述


    1. 编写思路

    动手写代码之前,先设计好要做哪些部分。下面所述的是我个人的思路,如果有更好的思路欢迎探讨。

    我们肯定能想到的是游戏界面的绘制,游戏的键盘控制,游戏逻辑。

    游戏逻辑中包括数字的生成,合并,分数计算,以及游戏结束的判断。

    棋盘是 4 x 4 的,且只需要显示数字,这可以用一个int数组来表示。

    游戏过程中用户移动之后生成数字,需要注意这个次序

    合并的顺序是按移动的逆方向来合并,而且一次移动只会合并一次。
    比如有一行是4 2 2 2
    那么向右划(移动)的结果是0 4 2 4
    向左划的结果是4 4 2 0

    不同的数字可以使用不同的颜色来显示方便辨识,提高玩家的游戏体验

    后续还可以推出联网天梯排行榜


    2. 界面绘制

    我们可以专门写一个函数来绘制游戏界面,这样每次刷新的时候调用一次就行了。
    首先定义一个4x4的“棋盘”来存放场面上的数字:

    const int W = 4;
    const int H = 4;
    int board[H][W];  //H:高  W:宽   board[2][1] 表示第二行第二个
    

    之前提到我们可以使用不同的颜色来显示不同的数字,以提高辨识度。

    定义一个颜色数组,这样对于棋盘上的数字i,color[log2(i)-1],就能得到他的颜色代码:

    const int color[] = {15,8,6,14, 4, 2,12 ,5,  13, 3,   10,  11,  1,   9, };
    //分别对应 //2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384
    

    比如数字8,取 log2(8) - 1 = 2 ,颜色代号是6,对应黄色

    然后写上设置文本颜色的函数

    void Set_Color(int color)
    {
        HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
    }
    

    关于这个具体的解释可以参考我的另一篇博客 控制台输出彩色文本

    接下来写display函数

    void display()
    {
        system("cls");  //调用cmd清屏
        for (int i = 0; i < H; i++)
        {
            for (int j = 0; j < W; j++)
            {
                if (board[i][j] == 0) printf("     ");
                else {
                    Set_Color(color[ (int)log2(board[i][j])-1 ]); //根据数字设置颜色
                    printf("%-5d", board[i][j]);
                    Set_Color(7);
                }if (j < 3) putchar('|');
            }
            putchar('\n');
            for (int r = 0; r < 23; r++) putchar('-');
            putchar('\n');
        }
        printf("当前得分: %d",score);
    }
    
    

    很简单,只需要遍历一下4x4的board数组依次打印出里面的数字即可。
    打印每个数字之前使用Set_Color(color[ (int)log2(board[i][j])-1 ]); 设置一下其专属颜色即可
    printf("%-5d", board[i][j]); 表示左对齐的格式化输出,数字宽度为5,长度不足5的数字用空格在右边补齐,以此来保证我们用-|画的格子是整齐的
    最后显示一下当前的得分,这个score的累加规则下一节会写到。


    3.数字的生成与合并

    这是2048最核心的部分。首先我们来考虑相对简单的数字生成。
    这里我们只生成2,2048经典版是10%的概率生成4,90%的概率生成2
    首先我们肯定得在空白的地方生成,也就是board数组中为0的位置
    遍历一遍,如果是0就n++,统计有多少个空格子。统计完之后我们只需要生成一个1~n的随机数就可以决定在哪个空格子里生成2
    这里也可以把空格子的位置记录下来,就不需要第二次遍历了,但是考虑到最多只有16个格子,我这里就直接遍历了:

    void newNum()
    {
        int flag = 0;
        int n = 0;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                if (board[i][j] == 0)
                    n++;
                    
        srand((unsigned)time(NULL));
        if (n == 0) return;
        int end = rand() % n;
        int t = 0;
        for (int i = 0; i < 4 && !flag; i++)
            for (int j = 0; j < 4 && !flag; j++)
            {
                if (board[i][j] == 0)
                {
                    if (t == end) {
                        board[i][j] += 2;
                        flag = 1;
                    }
                    else t++;
                    
                }
            }
    }
    
    

    这里t是从0开始的,因为rand()%n返回的是0~n-1的数字,如果t从1开始那么第n个数会对不上。
    因为可能出现场面上数字满了但是还没结束游戏(还有能合并的数字)的情况,所以一定得判断n是否等于0:if (n == 0) return;,不然对0取模会引发异常。

    然后就是数字的合并了。
    这里我为了省事引入dx和dy数组来表示纵向和横向的移动:

    const int dx[4] = { -1,1,0,0 };  //依次对应上下左右
    const int dy[4] = {  0,0,-1,1 };
    

    我们可以观察一下2048合并的规律:
    如果你按下右键,所有的数字向右移动,然后按从右往左的顺序合并,且一次移动不会合并多次(不会出现4 2 2移动一次就变成8)
    可见我们需要反向遍历:如果是向右移动,那么从最右边开始往左找,对每个格子重复以下操作:
    如果当前数字不为0,且右边没有数字可以合并但是还有空位,则移动到空位。
    如果当前数字不为0,且右边有数字可以合并,则合并(当前格子置为0,合并的格子翻倍),这里做完要继续往左边走并且把上一次合并的位置设置为底部,即不能再次合并了
    按照以上逻辑我们很容易写出控制合并的函数:

    void move(int dir)
    {
        int x=0,y=0;
        if (dy[dir]) //水平移动
        {
            for (int i = 0; i < H; i++) //遍历每一行
            {
                y = (dy[dir] == 1) ? 3 : 0;
                int j = y;
                int top = y;
                while (abs(j - y) < 3) {
                    j -= dy[dir];
                    if (board[i][top] == 0 &&board[i][j]!=0)
                    {
                        board[i][top] = board[i][j];
                        board[i][j] = 0;
                    }
                    else if (board[i][top]!=0 && board[i][j]==board[i][top])
                    {
                        board[i][top] *= 2;
                        score += board[i][top];
                        board[i][j] = 0;
                    }
                    else if (board[i][top] * board[i][j] != 0 && board[i][top] != board[i][j])
                    {
                        top -= dy[dir];
                        if (j != top)
                        {
                            board[i][top] = board[i][j];
                            board[i][j] = 0;
                        }
                    }
                }
    
            }
        
        }
        else if (dx[dir]) //垂直移动
        {
            for (int j = 0; j < W; j++) //遍历每一列
            {
                x = (dx[dir] == 1) ? 3 : 0;
                int i = x;
                int top = x;
                while (abs(i - x) < 3) {
                    i -= dx[dir];
                    if (board[top][j] == 0 && board[i][j] != 0)
                    {
                        board[top][j] = board[i][j];
                        board[i][j] = 0;
                    }
                    else if (board[top][j] != 0 && board[i][j] == board[top][j])
                    {
                        board[top][j] *= 2;
                        score += board[top][j];
                        board[i][j] = 0;
                    }
                    else if (board[top][j] * board[i][j] != 0 && board[top][j] != board[i][j])
                    {
                        top -= dx[dir];
                        if (i != top)
                        {
                            board[top][j] = board[i][j];
                            board[i][j] = 0;
                        }
                    }
                }
    
            }
    
        }
            
    }
    
    

    传入的参数dir是读取键盘按键识别来的,下一节会提到。
    y = (dy[dir] == 1) ? 3 : 0; 是找到遍历的起点,如果是向右移动则是找最右边也就是3,向左移动是0
    top变量记录当前的底部,来方便数字的移动,并且能防止多次合并。
    因为我使用的是dx和dy,所以垂直和水平方向的移动需要分别写出来。
    也可以用一个二维数组代替dx和dy来表示四个方向的单位位移,这样就只需要写一遍。
    score存储的是当前得分,积分规则是2+2=4,则加4分,加上合并出的数字的值


    4.键盘控制 / 游戏主循环

    因为2048不需要快速而频繁的键盘操作,我们使用_getch函数即可(如果需要快速低延迟的按键读取,则可以使用GetAsyncKeyState函数,可以参考#部分完整代码中注释掉的宏函数)
    为了方便我定义了一个keymap数组来储存四个方向键对应的值:

    const int keymap[4] = {72,80,75,77}; //依次为上下左右
    

    按照游戏的流程:生成数字->显示->玩家键盘按键->移动,合并数字为一个周期,不停的重复直到判定游戏结束为止即可

    void play()
    {
        newNum();
        display();
        while (true)
        {
            
            int ch = _getch();
            for (int i = 0; i < 4; i++)
                if (ch == keymap[i]) {
                move(i); 
                if(judge())
                	return;
                newNum();
                display();
            }
            Sleep(10);     //防止连按
        }
    }
    

    注意这里判断游戏是否结束应该在生成数字前判断


    5.游戏结束判定

    只要场面上没有空格子或者能合并的格子(相邻格子数字相等), 那么遍历找这两种情况就行了,如果没找到就是游戏结束了。

    bool judge()   //0:ok  1:gameover
    {
       
        for (int i = 0; i < H; i++)
            for (int j = 0; j < W; j++)
            {
                if (board[i][j] == 0)
                    return false;
                
                else if(i<3 && j<3)
                    if (board[i][j] == board[i + 1][j] || board[i][j]==board[i][j+1])
                        return false;
                   
            }
        return true;
    }
    

    #.完整代码

    #include <iostream>
    #include <windows.h>
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <time.h>
    
    //#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
    
    const int W = 4;
    const int H = 4;
    int board[H][W];  //H:高  W:宽   board[2][1] 表示第二行第二个
    int score;
    const int keymap[4] = {72,80,75,77}; //依次为上下左右
    const int dx[4] = { -1,1,0,0 };  //依次对应上下左右
    const int dy[4] = {  0,0,-1,1 };
                                            
                        //2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384  (超过这个数字的从头开始)
    const int color[] = {15,8,6,14, 4, 2,12 ,5,  13, 3,   10,  11,  1,   9, };
    
    /*  颜色说明:
     * 0 = 黑色       8 = 灰色
     * 1 = 蓝色       9 = 淡蓝色
     * 2 = 绿色       10 = 淡绿色
     * 3 = 浅绿色     11 = 淡浅绿色
     * 4 = 红色       12 = 淡红色
     * 5 = 紫色       13 = 淡紫色
     * 6 = 黄色       14 = 淡黄色
     * 7 = 白色       15 = 亮白色
     */
    bool judge()   //0:ok  1:gameover
    {
       
        for (int i = 0; i < H; i++)
            for (int j = 0; j < W; j++)
            {
                if (board[i][j] == 0)
                    return false;
                
                else if(i<3 && j<3)
                    if (board[i][j] == board[i + 1][j] || board[i][j]==board[i][j+1])
                        return false;
                   
            }
        return true;
    }
    
    void Set_Color(int color)
    {
        HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
    }
    
    void display()
    {
        system("cls");
        for (int i = 0; i < H; i++)
        {
            for (int j = 0; j < W; j++)
            {
                if (board[i][j] == 0) printf("     ");
                else {
                    Set_Color(color[ (int)log2(board[i][j])-1 ]); //根据数字设置颜色
                    printf("%-5d", board[i][j]);
                    Set_Color(7);
                }if (j < 3) putchar('|');
            }
            putchar('\n');
            for (int r = 0; r < 23; r++) putchar('-');
            putchar('\n');
        }
        printf("当前得分: %d",score);
    }
    
    
    void move(int dir)
    {
        int x=0,y=0;
        if (dy[dir]) //水平移动
        {
            for (int i = 0; i < H; i++) //遍历每一行
            {
                y = (dy[dir] == 1) ? 3 : 0;
                int j = y;
                int top = y;
                while (abs(j - y) < 3) {
                    j -= dy[dir];
                    if (board[i][top] == 0 &&board[i][j]!=0)
                    {
                        board[i][top] = board[i][j];
                        board[i][j] = 0;
                    }
                    else if (board[i][top]!=0 && board[i][j]==board[i][top])
                    {
                        board[i][top] *= 2;
                        score += board[i][top];
                        board[i][j] = 0;
                    }
                    else if (board[i][top] * board[i][j] != 0 && board[i][top] != board[i][j])
                    {
                        top -= dy[dir];
                        if (j != top)
                        {
                            board[i][top] = board[i][j];
                            board[i][j] = 0;
                        }
                    }
                }
    
            }
        
        }
        else if (dx[dir]) //垂直移动
        {
            for (int j = 0; j < W; j++) //遍历每一列
            {
                x = (dx[dir] == 1) ? 3 : 0;
                int i = x;
                int top = x;
                while (abs(i - x) < 3) {
                    i -= dx[dir];
                    if (board[top][j] == 0 && board[i][j] != 0)
                    {
                        board[top][j] = board[i][j];
                        board[i][j] = 0;
                    }
                    else if (board[top][j] != 0 && board[i][j] == board[top][j])
                    {
                        board[top][j] *= 2;
                        score += board[top][j];
                        board[i][j] = 0;
                    }
                    else if (board[top][j] * board[i][j] != 0 && board[top][j] != board[i][j])
                    {
                        top -= dx[dir];
                        if (i != top)
                        {
                            board[top][j] = board[i][j];
                            board[i][j] = 0;
                        }
                    }
                }
    
            }
    
        }
            
    }
    
    void newNum()
    {
        int flag = 0;
        int n = 0;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                if (board[i][j] == 0)
                    n++;
    
        srand((unsigned)time(NULL));
        if (n == 0) return;
        int end = rand() % n;
        int t = 0;
        for (int i = 0; i < 4 && !flag; i++)
            for (int j = 0; j < 4 && !flag; j++)
            {
                if (board[i][j] == 0)
                {
                    if (t == end) {
                        board[i][j] += 2;
                        flag = 1;
                    }
                    else t++;
                    
                }
            }
    }
    
    void play()
    {
        newNum();
        display();
        while (true)
        {
            
            int ch = _getch();
            for (int i = 0; i < 4; i++)
                if (ch == keymap[i]) {
                move(i);
                if (judge())
                    return;
                newNum();
                display();
            }
            Sleep(10);     //防止连按
        }
    
    }
    
    void init()
    {
        system("mode con:cols=24 lines=10");
        memset(board, 0, sizeof(board));
        score = 0;
    }
    
    int main()
    {
        init();
        play();
        system("cls");
        printf("\n\n\tGAME OVER!");
        printf("\n\n\tSCORE:%d", score);
        getchar();
    }
    
    
    展开全文
  • C++控制台RPG小游戏

    2018-06-05 21:04:03
    大学自己研究出来的一个带简单图形的控制台RPG小游戏,包括各种功能。 大学自己研究出来的一个带简单图形的控制台RPG小游戏,包括各种功能。 大学自己研究出来的一个带简单图形的控制台RPG小游戏,包括各种功能。 ...
  • C++控制台打飞机小游戏

    万次阅读 多人点赞 2019-10-24 17:26:22
    文章目录前言介绍 前言 我终于决定还是把这个放出来。...更多控制台操作可以看之前写的鼠标操作的文章,也可以直接在这个上面复制。 MinGW编译无错误无警告。 只有一个文件,没有任何其他的东西...

    前言

    我终于决定还是把这个放出来。

    介绍

    运行图
    具体信息主界面上都有写。

    按空格暂停,建议暂停后再升级属性。

    记录最高分的文件进行了加密。

    有boss。

    挺好玩的。

    可能有bug,不想改了,整体体验不错就行了。

    更多控制台操作可以看之前写的鼠标操作的文章,也可以直接在这个上面复制。

    MinGW编译无错误,只有lld输出的几个警告。
    编译图
    只有一个文件,没有任何其他的东西。

    可以直接扒下来编译。

    一开始写的时候打了很多注释,后来就不想打了。

    大家凑合着看吧,不清楚的就评论,如果我还记得到就答一下哈。

    对了,为了防止暂停作弊,暂停过后开始时鼠标会回到飞机的位置。


    这个代码我一个人可能总共肝了20多个小时,希望不要随意转载。注明出处就好。

    如果你能帮我改得更有趣,bug更少的话可以找我。


    更多内容看代码。


    我记不到这份代码是什么情况了,有可能是之前更新到一半的代码,反正我试着海星。

    代码

    #include<set>
    #include<cmath>
    #include<ctime>
    #include<cstdio>
    #include<cstdlib>
    #include<vector>
    #include<windows.h>
    #include<algorithm>
    #include<iostream>
    #include<conio.h>
    #include<fstream>
    using namespace std;
    
    #define fblack 0
    #define fblue 1
    #define fgreen 2
    #define fcyan 3
    #define fred 4
    #define fpurple 5
    #define fyellow 6
    #define fwhite 7
    #define fgray 8
    #define flight 8
    #define bblack 0
    #define bblue 16
    #define bgreen 32
    #define bcyan 48
    #define bfred 64
    #define bpurple 80
    #define byellow 96
    #define bwhite 112
    #define bgray 128
    #define blight 128
    #define dirkey -32
    #define upkey 72
    #define downkey 80
    #define leftkey 75
    #define rightkey 77
    #define wclear system("cls")
    #define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
    #define LL long long
    
    void flash(int times){
        while(times--){
            system("color 08");
            Sleep(300);
            system("color 80");
            Sleep(300);
        }
        //Sleep(1000);
        system("color 08");
    }
    void HindCursor(){
        HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
        CONSOLE_CURSOR_INFO CursorInfo;
        GetConsoleCursorInfo(handle,&CursorInfo);
        CursorInfo.bVisible=false;
        SetConsoleCursorInfo(handle,&CursorInfo);
    }
    struct Button{
        int x,y,color;
        const char *name;
        int len;
    };
    void GetPos(POINT &pt){
        HWND hwnd=GetForegroundWindow();
        GetCursorPos(&pt);
        ScreenToClient(hwnd,&pt);
        pt.y=pt.y/16,pt.x=pt.x/8;
        swap(pt.x,pt.y);
    }
    void color(int a){
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
    }
    void gto(int x,int y){
        COORD pos;pos.X=y;pos.Y=x;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
    }
    Button NewButton(int x,int y,int color,const char *name){
        Button t;
        t.x=x,t.y=y,t.name=name;
        t.color=color;
        t.len=strlen(name);
        return t;
    }
    bool Preserve(Button A){
        gto(A.x,A.y),color(A.color),printf("%s",A.name);
        POINT pt;
        GetPos(pt);
        if(pt.x==A.x&&(pt.y>=A.y&&pt.y<=A.y+A.len)){
            color(112),gto(A.x,A.y),printf("%s",A.name);
            if(KEY_DOWN(MOUSE_MOVED)) return 1;
        }
        return 0;
    }
    pair<int,int> GetXY(){
        HANDLE hStdout;
        CONSOLE_SCREEN_BUFFER_INFO pBuffer;
        hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
        GetConsoleScreenBufferInfo(hStdout, &pBuffer);
        return make_pair(pBuffer.dwCursorPosition.Y,pBuffer.dwCursorPosition.X);
    }
    template <typename T>void Tprint(int Nx,int Ny,int Color,T a){
        int x=GetXY().first,y=GetXY().second;
        gto(Nx,Ny),color(Color),cout<<a;
        gto(x,y);
    }
    void ColorPrint(){
        for(int i=0;i<256;i++)
            color(i),printf("%d\n",i);
    }
    void SetWindow(const char *name,int c,int w){
        char str[30];
        sprintf(str,"title %s",name);
        system(str);
        sprintf(str,"mode con cols=%d lines=%d",w,c);
        system(str);
    }
    void SetWindow(const char *name,int c,int w,int x,int y){
        SetConsoleTitle(name);
        HWND hwnd;
        hwnd=GetForegroundWindow();
        SetWindowPos(hwnd,HWND_TOP,y,x,w*8,c*16,SWP_SHOWWINDOW);
    }
    int read(){
        color(fwhite+flight);
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    #define TP Tprint
    #define WINDOWC 45
    #define WINDOWW 55
    #define INF 0x3f3f3f3f
    #define OC fwhite+flight+bblack //original color
    
    bool InRange(int x){
        return x>=0&&x<=WINDOWC;
    }
    
    int BossFlag;
    int OwnShotTimes,OwnLoseBlood,OwnShotOnTimes;
    int MoneyFlash,ScoreFlash;
    
    const int ConstNewDy[4]={-1,0,1};
    #define MAX_BULLET_TYPE_NUM 3
    const int ConstBulletColor[MAX_BULLET_TYPE_NUM+5]={0,fyellow,fred+flight,fred+flight,fblue+flight,fred+bwhite};
    const char ConstBulletShape[MAX_BULLET_TYPE_NUM+5]={0,'*','*','O','|','%'};
    const int ConstBulletDamage[MAX_BULLET_TYPE_NUM+5]={0,50,80,500,20,300};
    /*Move 1 block every 100-Speed ms*/
    const int ConstBulletSpeed[MAX_BULLET_TYPE_NUM+5]={0,50,30,10,80,20};
    /*The color of the full block in the blood line*/
    const int ConstBloodColor[4]={0,fred,fyellow,fgreen};
    
    #define MAX_BOSS_NUM 10
    const int ConstBossFullBlood[MAX_BOSS_NUM+5]={0,1000,3000,5000,10000,30000,50000,100000,300000,500000,1000000};
    const int ConstBossShotSpeed[MAX_BOSS_NUM+5][2]={{0,0},{30,-3900},{30,-3400},{50,-2900},{50,-2400},{70,-1900},{70,-1400},{90,-900},{90,-400},{100,-400},{100,-400}};
    const int ConstBossStopCD[MAX_BOSS_NUM+5]={0,3200,3400,3600,3800,4000,4200,4400,4600,4800,5000};
    const int ConstBossStopTime[MAX_BOSS_NUM+5]={0,3000,2800,2600,2400,2200,2000,1800,1600,1400,1200};
    const int ConstBossMoveSpeed[MAX_BOSS_NUM+5]={0,800,800,800,850,850,850,900,900,900,950};
    const int ConstBossScore[MAX_BOSS_NUM+5]={0,10000,20000,40000,80000,160000,320000,640000,1280000,2560000,5120000};
    const int ConstBossMoney[MAX_BOSS_NUM+5]={0,100,200,500,1000,2000,5000,8000,10000,20000,50000};
    const int ConstBossNeedScore[MAX_BOSS_NUM+5]={0,500,1000,1500,2000,2500,3000,3500,4000,4500,5000};
    
    struct Bullet{
        int isExist;
        int x,y,Type;
        int dx,dy,LastBulletRefreshTime;
        Bullet(){LastBulletRefreshTime=-INF;}
        Bullet(int isExist_,int x_,int y_,int Type_,int dx_,int dy_):
            isExist(isExist_),x(x_),y(y_),Type(Type_),dx(dx_),dy(dy_){}
    };
    
    void MoveBullet(Bullet&);
    /*We must use Bullet*, or we can't change the data(position of the bullet) in the set*/
    set<Bullet*> Ammo;
    void BulletsRefresh(){
        vector<set<Bullet*>::iterator> Throw;
        for(set<Bullet*>::iterator it=Ammo.begin();it!=Ammo.end();it++){
            Bullet *New=*it;
            MoveBullet(*New);
            /*We can't erase it right away*/
            if(!New->isExist)
                Throw.push_back(it);
        }
        for(int i=0;i<int(Throw.size());i++)
            Ammo.erase(Throw[i]);
    }
    
    int BEGINTIME;
    
    int UFOAddBlood,UFOAddShotSpeed,UFOAddMoveSpeed,Added;
    
    struct UFO{
        /*
        Shape of the UFO:
        0000/0000
           @@@
          (OOO)
           \-/
            V
        */
        int isExist;
        int x,y;//position of the head
        int dx,dy;
        int Blood,FullBlood;
        int ShotSpeed,LastShotTime;
        int MoveSpeed;
        int LastMoveTime;
        int Score,Money;
    
        UFO(){
            if(BossFlag&&!Added)
                UFOAddBlood+=100,UFOAddShotSpeed+=100,UFOAddMoveSpeed+=100,Added=1;
            if(!BossFlag&&Added)
                UFOAddBlood-=100,UFOAddShotSpeed-=100,UFOAddMoveSpeed-=100,Added=0;
            isExist=1;
            x=0,y=rand()%(WINDOWW-4)+4;//Must be in the screen
            FullBlood=rand()%300+100+UFOAddBlood;
            Blood=FullBlood;
            ShotSpeed=rand()%1000+UFOAddShotSpeed;
            /*Move 1 block every 1000-MoveSpeed ms*/
            MoveSpeed=rand()%600+300+UFOAddMoveSpeed;
            LastMoveTime=LastShotTime=-INF;
            dx=1,dy=0;
            Score=FullBlood/30+((clock()-BEGINTIME)/10000);
            Money=MoveSpeed/100.0+FullBlood/100.0;
        }
        /*effects when being hit*/
        void Flash(){
            /*the head is sure to be in the screen so we needn't check*/
            if(!isExist)
                return;
            if(x>0&&x<WINDOWC)
                TP(x,y,fpurple+bwhite,'V');
            if(x-1>0&&x-1<WINDOWC)
                TP(x-1,y-1,fpurple+bwhite,"\\-/");
            //Sleep(100);
            if(x>0&&x<WINDOWC)
                TP(x,y,fpurple+bblack,'V');
            if(x-1>0&&x-1<WINDOWC)
                TP(x-1,y-1,fpurple+bblack,"\\-/");
        }
        /*Check if hit only on the body*/
        bool Hit(int tx,int ty){
            return (tx==x&&ty==y)||
                   (tx==x-1&&ty>=y-1&&ty<=y+1);
        }
        /*To check if it will hit another UFO*/
        void BloodRefresh(int NewX,int NewY){
            /*To appear gradually, we should check the position*/
            if(x-2>=0){
                TP(x-2,y-1,OC,"   ");
                if(isExist)
                    if(NewX-2<WINDOWC){
                        /*Round up*/
                        int FullBlock=(Blood*3+FullBlood-1)/FullBlood;   //Number of "@"
                        int EmptyBlock=3-FullBlock;                      //Number of "O"
                        int BloodColor=ConstBloodColor[FullBlock];
                        /*Print the blood line*/
                        for(int i=1;i<=FullBlock;i++)
                            TP(NewX-2,NewY-2+i,BloodColor+bblack,'@');
                        for(int i=1;i<=EmptyBlock;i++)
                            TP(NewX-2,NewY-2+FullBlock+i,fgray+bblack,'O');
                    }
            }
            /*Print the blood/fullblood number*/
            /*Due to %06d we can't use TP*/
            if(x-3>=0){
                TP(x-3,y-4,OC,"         ");
                if(isExist){
                    if(NewX-3<WINDOWC){
                        gto(NewX-3,NewY-4),color(fcyan+bblack),printf("%04d",Blood);
                        TP(NewX-3,NewY,fcyan+bblack,'/');
                        gto(NewX-3,NewY+1),color(fcyan+bblack),printf("%04d",FullBlood);
                    }
                }
            }
            if(x-3>=WINDOWC)
                isExist=0;
        }
        /*Clear the shape after it died*/
        void ClearPrint(){
            BloodRefresh(x,y);
            if(x-1>=0&&x-1<WINDOWC)
                TP(x-1,y-1,OC,"   ");
            if(x>=0&&x<WINDOWC)
                TP(x,y,OC,' ');
        }
        void Shot(){
            int t=clock();
            if(!ShotSpeed||LastShotTime>=t-(5000-ShotSpeed))
                return;
            LastShotTime=t;
            if(x>0){
                Bullet *tmp=new Bullet(1,x+1,y,2,1,0);
                Ammo.insert(tmp);
            }
        }
    };
    /*It is similar to set<Bullet*> in struct Plane*/
    set<UFO*> Enemy;
    
    bool UFOCrash(int,int);
    bool UFOCrash(UFO,int,int,set<UFO*>::iterator);
    
    /*Move the plane to a new place*/
    void UFOMovePrint(UFO &me,set<UFO*>::iterator id){
        int t=clock();
        if(me.LastMoveTime>=t-(1000-me.MoveSpeed))
            return;
        me.LastMoveTime=t;
        /*Change the direction*/
        if(rand()%3==0)
            me.dy=ConstNewDy[rand()%3];
        int NewX=me.x+me.dx,NewY=me.y+me.dy;
        if(UFOCrash(me,NewX,NewY,id)||NewY-4<0||NewY+4>=WINDOWW)//||NewX<0||NewY-4<0||NewX>=WINDOWC||NewY+4>=WINDOWW){
            for(int i=0;i<3;i++){
                me.dy=ConstNewDy[rand()%3];
                NewX=me.x+me.dx,NewY=me.y+me.dy;
                if(!(UFOCrash(me,NewX,NewY,id)||NewY-4<0||NewY+4>=WINDOWW))//||NewX<0||NewY-4<0||NewX>=WINDOWC||NewY+4>=WINDOWW))
                    break;
            }
    
        if(UFOCrash(me,NewX,NewY,id)||NewY-4<0||NewY+4>=WINDOWW)//||NewX<0||NewY-4<0||NewX>=WINDOWC||NewY+4>=WINDOWW)
            return;
        //TP(me.x,me.y,OC,' ');
        if(NewX<WINDOWC){
            TP(me.x,me.y,fwhite+flight+bblack,' ');
            if(me.isExist) TP(NewX,NewY,fwhite+flight+bblack,'V');
        }
        if(NewX-1>=0&&NewX-1<WINDOWC){
            TP(me.x-1,me.y-1,fwhite+flight+bblack,"   ");
            if(me.isExist) TP(NewX-1,NewY-1,fwhite+flight+bblack,"\\-/");
        }
        me.BloodRefresh(NewX,NewY);
        me.x=NewX,me.y=NewY;
    }
    int UFORefreshTime=3000,LastUFORefreshTime=0;
    void UFORefresh(){
        int t=clock();
        if(LastUFORefreshTime<t-UFORefreshTime){
            UFO *tmp=new UFO;
            Enemy.insert(tmp);
            LastUFORefreshTime=t;
        }
        vector<set<UFO*>::iterator> Throw;
        for(set<UFO*>::iterator it=Enemy.begin();it!=Enemy.end();it++){
            UFO *New=*it;
            if(!New->isExist)
                Throw.push_back(it);
            UFOMovePrint(*New,it);
            New->Shot();
        }
        for(int i=0;i<int(Throw.size());i++)
            Enemy.erase(Throw[i]);
    }
    
    #define MAX_BUFF_NUM 5
    const int ConstBuffAppearPossibility[2][1000]={
        {1,2,2,2,2,2,2,3,4,5},
        {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,5}
    };
    const int ConstBuffAppearTime[MAX_BUFF_NUM+5]={0,5000,5000,5000,5000,5000};
    const int ConstBuffLastTime[MAX_BUFF_NUM+5]={0,5000,0,5000,10000,5000};
    const char ConstBuffName[MAX_BUFF_NUM+5]={0,'B','C','P','D','S'};
    const char ConstBuffColor[MAX_BUFF_NUM+5]={0,fblue+flight,fgreen+flight,fred+flight,fyellow+flight,fpurple+flight};
    
    struct Plane{
        /*
        Shape of the plane:
               ^             (x,y)
              / \            (x+1,y-1) to (x+1,y+1)
          |---------|        (x+2,y-5) to (x+2,y+5)
               |             (x+3,y)
              ---            (x+4,y-1) to (x+4,y+1)
           @@@@@@@@@         (x+5,y-4) to (x+5,y+4)
          (OOOOOOOOO)
         000000/000000       (x+6,y-6) to (x+6,y+6)  (Blood and full blood)
        */
        int x,y;//position of the head
        int Blood,FullBlood;
        int LastShotTime;
        int ShotSpeed;
        LL Score,BossScore;
        int Buffs[10],GetBuffTime[10];
        double AddAtack,AddShotSpeed;
        int Money;
        int MeetBossTimes;
        void Init(bool isDebug){
            if(isDebug){
                Ammo.clear();
                LastShotTime=-INF;
                /*It shot one time in at most 1000-ShotSpeed ms*/
                ShotSpeed=20;
                Blood=10000,FullBlood=10000;
                x=WINDOWC/2,y=WINDOWW-8;
                Score=BossScore=0;
                AddAtack=AddShotSpeed=50.0;
                MeetBossTimes=1;
                memset(Buffs,0,sizeof Buffs);
            }
            else{
                Ammo.clear();
                LastShotTime=-INF;
                /*It shot one time in at most 1000-ShotSpeed ms*/
                ShotSpeed=500;
                Blood=500,FullBlood=500;
                x=WINDOWC/2,y=WINDOWW-8;
                Score=BossScore=0;
                AddAtack=AddShotSpeed=1.0;
                MeetBossTimes=1;
                memset(Buffs,0,sizeof Buffs);
            }
        }
        bool NeedBoss(){
            if(Score>=ConstBossNeedScore[MeetBossTimes])
                return MeetBossTimes++,1;
            return 0;
        }
        void Flash(int fcolor){
            TP(x,y,fcolor+bwhite,'^');
            TP(x+1,y-1,fcolor+bwhite,'/'),TP(x+1,y+1,fcolor+bwhite,'\\');
            TP(x+2,y-5,fcolor+bwhite,'|');for(int i=y-4;i<=y+4;i++)TP(x+2,i,fcolor+bwhite,'-');TP(x+2,y+5,fcolor+bwhite,'|');
            TP(x+3,y,fcolor+bwhite,'|');
            TP(x+4,y-1,fcolor+bwhite,'-'),TP(x+4,y,fcolor+bwhite,'-'),TP(x+4,y+1,fcolor+bwhite,'-');
            Sleep(200);
            TP(x,y,OC,'^');
            TP(x+1,y-1,OC,'/'),TP(x+1,y+1,OC,'\\');
            TP(x+2,y-5,OC,'|');for(int i=y-4;i<=y+4;i++)TP(x+2,i,OC,'-');TP(x+2,y+5,OC,'|');
            TP(x+3,y,OC,'|');
            TP(x+4,y-1,OC,'-'),TP(x+4,y,OC,'-'),TP(x+4,y+1,OC,'-');
        }
        /*Check if hit only on the body*/
        bool Hit(int tx,int ty){
            return (tx==x&&ty==y)||
                   (tx==x+1&&ty>=y-1&&ty<=y+1)||
                   (tx==x+2&&ty>=y-5&&ty<=y+5)||
                   (tx==x+3&&ty==y)||
                   (tx==x+4&&ty>=y-1&&ty<=y+1);
        }
        /*Move the blood line(just move)*/
        /*Remember to check if the position is OK before using*/
        /*And it won't update the plane's position (x and y)*/
        void BloodRefresh(int NewX,int NewY){
            TP(x+5,y-4,OC,"         ");
            TP(x+6,y-6,OC,"             ");
            /*Round up*/
            int FullBlock=(Blood*9+FullBlood-1)/FullBlood;   //Number of "@"
            int EmptyBlock=9-FullBlock;                      //Number of "O"
            int BloodColor=ConstBloodColor[(FullBlock+2)/3];
            /*Print the blood line*/
            for(int i=1;i<=FullBlock;i++)
                TP(NewX+5,NewY-5+i,BloodColor+bblack,'@');
            for(int i=1;i<=EmptyBlock;i++)
                TP(NewX+5,NewY-5+FullBlock+i,fgray+bblack,'O');
            /*Print the blood/fullblood number*/
            /*Due to %06d we can't use TP*/
            gto(NewX+6,NewY-6),color(fgray+bblack),printf("%06d",Blood);
            TP(NewX+6,NewY,OC,'/');
            gto(NewX+6,NewY+1),color(fgray+bblack),printf("%06d",FullBlood);
        }
        /*Move the plane to a new place*/
        void MovePrint(int NewX,int NewY,int flag=1){
            /*Insure that player can control the plane when the mouse is out of screen*/
            NewX=min(NewX,WINDOWC-7);
            NewY=min(max(NewY,6),WINDOWW-7);
            if(flag&&NewX==x&&NewY==y)
                return;
            //gto(WINDOWC-1,0),color(OC),printf("%3d %3d",NewX,NewY);//Debug
            /*Clear the plane in the old position*/
            TP(x,y,OC,' ');
            TP(x+1,y-1,OC,' '),TP(x+1,y+1,OC,' ');
            for(int i=y-5;i<=y+5;i++) TP(x+2,i,OC,' ');
            TP(x+3,y,OC,' ');
            TP(x+4,y-1,OC,' '),TP(x+4,y,OC,' '),TP(x+4,y+1,OC,' ');
            /*Move the blood line*/
            BloodRefresh(NewX,NewY);
            /*Print in the new position*/
            x=NewX,y=NewY;
            TP(x,y,OC,'^');
            TP(x+1,y-1,OC,'/'),TP(x+1,y+1,OC,'\\');
            TP(x+2,y-5,OC,'|');for(int i=y-4;i<=y+4;i++)TP(x+2,i,OC,'-');TP(x+2,y+5,OC,'|');
            TP(x+3,y,OC,'|');
            TP(x+4,y-1,OC,'-'),TP(x+4,y,OC,'-'),TP(x+4,y+1,OC,'-');
            /*Refresh the bullets*/
        }
        void Shot(){
            /*Buff 5*/
            /*Faster shot*/
            int t=clock();
            if(Buffs[5]==1)
                ShotSpeed+=100,Buffs[5]=-1;
            if(Buffs[5]==-1&&t-GetBuffTime[5]>=ConstBuffLastTime[5]){
                ShotSpeed-=100;
                Buffs[5]=0;
                GetBuffTime[5]=0;
            }
            if(!ShotSpeed||LastShotTime>=t-(1000-ShotSpeed*AddShotSpeed))
                return;
            LastShotTime=t;
            if(x>0){
                OwnShotTimes++;
                int Type=1;
                /*Buff 3*/
                /*Get bullets more powerful*/
                if(Buffs[3]){
                    if(t-GetBuffTime[3]>=ConstBuffLastTime[3])
                        Buffs[3]=0,GetBuffTime[3]=0;
                    else
                        Type=3;
                }
                Ammo.insert(new Bullet(1,x-1,y,Type,-1,0));
                /*Buff 1*/
                /*5 lines of bullets*/
                if(Buffs[1]){
                    if(t-GetBuffTime[1]>=ConstBuffLastTime[1]){
                        Buffs[1]=0;
                        GetBuffTime[1]=0;
                        return;
                    }
                    Ammo.insert(new Bullet(1,x-1,y-2,Type,-1,0));
                    Ammo.insert(new Bullet(1,x-1,y-1,Type,-1,0));
                    Ammo.insert(new Bullet(1,x-1,y+1,Type,-1,0));
                    Ammo.insert(new Bullet(1,x-1,y+2,Type,-1,0));
                }
            }
        }
    }Own;
    
    struct Buff{
        int x,y;
        int Type;
        int DisappearTime;
        Buff(){}
        Buff(int t){x=rand()%(WINDOWC-3)+1,y=rand()%(WINDOWW-2)+1,Type=t,DisappearTime=clock()+ConstBuffAppearTime[t];}
    };
    set<Buff*> BuffIn;
    int LastBuffAppearTime;
    int BuffAppearCD=3000;
    void BuffRefresh(){
        int T=clock();
        /*New buff in the screen*/
        if(LastBuffAppearTime+BuffAppearCD<=T){
            int id=rand();
            int t=ConstBuffAppearPossibility[BossFlag][id%10];
            if(t)
                BuffIn.insert(new Buff(t));
            LastBuffAppearTime=T;
        }
        vector<set<Buff*>::iterator> Throw;
        for(set<Buff*>::iterator it=BuffIn.begin();it!=BuffIn.end();it++){
            Buff *p=*it;
            TP(p->x,p->y,ConstBuffColor[p->Type],ConstBuffName[p->Type]);
            if(Own.Hit(p->x,p->y)){
                /*Buff 2*/
                /*Recover 100 blood*/
                if(p->Type==2){
                    Own.Blood=min(Own.Blood+100,Own.FullBlood);
                    Own.BloodRefresh(Own.x,Own.y);
                }
                else{
                    Own.Buffs[p->Type]=1;
                    Own.GetBuffTime[p->Type]=T;
                }
                Throw.push_back(it);
                TP(p->x,p->y,OC,' ');
            }
            else if(T>=p->DisappearTime){
                Throw.push_back(it);
                TP(p->x,p->y,OC,' ');
            }
        }
        for(int i=0;i<int(Throw.size());i++)
            BuffIn.erase(Throw[i]);
        //for(int i=1;i<=MAX_BUFF_NUM;i++)
        //    if(Own.Buffs[i]&&clock()-Own.GetBuffTime[i]>=ConstBuffLastTime[i])
        //        Own.Buffs[i]=0;
    }
    
    
    const char CHART[15]={'|','?','^','&','=','!','@',':','p','\\'};
    
    void GameOver(){
        color(OC);
        system("cls");
        /*Get max score before*/
        LL MaxScore=0;
        LL num=((MaxScore*18-2)*38-1314)/2*100+52;
        ifstream R("MaxScore.sc");
        if(!R.is_open())
            TP(0,0,OC,"ERROR");
        string str;
        R>>str;
        if(str.length()){
            num=0;
            for(int i=0;i<int(str.length());i++)
                if(isdigit(str[i]))
                    num=num*10ll+str[i]-'0';
        }
        R.close();
        /*unlock*/
        MaxScore=(((num-52)/100*2+1314)/38+2)/18;
        TP(WINDOWC/2-2,(WINDOWW+40-10)/2,fred+flight+bblack,"Game Over!");
        TP(WINDOWC/2-1,(WINDOWW+40-15)/2,OC,"Your score: ");
        gto(WINDOWC/2-1,(WINDOWW+40-15)/2+12),color(OC),printf("%08lld",Own.Score+Own.BossScore);
        TP(WINDOWC/2,(WINDOWW+40-15)/2,OC,"MaxScore: ");
        gto(WINDOWC/2,(WINDOWW+40-15)/2+12),color(OC),printf("%08lld",max(Own.Score+Own.BossScore,MaxScore));
        if(Own.Score+Own.BossScore>MaxScore){
            TP(WINDOWC/2+1,(WINDOWW+40-15)/2+2,fred+flight+bblack,"(Refreshed!)"),MaxScore=Own.Score+Own.BossScore;
            /*lock*/
            num=((MaxScore*18-2)*38-1314)/2*100+52;
            string New;
            for(int i=1;i<=30;i++){
                if(rand()%2)
                    New+=CHART[rand()%10];
                else if(num)
                    New+=num%10+'0',num/=10;
            }
            while(num)
                New+=num%10+'0',num/=10;
            while(New.length()<30)
                New+=CHART[rand()%10];
            reverse(New.begin(),New.end());
            fstream CLEAR("MaxScore.sc", ios::trunc);
            CLEAR.close();
            ofstream T("MaxScore.sc");
            if(!T.is_open())
                TP(0,0,OC,"ERROR");
            T<<New;
            T.close();
        }
        TP(WINDOWC/2+2,(WINDOWW+40-15)/2-3,OC,"(Press any key to exit)");
        getch();
        gto(WINDOWC/2+4,0),exit(0);
    }
    
    bool isHit(int,int,int);
    
    void MoveBullet(Bullet &me){
        int t=clock();
        if(me.LastBulletRefreshTime>=t-(100-ConstBulletSpeed[me.Type]))
            return;
        me.LastBulletRefreshTime=t;
        int tx=me.x+me.dx,ty=me.y+me.dy;
        TP(me.x,me.y,OC,' ');
        /*It runs out of the screen => erase it*/
        if(tx<0||tx>=WINDOWC||ty<0||ty>=WINDOWW||isHit(tx,ty,me.Type)){
            me.isExist=0;
            return;
        }
        TP(me.x=tx,me.y=ty,ConstBulletColor[me.Type],ConstBulletShape[me.Type]);
    }
    
    #define MAX_BUFFFULLNAME_LEN 16
    const int ConstBuffTipPosition[MAX_BUFF_NUM+5][2]={{0,0},{13,WINDOWW+3},{14,WINDOWW+3},{15,WINDOWW+3},{16,WINDOWW+3},{17,WINDOWW+3}};
    const char ConstBuffFullName[MAX_BUFF_NUM+5][MAX_BUFFFULLNAME_LEN+5]={"","4 more bullets","recover 50 blood","more powerful","double score","shot faster"};
    const int ConstMaxBuffFullNameLen[MAX_BUFF_NUM+5]={0,16,16,16,16,16};
    void BuffTipRefresh(){
        /*
        TP(12,WINDOWW+3,OC,"---------Details of Buffs---------");
        TP(18,WINDOWW+3,OC,"----------------------------------");
        */
        int C=fgray;
        for(int i=1;i<=MAX_BUFF_NUM;i++){
            TP(ConstBuffTipPosition[i][0],ConstBuffTipPosition[i][1],C,ConstBuffName[i]);
            TP(ConstBuffTipPosition[i][0],ConstBuffTipPosition[i][1]+1,C,": ");
            TP(ConstBuffTipPosition[i][0],ConstBuffTipPosition[i][1]+3,C+(Own.Buffs[i]?bwhite+blight:0),ConstBuffFullName[i]);
            gto(ConstBuffTipPosition[i][0],ConstBuffTipPosition[i][1]+3+ConstMaxBuffFullNameLen[i]),color(C+(Own.Buffs[i]?bwhite+blight:0)),printf("[%02d S]",int(Own.Buffs[i]?(ConstBuffLastTime[i]-(clock()-Own.GetBuffTime[i])+999)/1000:0));
        }
    }
    
    void EnemyClear(){
        int tmp=UFORefreshTime;
        UFORefreshTime=INF;
        for(set<UFO*>::iterator it=Enemy.begin();it!=Enemy.end();it++)
            (*it)->isExist=0;
        UFORefresh();
        UFORefreshTime=tmp;
    }
    
    double Performance();
    
    //D C B A S
    const int PerfColor[10]={fblack+bwhite,fgray+bwhite,fpurple+bwhite,fgreen+bwhite,fred+bwhite};
    const char PerfLevel[10][8]={"D.","C.","B.","A!","S!!"};
    
    struct BOSS{
        /*Shape of the boss:
          0000000/0000000           (x-7,y-7) to (x-7,y+7)
          @@@@@@@@@@@@@@@           (x-6,y-7) to (x-6,y+7)
         (OOOOOOOOOOOOOOO)
           [-----------]            (x-5,y-6) to (x-5,y+6)
             \OOXXXOO/              (x-4,y-4) to (x-4,y+4)
          +---\XXOXX/---+           (x-3,y-7) to (x-3,y+7)
          V    \OOO/    V           (x-2,y-7) to (x-2,y+7)
                \O/                 (x-1,y-1) to (x-1,y+1)
                 V                  (x,y)
        */
        int isExist;
        int x,y;//position of the head
        int dx,dy;
        int Blood,FullBlood;
        int ShotSpeed1,ShotSpeed2,LastShotTime1,LastShotTime2,flag2;
        int MoveSpeed,LastMoveTime;
        int Score,AppearTime;
        int StopCD,StopTime,LastStopTime,isStop;
        int Money;
        bool Hit(int tx,int ty){
            return (tx==x-5&&ty>=y-6&&ty<=y+6)||
                   (tx==x-4&&ty>=y-4&&ty<=y+4)||
                   (tx==x-3&&ty>=y-7&&ty<=y+7)||
                   (tx==x-2&&((ty==y-7)||(ty==y+7)||(ty>=y-2&&ty<=y+2)))||
                   (tx==x-1&&ty>=y-1&&ty<=y+1)||
                   (tx==x&&ty==y);
        }
        void Die(){
            flash(3);
            BossFlag=0;
            double tmp=Performance();
            int Add=int(Score*tmp);
            Own.BossScore+=Add;
            Own.Money+=Money*(tmp/3.0);
            ScoreFlash=MoneyFlash=1;
            TP(WINDOWC/2-1,WINDOWW/2-18,OC,"+-----------------------------------+");
            TP(WINDOWC/2  ,WINDOWW/2-18,OC,'|'),gto(WINDOWC/2,WINDOWW/2-7),color(PerfColor[int(tmp)]),printf("%s",PerfLevel[int(tmp)]),printf("  + %d scores !",Add),TP(WINDOWC/2  ,WINDOWW/2+18,OC,'|');
            TP(WINDOWC/2+1,WINDOWW/2-18,OC,"+-----------------------------------+");
            Sleep(1500);
            TP(WINDOWC/2-1,WINDOWW/2-18,OC,"                                     ");
            TP(WINDOWC/2  ,WINDOWW/2-18,OC,"                                     ");
            TP(WINDOWC/2+1,WINDOWW/2-18,OC,"                                     ");
            if(x-7>=0) TP(x-7,y-7,OC,"               ");
            if(x-6>=0) TP(x-6,y-7,OC,"               ");
            if(InRange(x)) TP(x,y,OC,' ');
            if(InRange(x-1)) TP(x-1,y-1,OC,"   ");
            if(InRange(x-2)) TP(x-2,y-7,OC,"               ");
            if(InRange(x-3)) TP(x-3,y-7,OC,"               ");
            if(InRange(x-4)) TP(x-4,y-4,OC,"         ");
            if(InRange(x-5)) TP(x-5,y-6,OC,"             ");
            EnemyClear();
        }
        void Flash(){
            if(InRange(x-5)) TP(x-5,y-6,fblack+bwhite,"[-----------]");
            if(InRange(x-4)) TP(x-4,y-4,fblack+bwhite,'\\'),TP(x-4,y-3,fblack+bwhite,"OO"),TP(x-4,y-1,fblack+bwhite,"XXX"),TP(x-4,y+2,fblack+bwhite,"OO"),TP(x-4,y+4,fblack+bwhite,"/");
            if(InRange(x-3)) TP(x-3,y-7,fblack+bwhite,"+---\\XX"),TP(x-3,y,fblack+bwhite,'O'),TP(x-3,y+1,fblack+bwhite,"---+");
            if(InRange(x-2)) TP(x-2,y-7,fblack+bwhite,'V'),TP(x-2,y-2,fblack+bwhite,'\\'),TP(x-2,y-1,fblack+bwhite,"OOO"),TP(x-2,y+2,fblack+bwhite,'/'),TP(x-2,y+7,fblack+bwhite,'V');
            if(InRange(x-1)) TP(x-1,y-1,fblack+bwhite,'\\'),TP(x-1,y,fblack+bwhite,'O'),TP(x-1,y+1,fblack+bwhite,'/');
            if(InRange(x-5)) TP(x-5,y-6,OC,"[-----------]");
            if(InRange(x-4)) TP(x-4,y-4,OC,'\\'),TP(x-4,y-3,fgray+bblack,"OO"),TP(x-4,y-1,OC,"XXX"),TP(x-4,y+2,fgray+bblack,"OO"),TP(x-4,y+4,OC,"/");
            if(InRange(x-3)) TP(x-3,y-7,OC,"+---\\XX"),TP(x-3,y,fgray+bblack,'O'),TP(x-3,y+1,OC,"---+");
            if(InRange(x-2)) TP(x-2,y-7,fgray+bblack,'V'),TP(x-2,y-2,OC,'\\'),TP(x-2,y-1,fgray+bblack,"OOO"),TP(x-2,y+2,OC,'/'),TP(x-2,y+7,fgray+bblack,'V');
            if(InRange(x-1)) TP(x-1,y-1,OC,'\\'),TP(x-1,y,fgray+bblack,'O'),TP(x-1,y+1,OC,'/');
            if(InRange(x)) TP(x,y,OC,' ');
            if(InRange(x)) TP(x,y,OC,'V');
        }
        void Init(int S){
            Blood=FullBlood=ConstBossFullBlood[S];
            x=0,y=rand()%(WINDOWW-14)+7;//Must be in the screen
            dx=1,dy=0;
            LastShotTime1=LastShotTime2=0;
            flag2=0;
            ShotSpeed1=ConstBossShotSpeed[S][0],ShotSpeed2=ConstBossShotSpeed[S][1];
            MoveSpeed=ConstBossMoveSpeed[S];
            LastMoveTime=0;
            Score=ConstBossScore[S];
            AppearTime=clock();
            isExist=1;
            StopTime=ConstBossStopTime[S],StopCD=ConstBossStopCD[S],LastStopTime=isStop=0;
            Money=ConstBossMoney[S];
        }
        void BloodRefresh(int NewX,int NewY){
            /*Print the blood/fullblood number*/
            /*Due to %06d we can't use TP*/
            if(x-7>=0){
                dx=0;
                TP(x-7,y-7,OC,"               ");
                if(isExist){
                    if(NewX-7<WINDOWC){
                        gto(NewX-7,NewY-7),color(fcyan+bblack),printf("%07d",Blood);
                        TP(NewX-7,NewY,fcyan+bblack,'/');
                        gto(NewX-7,NewY+1),color(fcyan+bblack),printf("%07d",FullBlood);
                    }
                }
            }
            /*To appear gradually, we should check the position*/
            if(x-6>=0){
                TP(x-6,y-7,OC,"               ");
                if(isExist)
                    if(NewX-6<WINDOWC){
                        /*Round up*/
                        int FullBlock=(Blood*15+FullBlood-1)/FullBlood;   //Number of "@"
                        int EmptyBlock=15-FullBlock;                       //Number of "O"
                        int BloodColor=ConstBloodColor[(FullBlock+4)/5];
                        /*Print the blood line*/
                        for(int i=1;i<=FullBlock;i++)
                            TP(NewX-6,NewY-8+i,BloodColor+bblack,'@');
                        for(int i=1;i<=EmptyBlock;i++)
                            TP(NewX-6,NewY-8+FullBlock+i,fgray+bblack,'O');
                    }
            }
            if(x-7>=WINDOWC)
                isExist=0;
        }
        /*Only one boss so we don't have to make the function out*/
        void MovePrint(){
            int t=clock();
            if(LastMoveTime>=t-(1000-MoveSpeed))
                return;
            LastMoveTime=t;
            /*Change the direction*/
            if(rand()%10==0)
                dy=ConstNewDy[rand()%3];
            int NewX=x+dx,NewY=y+dy;
            if(UFOCrash(NewX,NewY)||NewY-7<0||NewY+7>=WINDOWW)
                for(int i=0;i<3;i++){
                    dy=ConstNewDy[rand()%3];
                    NewX=x+dx,NewY=y+dy;
                    if(!(UFOCrash(NewX,NewY)||NewY-7<0||NewY+7>=WINDOWW))
                        break;
                }
            if(UFOCrash(NewX,NewY)||NewY-7<0||NewY+7>=WINDOWW)
                return;
            if(InRange(x)) TP(x,y,OC,' ');
            if(InRange(NewX)) TP(NewX,NewY,OC,'V');
            if(InRange(x-1)) TP(x-1,y-1,OC,"   ");
            if(InRange(NewX-1))
                TP(NewX-1,NewY-1,OC,'\\'),
                TP(NewX-1,NewY,fgray+bblack,'O'),
                TP(NewX-1,NewY+1,OC,'/');
            if(InRange(x-2)) TP(x-2,y-7,OC,"               ");
            if(InRange(NewX-2)) TP(NewX-2,NewY-7,fgray+bblack,'V'),TP(NewX-2,NewY-2,OC,'\\'),TP(NewX-2,NewY-1,fgray+bblack,"OOO"),TP(NewX-2,NewY+2,OC,'/'),TP(NewX-2,NewY+7,fgray+bblack,'V');
            if(InRange(x-3)) TP(x-3,y-7,OC,"               ");
            if(InRange(NewX-3)) TP(NewX-3,NewY-7,OC,"+---\\XX"),TP(NewX-3,NewY,fgray+bblack,'O'),TP(NewX-3,NewY+1,OC,"XX/---+");
            if(InRange(x-4)) TP(x-4,y-4,OC,"         ");
            if(InRange(NewX-4)) TP(NewX-4,NewY-4,OC,'\\'),TP(NewX-4,NewY-3,fgray+bblack,"OO"),TP(NewX-4,NewY-1,OC,"XXX"),TP(NewX-4,NewY+2,fgray+bblack,"OO"),TP(NewX-4,NewY+4,OC,"/");
            if(InRange(x-5)) TP(x-5,y-6,OC,"             ");
            if(InRange(NewX-5)) TP(NewX-5,NewY-6,OC,"[-----------]");
            BloodRefresh(NewX,NewY);
            x=NewX,y=NewY;
        }
        void Shot(){
            int t=clock();
            if(LastShotTime1<t-(100-ShotSpeed1)){
                LastShotTime1=t;
                if(x-1>=0){
                    Ammo.insert(new Bullet(1,x-1,y-7,4,1,0));
                    Ammo.insert(new Bullet(1,x-1,y+7,4,1,0));
                }
            }
            if(LastShotTime2<t-(100-ShotSpeed2-500)){
                LastShotTime2=t,flag2=1;
                TP(x,y,fred+flight+bgray,'V');
            }
            if(flag2&&t>=LastShotTime2+500){
                flag2=0;
                if(x+1>=0)
                    Ammo.insert(new Bullet(1,x+1,y,5,1,0));
            }
        }
    }Boss;
    
    /*There's an awful problem that set<UFO*>Enemy will be use in the struct UFO but it needs the declaration of struct UFO so we can neither put it in front of the struct UFO nor put it after the struct UFO...*/
    /*So we have to get the function Crash out of the struct UFO.*/ /*Eating shit*/
    /*To check if it will hit another UFO*/
    void UFOMovePrint(UFO&,set<UFO*>::iterator);
    bool UFOCrash(UFO me,int NewX,int NewY,set<UFO*>::iterator ID){
        for(set<UFO*>::iterator it=Enemy.begin();it!=Enemy.end();it++){
            int ox=(*it)->x,oy=(*it)->y;
            if(it==ID||ox<NewX) continue;
            if(NewX<=ox+4&&NewX>=ox-4&&NewY>=oy-8&&NewY<=oy+8){
                /*avoid disfluency*/
                UFO *New=*it;
                UFOMovePrint(*New,it);
                return 1;
            }
        }
        if(BossFlag&&NewX<=Boss.x&&NewX>=Boss.x-5&&NewY>=Boss.y-9&&NewY<=Boss.y+9)
            return 1;
        return 0;
    }
    bool UFOCrash(int NewX,int NewY){
        for(set<UFO*>::iterator it=Enemy.begin();it!=Enemy.end();it++){
            int ox=(*it)->x,oy=(*it)->y;
            if(ox<NewX) continue;
            if(NewX<=ox+9&&NewX>=ox-9&&NewY>=oy-9&&NewY<=oy+9)
                return 1;
        }
        return 0;
    }
    
    //OwnShotTimes,OwnLoseBlood,OwnShotOnTimes;
    double Performance(){//(0,5]
        double p1=double(OwnShotOnTimes)/max(OwnShotTimes,1);
        double p2=max(double(Own.FullBlood-OwnLoseBlood)/Own.FullBlood,0.0);
        return min((p1+p2)*2.5,4.999999);
    }
    
    void BossRefresh(){
        Boss.MovePrint();
        int t=clock();
        if(!Boss.isStop)
            Boss.Shot();
        if(!Boss.isStop&&Boss.LastStopTime+Boss.StopTime+Boss.StopCD<=t)
            Boss.LastStopTime=t,Boss.isStop=1;
        if(Boss.isStop&&t-Boss.LastStopTime>=Boss.StopTime)
            Boss.isStop=0;
    }
    
    void Init(){
        srand((unsigned)time(NULL));
        //SetWindow("HPF",WINDOWC+12,WINDOWW+45,0,500);
        SetWindow("HPF",WINDOWC+2,WINDOWW+40);
        HindCursor();
        TP(0,0,OC,"+---------------------------------------------------------------------------------------------+");
        TP(2,(WINDOWW+40)/2-7,OC,"Hape Flying Game");
        TP(7,0,OC,"+---------------------------------------------------------------------------------------------+");
        Button Start=NewButton(4,(WINDOWW+40)/2-4,OC,"> Start <");
        Button More=NewButton(5,(WINDOWW+40)/2-4,OC,"> More  <");
        while(1){
            if(Preserve(Start)){
                Own.Init(0);
                break;
            }
            if(Preserve(More)){
                TP(6,3,fred,"Input the password: ");
                gto(6,22),color(fgray);
                char Key[15];
                fgets(Key,10,stdin);
                if(!strcmp(Key,"cxhsdsb\n")){
                    Own.Init(1);
                    break;
                }
                fflush(stdin);
                color(OC);
                system("cls");
                TP(0,0,OC,"+---------------------------------------------------------------------------------------------+");
                TP(2,(WINDOWW+40)/2-7,OC,"Hape Flying Game");
                TP(7,0,OC,"+---------------------------------------------------------------------------------------------+");
            }
            Sleep(50);
        }
        color(OC);
        system("cls");
    }
    
    /*Meet the awful problem again*/
    bool isHit(int NewX,int NewY,int Type){
        if(Type==1||Type==3){
            int DM=int(ConstBulletDamage[Type]*Own.AddAtack);
            for(set<UFO*>::iterator it=Enemy.begin();it!=Enemy.end();it++){
                if((*it)->Hit(NewX,NewY)){
                    /*Mention the order, or it won't be cleared*/
                    UFO *t=*it;
                    t->Flash();
                    t->Blood=max(t->Blood-DM,0);
                    t->BloodRefresh(t->x,t->y);
                    if(t->Blood<=0){
                        Own.Money+=t->Money;
                        MoneyFlash=1;
                        ScoreFlash=1;
                        t->isExist=0;
                        t->ClearPrint();
                        int Add=t->Score;
                        /*Buff 4*/
                        /*Double score*/
                        if(Own.Buffs[4]){
                            if(Own.GetBuffTime[4]+ConstBuffLastTime[4]>=clock()){
                                Own.Buffs[4]=0;
                                Own.GetBuffTime[4]=0;
                            }
                            Add+=t->Score;
                        }
                        if(BossFlag)
                            Add/=10;
                        Own.Score+=Add;
                    }
                    return 1;
                }
            }
            if(BossFlag&&Boss.Hit(NewX,NewY)){
                Boss.Flash();
                Boss.Blood=max(Boss.Blood-DM/2,0);
                Boss.BloodRefresh(Boss.x,Boss.y);
                OwnShotOnTimes++;
                if(Boss.Blood<=0)
                    Boss.Die(),BossFlag=0;
                return 1;
            }
        }
        else if(Own.Hit(NewX,NewY)){
            Own.Flash(fred+flight);
            OwnLoseBlood+=min(Own.Blood,ConstBulletDamage[Type]);
            Own.Blood=max(Own.Blood-ConstBulletDamage[Type],0);
            Own.BloodRefresh(Own.x,Own.y);
            if(Own.Blood<=0)
                GameOver();
            return 1;
        }
        return 0;
    }
    
    #define MAX_GRADE 10
    const int ConstUpgradeCost[MAX_GRADE+5]={10,20,50,100,200,500,1000,2000,5000,10000,INF};
    const char ConstUpgradeCostStr[MAX_GRADE+5][10]={"(M 10)","(M 20)","(M 50)","(M 100)","(M 200)","(M 500)","(M 1000)","(M 2000)","(M 5000)","(M 10000)","(M INF)  "};
    const int ConstGradeColor[MAX_GRADE+5]={fgreen+flight+bblack,fgreen+flight+bblack,fgreen+bblack,fblue+flight+bblack,fblue+flight+bblack,fblue+bblack,fyellow+flight+bblack,fyellow+bblack,fyellow+bblack,fred+flight+bblack,fred+bblack,fred+bblack};
    const char ConstGradeName[MAX_GRADE+5][20]={"[G0]","[G1]","[G2]","[G3]","[G4]","[G5]","[G6]","[G7]","[G8]","[G9]","[G10]"};
    
    int main(){
        //GameOver();
        //ColorPrint();
        //getchar();
        Init();
        HWND hd;
        hd=GetForegroundWindow();
        TP(12,WINDOWW+3,OC,"---------Details of Buffs---------");
        TP(18,WINDOWW+3,OC,"----------------------------------");
        //Own.Blood=100;
        int cnt=1;
        BossFlag=0;
        int LastT=clock()/1000-2,LastMoney=-1;
        BEGINTIME=clock();
        int _____=0,STOP=0,LastPreserveTime=-INF;
    
        Button AddFullBlood,AddAttack,AddShotSpeed;
        int FullBloodGrade=0,AttackGrade=0,ShotSpeedGrade=0;
        string AddFullBloodTip("> Add your max blood by 500"),AddAttackTip("> Add your attack by 10%"),AddShotSpeedTip("> Add your shot speed by 10%");
        AddFullBlood=NewButton(5,WINDOWW+3,OC,"> Add your max blood by 200");
        AddAttack=NewButton(6,WINDOWW+3,OC,"> Add your attack by 10%");
        AddShotSpeed=NewButton(7,WINDOWW+3,OC,"> Add your shot speed by 5%");
        //Own.Money=10000000;
        while(1){
            if(!STOP){
                if(_____%10==0){
                    gto(0,0),color(OC);
                    for(int i=1;i<=WINDOWW+40;i++)
                        putchar('-');
                    gto(WINDOWC,0),color(OC);
                    for(int i=1;i<=WINDOWW+40;i++)
                        putchar('-');
                }
                _____++;
                POINT k;
                GetPos(k);
                Own.MovePrint(min(max(int(k.x)-3,1),WINDOWC-1),min(max(int(k.y),0),WINDOWW-1));
                if(KEY_DOWN(MOUSE_MOVED))
                    Own.Shot();
                BulletsRefresh();
                if(BossFlag)
                    BossRefresh();
                UFORefresh();
                BuffRefresh(),BuffTipRefresh();
                if(ScoreFlash){
                    ScoreFlash=0;
                    TP(10,WINDOWW+3,fred+flight+bwhite,"[ "),
                    TP(10,WINDOWW+5,OC-bblack+bwhite,"Score: "),
                    gto(10,WINDOWW+12),color(OC-bblack+bwhite),printf("%04lld + %08lld",Own.Score,Own.BossScore),
                    TP(10,WINDOWW+27,fred+flight+bwhite," ]");
                    Sleep(100);
                }
                TP(10,WINDOWW+3,fred+flight+bblack,"[ "),
                TP(10,WINDOWW+5,OC,"Score: "),
                gto(10,WINDOWW+12),color(OC),printf("%04lld + %08lld",Own.Score,Own.BossScore),
                TP(10,WINDOWW+27,fred+flight+bblack," ]");
                int T=(clock()-BEGINTIME)/1000;
                if(T!=LastT){
                    TP(9,WINDOWW+3,fred+flight+bblack,"[ "),TP(9,WINDOWW+5,OC,"Time: "),gto(9,WINDOWW+11),color(OC),printf("%05d",T),TP(9,WINDOWW+16,fred+flight+bblack," ]");
                    LastT=T;
                }
            }
            if(Own.Money!=LastMoney){
                if(MoneyFlash){
                    MoneyFlash=0;
                    TP(1,WINDOWW+3,fred+flight+bwhite,"[ "),
                    TP(1,WINDOWW+6,OC-bblack+bwhite,"Money: "),
                    gto(1,WINDOWW+13),color(OC-bblack+bwhite),printf("%08d",LastMoney=Own.Money),
                    TP(1,WINDOWW+21,fred+flight+bwhite," ]");
                    Sleep(100);
                }
                TP(1,WINDOWW+3,fred+flight+bblack,"[ "),
                TP(1,WINDOWW+6,OC,"Money: "),
                gto(1,WINDOWW+13),color(OC),printf("%08d",LastMoney=Own.Money),
                TP(1,WINDOWW+21,fred+flight+bblack," ]");
    
            }
            if(clock()-LastPreserveTime>=100){
                LastPreserveTime=clock();
                if(Preserve(AddFullBlood)){
                    if(Own.Money>=ConstUpgradeCost[FullBloodGrade]){
                        Own.Money-=ConstUpgradeCost[FullBloodGrade];
                        Own.FullBlood+=200;
                        MoneyFlash=1;
                        FullBloodGrade++;
                    }
                }
                if(Preserve(AddAttack)){
                    if(Own.Money>=ConstUpgradeCost[AttackGrade]){
                        Own.Money-=ConstUpgradeCost[AttackGrade];
                        Own.AddAtack+=0.1;
                        MoneyFlash=1;
                        AttackGrade++;
                    }
                }
                if(Preserve(AddShotSpeed)){
                    if(Own.Money>=ConstUpgradeCost[ShotSpeedGrade]){
                        Own.Money-=ConstUpgradeCost[ShotSpeedGrade];
                        Own.AddShotSpeed+=0.05;
                        MoneyFlash=1;
                        ShotSpeedGrade++;
                    }
                }
                TP(5,WINDOWW+31,ConstGradeColor[FullBloodGrade+1],ConstUpgradeCostStr[FullBloodGrade]);
                TP(2,WINDOWW+3,OC,"Max Blood: "),gto(2,WINDOWW+18),color(OC),printf("%06d",Own.FullBlood);
                TP(2,WINDOWW+25,ConstGradeColor[FullBloodGrade],ConstGradeName[FullBloodGrade]);
                Own.MovePrint(Own.x,Own.y,0);
                TP(6,WINDOWW+31,ConstGradeColor[AttackGrade+1],ConstUpgradeCostStr[AttackGrade]);
                TP(3,WINDOWW+3,OC,"Attack: "),gto(3,WINDOWW+18),color(OC),printf("%06d",int((Own.Buffs[3]?ConstBulletDamage[3]:ConstBulletDamage[1])*Own.AddAtack));
                TP(3,WINDOWW+25,ConstGradeColor[AttackGrade],ConstGradeName[AttackGrade]);
                TP(7,WINDOWW+31,ConstGradeColor[ShotSpeedGrade+1],ConstUpgradeCostStr[ShotSpeedGrade]);
                TP(4,WINDOWW+3,OC,"Attack Speed: "),gto(4,WINDOWW+18),color(OC),printf("%06d",int(Own.ShotSpeed*Own.AddShotSpeed));
                TP(4,WINDOWW+25,ConstGradeColor[ShotSpeedGrade],ConstGradeName[ShotSpeedGrade]);
            }
            if(kbhit()){
                char c=getch();
                if(c==' '){
                    if(!STOP){
                        TP(WINDOWC/2-1,WINDOWW/2-16,OC,"+----------------------------------+");
                        TP(WINDOWC/2  ,WINDOWW/2-16,OC,"|   Press space bar to continue.   |");
                        TP(WINDOWC/2+1,WINDOWW/2-16,OC,"+----------------------------------+");
                        STOP=1;
                    }
                    else{
                        TP(WINDOWC/2-1,WINDOWW/2-16,OC,"                                    ");
                        TP(WINDOWC/2  ,WINDOWW/2-16,OC,"                                    ");
                        TP(WINDOWC/2+1,WINDOWW/2-16,OC,"                                    ");
                        STOP=0;
                        RECT W;
                        GetWindowRect(hd,&W);
                        SetCursorPos(W.left+Own.y*8+10,W.top+Own.x*16+80);
                    }
                }
            }
            /*Boos*/
            if(!BossFlag&&Own.NeedBoss()){
            //if(!BossFlag)
                Sleep(200);
                flash(3);
                OwnShotTimes=OwnLoseBlood=OwnShotOnTimes=0;
                EnemyClear();
                //UFORefreshTime=5000;
                //BuffAppearCD=5000;
                Boss.Init(cnt);
                BossFlag=1;
                cnt++;
            }
        }
    }
    

    后记

    特别鸣谢专业bug师万年大神犇程老,他帮我找出了数十个bug。

    展开全文
  • 一个用C++写的控制台贪吃蛇小游戏,可以在游戏的开始生成随机的地图,有计分功能,基本实现了贪吃蛇应有的功能,只是还有一些bug。注意用VS2015来打开该文件。
  • C++开发的控制台自动格斗小游戏,为了熟悉类的继承调用。其中包括一个角色类CRole类(基类),一个英雄类(继承自基类),一个敌人类(继承自基类)和一个战斗类(实现每场战斗的控制)。
  • 主要为大家详细介绍了C++控制台实现贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的伙伴们可以参考一下
  • 可作为C++课程设计内容,包含游戏编译执行全部代码
  • 2048小游戏,VS2013下编译通过,控制台程序,顺便想请教UI该怎么做
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼大家来看看是否还有BUG,如果有请提出来,代码质量可能不是很好,如大家有更好的方案希望能分享一下。可能有许多地方没有注释好,不过头文件的我都写上注释了。...
  • 主要为大家详细介绍了C++控制台实现俄罗斯方块游戏,具有一定的参考价值,感兴趣的伙伴们可以参考一下
  • C++ 控制台 升级打怪小游戏

    千次阅读 热门讨论 2018-07-25 11:24:16
    小游戏介绍:输入“勇士”生日,判断“勇士”星座,给出“勇士”的初始化属性(体力、智力和敏捷)。菜单栏有2个功能"查看状态”和“任务选择”。“查看状态”可以显示“勇士”的基本属性。“任务选择”可以选择...
  • 1 // 游戏菜单.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 #include"windows.h" 7 #define KEY_DOWN(vk_code) (Ge...
  • C++控制台贪吃蛇小游戏详细教程

    千次阅读 2018-01-04 21:59:10
    游戏截图     开始动画:    游戏过程:  游戏架构设计 该游戏的玩法简单,玩家通过键盘方向键控制蛇上下左右移动,吃到食物得分并增长,碰到墙或者自己的身体则死亡,游戏结束。  整个游戏...
  • 今天我为大家带来的是使用c++控制台的一个简单C++小游戏,我叫它速算王者,这是个比较简单的程序,不到100行就可以实现,我们来逐步看实现这个程序需要什么。 首先看第一段代码。 #include <bits/stdc++.h>//...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 383
精华内容 153
关键字:

c++控制台小游戏

c++ 订阅