问题标题: 谁有坦克大战代码

0
0

1
已采纳
梁彦博
梁彦博
初级光能
初级光能

坦克大战c++版

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

void gotoxy(int x,int y);//控制光标。X表示横坐标,Y表示纵坐标
void my_print();//设置界面
void print_thing();//打印物品
void print_home();//打印老家
void refresh_map();//刷新地图
void stop();//暂停

void print_my_tank();//打印我的坦克
void print_tank_1();//打印坦克1号
void print_tank_2();//打印坦克2号
void print_tank_3();//打印坦克3号

void clear_my_tank();//清除我的坦克,用于坦克移动后
void clear_tank_1();//清除坦克1号
void clear_tank_2();//清除坦克2号
void clear_tank_3();//清除坦克3号

void turn_up(int a[][3]);//我的坦克上转
void turn_down(int a[][3]);//我的坦克下转
void turn_left(int a[][3]);//我的坦克左转
void turn_right(int a[][3]);//我的坦克右转

void turn_up_1(int a[][3]);//坦克1号上转
void turn_down_1(int a[][3]);//坦克1号下转
void turn_left_1(int a[][3]);//坦克1号左转
void turn_right_1(int a[][3]);//坦克1号右转

void turn_up_2(int a[][3]);//坦克2号上转
void turn_down_2(int a[][3]);//坦克2号下转
void turn_left_2(int a[][3]);//坦克2号左转
void turn_right_2(int a[][3]);//坦克2号右转

void turn_up_3(int a[][3]);//坦克3号上转
void turn_down_3(int a[][3]);//坦克3号下转
void turn_left_3(int a[][3]);//坦克3号左转
void turn_right_3(int a[][3]);//坦克3号右转

void my_move();//我的坦克移动
void move_1();//坦克1号移动
void move_2();//坦克2号移动
void move_3();//坦克3号移动

void print_bullet(int x,int y);//打印敌方坦克的子弹
void print_my_bullet(int x,int y);//打印我的子弹
void clear_bullet(int x,int y);//清楚子弹
int  check_bullet(int x,int y);//检查子弹是否碰撞,没碰返回1,碰到返回0
void shoot();//计算我的坦克子弹的坐标
void shoot_1();//计算坦克1号子弹的坐标
void shoot_2();//计算坦克2号子弹的坐标
void shoot_3();//计算坦克3号子弹的坐标

void change_thing();//记录物品的变化
void change_home();//记录老家的变化
void change_bullet();//纪录子弹的变化
void change_star();//记录星星的变化
void change_tank();//记录我的坦克的变化
void change_tank_1();//记录坦克1号的变化
void change_tank_2();//记录坦克2号的变化
void change_tank_3();//记录坦克3号的变化

void switch_weapons();//切换武器
void switch_skin();//切换皮肤
void help();//帮助
void check_game();//检查游戏胜负
void check_lv();//检查等级
void next_level();//下一关
void get_map();//获得每一关的地图
void initial();//将所有量初始化
void gameover();//游戏结束

void console();//控制窗口
void screen_1();//屏幕1
void screen_2(char *p,int color);//屏幕2
void screen_3();//屏幕3
void produce_star();//产生一个星星
void print_star();//打印星星
void check_star();//检查星星的数量
void clear_star();//清除星星

int my_abs(int x);//绝对值函数,用系统的会有问题
int judge(int x,int y,int state);//判断我的坦克能否前进
int judge2(int x,int y,int state);// 辅助电脑判断能否前进

int check1(int x,int y);//辅助电脑判断的函数
int check2(int x,int y);//辅助电脑判断的函数
int check3(int x,int y);//辅助电脑判断的函数


int life=3;//生命
int enemy=13;//敌人数量
int level=1;//关卡
int weapons=1;//武器
int skin=1;//皮肤
int star=1;//星星
int s=0,t=0;//星星坐标
int score=0;//分数
int lv=1;//等级
int speed=10;//速度
char *info[5]={" "," "," "," "," "};//通知

int map[30][30]={0};//记录整个屏幕上的物体
int thing[28][28]={0};//障碍物,不包括边界
int home[3][4]={{2,2,2,2},{2,1,1,2},{2,1,1,2}};//老家,3行4列

int my_tank[3][3]={0};//我的坦克
int tank_1[3][3]={0};//敌人的坦克1号
int tank_2[3][3]={0};//敌人的坦克2号
int tank_3[3][3]={0};//敌人的坦克3号

int x  , y ;//我的坦克中心坐标
int x1 , y1;//坦克1号中心坐标
int x2 , y2;//坦克2号中心坐标
int x3 , y3;//坦克3号中心坐标

int m=0  , n=0 ;//我的坦克子弹的坐标
int m1=0 , n1=0;//坦克1号子弹的坐标
int m2=0 , n2=0;//坦克2号子弹的坐标
int m3=0 , n3=0;//坦克3号子弹的坐标

int state=0; //我的坦克方向(1上,2下,3左,4右)
int state_1=0;//坦克1号方向
int state_2=0;//坦克2号方向
int state_3=0;//坦克3号方向

int direction=0;//我的坦克子弹射向
int direction_1=0;//坦克1号子弹射向
int direction_2=0;//坦克2号子弹射向
int direction_3=0;//坦克3号子弹射向

int cp1=2;//辅助电脑判断的变量
int cp2=2;//辅助电脑判断的变量
int cp3=2;//辅助电脑判断的变量

int main()//主函数
{
    srand(time(NULL));//设置随机数种子
    console();//设置窗口
    my_print();//打印边框
    initial();//所有量初始化
    while(1)
    {
        int i1,i2,i3,i4,i5,i6,i7;
        my_move();//控制我的坦克移动
        if(i1++%30==0) //控制敌人坦克速度
            move_1();
        if(i2++%30==0) 
            move_2();
        if(i3++%30==0) 
            move_3();
        if(i4++%speed==0)   //控制子弹速度
            shoot();
        if(i5++%speed==0)
            shoot_1();
        if(i6++%speed==0)
            shoot_2();
        if(i7++%speed==0)
            shoot_3();
        screen_1();//刷新屏幕
        Sleep(30);
    }
    return 0;
}

//设置光标输出的位置函数
void gotoxy(int x,int y)//X表示横坐标,Y表示纵坐标。
{
    HANDLE app;
    COORD  pos;
    pos.X=x;
    pos.Y=y;
    app=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(app,pos);
}

//控制窗口
void console()
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);  
    CONSOLE_SCREEN_BUFFER_INFO bInfo; 
    GetConsoleScreenBufferInfo(hOut, &bInfo );  
    SetConsoleTitle("坦克大战"); // 设置窗口的标题
    COORD size = {90, 32};//设置窗口大小
    SetConsoleScreenBufferSize(hOut,size);  
    SMALL_RECT rc = {0,0, 63, 31};
    SetConsoleWindowInfo(hOut,true ,&rc);
}

//打印边界
void my_print()
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE |FOREGROUND_INTENSITY);//蓝色
    printf("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ |﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊﹊|\n");
    for(int i=0;i<13;i++)
    printf("■                                                        ■ |                          |\n");
    printf("■                                                        ■ |--------------------------|\n");
    for(int j=14;j<28;j++)
    printf("■                                                        ■ |                          |\n");
    printf("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ |﹍﹍﹍﹍﹍﹍﹍﹍﹍﹍﹍﹍﹍|\n");
}


//打印与清除坦克
void print_my_tank()
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            if(my_tank[i][j]==1)
            {
                switch(skin)
                {
                case 1 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);//淡蓝色
                        gotoxy(2*x+2*j-2,y+i-1);
                        printf("■");
                    }break;
                case 2 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);//绿色
                        gotoxy(2*x+2*j-2,y+i-1);
                        printf("■");
                    }break;
                case 3 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED);//黄色
                        gotoxy(2*x+2*j-2,y+i-1);
                        printf("■");
                    }break;
                case 4 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);//白色
                        gotoxy(2*x+2*j-2,y+i-1);
                        printf("■");
                    }break;
                case 5 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);//紫色
                        gotoxy(2*x+2*j-2,y+i-1);
                        printf("■");
                    }break;
                case 6 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);//红色
                        gotoxy(2*x+2*j-2,y+i-1);
                        printf("■");
                    }break;
                case 7 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);//蓝色
                        gotoxy(2*x+2*j-2,y+i-1);
                        printf("■");
                    }break;

                }

            }
}
void clear_my_tank()
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            {
                gotoxy(2*x+2*j-2,y+i-1);
                printf("  ");
            }
}
void print_tank_1()
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            if(tank_1[i][j]==1)
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);// 紫色
                gotoxy(2*x1+2*j-2,y1+i-1);
                printf("■");
            }
}
void clear_tank_1()
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            {
                gotoxy(2*x1+2*j-2,y1+i-1);
                printf("  ");
            }
}
void print_tank_2()
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            if(tank_2[i][j]==1)
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);// 紫色
                gotoxy(2*x2+2*j-2,y2+i-1);
                printf("■");
            }
}
void clear_tank_2()
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            {
                gotoxy(2*x2+2*j-2,y2+i-1);
                printf("  ");
            }
}
void print_tank_3()
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            if(tank_3[i][j]==1)
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);// 紫色
                gotoxy(2*x3+2*j-2,y3+i-1);
                printf("■");
            }
}
void clear_tank_3()
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            {
                gotoxy(2*x3+2*j-2,y3+i-1);
                printf("  ");
            }
}

void print_thing()                // 打印物品
{
    for(int j=0;j<28;j++)         // 从坐标(1,1)点开始打印
        for(int i=0;i<28;i++)
            if(thing[i][j]==1)
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
                gotoxy(2+2*j,1+i);
                printf("■");
            }
            else if(thing[i][j]==2)
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED);
                gotoxy(2+2*j,1+i);
                printf("■");
            }
            else if(thing[i][j]==3)
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
                gotoxy(2+2*j,1+i);
                printf("■");
            }
            else if(thing[i][j]==4)
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);
                gotoxy(2+2*j,1+i);
                printf("■");
            }
}

void print_home()                 //打印老家
{


    for(int i=0;i<3;i++)          //打印老家外墙       
        for(int j=0;j<4;j++)
            if(home[i][j]==1)
                {
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
                    gotoxy(26+2*j,26+i);
                    printf("■");
                }
            else if(home[i][j]==2)
                {
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED);
                    gotoxy(26+2*j,26+i);
                    printf("■");
                }
            else if(home[i][j]==3)
                {
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
                    gotoxy(26+2*j,26+i);
                    printf("■");
                }


    {
    for(int i=1;i<3;i++)          //打印老家内部
        for(int j=1;j<3;j++)
                {
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
                    gotoxy(26+2*j,26+i);
                    printf("■");
                }
    }

}


void print_bullet(int x,int y)    //打印敌方坦克的子弹子弹
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
    gotoxy(2*x,y);
    printf("⊕");
}

void print_my_bullet(int x,int y)    //打印我的子弹
{
    switch(weapons)
    {
    case 1 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
            gotoxy(2*x,y);
            printf("⊕");
        }break;
    case 2 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
            gotoxy(2*x,y);
            printf("∷");
        }break;
    case 3 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
            gotoxy(2*x,y);
            printf("◎");
        }break;
    case 4 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
            gotoxy(2*x,y);
            printf("※");
        }break;
    case 5 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
            gotoxy(2*x,y);
            printf("●");
        }break;
    }

}

void clear_bullet(int x,int y)
{
    gotoxy(2*x,y);
    printf("  ");
}


void screen_1()
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED);
    gotoxy(62,2);
    printf("          第 %d 关         ",level);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
    gotoxy(62,4);
    printf("分数: %d",score);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE|FOREGROUND_RED);
    gotoxy(80,4);
    printf("LV: %d ",lv);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
    gotoxy(62,6);
    printf("生命:     坦克×%d         ",life-1);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
    gotoxy(62,8);
    printf("敌方:     坦克×%d        ",enemy);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
    gotoxy(62,11);
    printf("当前武器:                 ");
    switch(weapons)
    {
    case 1 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
            gotoxy(62,13);
            printf("         普通子弹 ⊕      ");
        }break;
    case 2 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
            gotoxy(62,13);
            printf("           散弹   ∷      ");
        }break;
    case 3 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
            gotoxy(62,13);
            printf("          气泡弹  ◎      ");
        }break;
    case 4 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
            gotoxy(62,13);
            printf("          雪花弹  ※      ");
        }break;
    case 5 :
        {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
            gotoxy(62,13);
            printf("         超级炮弹 ●      ");
        }break;
    }


}

void screen_2(char *p,int color)
{

    for(int i=15;i<27;i++)//先清屏
    {
        gotoxy(62,i);
        printf("                          ");
    }

    info[0]=info[1];//内容上移
    info[1]=info[2];
    info[2]=info[3];
    info[3]=info[4];
    info[4]=p;

    for(int j=15;j<22;j=j+2)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
        gotoxy(62,j);
        printf("%s",info[(j+1)/2-8]);
    }
    switch(color)
    {
    case 1 :
        {
             SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);//绿
             gotoxy(62,23);
             printf("%s",info[4]);
        }break;
    case 2 :
        {
             SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);//淡蓝
             gotoxy(62,23);
             printf("%s",info[4]);
        }break;
    case 3 :
        {
             SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED);//黄
             gotoxy(62,23);
             printf("%s",info[4]);
        }break;
    case 4 :
        {
             SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);//红
             gotoxy(62,23);
             printf("%s",info[4]);
        }break;
    }
}

void screen_3()
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);
    gotoxy(62,27);
    printf("          h键帮助  Esc退出");
    gotoxy(62,28);
    printf("                          ");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
    if(star<=13)
    for(int i=1;i<=star;i++)
    {
        gotoxy(60+2*i,28);
        printf("★");
    }
}


void produce_star()
{
    int a=0;
    for(int i=4;i<26;i++)
    {
        for(int j=1;j<29;j++)
            if(map[i][j]==0 && rand()%300==0)
            {
                s=j,t=i;
                print_star();
                a=1;
                break;
            }
        if(a)
            break;
    }

}

void print_star()
{
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
        gotoxy(2*s,t);
        printf("★");
}

void change_star()
{
    if(s==x&&t==(y-1) || s==x&&t==(y+1) || s==(x-1)&&t==y || s==(x+1)&&t==y)
    {
        clear_star();
        s=0,t=0;
        star++;
        screen_2("恭喜你获得一颗星星",2);
        printf("\7");
        check_star();
        print_my_tank();
    }
    if(s==x1&&t==(y1-1) || s==x1&&t==(y1+1) || s==(x1-1)&&t==y1 || s==(x1+1)&&t==y1)
    {
        clear_star();
        s=0,t=0;
        screen_2("很遗憾星星被抢走了",4);
        printf("\7");
        print_tank_1();
    }
    if(s==x2&&t==(y2-1) || s==x2&&t==(y2+1) || s==(x2-1)&&t==y2 || s==(x2+1)&&t==y2)
    {
        clear_star();
        s=0,t=0;
        screen_2("很遗憾星星被抢走了",4);
        printf("\7");
        print_tank_2();
    }

    if(s==x3&&t==(y3-1) || s==x3&&t==(y3+1) || s==(x3-1)&&t==y3 || s==(x3+1)&&t==y3)
    {
        clear_star();
        s=0,t=0;
        screen_2("很遗憾星星被抢走了",4);
        printf("\7");
        print_tank_3();
    }



}

void clear_star()
{
    gotoxy(2*s,t);
    printf("  ");
}

void check_star()
{
    switch(star)
    {
    case 2 :screen_2("解锁新武器:  散弹",4),screen_3();break;
    case 3 :screen_2("成功解锁  绿色皮肤",2),screen_3();break;
    case 4 :screen_2("解锁新武器:  气泡弹",2),screen_3();break;
    case 5 :screen_2("成功解锁  黄色皮肤",3),screen_3();break;
    case 6 :screen_2("解锁新武器:  雪花弹",1),screen_3();break;
    case 7 :screen_2("成功解锁  白色皮肤",1),screen_3();break;
    case 8 :screen_2("解锁新武器:  超级炮弹",4),screen_3();break;
    case 9 :screen_2("成功解锁  紫色皮肤",1),screen_3();break;
    case 10 :screen_2("您已拥有10颗星啦",3),screen_3();break;
    case 11 :screen_2("成功解锁  红色皮肤",4),screen_3();break;
    case 12 :screen_2("您已拥有12颗星啦",3),screen_3();break;
    case 13 :screen_2("成功解锁 蓝色皮肤",1),screen_3();break;
    }

}

void switch_weapons()
{
    weapons++;
    if(weapons>star/2+1)
        weapons=1;
    if(star==1)
        screen_2("当前星星数不足,赶快收集吧",1);
    else
    {
        switch(weapons)
        {
        case 1 :screen_2("切换到普通子弹",1);break;
        case 2 :screen_2("切换到散弹",1);break;
        case 3 :screen_2("切换到气泡弹",1);break;
        case 4 :screen_2("切换到雪花弹",1);break;
        case 5 :screen_2("切换到超级炮弹弹",1);break;
        }
    }

}

void switch_skin()
{
    skin++;
    if(skin>(star-1)/2+1)
        skin=1;
    if(star==1 || star==2)
        screen_2("当前星星数不足,赶快收集吧",1);
    else
    {
        switch(skin)
        {
        case 1 :screen_2("切换到淡蓝色皮肤",1);break;
        case 2 :screen_2("切换到绿色皮肤",1);break;
        case 3 :screen_2("切换到黄色皮肤",1);break;
        case 4 :screen_2("切换到白色皮肤",1);break;
        case 5 :screen_2("切换到紫色皮肤",1);break;
        case 6 :screen_2("切换到红色皮肤",1);break;
        case 7 :screen_2("切换到蓝色皮肤",1);break;
        }
    }


}

void shoot()
{

    if(m!=0 || n!=0)
        if(map[n][m]==0)//如果子弹还留在地图上,就清除掉       
            clear_bullet(m,n);
    if(m==0 && n==0)//代表现在场上没有我的坦克的子弹,则重新发射子弹
    {
        switch(state)
        {
            case 1 :
                {
                    m=x;
                    n=y-2;
                    direction=1;
                }break;
            case 2 :
                {
                    m=x;
                    n=y+2;
                    direction=2;
                }break;
            case 3 :
                {
                    m=x-2;
                    n=y;
                    direction=3;
                }break;
            case 4 :
                {
                    m=x+2;
                    n=y;
                    direction=4;
                }break;
        }
    }
    else
    {
        switch(direction)
        {
            case 1 :n--;break;
            case 2 :n++;break;
            case 3 :m--;break;
            case 4 :m++;break;
        }
    }
    change_thing();//检查是否击中障碍物
    change_home();//检查是否击中老家
    change_bullet();//检查是否击中子弹
    change_tank_1();//检查是否击中坦克1号
    change_tank_2();//检查是否击中坦克2号
    change_tank_3();//检查是否击中坦克3号
    if(check_bullet(m,n))   
        print_my_bullet(m,n);
    else
        m=0,n=0;
}

void shoot_1()
{

    if(m1!=0 || n1!=0)
        if(map[n1][m1]==0)//如果子弹还留在地图上,就清除掉     
            clear_bullet(m1,n1);
    if(m1==0 && n1==0)//代表现在场上没有坦克1号的子弹,则重新发射子弹
    {
        switch(state_1)
        {
            case 1 :
                {
                    m1=x1;
                    n1=y1-2;
                    direction_1=1;
                }break;
            case 2 :
                {
                    m1=x1;
                    n1=y1+2;
                    direction_1=2;
                }break;
            case 3 :
                {
                    m1=x1-2;
                    n1=y1;
                    direction_1=3;
                }break;
            case 4 :
                {
                    m1=x1+2;
                    n1=y1;
                    direction_1=4;
                }break;
        }
    }
    else
    {
        switch(direction_1)
        {
            case 1 :n1--;break;
            case 2 :n1++;break;
            case 3 :m1--;break;
            case 4 :m1++;break;
        }
    }
    change_thing();//检查是否击中障碍物
    change_home();//检查是否击中老家
    change_bullet();//检查是否击中子弹
    change_tank();//检查是否击中我的坦克
    if(check_bullet(m1,n1)) 
        print_bullet(m1,n1);
    else
        m1=0,n1=0;
}

void shoot_2()
{

    if(m2!=0 || n2!=0)
        if(map[n2][m2]==0)//如果子弹还留在地图上,就清除掉     
            clear_bullet(m2,n2);
    if(m2==0 && n2==0)//代表现在场上没有坦克2号的子弹,则重新发射子弹
    {
        switch(state_2)
        {
            case 1 :
                {
                    m2=x2;
                    n2=y2-2;
                    direction_2=1;
                }break;
            case 2 :
                {
                    m2=x2;
                    n2=y2+2;
                    direction_2=2;
                }break;
            case 3 :
                {
                    m2=x2-2;
                    n2=y2;
                    direction_2=3;
                }break;
            case 4 :
                {
                    m2=x2+2;
                    n2=y2;
                    direction_2=4;
                }break;
        }
    }
    else
    {
        switch(direction_2)
        {
            case 1 :n2--;break;
            case 2 :n2++;break;
            case 3 :m2--;break;
            case 4 :m2++;break;
        }
    }
    change_thing();//检查是否击中障碍物
    change_home();//检查是否击中老家
    change_bullet();//检查是否击中子弹
    change_tank();//检查是否击中我的坦克
    if(check_bullet(m2,n2)) 
        print_bullet(m2,n2);
    else
        m2=0,n2=0;
}


void shoot_3()
{

    if(m3!=0 || n3!=0)
        if(map[n3][m3]==0)//如果子弹还留在地图上,就清除掉     
            clear_bullet(m3,n3);
    if(m3==0 && n3==0)//代表现在场上没有坦克3号的子弹,则重新发射子弹
    {
        switch(state_3)
        {
            case 1 :
                {
                    m3=x3;
                    n3=y3-2;
                    direction_3=1;
                }break;
            case 2 :
                {
                    m3=x3;
                    n3=y3+2;
                    direction_3=2;
                }break;
            case 3 :
                {
                    m3=x3-2;
                    n3=y3;
                    direction_3=3;
                }break;
            case 4 :
                {
                    m3=x3+2;
                    n3=y3;
                    direction_3=4;
                }break;
        }
    }
    else
    {
        switch(direction_3)
        {
            case 1 :n3--;break;
            case 2 :n3++;break;
            case 3 :m3--;break;
            case 4 :m3++;break;
        }
    }
    change_thing();//检查是否击中障碍物
    change_home();//检查是否击中老家
    change_bullet();//检查是否击中子弹
    change_tank();//检查是否击中我的坦克
    if(check_bullet(m3,n3))
        print_bullet(m3,n3);
    else
        m3=0,n3=0;
}

void turn_up(int a[][3])
{
    int tank_up[3][3]={{0,1,0},{1,1,1},{1,0,1}};
    if(state==1)
    {
        if(judge(x,y,state))
        {
            clear_my_tank();
            y--;
            print_my_tank();
            refresh_map();
        }
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_up[i][j];
        clear_my_tank();
        print_my_tank();
        state=1;
        refresh_map();

    }
    change_star();
}


void turn_down(int a[][3])
{
    int tank_down[3][3]={{1,0,1},{1,1,1},{0,1,0}};
    if(state==2)
    {
        if(judge(x,y,state))
        {
            clear_my_tank();
            y++;
            print_my_tank();
            refresh_map();
        }
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_down[i][j];
        clear_my_tank();
        print_my_tank();
        state=2;
        refresh_map();
    }
    change_star();

}

void turn_left(int a[][3])
{
    int tank_left[3][3]={{0,1,1},{1,1,0},{0,1,1}};
    if(state==3)
    {
        if(judge(x,y,state))
        {
            clear_my_tank();
            x--;
            print_my_tank();
            refresh_map();
        }
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_left[i][j];
        clear_my_tank();
        print_my_tank();
        state=3;
        refresh_map();
    }
    change_star();

}

void turn_right(int a[][3])
{
    int tank_right[3][3]={{1,1,0},{0,1,1},{1,1,0}};
    if(state==4)
    {
        if(judge(x,y,state))
        {
            clear_my_tank();
            x++;
            print_my_tank();
            refresh_map();
        }
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_right[i][j];
        clear_my_tank();
        print_my_tank();
        state=4;
        refresh_map();
    }
    change_star();

}

void turn_up_1(int a[][3])
{
    int tank_up[3][3]={{0,1,0},{1,1,1},{1,0,1}};
    if(state_1==1)
    {
        clear_tank_1();
        y1--;
        print_tank_1();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_up[i][j];
        clear_tank_1();
        print_tank_1();
        state_1=1;
        refresh_map();
    }
}

void turn_down_1(int a[][3])
{
    int tank_down[3][3]={{1,0,1},{1,1,1},{0,1,0}};
    if(state_1==2)
    {
        clear_tank_1();
        y1++;
        print_tank_1();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_down[i][j];
        clear_tank_1();
        print_tank_1();
        state_1=2;
        refresh_map();
    }
}

void turn_left_1(int a[][3])
{
    int tank_left[3][3]={{0,1,1},{1,1,0},{0,1,1}};
    if(state_1==3)
    {
        clear_tank_1();
        x1--;
        print_tank_1();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_left[i][j];
        clear_tank_1();
        print_tank_1();
        state_1=3;
        refresh_map();
    }
}

void turn_right_1(int a[][3])
{
    int tank_right[3][3]={{1,1,0},{0,1,1},{1,1,0}};
    if(state_1==4)
    {
        clear_tank_1();
        x1++;
        print_tank_1();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_right[i][j];
        clear_tank_1();
        print_tank_1();
        state_1=4;
        refresh_map();
    }
}

void turn_up_2(int a[][3])
{
    int tank_up[3][3]={{0,1,0},{1,1,1},{1,0,1}};
    if(state_2==1)
    {
        clear_tank_2();
        y2--;
        print_tank_2();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_up[i][j];
        clear_tank_2();
        print_tank_2();
        state_2=1;
        refresh_map();
    }
}

void turn_down_2(int a[][3])
{
    int tank_down[3][3]={{1,0,1},{1,1,1},{0,1,0}};
    if(state_2==2)
    {
        clear_tank_2();
        y2++;
        print_tank_2();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_down[i][j];
        clear_tank_2();
        print_tank_2();
        state_2=2;
        refresh_map();
    }
}

void turn_left_2(int a[][3])
{
    int tank_left[3][3]={{0,1,1},{1,1,0},{0,1,1}};
    if(state_2==3)
    {
        clear_tank_2();
        x2--;
        print_tank_2();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_left[i][j];
        clear_tank_2();
        print_tank_2();
        state_2=3;
        refresh_map();
    }
}

void turn_right_2(int a[][3])
{
    int tank_right[3][3]={{1,1,0},{0,1,1},{1,1,0}};
    if(state_2==4)
    {
        clear_tank_2();
        x2++;
        print_tank_2();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_right[i][j];
        clear_tank_2();
        print_tank_2();
        state_2=4;
        refresh_map();
    }
}

void turn_up_3(int a[][3])
{
    int tank_up[3][3]={{0,1,0},{1,1,1},{1,0,1}};
    if(state_3==1)
    {
        clear_tank_3();
        y3--;
        print_tank_3();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_up[i][j];
        clear_tank_3();
        print_tank_3();
        state_3=1;
        refresh_map();
    }
}

void turn_down_3(int a[][3])
{
    int tank_down[3][3]={{1,0,1},{1,1,1},{0,1,0}};
    if(state_3==2)
    {
        clear_tank_3();
        y3++;
        print_tank_3();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_down[i][j];
        clear_tank_3();
        print_tank_3();
        state_3=2;
        refresh_map();
    }
}

void turn_left_3(int a[][3])
{
    int tank_left[3][3]={{0,1,1},{1,1,0},{0,1,1}};
    if(state_3==3)
    {
        clear_tank_3();
        x3--;
        print_tank_3();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_left[i][j];
        clear_tank_3();
        print_tank_3();
        state_3=3;
        refresh_map();
    }
}

void turn_right_3(int a[][3])
{
    int tank_right[3][3]={{1,1,0},{0,1,1},{1,1,0}};
    if(state_3==4)
    {
        clear_tank_3();
        x3++;
        print_tank_3();
        refresh_map();
    }
    else
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                a[i][j]=tank_right[i][j];
        clear_tank_3();
        print_tank_3();
        state_3=4;
        refresh_map();
    }
}

int judge(int x,int y,int state)//x,y坦克当前坐标,state坦克当前方向
{
    switch(state)
    {
    case 1 :if(map[y-2][x]==0 && map[y-1][x-1]==0 && map[y-1][x+1]==0 && map[y-2][x-1]==0 && map[y-2][x+1]==0)
                return 1;
            else
                return 0;
    case 2 :if(map[y+2][x]==0 && map[y+1][x-1]==0 && map[y+1][x+1]==0 && map[y+2][x-1]==0 && map[y+2][x+1]==0)
                return 1;
            else
                return 0;
    case 3 :if(map[y][x-2]==0 && map[y-1][x-1]==0 && map[y+1][x-1]==0 && map[y-1][x-2]==0 && map[y+1][x-2]==0)
                return 1;
            else
                return 0;
    case 4 :if(map[y][x+2]==0 && map[y-1][x+1]==0 && map[y+1][x+1]==0 && map[y-1][x+2]==0 && map[y+1][x+2]==0)
                return 1;
            else
                return 0;
    }
}

int judge2(int x,int y,int state)//x,y坦克当前坐标,state坦克当前方向
{
    switch(state)
    {
    case 1 :if(map[y-2][x]==0 && map[y-2][x-1]==0 && map[y-2][x+1]==0)
                return 1;
            else
                return 0;
    case 2 :if(map[y+2][x]==0 && map[y+2][x-1]==0 && map[y+2][x+1]==0)
                return 1;
            else
                return 0;
    case 3 :if(map[y][x-2]==0 && map[y-1][x-2]==0 && map[y+1][x-2]==0)
                return 1;
            else
                return 0;
    case 4 :if(map[y][x+2]==0 && map[y-1][x+2]==0 && map[y+1][x+2]==0)
                return 1;
            else
                return 0;
    }
}

void refresh_map()               //i代表行,即纵坐标;j代表列,即横坐标
{
    {
        for(int i=0;i<30;i++)          //首先地图清零
            for(int j=0;j<30;j++)
                map[i][j]=0;
    }

    {
        for(int i=0;i<30;i++)    //地图第一部分:围墙(完全不动)
        {
            map[i][0]=1;
            map[i][29]=1;
        }
        for(int j=0;j<30;j++) 
        {
            map[0][j]=1;
            map[29][j]=1;
        }
    }

    {
        for(int i=0;i<3;i++)   //地图第二部分:老家(几乎不动)
            for(int j=0;j<4;j++)
                map[i+26][j+13]=home[i][j];
    }

    {
        for(int i=0;i<28;i++)  //地图第三部分:障碍物(有时改变)
            for(int j=0;j<28;j++)
                map[i+1][j+1]=thing[i][j];
    }

    {
        switch(state)          //地图第四部分:坦克(总是改变)
        {
        case 1 :
            {
                map[y-1][x-1]=0;  map[y-1][x]=1;      map[y-1][x+1]=0;
                map[y][x-1]=1;    map[y][x]=1;        map[y][x+1]=1;
                map[y+1][x-1]=1;  map[y+1][x]=0;      map[y+1][x+1]=1;

            }break;
        case 2 :
            {
                map[y-1][x-1]=1;  map[y-1][x]=0;      map[y-1][x+1]=1;
                map[y][x-1]=1;    map[y][x]=1;        map[y][x+1]=1;
                map[y+1][x-1]=0;  map[y+1][x]=1;      map[y+1][x+1]=0;
            }break;
        case 3 :
            {
                map[y-1][x-1]=0;  map[y-1][x]=1;      map[y-1][x+1]=1;
                map[y][x-1]=1;    map[y][x]=1;        map[y][x+1]=0;
                map[y+1][x-1]=0;  map[y+1][x]=1;      map[y+1][x+1]=1;
            }break;
        case 4 :
            {
                map[y-1][x-1]=1;  map[y-1][x]=1;      map[y-1][x+1]=0;
                map[y][x-1]=0;    map[y][x]=1;        map[y][x+1]=1;
                map[y+1][x-1]=1;  map[y+1][x]=1;      map[y+1][x+1]=0;
            }break;
        }

        switch(state_1)
        {
        case 1 :
            {
                map[y1-1][x1-1]=0;  map[y1-1][x1]=1;      map[y1-1][x1+1]=0;
                map[y1][x1-1]=1;    map[y1][x1]=1;        map[y1][x1+1]=1;
                map[y1+1][x1-1]=1;  map[y1+1][x1]=0;      map[y1+1][x1+1]=1;

            }break;
        case 2 :
            {
                map[y1-1][x1-1]=1;  map[y1-1][x1]=0;      map[y1-1][x1+1]=1;
                map[y1][x1-1]=1;    map[y1][x1]=1;        map[y1][x1+1]=1;
                map[y1+1][x1-1]=0;  map[y1+1][x1]=1;      map[y1+1][x1+1]=0;
            }break;
        case 3 :
            {
                map[y1-1][x1-1]=0;  map[y1-1][x1]=1;      map[y1-1][x1+1]=1;
                map[y1][x1-1]=1;    map[y1][x1]=1;        map[y1][x1+1]=0;
                map[y1+1][x1-1]=0;  map[y1+1][x1]=1;      map[y1+1][x1+1]=1;
            }break;
        case 4 :
            {
                map[y1-1][x1-1]=1;  map[y1-1][x1]=1;      map[y1-1][x1+1]=0;
                map[y1][x1-1]=0;    map[y1][x1]=1;        map[y1][x1+1]=1;
                map[y1+1][x1-1]=1;  map[y1+1][x1]=1;      map[y1+1][x1+1]=0;
            }break;
        }

        switch(state_2)
        {
        case 1 :
            {
                map[y2-1][x2-1]=0;  map[y2-1][x2]=1;      map[y2-1][x2+1]=0;
                map[y2][x2-1]=1;    map[y2][x2]=1;        map[y2][x2+1]=1;
                map[y2+1][x2-1]=1;  map[y2+1][x2]=0;      map[y2+1][x2+1]=1;

            }break;
        case 2 :
            {
                map[y2-1][x2-1]=1;  map[y2-1][x2]=0;      map[y2-1][x2+1]=1;
                map[y2][x2-1]=1;    map[y2][x2]=1;        map[y2][x2+1]=1;
                map[y2+1][x2-1]=0;  map[y2+1][x2]=1;      map[y2+1][x2+1]=0;
            }break;
        case 3 :
            {
                map[y2-1][x2-1]=0;  map[y2-1][x2]=1;      map[y2-1][x2+1]=1;
                map[y2][x2-1]=1;    map[y2][x2]=1;        map[y2][x2+1]=0;
                map[y2+1][x2-1]=0;  map[y2+1][x2]=1;      map[y2+1][x2+1]=1;
            }break;
        case 4 :
            {
                map[y2-1][x2-1]=1;  map[y2-1][x2]=1;      map[y2-1][x2+1]=0;
                map[y2][x2-1]=0;    map[y2][x2]=1;        map[y2][x2+1]=1;
                map[y2+1][x2-1]=1;  map[y2+1][x2]=1;      map[y2+1][x2+1]=0;
            }break;
        }

        switch(state_3)
        {
        case 1 :
            {
                map[y3-1][x3-1]=0;  map[y3-1][x3]=1;      map[y3-1][x3+1]=0;
                map[y3][x3-1]=1;    map[y3][x3]=1;        map[y3][x3+1]=1;
                map[y3+1][x3-1]=1;  map[y3+1][x3]=0;      map[y3+1][x3+1]=1;

            }break;
        case 2 :
            {
                map[y3-1][x3-1]=1;  map[y3-1][x3]=0;      map[y3-1][x3+1]=1;
                map[y3][x3-1]=1;    map[y3][x3]=1;        map[y3][x3+1]=1;
                map[y3+1][x3-1]=0;  map[y3+1][x3]=1;      map[y3+1][x3+1]=0;
            }break;
        case 3 :
            {
                map[y3-1][x3-1]=0;  map[y3-1][x3]=1;      map[y3-1][x3+1]=1;
                map[y3][x3-1]=1;    map[y3][x3]=1;        map[y3][x3+1]=0;
                map[y3+1][x3-1]=0;  map[y3+1][x3]=1;      map[y3+1][x3+1]=1;
            }break;
        case 4 :
            {
                map[y3-1][x3-1]=1;  map[y3-1][x3]=1;      map[y3-1][x3+1]=0;
                map[y3][x3-1]=0;    map[y3][x3]=1;        map[y3][x3+1]=1;
                map[y3+1][x3-1]=1;  map[y3+1][x3]=1;      map[y3+1][x3+1]=0;
            }break;
        }
    }
}


void my_move()
{
    char key;
    if (kbhit()) //检测,如果有按键就执行if里面的
    {
        key = getch();//捕获按键
        switch( key ) 
        {
        case 72:turn_up(my_tank);//上
            break;
        case 75:turn_left(my_tank);//左
            break;
        case 77:turn_right(my_tank);//右
            break;
        case 80:turn_down(my_tank);//下
            break;
        case 32:stop();//空格 暂停或开始
            break;
        case 104:help();//小h切换到帮助菜单
            break;
        case 115:switch_skin(),print_my_tank();//小s键切换皮肤
            break;
        case 119:switch_weapons();//小w键切换武器
            break;

        case 27:exit(0);//Esc 退出
        default: ;
        }
    }
}

int check1(int x,int y)//在正上面,用它检测
{
    for(int j=y;j<27;j++)
        if(map[j][x]==4)
            return 0;
    return 1;
}

int check2(int x,int y)//在正左面,用它检测
{
    for(int i=x;i<14;i++)
        if(map[y][i]==4)
            return 0;
    return 1;
}

int check3(int x,int y)//在正右面,用它检测
{
    for(int i=x;i>15;i--)
        if(map[y][i]==4)
            return 0;
    return 1;
}

void move_1()
{
    if((x1==14 || x1==15) && check1(x1,y1))//在正上面
    {
            if(state_1!=2)
                turn_down_1(tank_1);
    }
    else if(x1<14 && y1==27 && check2(x1,y1))//在正左面
    {
            if(state_1!=4)
                turn_right_1(tank_1);
    }
    else if(x1>15 && y1==27 && check3(x1,y1))//在正右面
    {
            if(state_1!=3)
                turn_left_1(tank_1);
    }
    else
    {
        if(judge2(x1,y1,cp1))
            switch(cp1)
            {
            case 1 :turn_up_1(tank_1);break;
            case 2 :turn_down_1(tank_1);break;
            case 3 :turn_left_1(tank_1);break;
            case 4 :turn_right_1(tank_1);break;
            }
        while(judge2(x1,y1,cp1) == 0)
        {
            cp1=(rand()%4+1);
        }

    }


}

void move_2()
{
    if((x2==14 || x2==15) && check1(x2,y2))//在正上面
    {
            if(state_2!=2)
                turn_down_2(tank_2);
    }
    else if(x2<14 && y2==27 && check2(x2,y2))//在正左面
    {
            if(state_2!=4)
                turn_right_2(tank_2);
    }
    else if(x2>15 && y2==27 && check3(x2,y2))//在正右面
    {
            if(state_2!=3)
                turn_left_2(tank_2);
    }
    else
    {
        if(judge2(x2,y2,cp2))
            switch(cp2)
            {
            case 1 :turn_up_2(tank_2);break;
            case 2 :turn_down_2(tank_2);break;
            case 3 :turn_left_2(tank_2);break;
            case 4 :turn_right_2(tank_2);break;
            }
        while(judge2(x2,y2,cp2) == 0)
        {
            cp2=(rand()%4+1);
        }

    }
}

void move_3()
{
    if((x3==14 || x3==15) && check1(x3,y3))//在正上面
    {
            if(state_3!=2)
                turn_down_3(tank_3);
    }
    else if(x3<14 && y3==27 && check2(x3,y3))//在正左面
    {
            if(state_3!=4)
                turn_right_3(tank_3);
    }
    else if(x3>15 && y3==27 && check3(x3,y3))//在正右面
    {

            if(state_3!=3)
                turn_left_3(tank_3);
    }
    else
    {
        if(judge2(x3,y3,cp3))
            switch(cp3)
            {
            case 1 :turn_up_3(tank_3);break;
            case 2 :turn_down_3(tank_3);break;
            case 3 :turn_left_3(tank_3);break;
            case 4 :turn_right_3(tank_3);break;
            }
        while(judge2(x3,y3,cp3) == 0)
        {
            cp3=(rand()%4+1);
        }



    }
}

int check_bullet(int x,int y)
{
    if(map[y][x])
        return 0;
    return 1;
}

void change_thing()//物品被子弹击中会改变
{
    if(m>0&&m<29 && n>0&&n<29)//被我的子弹击中
        if(thing[n-1][m-1]==1)//打中第一种方块
        {
            if(weapons==2)
            {
                if(thing[n][m-1]==1)
                    thing[n][m-1]=0;
                    gotoxy(2*m,n+1);
                    printf("  ");//擦去方块
                if(thing[n-2][m-1]==1)
                    thing[n-2][m-1]=0;
                    gotoxy(2*m,n-1);
                    printf("  ");//擦去方块
                if(thing[n-1][m]==1)
                    thing[n-1][m]=0;
                    gotoxy(2*(m+1),n);
                    printf("  ");//擦去方块
                if(thing[n-1][m-2]==1)
                    thing[n-1][m-2]=0;
                    gotoxy(2*(m-1),n);
                    printf("  ");//擦去方块
                thing[n-1][m-1]=0;
                gotoxy(2*m,n);
                printf("  ");//擦去方块
                m=0,n=0;//子弹消失
                print_thing();
                refresh_map();
            }
            else if(weapons==3)
            {
                thing[n-1][m-1]=0;
                gotoxy(2*m,n);
                printf("  ");//擦去方块
                print_my_bullet(m,n);
                print_thing();
                refresh_map();
            }
            else
            {
                thing[n-1][m-1]=0;
                gotoxy(2*m,n);
                printf("  ");//擦去方块
                m=0,n=0;//子弹消失
                print_thing();
                refresh_map();
            }



        }

        else if(thing[n-1][m-1]==2)//打到第二种方块
        {
            if(weapons==5)
            {
                thing[n-1][m-1]=0;
                gotoxy(2*m,n);
                printf("  ");
                m=0,n=0;//子弹消失
                print_thing();
                refresh_map();
            }
            else if(weapons==2)
            {
                m=0,n=0;
            }
            else
            {
                thing[n-1][m-1]=1;
                m=0,n=0;//子弹消失
                print_thing();
                refresh_map();
            }
        }

        else if(thing[n-1][m-1]==3)
        {
            if(weapons==4 || weapons==2)
                m=0,n=0;
            else if(weapons==5)
            {
                thing[n-1][m-1]=0;
                gotoxy(2*m,n);
                printf("  ");
                m=0,n=0;//子弹消失
                print_thing();
                refresh_map();
            }
            else
            {
                thing[n-1][m-1]=2;
                m=0,n=0;//子弹消失
                print_thing();
                refresh_map();
            }
        }

        else if(thing[n-1][m-1]==4)//此方块不受子弹影响
        {
            m=0,n=0;//子弹消失
        }

    if(m1>0&&m1<29 && n1>0&&n1<29)//被坦克1号子弹击中
        if(thing[n1-1][m1-1]==1)
        {
            thing[n1-1][m1-1]=0;
            gotoxy(2*m1,n1);
            printf("  ");
            m1=0,n1=0;
            print_thing();
            refresh_map();
        }
        else if(thing[n1-1][m1-1]==2)
        {
            thing[n1-1][m1-1]=1;
            m1=0,n1=0;//子弹消失
            print_thing();
            refresh_map();
        }
        else if(thing[n1-1][m1-1]==3)
        {
            thing[n1-1][m1-1]=2;
            m1=0,n1=0;//子弹消失
            print_thing();
            refresh_map();
        }
        else if(thing[n-1][m-1]==4)//此方块不受子弹影响
        {
            m1=0,n1=0;//子弹消失
        }

    if(m2>0&&m2<29 && n2>0&&n2<29)
        if(thing[n2-1][m2-1]==1)
        {
            thing[n2-1][m2-1]=0;
            gotoxy(2*m2,n2);
            printf("  ");
            m2=0,n2=0;
            print_thing();
            refresh_map();
        }
        else if(thing[n2-1][m2-1]==2)
        {
            thing[n2-1][m2-1]=1;
            m2=0,n2=0;//子弹消失
            print_thing();
            refresh_map();
        }
        else if(thing[n2-1][m2-1]==3)
        {
            thing[n2-1][m2-1]=2;
            m2=0,n2=0;//子弹消失
            print_thing();
            refresh_map();
        }
        else if(thing[n2-1][m2-1]==4)//此方块不受子弹影响
        {
            m2=0,n2=0;//子弹消失
        }

    if(m3>0&&m3<29 && n3>0&&n3<29)
        if(thing[n3-1][m3-1]==1)
        {
            thing[n3-1][m3-1]=0;
            gotoxy(2*m3,n3);
            printf("  ");
            m3=0,n3=0;
            print_thing();
            refresh_map();
        }
        else if(thing[n3-1][m3-1]==2)
        {
            thing[n3-1][m3-1]=1;
            m3=0,n3=0;//子弹消失
            print_thing();
            refresh_map();
        }
        else if(thing[n3-1][m3-1]==3)
        {
            thing[n3-1][m3-1]=2;
            m3=0,n3=0;//子弹消失
            print_thing();
            refresh_map();
        }
        else if(thing[n3-1][m3-1]==4)//此方块不受子弹影响
        {
            m3=0,n3=0;//子弹消失
        }



}

void change_home()
{
    if(m==14&&n==27 || m==15&&n==27 || m==14&&n==28 || m==15&&n==28)//如果子弹打到老家里,游戏结束
         gameover();
    else if(m>12 && n>25 && m<17 && n<29)
        if(weapons==4)//只有4号子弹对老家的墙有效
        {
            home[n-26][m-13]=3;
            screen_2("你修复了老家哦!",1);
            m=0,n=0;   //子弹消失
            print_home();
            refresh_map();
        }
        else
            m=0,n=0;


    if(m1==14&&n1==27 || m1==15&&n1==27 || m1==14&&n1==28 || m1==15&&n1==28)
         gameover();
    else if(m1>12 && n1>25 && m1<17 && n1<29)

            if(home[n1-26][m1-13]==1)         
            {
                home[n1-26][m1-13]=0;
                screen_2("警报! 警报!",4);
                gotoxy(2*m1,n1);
                printf("  ");
                m1=0,n1=0;
                print_home();
                refresh_map();
            }
            else if(home[n1-26][m1-13]==2)        
            {
                home[n1-26][m1-13]=1;
                screen_2("敌人威胁到了你的老家",4);
                m1=0,n1=0;   //子弹消失
                print_home();
                refresh_map();
            }
            else if(home[n1-26][m1-13]==3)         
            {
                home[n1-26][m1-13]=2;
                screen_2("敌人对你的防御开始了打击",4);
                m1=0,n1=0;   //子弹消失
                print_home();
                refresh_map();
            }

    if(m2==14&&n2==27 || m2==15&&n2==27 || m2==14&&n2==28 || m2==15&&n2==28)
         gameover();
    else if(m2>12 && n2>25 && m2<17 && n2<29)
        if(home[n2-26][m2-13]==1)         
        {
            home[n2-26][m2-13]=0;
            screen_2("警报! 警报!",4);
            gotoxy(2*m2,n2);
            printf("  ");
            m2=0,n2=0;
            print_home();
            refresh_map();
        }
        else if(home[n2-26][m2-13]==2)        
        {
            home[n2-26][m2-13]=1;
            screen_2("敌人威胁到了你的老家",4);
            m2=0,n2=0;   //子弹消失
            print_home();
            refresh_map();
        }
        else if(home[n2-26][m2-13]==3)         
        {
            home[n2-26][m2-13]=2;
            screen_2("敌人对你的防御开始了打击",4);
            m2=0,n2=0;   //子弹消失
            print_home();
            refresh_map();
        }

    if(m3==14&&n3==27 || m3==15&&n3==27 || m3==14&&n3==28 || m3==15&&n3==28)
         gameover();
    else if(m3>12 && n3>25 && m3<17 && n3<29)
        if(home[n3-26][m3-13]==1)        
        {
            home[n3-26][m3-13]=0;
            screen_2("警报! 警报!",4);
            gotoxy(2*m3,n3);
            printf("  ");
            m3=0,n3=0;
            print_home();
            refresh_map();
        }
        else if(home[n3-26][m3-13]==2)        
        {
            home[n3-26][m3-13]=1;
            screen_2("敌人威胁到了你的老家",4);
            m3=0,n3=0;   //子弹消失
            print_home();
            refresh_map();
        }
        else if(home[n3-26][m3-13]==3)         
        {
            home[n3-26][m3-13]=2;
            screen_2("敌人对你的防御开始了打击",4);
            m3=0,n3=0;   //子弹消失
            print_home();
            refresh_map();
        }


}

void change_bullet()//当我的坦克子弹和敌人坦克子弹碰撞
{
    if(m!=0 && m==m1 && n==n1)
    {
        clear_bullet(m,n);
        m=0,n=0,
        clear_bullet(m1,n1);
        m1=0,n1=0;
    }
    if(m!=0 && m==m2 && n==n2)
    {
        clear_bullet(m,n);
        m=0,n=0,
        clear_bullet(m2,n2);
        m2=0,n2=0;
    }
    if(m!=0 && m==m3 && n==n3)
    {
        clear_bullet(m,n);
        m=0,n=0,
        clear_bullet(m3,n3);
        m3=0,n3=0;
    }
}

void change_tank()
{
    switch(state)
    {
    case 1 :                           //当我的坦克方向向上时
        {
            if(x==m1&&(y-1)==n1 || (x-1)==m1&&y==n1 || x==m1&&y==n1 || (x+1)==m1&&y==n1 || (x-1)==m1&&(y+1)==n1 || (x+1)==m1&&(y+1)==n1)//如果坦克1号子弹打到我的坦克
                clear_my_tank(),screen_2("坦克1号击中了你  生命值减1",4),x=10,y=27,m1=0,n1=0,life--,check_game(),turn_up(my_tank);//我的坦克回到初始位置,坦克1号子弹消失,生命值减1,检查游戏是否结束,若没结束初始化方向
            if(x==m2&&(y-1)==n2 || (x-1)==m2&&y==n2 || x==m2&&y==n2 || (x+1)==m2&&y==n2 || (x-1)==m2&&(y+1)==n2 || (x+1)==m2&&(y+1)==n2)//如果坦克2号子弹打到我的坦克
                clear_my_tank(),screen_2("坦克2号击中了你  生命值减1",4),x=10,y=27,m2=0,n2=0,life--,check_game(),turn_up(my_tank);//我的坦克回到初始位置,坦克2号子弹消失,生命值减1,检查游戏是否结束,若没结束初始化方向
            if(x==m3&&(y-1)==n3 || (x-1)==m3&&y==n3 || x==m3&&y==n3 || (x+1)==m3&&y==n3 || (x-1)==m3&&(y+1)==n3 || (x+1)==m3&&(y+1)==n3)//如果坦克3号子弹打到我的坦克
                clear_my_tank(),screen_2("坦克3号击中了你  生命值减1",4),x=10,y=27,m3=0,n3=0,life--,check_game(),turn_up(my_tank);//我的坦克回到初始位置,坦克3号子弹消失,生命值减1,检查游戏是否结束,若没结束初始化方向
        }break;
    case 2 :
        {
            if(x==m1&&(y+1)==n1 || (x-1)==m1&&y==n1 || x==m1&&y==n1 || (x+1)==m1&&y==n1 || (x-1)==m1&&(y-1)==n1 || (x+1)==m1&&(y-1)==n1)
                clear_my_tank(),screen_2("坦克1号击中了你  生命值减1",4),x=10,y=27,m1=0,n1=0,life--,check_game(),turn_up(my_tank);
            if(x==m2&&(y+1)==n2 || (x-1)==m2&&y==n2 || x==m2&&y==n2 || (x+1)==m2&&y==n2 || (x-1)==m2&&(y-1)==n2 || (x+1)==m2&&(y-1)==n2)
                clear_my_tank(),screen_2("坦克2号击中了你  生命值减1",4),x=10,y=27,m2=0,n2=0,life--,check_game(),turn_up(my_tank);
            if(x==m3&&(y+1)==n3 || (x-1)==m3&&y==n3 || x==m3&&y==n3 || (x+1)==m3&&y==n3 || (x-1)==m3&&(y-1)==n3 || (x+1)==m3&&(y-1)==n3)
                clear_my_tank(),screen_2("坦克3号击中了你  生命值减1",4),x=10,y=27,m3=0,n3=0,life--,check_game(),turn_up(my_tank);

        }
    case 3 :
        {
            if(x==m1&&(y-1)==n1 || (x-1)==m1&&y==n1 || x==m1&&y==n1 || (x+1)==m1&&(y-1)==n1 || x==m1&&(y+1)==n1 || (x+1)==m1&&(y+1)==n1)
                clear_my_tank(),screen_2("坦克1号击中了你  生命值减1",4),x=10,y=27,m1=0,n1=0,life--,check_game(),turn_up(my_tank);
            if(x==m2&&(y-1)==n2 || (x-1)==m2&&y==n2 || x==m2&&y==n2 || (x+1)==m2&&(y-1)==n2 || x==m2&&(y+1)==n2 || (x+1)==m2&&(y+1)==n2)
                clear_my_tank(),screen_2("坦克2号击中了你  生命值减1",4),x=10,y=27,m2=0,n2=0,life--,check_game(),turn_up(my_tank);
            if(x==m3&&(y-1)==n3 || (x-1)==m3&&y==n3 || x==m3&&y==n3 || (x+1)==m3&&(y-1)==n3 || x==m3&&(y+1)==n3 || (x+1)==m3&&(y+1)==n3)
                clear_my_tank(),screen_2("坦克3号击中了你  生命值减1",4),x=10,y=27,m3=0,n3=0,life--,check_game(),turn_up(my_tank);
        }
    case 4 :
        {
            if(x==m1&&(y-1)==n1 || (x-1)==m1&&(y-1)==n1 || x==m1&&y==n1 || (x-1)==m1&&(y+1)==n1 || x==m1&&(y+1)==n1 || (x+1)==m1&&y==n1)
                clear_my_tank(),screen_2("坦克1号击中了你  生命值减1",4),x=10,y=27,m1=0,n1=0,life--,check_game(),turn_up(my_tank);
            if(x==m2&&(y-1)==n2 || (x-1)==m2&&(y-1)==n2 || x==m2&&y==n2 || (x-1)==m2&&(y+1)==n2 || x==m2&&(y+1)==n2 || (x+1)==m2&&y==n2)
                clear_my_tank(),screen_2("坦克2号击中了你  生命值减1",4),x=10,y=27,m2=0,n2=0,life--,check_game(),turn_up(my_tank);
            if(x==m3&&(y-1)==n3 || (x-1)==m3&&(y-1)==n3 || x==m3&&y==n3 || (x-1)==m3&&(y+1)==n3 || x==m3&&(y+1)==n3 || (x+1)==m3&&y==n3)
                clear_my_tank(),screen_2("坦克3号击中了你  生命值减1",4),x=10,y=27,m3=0,n3=0,life--,check_game(),turn_up(my_tank);
        }
    }
}

void change_tank_1()
{
    switch(state_1)
    {
    case 1 :
        {
            if(x1==m&&(y1-1)==n || (x1-1)==m&&y1==n || x1==m&&y1==n || (x1+1)==m&&y1==n || (x1-1)==m&&(y1+1)==n || (x1+1)==m&&(y1+1)==n)//如果我的坦克子弹打到坦克1号
                clear_tank_1(),screen_2("你击中了坦克1号   +100分",3),x1=2,y1=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();//坦克1号回到初始位置,我的坦克号子弹消失,敌人数量值减1,分数加100,检查胜负

        }break;
    case 2 :
        {
            if(x1==m&&(y1+1)==n || (x1-1)==m&&y1==n || x1==m&&y1==n || (x1+1)==m&&y1==n || (x1-1)==m&&(y1-1)==n || (x1+1)==m&&(y1-1)==n)
                clear_tank_1(),screen_2("你击中了坦克1号   +100分",3),x1=2,y1=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    case 3 :
        {
            if(x1==m&&(y1-1)==n || (x1-1)==m&&y1==n || x1==m&&y1==n || (x1+1)==m&&(y1-1)==n || x1==m&&(y1+1)==n || (x1+1)==m&&(y1+1)==n)
                clear_tank_1(),screen_2("你击中了坦克1号   +100分",3),x1=2,y1=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    case 4 :
        {
            if(x1==m&&(y1-1)==n || (x1-1)==m&&(y1-1)==n || x1==m&&y1==n || (x1-1)==m&&(y1+1)==n || x1==m&&(y1+1)==n || (x1+1)==m&&y1==n)
                clear_tank_1(),screen_2("你击中了坦克1号   +100分",3),x1=2,y1=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    }
}

void change_tank_2()
{
    switch(state_2)
    {
    case 1 :
        {
            if(x2==m&&(y2-1)==n || (x2-1)==m&&y2==n || x2==m&&y2==n || (x2+1)==m&&y2==n || (x2-1)==m&&(y2+1)==n || (x2+1)==m&&(y2+1)==n)//如果我的坦克子弹打到坦克2号
                clear_tank_2(),screen_2("你击中了坦克2号   +100分",3),x2=14,y2=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();//坦克2号回到初始位置,我的坦克号子弹消失,敌人数量值减1,分数加100,检查胜负

        }break;
    case 2 :
        {
            if(x2==m&&(y2+1)==n || (x2-1)==m&&y2==n || x2==m&&y2==n || (x2+1)==m&&y2==n || (x2-1)==m&&(y2-1)==n || (x2+1)==m&&(y2-1)==n)
                clear_tank_2(),screen_2("你击中了坦克2号   +100分",3),x2=14,y2=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    case 3 :
        {
            if(x2==m&&(y2-1)==n || (x2-1)==m&&y2==n || x2==m&&y2==n || (x2+1)==m&&(y2-1)==n || x2==m&&(y2+1)==n || (x2+1)==m&&(y2+1)==n)
                clear_tank_2(),screen_2("你击中了坦克2号   +100分",3),x2=14,y2=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    case 4 :
        {
            if(x2==m&&(y2-1)==n || (x2-1)==m&&(y2-1)==n || x2==m&&y2==n || (x2-1)==m&&(y2+1)==n || x2==m&&(y2+1)==n || (x2+1)==m&&y2==n)
                clear_tank_2(),screen_2("你击中了坦克2号   +100分",3),x2=14,y2=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    }
}

void change_tank_3()
{
    switch(state_3)
    {
    case 1 :
        {
            if(x3==m&&(y3-1)==n || (x3-1)==m&&y3==n || x3==m&&y3==n || (x3+1)==m&&y3==n || (x3-1)==m&&(y3+1)==n || (x3+1)==m&&(y3+1)==n)//如果我的坦克子弹打到坦克3号
                clear_tank_3(),screen_2("你击中了坦克3号   +100分",3),x3=27,y3=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();//坦克3号回到初始位置,我的坦克号子弹消失,敌人数量值减1,分数加100,检查胜负

        }break;
    case 2 :
        {
            if(x3==m&&(y3+1)==n || (x3-1)==m&&y3==n || x3==m&&y3==n || (x3+1)==m&&y3==n || (x3-1)==m&&(y3-1)==n || (x3+1)==m&&(y3-1)==n)
                clear_tank_3(),screen_2("你击中了坦克3号   +100分",3),x3=27,y3=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    case 3 :
        {
            if(x3==m&&(y3-1)==n || (x3-1)==m&&y3==n || x3==m&&y3==n || (x3+1)==m&&(y3-1)==n || x3==m&&(y3+1)==n || (x3+1)==m&&(y3+1)==n)
                clear_tank_3(),screen_2("你击中了坦克3号   +100分",3),x3=27,y3=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    case 4 :
        {
            if(x3==m&&(y3-1)==n || (x3-1)==m&&(y3-1)==n || x3==m&&y3==n || (x3-1)==m&&(y3+1)==n || x3==m&&(y3+1)==n || (x3+1)==m&&y3==n)
                clear_tank_3(),screen_2("你击中了坦克3号   +100分",3),x3=27,y3=2,m=0,n=0,enemy--,score=score+100,check_lv(),produce_star(),check_game();

        }
    }
}

void check_lv()
{

    switch(score/1000)
    {
    case 0 :lv=1,speed=10;break;
    case 1 :if(lv==1) screen_2("恭喜升到2级!",2);lv=2,speed=9;break;
    case 2 :if(lv==2) screen_2("恭喜升到3级!",2);lv=3,speed=8;break;
    case 3 :if(lv==3) screen_2("恭喜升到4级!",2);lv=4,speed=7;break;
    case 4 :if(lv==4) screen_2("恭喜升到5级!",2);lv=5,speed=6;break;
    case 5 :if(lv==5) screen_2("恭喜升到6级!",2);lv=6,speed=5;break;
    case 6 :if(lv==6) screen_2("恭喜升到7级!",2);lv=7,speed=4;break;
    case 7 :if(lv==7) screen_2("恭喜升到8级!",2);lv=8,speed=3;break;
    case 8 :if(lv==8) screen_2("恭喜升到9级!",2);lv=9,speed=2;break;
    case 9 :if(lv==9) screen_2("恭喜升到10级!,满级啦",2);lv=10,speed=1;break;
    }

}

void get_map()
{
    int map1[28][28]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,1,1,1,2,2,2,1,1,1,1,1,1,3,3,3,3,1,1,1,1,1,1,1,1,0,0,0},{1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},{1,1,1,1,2,2,2,1,1,1,1,1,1,3,3,3,3,1,1,1,1,1,1,1,1,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{0,0,0,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1},{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},{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,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{0,0,0,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},{0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
    int map2[28][28]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1},{1,1,1,1,1,1,0,0,1,3,3,3,3,3,3,3,3,3,3,3,1,0,0,1,1,1,1,1},{1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1},{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},{1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1},{1,1,1,1,1,1,0,0,1,4,4,4,4,4,4,4,4,4,4,4,1,0,0,1,1,1,1,1},{1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1},{4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4},{3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3},{1,1,1,1,3,3,0,0,3,3,1,1,1,1,1,1,1,1,3,3,0,0,3,3,1,1,1,1},{3,3,3,3,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,3,3,3,3},{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},{1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1},{2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2},{3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3},{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},{3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3},{2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2},{1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
    int map3[28][28]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},{0,2,2,2,2,2,0,4,4,4,4,0,1,1,1,1,0,4,4,4,4,0,2,2,2,2,2,0},{0,0,2,2,2,0,4,4,4,4,4,4,0,1,1,0,4,4,4,4,4,4,0,2,2,2,0,0},{0,0,0,2,0,4,4,4,4,4,4,4,4,0,0,4,4,4,4,4,4,4,4,0,2,0,0,0},{0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0},{0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0},{0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0},{1,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,1},{1,1,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,1,1},{1,1,1,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,1,1,1},{1,1,1,4,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,1,1,1,1},{1,1,1,3,4,0,0,0,0,0,0,4,4,4,4,4,4,0,0,0,0,0,0,4,1,1,1,1},{1,1,1,1,3,4,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,4,3,1,1,1,1},{1,1,1,1,1,3,4,0,0,0,0,0,0,4,4,0,0,0,0,0,0,4,3,1,1,1,1,1},{1,1,1,1,1,1,3,4,0,0,0,0,0,0,0,0,0,0,1,0,4,3,1,1,1,1,1,1},{1,1,1,1,1,1,1,3,4,0,0,0,0,0,1,0,0,0,0,4,3,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,3,4,0,0,0,0,0,0,0,0,4,3,1,1,1,1,1,1,1,1},{3,3,3,3,3,3,3,3,4,0,0,0,0,0,0,0,0,0,0,4,3,3,3,3,3,3,3,3},{4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
    int map4[28][28]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4},{0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0},{1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1},{1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
    int map5[28][28]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},{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,4,4,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,4,4,3,3,3,3,3,3},{1,1,4,4,1,1,1,1,1,1,1,3,3,1,1,4,4,1,1,4,4,1,1,1,1,1,1,1},{1,1,4,4,1,1,1,1,1,1,1,3,3,1,1,1,4,4,4,4,1,1,1,1,1,1,1,1},{1,1,4,4,1,1,1,1,1,1,1,3,3,1,1,1,1,4,4,1,1,1,1,1,1,1,1,1},{1,1,4,4,1,1,1,1,1,1,1,3,3,1,1,1,1,4,4,1,1,1,1,1,1,1,1,1},{1,1,4,4,1,1,1,1,1,1,1,3,3,1,1,1,1,4,4,1,1,1,1,1,1,1,1,1},{1,1,4,4,1,1,1,1,1,1,1,3,3,1,1,1,1,4,4,1,1,1,1,1,1,1,1,1},{1,1,4,4,1,1,1,1,1,1,1,3,3,1,1,1,1,4,4,1,1,1,1,1,1,1,1,1},{1,1,4,4,1,1,1,1,1,1,1,3,3,1,1,1,1,4,4,1,1,1,1,1,1,1,1,1},{1,1,4,4,4,4,4,4,4,1,1,3,3,1,1,1,1,4,4,1,1,1,1,1,1,1,1,1},{1,1,4,4,4,4,4,4,4,1,1,3,3,1,1,1,1,4,4,1,1,1,1,1,1,1,1,1},{3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3},{1,1,1,1,1,1,1,1,1,1,2,3,3,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,2,3,3,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,2,3,3,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,2,3,3,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
    int map6[28][28]={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,1,1,1,4,0,0,0,4,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0},{1,1,1,1,4,0,0,0,4,1,1,0,0,0,1,1,1,1,1,4,4,4,4,4,4,0,0,0},{1,1,0,1,4,0,0,0,4,1,1,0,0,0,1,1,1,1,1,4,0,0,0,0,0,0,0,0},{1,1,0,1,4,0,0,0,4,1,1,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0},{1,1,0,1,4,0,0,4,1,1,1,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0},{1,1,0,1,4,0,0,0,4,1,1,0,0,0,0,0,0,0,0,4,0,0,0,3,4,0,0,0},{1,1,0,1,4,0,0,0,4,4,4,4,4,4,4,4,0,0,0,4,0,0,0,3,4,0,0,0},{1,1,0,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,3,4,0,0,0},{1,1,0,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,3,4,0,0,0},{1,1,0,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,3,4,0,0,0},{4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,4,4,4,4,0,0,0,3,4,0,0,0},{1,1,0,1,1,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,0,0},{1,1,0,1,1,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,0,0},{1,1,0,1,1,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,0,0},{1,1,0,1,1,1,4,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,3,4,0,0,0},{1,1,0,1,1,1,4,0,0,0,1,2,1,3,3,3,3,3,3,3,3,3,3,3,4,0,0,0},{1,1,0,4,4,4,4,0,0,0,1,2,1,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,1,1,1,1,1,1,1,2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{0,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};


    switch(level)//判断是第几关,然后载入相应地图
    {
    case 1 :
        {
            for(int i=0;i<28;i++)
                for(int j=0;j<28;j++)
                    thing[i][j]=map1[i][j];
        }break;
    case 2 :
        {
            for(int i=0;i<28;i++)
                for(int j=0;j<28;j++)
                    thing[i][j]=map2[i][j];
        }break;
    case 3 :
        {
            for(int i=0;i<28;i++)
                for(int j=0;j<28;j++)
                    thing[i][j]=map3[i][j];
        }break;
    case 4 :
        {
            for(int i=0;i<28;i++)
                for(int j=0;j<28;j++)
                    thing[i][j]=map4[i][j];
        }break;
    case 5 :
        {
            for(int i=0;i<28;i++)
                for(int j=0;j<28;j++)
                    thing[i][j]=map5[i][j];
        }break;
    case 6 :
        {
            for(int i=0;i<28;i++)
                for(int j=0;j<28;j++)
                    thing[i][j]=map6[i][j];
        }break;
    default :
        {
            for(int i=4;i<24;i++)
                for(int j=0;j<28;j++)
                    thing[i][j]=rand()%5;
        }
    }
}

void stop()
{
    int a=0;
    char *poem[50]={"      壮哉神将陆伯言","      丈八二桃把营连","      一兵队友张文远","      二兵袁术只等闲","      己方残血放万箭","      敌人弱势开桃园","      转眼队友全托管","      挂上闪电继续连","      铁索全场遭天谴","      一道闪电划过天","      苦心经营几十年","      一夜回到解放前","      队友绝望人心散","      濒死求桃无人怜","      凡人闻之结叹惋","      只见神将笑不言","      我有牌堆很简单","      神技自救不要钱","      连完桃来再连酒","      救完自己救队友","      年轻任性谁能管","      笑看三核被炸残","      只是敌人太狡诈","      各种刷牌各种卡","      凡人皆畏二术禅","      国太香香没得玩","      手牌装备全都有","      体力瞬间就回满","      队友全问怎么办","      怀疑陆神要崩盘","      神将表示莫惊慌","      掏出神器从裤裆","      要问神器是什么","      连弩44杀清全场","      凡人表示瞎狗眼","      不识神将在眼前","      从此美名天下传","      众神闻之皆跪舔","      遍寻三国名将传","      谁人不识陆伯言"," "," "," "," ","     你居然看完。。。     ","  ","  ","  ","  ","  "};
    char key;
    screen_2("游戏暂停",4);
    while(1)
    {
        for(int i=0;i<50;i++)
        {
            Sleep(2000);
            if (kbhit()) //检测
            {
                key = getch();//捕获按键
                if(key==32)
                {
                    screen_2("准备开始",2);
                    a=1;
                    break;
                }
            }
            screen_2(poem[i],2);
            if(a)
                break;
        }
        if(a)
            break;

    }

}


void help()
{
    char key1,key2;
    int a=1;
    for(int i=15;i<29;i++)//先清屏
    {
        gotoxy(62,i);
        printf("                          ");
    }

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
    gotoxy(62,15);
    printf("           帮助           ");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
    gotoxy(62,17);
    printf("↑ ↓ ← →   控制方向");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
    gotoxy(62,19);
    printf(" 小写 w       切换武器");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
    gotoxy(62,21);
    printf(" 小写 s       切换皮肤");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
    gotoxy(62,23);
    printf(" 小写 h       帮助/退出");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
    gotoxy(62,25);
    printf("  空格        暂停/开始");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_GREEN);
    gotoxy(62,27);
    printf("按0查看更多");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);
    gotoxy(62,28);
    printf("                 版本:1.0");

    while(1)
    {
        if (kbhit()) //检测,如果有按键就执行if里面的
        {
            key1 = getch();//捕获按键
            if( 104 == key1 )
            {
                screen_2("看完帮助 继续游戏吧",2);
                screen_3();
                break;
            }

            else if( 48 == key1 )
            {
                while(1)
                {
                for(int i=17;i<29;i++)//先清屏
                {
                    gotoxy(62,i);
                    printf("                          ");
                }

                switch(a)
                {
                case 1 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
                        gotoxy(62,17);
                        printf("■  绿色方块可承受一次打击");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED);
                        gotoxy(62,19);
                        printf("■  黄色油块可承受两次打击");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE);
                        gotoxy(62,21);
                        printf("■  白色冰块可承受三次打击");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);
                        gotoxy(62,23);
                        printf("■  蓝色石块无法被破环");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_GREEN);
                        gotoxy(62,27);
                        printf("按空格键继续");

                    }break;

                case 2 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
                        gotoxy(62,17);
                        printf("⊕  普通子弹攻击力为1     ");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
                        gotoxy(62,19);
                        printf("∷  散弹可对绿色方块造成大");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
                        gotoxy(62,21);
                        printf("范围破坏,但是无法对其它类");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
                        gotoxy(62,23);
                        printf("型的方块造成破坏          ");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
                        gotoxy(62,25);
                        printf("◎  气泡弹可以对一排的绿色");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
                        gotoxy(62,27);
                        printf("方块造成破坏");

                    }break;

                case 3 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,17);
                        printf("※  雪花弹对白色冰块无效,");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,19);
                        printf("但是可以将老家的围墙修成白");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,21);
                        printf("色冰块,从而保护老家");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
                        gotoxy(62,23);
                        printf("●  超级炮弹可以对除蓝色石");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
                        gotoxy(62,25);
                        printf("块外所有方块造成一次性的巨");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
                        gotoxy(62,27);
                        printf("大破坏");

                    }break;

                case 4 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,17);
                        printf("每打掉一辆坦克加100 分,同");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,19);
                        printf("时有一定几率掉落星星,收集");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,21);
                        printf("星星可解锁武器和皮肤。每当");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,23);
                        printf("分数达到整千时,你将升级,");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,25);
                        printf("升级后,子弹速度将会变快,");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,27);
                        printf("同时敌人也将变强");

                    }break;

                case 5 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,17);
                        printf("游戏内置六张地图,第六关往");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,19);
                        printf("后将会出现系统的随机地图");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,21);
                        printf("友情提示:你自己的子弹都");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,23);
                        printf("无法对老家的围墙造成破坏");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,25);
                        printf(",但是可以对内部造成破坏");
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED);
                        gotoxy(62,27);
                        printf(",因此别总把枪口对着老家");

                    }break;

                case 6 :
                    {
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_GREEN);
                        gotoxy(62,27);
                        printf("按空格键退出");

                    }break;

                }


                while(1)
                {
                    if (32==getch()) a++;break;
                }
                if(a==7)break;
            }

        }
        }
        if(a==7)
            {
                screen_2("看完帮助 继续游戏吧",2);
                screen_3();
                break;
            }           
    }

}

void check_game()
{
    if(life==0)
        gameover();
    if(enemy==0)
        next_level();
}

void next_level()
{
    screen_1();
    level++;
    for(int i=15;i<29;i++)//先清屏
    {
        gotoxy(62,i);
        printf("                          ");
    }

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
    gotoxy(62,17);
    printf("          恭喜过关        ");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
    gotoxy(62,23);
    printf("    按 空格键 继续游戏    ");

    while(1)
    {
        if(32 == getch())
        {

            int home0[3][4]={{2,2,2,2},{2,1,1,2},{2,1,1,2}};//定义一个老家的初始化值

            {
                for(int i=0;i<5;i++)
                    info[i]=" ";//通知清零
            }
            {
                for(int i=0;i<3;i++)//老家初始化
                    for(int j=0;j<4;j++)
                        home[i][j]=home0[i][j];
            }   

            m=0  , n=0 ;//我的坦克子弹的坐标清零
            m1=0 , n1=0;//坦克1号子弹的坐标清零
            m2=0 , n2=0;//坦克2号子弹的坐标清零
            m3=0 , n3=0;//坦克3号子弹的坐标清零

            {
            for(int i=1;i<29;i++)
                for(int j=1;j<29;j++)
                {
                    gotoxy(2*i,j);
                    printf("  ");
                }
            }


            life=3;//生命初始化
            enemy=13;//敌人数量初始化
            s=0,t=0;//星星坐标
            get_map();//获得地图
            refresh_map();//刷新地图
            print_home();//打印老家
            print_thing();//打印物品

            direction=0;//我的坦克子弹射向初始化
            direction_1=0;//坦克1号子弹射向初始化
            direction_2=0;//坦克2号子弹射向初始化
            direction_3=0;//坦克3号子弹射向初始化

            x=10;y=27;//我的坦克位置初始化
            state=0;
            turn_up(my_tank);//我的坦克方向初始化


            x1=2;y1=2;//坦克1号位置初始化
            state_1=0;
            turn_down_1(tank_1);//坦克1号方向初始化

            x2=14;y2=2;//坦克2号位置初始化
            state_2=0;
            turn_down_2(tank_2);//坦克2号方向初始化

            x3=27;y3=2;//坦克3号位置初始化
            state_3=0;
            turn_down_3(tank_3);//坦克3号方向初始化

            screen_1();
            screen_2("游戏开始",4);
            break;
        }
    }



}


void gameover()
{

    for(int i=15;i<29;i++)//先清屏
    {
        gotoxy(62,i);
        printf("                          ");
    }

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
    gotoxy(62,17);
    printf("          游戏结束        ");

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
    gotoxy(62,23);
    printf("    按 空格键 重新开始    ");

    while(1)
    {
        if(32 == getch())
        {
            initial();
            break;
        }
    }
}

void initial()
{
            int home0[3][4]={{2,2,2,2},{2,1,1,2},{2,1,1,2}};//定义一个老家的初始化值
            life=3;//生命初始化
            enemy=13;//敌人数量初始化
            level=1;//关卡初始化
            weapons=1;//武器初始化
            skin=1;//皮肤初始化
            star=1;//星星初始化
            s=0,t=0;//星星坐标
            score=0;//分数初始化
            lv=1;//等级初始化
            speed=10;//速度初始化
            {
                for(int i=0;i<5;i++)
                    info[i]=" ";//通知清零
            }
            {
                for(int i=0;i<3;i++)//老家初始化
                    for(int j=0;j<4;j++)
                        home[i][j]=home0[i][j];
            }   

            m=0  , n=0 ;//我的坦克子弹的坐标清零
            m1=0 , n1=0;//坦克1号子弹的坐标清零
            m2=0 , n2=0;//坦克2号子弹的坐标清零
            m3=0 , n3=0;//坦克3号子弹的坐标清零

            {
            for(int i=1;i<29;i++)
                for(int j=1;j<29;j++)
                {
                    gotoxy(2*i,j);
                    printf("  ");
                }
            }

            get_map();//获得地图
            refresh_map();//刷新地图
            print_home();//打印老家
            print_thing();//打印物品

            direction=0;//我的坦克子弹射向初始化
            direction_1=0;//坦克1号子弹射向初始化
            direction_2=0;//坦克2号子弹射向初始化
            direction_3=0;//坦克3号子弹射向初始化

            x=10;y=27;//我的坦克位置初始化
            state=0;
            turn_up(my_tank);//我的坦克方向初始化

            x1=2;y1=2;//坦克1号位置初始化
            state_1=0;
            turn_down_1(tank_1);//坦克1号方向初始化

            x2=14;y2=2;//坦克2号位置初始化
            state_2=0;
            turn_down_2(tank_2);//坦克2号方向初始化

            x3=27;y3=2;//坦克3号位置初始化
            state_3=0;
            turn_down_3(tank_3);//坦克3号方向初始化

            screen_1();
            screen_2("游戏开始",4);
            screen_3();
}

 

0
0
邵逸儒
邵逸儒
中级天翼
中级天翼
#include<iostream>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<string>
using namespace std;
typedef struct Frame
{
    COORD position[2];
    int flag;
}Frame;
void SetPos(COORD a)
{
    HANDLE out=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(out, a);
}
void SetPos(int i, int j)
{
    COORD pos={i, j};
    SetPos(pos);
}
void HideCursor()
{
    CONSOLE_CURSOR_INFO cursor_info = {1, 0}; 
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

//把第y行,[x1, x2) 之间的坐标填充为 ch
void drawRow(int y, int x1, int x2, char ch)
{
    SetPos(x1,y);
    for(int i = 0; i <= (x2-x1); i++) cout<<ch;
}

//在a, b 纵坐标相同的前提下,把坐标 [a, b] 之间填充为 ch
void drawRow(COORD a, COORD b, char ch)
{
    if(a.Y == b.Y) drawRow(a.Y, a.X, b.X, ch);
    else {
        SetPos(0, 25);
        cout<<"error code 01:无法填充行,因为两个坐标的纵坐标(x)不相等";
        system("pause");
    }
}

//把第x列,[y1, y2] 之间的坐标填充为 ch
void drawCol(int x, int y1, int y2, char ch)
{
    int y=y1;
    while(y!=y2+1) {
        SetPos(x, y);
        cout<<ch;
        y++;
    }
}

//在a, b 横坐标相同的前提下,把坐标 [a, b] 之间填充为 ch
void drawCol(COORD a, COORD b, char ch)
{
    if(a.X == b.X) drawCol(a.X, a.Y, b.Y, ch);
    else {
        SetPos(0, 25);
        cout<<"error code 02:无法填充列,因为两个坐标的横坐标(y)不相等";
        system("pause");
    }
}

//左上角坐标、右下角坐标、用row填充行、用col填充列
void drawFrame(COORD a, COORD  b, char row, char col)
{
    drawRow(a.Y, a.X+1, b.X-1, row);
    drawRow(b.Y, a.X+1, b.X-1, row);
    drawCol(a.X, a.Y+1, b.Y-1, col);
    drawCol(b.X, a.Y+1, b.Y-1, col);
}

void drawFrame(int x1, int y1, int x2, int y2, char row, char col)
{
    COORD a={x1, y1};
    COORD b={x2, y2};
    drawFrame(a, b, row, col);
}

void drawFrame(Frame frame, char row, char col)
{
    COORD a = frame.position[0];
    COORD b = frame.position[1];
    drawFrame(a, b, row, col);
}

void drawPlaying()
{
    drawFrame(0, 0, 48, 24, '=', '|');//    draw map frame;
    drawFrame(49, 0, 79, 4, '-', '|');//        draw output frame
    drawFrame(49, 4, 79, 9, '-', '|');//        draw score frame
    drawFrame(49, 9, 79, 20, '-', '|');//   draw operate frame
    drawFrame(49, 20, 79, 24, '-', '|');//  draw other message frame
    SetPos(52, 6);
    cout<<"得分:";
    SetPos(52, 7);
    cout<<"称号:";
    SetPos(52,10);
    cout<<"操作方式:";
    SetPos(52,12);
    cout<<"  a,s,d,w 控制战机移动。";
    SetPos(52,14);
    cout<<"  p 暂停游戏。";
    SetPos(52,16);
    cout<<"  e 退出游戏。";
    SetPos(52,18);
    cout<<"  k 发射火箭。";
}

//在[a, b)之间产生一个随机整数
int random(int a, int b)
{
    int c=(rand() % (a-b))+ a;
    return c;
}

//在两个坐标包括的矩形框内随机产生一个坐标
COORD random(COORD a, COORD b)
{
    int x=random(a.X, b.X);
    int y=random(a.Y, b.Y);
    COORD c={x, y};
    return c;
}

bool  judgeCoordInFrame(Frame frame, COORD spot)
{
    if(spot.X>=frame.position[0].X)
        if(spot.X<=frame.position[1].X)
            if(spot.Y>=frame.position[0].Y)
                if(spot.Y<=frame.position[0].Y)
                    return true;
    return false;
}

void printCoord(COORD a)
{
    cout    <<"( "<<a.X<<" , "<<a.Y<<" )";
}

void printFrameCoord(Frame a)
{
    printCoord(a.position[0]);
    cout    <<" - ";
    printCoord(a.position[1]);
}

int drawMenu()
{
    SetPos(30, 1);
    cout<<"Plane War";
    drawRow(3, 0, 79, '-');
    drawRow(5, 0, 79, '-');
    SetPos(28, 4);
    cout<<"w 和 s 选择, k 确定";
    SetPos(15, 11);
    cout<<"1. 简单的敌人";
    SetPos(15, 13);
    cout<<"2. 冷酷的敌人";
    drawRow(20, 0, 79, '-');
    drawRow(22, 0, 79, '-');
    SetPos(47, 11);
    cout<<"简单的敌人:";
    SetPos(51, 13);
    cout<<"简单敌人有着较慢的移动速度。";
    int j=11;
    cout<<">>";
    while(1) {
        if( _kbhit() ) {    
            char x=_getch();
            switch (x) {
              case 'w' : {  
                if( j == 13) {
                  SetPos(12, j);
                  cout<<" ";
                  j = 11;
                  SetPos(12, j);
                  cout<<">>";
                  SetPos(51, 13);
                  cout<<"            ";
                  SetPos(47, 11);
                  cout<<"简单的敌人:";
                  SetPos(51, 13);
                  cout<<"简单的敌人有着较慢的移动速度。";
                }
                break;
              }
              case 's' : {  
                if( j == 11 ) {
                  SetPos(12, j);
                  cout<<" ";        
                  j = 13;
                  SetPos(12, j);
                  cout<<">>";
                  SetPos(51, 13);
                   cout<<"              ";
                   SetPos(47, 11);
                   cout<<"冷酷的敌人:";
                   SetPos(51, 13);
                   cout<<"冷酷的敌人有着较快的移动速度。";
                }
                break;
              }
              case 'k' : {  
                if (j == 8) return 1; else return 2;
              }
            }
        }
    }
}
/*================== the Game Class ==================*/

class Game
{
public:
    COORD position[10];
    COORD bullet[10];
    Frame enemy[8];
    int score;
    int rank;
    int rankf;
    string title;
    int flag_rank;

    Game ();

    //初始化所有
    void initPlane();
    void initBullet();
    void initEnemy();

    //初始化其中一个
    //void initThisBullet( COORD );
    //void initThisEnemy( Frame );

    void planeMove(char);
    void bulletMove();
    void enemyMove();

    //填充所有
    void drawPlane();
    void drawPlaneToNull();
    void drawBullet();
    void drawBulletToNull();
    void drawEnemy();
    void drawEnemyToNull();

    //填充其中一个
    void drawThisBulletToNull( COORD );
    void drawThisEnemyToNull( Frame );

    void Pause();
    void Playing();
    void judgePlane();
    void judgeEnemy();

    void Shoot();

    void GameOver();
    void printScore();
};

Game::Game()
{
    initPlane();
    initBullet();
    initEnemy();
    score = 0;
    rank = 25;
    rankf = 0;
    flag_rank = 0;
}

void Game::initPlane()
{
    COORD centren={39, 22};
    position[0].X=position[5].X=position[7].X=position[9].X=centren.X;
    position[1].X=centren.X-2;  
    position[2].X=position[6].X=centren.X-1;
    position[3].X=position[8].X=centren.X+1;
    position[4].X=centren.X+2;
    for(int i=0; i<=4; i++)
        position[i].Y=centren.Y;
    for(int i=6; i<=8; i++)
        position[i].Y=centren.Y+1;
    position[5].Y=centren.Y-1;
    position[9].Y=centren.Y-2;
}

void Game::drawPlane()
{
    for(int i=0; i<9; i++)
    {
        SetPos(position[i]);
        if(i!=5)
            cout<<"O";
        else if(i==5)
            cout<<"|";      
    }
}

void Game::drawPlaneToNull()
{
    for(int i=0; i<9; i++)
    {
        SetPos(position[i]);
        cout<<" ";
    }   
}

void Game::initBullet()
{
    for(int i=0; i<10; i++)
        bullet[i].Y = 30;
}

void Game::drawBullet()
{
    for(int i=0; i<10; i++)
    {
        if( bullet[i].Y != 30)
        {
            SetPos(bullet[i]);
            cout<<"^";  
        }
    }
}

void Game::drawBulletToNull()
{
    for(int i=0; i<10; i++)
        if( bullet[i].Y != 30 )
            {
                COORD pos={bullet[i].X, bullet[i].Y+1};
                SetPos(pos);
                cout<<" ";
            }   
}

void Game::initEnemy()
{
    COORD a={1, 1};
    COORD b={45, 15};
    for(int i=0; i<8; i++)
    {
        enemy[i].position[0] = random(a, b);
        enemy[i].position[1].X = enemy[i].position[0].X + 3;
        enemy[i].position[1].Y = enemy[i].position[0].Y + 2;
    }
}

void Game::drawEnemy()
{
    for(int i=0; i<8; i++)
        drawFrame(enemy[i].position[0], enemy[i].position[1], '-', '|');
}

void Game::drawEnemyToNull()
{
    for(int i=0; i<8; i++)
    {
        drawFrame(enemy[i].position[0], enemy[i].position[1], ' ', ' ');
    }       
}

void Game::Pause()
{
    SetPos(61,2);
    cout<<"               ";
    SetPos(61,2);
    cout<<"暂停中...";
    char c=_getch();
    while(c!='p')
        c=_getch();
    SetPos(61,2);
    cout<<"         ";
}

void Game::planeMove(char x)
{
    if(x == 'a')
        if(position[1].X != 1)
            for(int i=0; i<=9; i++)
                position[i].X -= 2;

    if(x == 's')
        if(position[7].Y != 23)
            for(int i=0; i<=9; i++)
                position[i].Y += 1;

    if(x == 'd')
        if(position[4].X != 47)
            for(int i=0; i<=9; i++)
                position[i].X += 2;

    if(x == 'w')
        if(position[5].Y != 3)
            for(int i=0; i<=9; i++)
                position[i].Y -= 1;
}

void Game::bulletMove()
{
    for(int i=0; i<10; i++)
    {
        if( bullet[i].Y != 30)
        {
            bullet[i].Y -= 1;
            if( bullet[i].Y == 1 )
            {
                COORD pos={bullet[i].X, bullet[i].Y+1};
                drawThisBulletToNull( pos );
                bullet[i].Y=30;
            }

        }
    }
}

void Game::enemyMove()
{
    for(int i=0; i<8; i++)
    {
        for(int j=0; j<2; j++)
            enemy[i].position[j].Y++;

        if(24 == enemy[i].position[1].Y)
        {
            COORD a={1, 1};
            COORD b={45, 3};
            enemy[i].position[0] = random(a, b);
            enemy[i].position[1].X = enemy[i].position[0].X + 3;
            enemy[i].position[1].Y = enemy[i].position[0].Y + 2;
        }
    }
}

void Game::judgePlane()
{
    for(int i = 0; i < 8; i++)
        for(int j=0; j<9; j++)
            if(judgeCoordInFrame(enemy[i], position[j]))
            {
                SetPos(62, 1);
                cout<<"坠毁";
                drawFrame(enemy[i], '+', '+');
                Sleep(1000);
                GameOver();
                break;
            }
}

void Game::drawThisBulletToNull( COORD c)
{
    SetPos(c);
    cout<<" ";
}

void Game::drawThisEnemyToNull( Frame f )
{
    drawFrame(f, ' ', ' ');
}

void Game::judgeEnemy()
{
    for(int i = 0; i < 8; i++)
        for(int j = 0; j < 10; j++)
            if( judgeCoordInFrame(enemy[i], bullet[j]) )
            {
                score += 5;
                drawThisEnemyToNull( enemy[i] );
                COORD a={1, 1};
                COORD b={45, 3};
                enemy[i].position[0] = random(a, b);
                enemy[i].position[1].X = enemy[i].position[0].X + 3;
                enemy[i].position[1].Y = enemy[i].position[0].Y + 2;                    
                drawThisBulletToNull( bullet[j] );
                bullet[j].Y = 30;
            }
}

void Game::Shoot()
{
    for(int i=0; i<10; i++)
        if(bullet[i].Y == 30)
        {
            bullet[i].X = position[5].X;
            bullet[i].Y = position[5].Y-1;
            break;
        }
}

void Game::printScore()
{
    if(score == 120 && flag_rank == 0)
    {
        rank -= 3;
        flag_rank = 1;
    }

    else if( score == 360 && flag_rank == 1)
    {
        rank -= 5;
        flag_rank = 2;
    }
    else if( score == 480 && flag_rank == 2)
    {
        rank -= 5;
        flag_rank = 3;
    }
    int x=rank/5;
    SetPos(60, 6);
    cout<<score;
    if( rank!=rankf )
    {
        SetPos(60, 7);
        if( x == 4)
            title="初级飞行员";
        else if( x == 3)
            title="中级飞行员";
        else if( x == 2)
            title="高级飞行员";
        else if( x == 1 )
            title="王牌飞行员";
        cout<<title;
    }
    rankf = rank;
}

void Game::Playing()
{
    //HANDLE MFUN;
    //MFUN= CreateThread(NULL, 0, MusicFun, NULL, 0, NULL); 

    drawEnemy();
    drawPlane();

    int flag_bullet = 0;
    int flag_enemy = 0;

    while(1)
    {
        Sleep(8);
        if(_kbhit())
        {
            char x = _getch();
            if ('a' == x || 's' == x || 'd' == x || 'w' == x)
            {
                drawPlaneToNull();
                planeMove(x);
                drawPlane();
                judgePlane();
            }           
            else if ('p' == x)
                Pause();
            else if( 'k' == x)
                Shoot();
            else if( 'e' == x)
            {
                //CloseHandle(MFUN);
                GameOver();
                break;
            }

        }
        /* 处理子弹 */
        if( 0 == flag_bullet )
        {
            bulletMove();
            drawBulletToNull();
            drawBullet();
            judgeEnemy();
        }           
        flag_bullet++;
        if( 5 == flag_bullet )
            flag_bullet = 0;

        /* 处理敌人 */
        if( 0 == flag_enemy )
        {
            drawEnemyToNull();
            enemyMove();            
            drawEnemy();
            judgePlane();
        }
        flag_enemy++;
        if( flag_enemy >= rank )
            flag_enemy = 0;

        /* 输出得分 */
        printScore();
    }
}

void Game::GameOver()
{
    system("cls");              
    COORD p1={28,9};
    COORD p2={53,15};
    drawFrame(p1, p2, '=', '|');
    SetPos(36,12);
    string str="Game Over!";
    for(int i=0; i<str.size(); i++)
    {
        Sleep(80);
        cout<<str[i];
    }
    Sleep(1000);
    system("cls");
    drawFrame(p1, p2, '=', '|');
    SetPos(31, 11);
    cout<<"击落敌机:"<<score/5<<" 架";
    SetPos(31, 12);
    cout<<"得  分:"<<score;
    SetPos(31, 13);
    cout<<"获得称号:"<<title;
    SetPos(30, 16);
    Sleep(1000);
    cout<<"继续? 是(y)| 否(n)";
as:
    char x=_getch();
    if (x == 'n')
        exit(0);
    else if (x == 'y')
    {
        system("cls");
        Game game;
        int a = drawMenu();
        if(a == 2)
            game.rank = 20;
        system("cls");
        drawPlaying();
        game.Playing();
    }
    else goto as;
}

/*================== the main function ==================*/
int main()
{
    cout << string(13, '\n');
    cout << string(50, ' ') << "Game Loading" << endl << ".";
    Sleep(500);
    cout << "\t.";
    Sleep(500);
    cout << "\t\t.";
    Sleep(500);
    cout << "\t\t\t.";
    Sleep(500);
    cout << "\t\t\t.";
    Sleep(500);
    cout << "\t\t.";
    Sleep(500);
    cout << "\t\t.";
    Sleep(500);
    cout << "\t.";
    Sleep(2000);
    system("cls");
    //游戏准备
    srand((int)time(0));    //随机种子
    HideCursor();   //隐藏光标

    Game game;
    int a = drawMenu();
    if(a == 2)
        game.rank = 20;
    system("cls");
    drawPlaying();
    game.Playing();
}

0
黄俊博
黄俊博
资深光能
资深光能

大哥你这是飞机大战的

0
0
0
0
0
方亦欧
方亦欧
新手光能
新手光能

我只有Pascal的。 

PROGRAM The_War_of_Tank_____By_Fallen_Breath;

{$M 1000000000,0,maxlongint}
{$inline on}

USES Crt,Dos,SysUtils,Math,Windows,BetterInput,MmSystem;

CONST
/////////////////////////Program Information/////////////////////////

      AppName                  = '坦克大战';
      Version                  = 'V1.0.0_build7';
      ApplicationVersion       = 'Beta 1.0.0+';
      Date                     = '2017.4.10';

{$I 定义.inc}

procedure F4;
begin
  write('Press F4 here!');
  explode(maxx div 2,maxy div 2,maxexplodehard,0,1);
end;

function gettick:int64;
var t:SYSTEMTIME;
    u,x,y:int64;
begin
  GetLocalTime(t);
  u:=1;
  with t do
  begin
    gettick:=u*wMilliseconds+u*1000*wSecond+u*1000*60*wMinute;
    gettick:=gettick+u*1000*60*60*wHour+u*1000*60*60*24*wDay;
  end;
end;

procedure gt(var n:Ttime);inline;
begin
  n.time:=gettick;
  if gaming then n.tick:=tick;
end;

function td(o,n:Ttime):int64;
begin
  exit(n.time-o.time);
end;

function color(now,max:longint):longint;
var i:longint;
begin
  if (now<0) or (max=0) then exit(12);
  case trunc(now/max*100) of
    0..25:color:=12;
    26..50:color:=14;
    51..75:color:=11;
    76..100:color:=10;
  end;
end;

procedure delay(x:longint);
var st:longint;
begin
  st:=getmscount;
  while (getmscount-st<x) and (keypressed=false) do;
  if keypressed then readkey;
end;

function lenlimit(s:string;max:longint):string;
var l,r,i:longint;
begin
  if length(s)<=max then exit(s);
  l:=1;r:=length(s);
  exit(copy(s,1,r-4-(r-max))+'..'+copy(s,r-1,2));
end;

function getastr(len:longint):string;
var i:longint;
begin
  getastr:='';
  for i:=1 to len do
    getastr:=getastr+chr(random(256));
end;

procedure runmusic;
var i:longint;
    s:ansistring;m:string;
begin
  s:=musicparameter;
  musicthreadok:=true;
  exec(musicplayerprogramnam,s);

 { s:=musicparameter[1];
  m:=musicparameter[2];
  if length(s)=0 then exitthread(0);
  if length(m)=0 then m:='0';
  case m[1] of
    '0':sndplaysound(pchar(s),SND_ASYNC);//播放一次
    '1':begin
          sndplaysound(pchar(s),SND_LOOP);//播放多次
          while FileExists(pchar('stopplaymucsic'))=false do;
        end;
  end;
  musicparameter[1]:='';musicparameter[2]:=''; }
  exitthread(0);
end;

procedure playmusic(s,m:string);//inline;
var f:text;
    ff:file;
begin
  if (setting.musicon=0) then exit;
  musicparameter:=s+' '+m;
  {s:=s1;
  musicparameter[1]:=s;
  musicparameter[2]:=m;  }
  musicthreadok:=false;
  if (createthread(nil,0,@runmusic,nil,0,tid)=0) then exit;
  while (musicthreadok=false) do;
  //sndplaysound(pchar(s),SND_ASYNC);
  exit;
end;

function chooseone(s:ansistring):longint;
begin
  chooseone:=betterinput.chooseone(s);
  playmusic('music/click.wav','0');
end;

procedure findfiles(fn:ansistring;var res:findfilesres);
var wjin,wjout:text;
    i,j:longint;
    r:tsearchrec;
    s:string;

   procedure qsort(l,r:longint);
   var i,j:longint;
       x,y:string;
   begin
     i:=l;
     j:=r;
     x:=res.filenam[(l+r)div 2];
     repeat
       while res.filenam[i]<x do inc(i);
       while res.filenam[j]>x do dec(j);
       if i<=j then
       begin
         y:=res.filenam[i];
         res.filenam[i]:=res.filenam[j];
         res.filenam[j]:=y;
         inc(i);
         dec(j);
       end;
     until i>j;
     if i<r then qsort(i,r);
     if l<j then qsort(l,j);
   end;

begin
  with res do
  begin
    filenum:=0;
    maxlen:=0;
    i:=sysutils.findfirst(fn,faanyfile,r);
    while I=0 do
    begin
      inc(filenum);
      filenam[filenum]:=r.name;
      maxlen:=max(maxlen,length(filenam[filenum]));
      i:=sysutils.findnext(r);
    end;
    sysutils.findclose(r);
  end;
  if res.filenum=0 then exit;
  qsort(1,res.filenum);
end;

function getfx(x1,y1,x2,y2:longint):longint;
begin
  if x2=x1 then
  begin
    if y2>y1 then exit(2)
     else exit(0);
  end
   else if y1=y2 then
   begin
     if x2>x1 then exit(1)
      else exit(3);
   end;

  if x1>x2 then
  begin
    if y1>y2 then
    begin
      if (y1-y2)>(x1-x2) then exit(0)
       else exit(3);
    end
     else begin
       if (y2-y1)>(x1-x2) then exit(2)
        else exit(3);
     end;
  end
   else begin
     if y1>y2 then
     begin
       if (y1-y2)>=(x2-x1) then exit(0)
        else exit(1);
     end
      else begin
        if (y2-y1)>=(x2-x1) then exit(2)
         else exit(1);
      end;
   end;
end;
function getfx(x1,x2:Tpos):longint;
begin
  exit(getfx(x1.x,x1.y,x2.x,x2.y));
end;
function getfx(x1:Tpos;x2,y2:longint):longint;
begin
  exit(getfx(x1.x,x1.y,x2,y2));
end;
function getfx(x1,y1:longint;x2:Tpos):longint;
begin
  exit(getfx(x1,y1,x2.x,x2.y));
end;

function getmobharmtype(id:longint):longint;
begin
  case id of
    1,3:exit(1);
    2:exit(2);
    4:exit(3);
  end;
end;
function getmobharmtype(who:Ttank):longint;
begin
  exit(getmobharmtype(who.id));
end;

procedure print(x,y,tbc,tcc:longint;st:string);
var i:longint;
begin
  if inmap(x,y)=false then
  begin
    clrscr;tc(15);tb(0);
    writeln('Error!');
    writeln('Wrong x or y in procedure print');
    writeln('x=',x,'  y=',y);
    delay(2000);
    halt;
  end;
  if tbc=-1 then tbc:=blockbackground[mm.map[x,y].id];

   with newsc[x,y] do
   begin
    // gotoxy(x*2+1,y+1);
     bg:=tbc;col:=tcc;
     ch:=st;
   end;//end with
end;
procedure print(zb:Tpos;tbc,tcc:longint;st:string);
begin
  print(zb.x,zb.y,tbc,tcc,st);
end;

function inmap(x,y:longint):boolean;
begin
  if (x<1) or (x>maxx) or (y<1) or (y>maxy) then exit(false);
  exit(true);
end;
function inmap(zb:Tpos):boolean;
begin
  exit(inmap(zb.x,zb.y));
end;

function can(x,y,typ:longint):boolean; //typ:1:坦克 2:mob
var i:longint;
begin
  if inmap(x,y)=false then exit(false);
  with mm.map[x,y] do
  begin
    if typ=2 then exit(id in cangoblock_mob);
    if (hitbox[x][y]>=tick*2) and (tick>0) then
    begin
      if (hitbox[x][y]=tick*2) then exit(false);
      exit(true);
    end;
    hitbox[x][y]:=tick*2;
    for i:=1 to maxai do
     with ai[i] do
      if (zb.x=x)and (zb.y=y) then
      begin
        if living then exit(false)
      //   else if tick-ldt.tick<dyinglast then exit(false);
      end;
    for i:=1 to setting.playernum do
     with player[i] do
      if (zb.x=x)and (zb.y=y) then
      begin
        if living then exit(false)
       //  else if tick-ldt.tick<dyinglast then exit(false);
      end;
    if id in cangoblock_tank=false then exit(false);
  end;
  if (tick>0) then hitbox[x][y]:=tick*2+1;
  exit(true);
end;
function can(zb:Tpos;typ:longint):boolean;
begin
  exit(can(zb.x,zb.y,typ));
end;

function whichmob(x,y:longint):longint;{exit -1:no}
var i,j,n,t,w:longint;
    a:array[1..maxmob] of longint;
begin
  n:=0;
  for i:=1 to maxmob do
   with mob[i] do
    if living then
      if (zb.x=x) and (zb.y=y) then
      begin
        inc(n);
        a[n]:=i;
      end;
  if n=0 then exit(-1);
  exit(a[random(n)+1]);
end;
function whichmob(zb:Tpos):longint;
begin
  exit(whichmob(zb.x,zb.y));
end;

function whichtank(x,y:longint):longint;{exit 0:no}
var i,j,n,t,w:longint;
begin
  for i:=1 to maxai do
   with ai[i] do
    if (zb.x=x) and (zb.y=y) then
     if living{ or (((tick-ldt.tick) mod dyingblinklast<=dyingblinklast div 2) and (tick<=ldt.tick+dyinglast)) }then exit(i);
  for i:=1 to maxplayer do
   with player[i] do
    if (zb.x=x) and (zb.y=y) then
     if living {or (((tick-ldt.tick) mod dyingblinklast<=dyingblinklast div 2) and (tick<=ldt.tick+dyinglast))} then exit(-i);
  exit(0);
end;
function whichtank(zb:Tpos):longint;
begin
  exit(whichtank(zb.x,zb.y));
end;

function ju(x1,y1,x2,y2:longint):longint;
begin
  exit(abs(x1-x2)+abs(y1-y2));
end;
function ju(a,b:Tpos):longint;
begin
  exit(ju(a.x,a.y,b.x,b.y));
end;
function ju(a:Tpos;x,y:longint):longint;
begin
  exit(ju(a.x,a.y,x,y));
end;
function ju(x,y:longint;a:Tpos):longint;
begin
  exit(ju(x,y,a.x,a.y));
end;

function findblock(did,isrnd:longint):Tpos;//idrnd 1:random
var i,j,n:longint;
    a:array[0..maxblock] of Tpos;
begin
  n:=0;
  a[0].x:=-1;
  a[0].y:=-1;
  for i:=1 to maxx do
   for j:=1 to maxy do
    if mm.map[i,j].id=did then
    begin
      inc(n);
      a[n].x:=i;
      a[n].y:=j;
    end;
  if n=0 then exit(a[0]);
  if isrnd=0 then exit(a[1]);
  exit(a[random(n)+1]);
end;



procedure destroy(x,y,fromx,fromy,harm,ht:longint);
var i,j,n,t,w:longint;
    zb:Tpos;
begin
  if inmap(x,y)=false then
  begin
    clrscr;tc(15);tb(0);
    writeln('Error!');
    writeln('Wrong x or y in procedure destroy');
    writeln('x=',x,'  y=',y);
    delay(2000);
    halt;
  end;
  with mm.map[x,y] do
  begin
    if unbreakble then exit;
    if ht<>0 then
     if id in candestroyblock[ht]=false then exit;
   { if id in [10] then
     if ht=3 then exit;}
    dec(hard,harm);
    if id=4 then
     with playerflag do
       dec(hp,harm);
    if id=5 then
     with aiflag do
       dec(hp,harm);
    if ht<>3 then
    case id of
      1,2,6,7:playmusic('music\stone'+chr(random(4)+1+ord('0'))+'.wav','0');
      4,5:playmusic('music\wood'+chr(random(4)+1+ord('0'))+'.wav','0');
      8:playmusic('music\fuse.wav','0');
    end;
    if hard<=0 then
    begin
      case id of
        4:repeat
            gamelose:=true;gameendtick:=tick;
            init_tip('游戏失败',10,gamefinishtipshowlast);
            zb:=findblock(5,0);
            if zb.x=-1 then break;
            mm.map[zb.x,zb.y].unbreakble:=true;
          until true;
        5:repeat
            gamewin:=true;gameendtick:=tick;
            init_tip('游戏胜利',12,gamefinishtipshowlast);
            zb:=findblock(4,0);
            if zb.x=-1 then break;
            mm.map[zb.x,zb.y].unbreakble:=true;
          until true;
        8:repeat
            if (harm>TNTgenerateharmlimit) then break;
            t:=new_mob(x,y,-1,4,0);
            if ht=3 then
            begin
              mob[t].lst.tick:=tick-(random(6)+1)*TNTblinklast div 2+random(3)-1;
              mob[t].fx:=getfx(fromx,fromy,x,y);
            end
             else mob[t].speed:=maxlongint;
          until true;
      end;//end case
     // if id in candestroyblock[ht] then
      begin
        id:=0;
        print(x,y,blockbackground[id],15,blockchar[id,fx]);
      end;
    end;//end if destroyed
  end;
end;

procedure explode(mx,my,hard,fromwho,hurtfrom,nomusic:longint); //hard:1~15
var maxju,i,tmp:longint;
    explodeed:array[1..maxx,1..maxy] of boolean;
    candes:boolean;

   procedure bfs(x,y,hard:longint);
   type dl=record
             x,y,pre,h:longint;
           end;
   var i,ii,j,xx,yy,n,head,tail:longint;
       q:array[1..10000] of dl;
       b:array[0..3] of boolean;

      procedure work(x,y,harm:longint);
      begin
        explodeed[x,y]:=true;
        hurt_mob(whichmob(x,y),mx,my,harm,3,fromwho);
        if candes=true then
         if inmap(mx,my) then
          if mm.map[mx,my].id in [3]=false then
          begin
            tmp:=whichtank(x,y);
            if (fromwho<>tmp) or (hurtfrom=1) then hurt_tank(tmp,harm,3,fromwho);
            destroy(x,y,mx,my,harm,3);
          end;
      end;

   begin;

     head:=0;tail:=1;
     q[tail].x:=x;q[tail].y:=y;q[tail].pre:=0;q[tail].h:=hard;
     if inmap(x,y) then
     begin
       work(x,y,explodeharm[hard]);
     end;
     while head<>tail do
     begin
       inc(head);
       fillchar(b,sizeof(b),true);
       for ii:=0 to 3 do
       begin
      //   write(candes);
         repeat
           i:=random(4);
         until b[i];
         b[i]:=false;
         xx:=q[head].x+gox[i];
         yy:=q[head].y+goy[i];
         if inmap(xx,yy)=false then continue;
         if explodeed[xx,yy] then continue;
         if (mm.map[xx,yy].hard>explodeharm[q[head].h]) or (mm.map[xx,yy].id in [0]+candestroyblock[3]-[3]=false)
         or ((candes=false) and (mm.map[xx,yy].id in cangoblock_mob=false)) then
         begin
           work(xx,yy,explodeharm[q[tail].h]);
           continue;
         end;
         if (q[head].h>1) then
         begin
           inc(tail);
           q[tail].x:=xx;q[tail].y:=yy;q[tail].pre:=head;q[tail].h:=q[head].h-1;
           work(xx,yy,explodeharm[q[tail].h]);
           if (mm.map[xx,yy].id in [0]=false) then q[tail].h:=q[head].h-mm.map[xx,yy].hard div 3-1;
         end;//end if can
       end;// end for
     end; //end while
   end;//end bfs

begin
  if (nomusic=0) then playmusic('music\boom'+chr(random(4)+1+ord('0'))+'.wav','0');
  hard:=min(hard,maxexplodehard);
  hard:=max(hard,0);
  fillchar(explodeed,sizeof(explodeed),false);
  candes:=true;
  if inmap(mx,my) then
   if mm.map[mx,my].id in [3] then candes:=false;
  bfs(mx,my,hard);
end;    
procedure explode(mx,my,hard,fromwho,hurtfrom:longint);
begin
  explode(mx,my,hard,fromwho,hurtfrom,0);
end;
procedure explode(m:Tpos;hard,fromwho,hurtfrom,nomusic:longint);
begin
  explode(m.x,m.y,hard,fromwho,hurtfrom,nomusic);
end;
procedure explode(m:Tpos;hard,fromwho,hurtfrom:longint);
begin
  explode(m.x,m.y,hard,fromwho,hurtfrom,0);
end;

procedure print_tip(s:string;color:longint);
var i,j,t:longint;
begin
  gotoxy(maxtiplength div 2-(length(s) div 2)+3,maxy+2);
  tc(color);tb(8);write(s);
end;

procedure init_tip(s:string;c,lf:longint);
var i,j,t:longint;
begin
  with tip do
  begin
    if twn=maxtip then exit;
    inc(twn);
    with tipwaiting[twn] do
    begin
      st:=s;
      color:=c;
      lastfor:=lf;
      if twn>1 then exit;
      gt(starttime);
      print_tip(st,color);
    end;//end with
  end;//end with
end;

procedure hurt_mob(var who:Tmob;fromx,fromy,harm,ht,fromwho:longint);
var i,n,gf:longint;
begin
  with who do
  begin
    if living=false then exit;
    if getmobharmtype(id) in [2] then exit;
    if (fromx=zb.x) and (fromy=zb.y) then exit;
    gf:=getfx(fromx,fromy,zb.x,zb.y);
    repeat
      if fx=-1 then break;
      if abs(gf-fx)=2 then
      begin
        speed:=max(speed,10-harm);
        if speed<0 then
        begin
          fx:=gf;
          speed:=-speed;
        end;
      end
       else if gf=fx then
       begin
         dec(speed,harm div 2+1);
       end;
    until true;
    if speed=maxlongint then speed:=10-harm;
   // speed:=max(speed,0);

    if harm>2 then fx:=gf;
    whos:=fromwho;
    print_mob(who);
  end;//end with
end;
procedure hurt_mob(n,fromx,fromy,harm,ht,fromwho:longint);
begin
  if n<1 then exit;
  hurt_mob(mob[n],fromx,fromy,harm,ht,fromwho);
end;

procedure hurt_tank(var who:Ttank;harm,ht,fromwho:longint);
var i,n:longint;
begin
  with who do
  begin
    if living=false then exit;
    if (nam='Player') and god then exit;
    if unbreakble then exit;

    if (occup<>2) or (skillusing=false) then dec(hp,harm)
     else begin
       dec(hp,harm div 10);
       if system.random<=harm mod 10/10 then dec(hp,1);
       playmusic('music\hitiron'+chr(random(4)+1+ord('0'))+'.wav','0');
     end;
    print_tank(who);
    checkdie(who);

    if living=false then
    begin
      if nam='Ai' then
       if (fromwho<0) and (god=false) and (cmdused=false) then
       begin
         init_tip('金钱增加'+inttostr(killaiprize[occup]),14,killaitipshowlast);
         inc(profile.money,killaiprize[occup]);
         inc(killnum[-fromwho,occup]);
         if ((setting.gamehard<2) or (player[-fromwho].occup=0)) and (player[-fromwho].occup in [0,1,3,4]) and (player[-fromwho].living) and (random(setting.gamehard+1)=0) then player[-fromwho].hp:=min(player[-fromwho].hp+1,player[-fromwho].maxhp);
         playmusic('music\kill.wav','0');
       end;
      if nam='Player' then
      begin
        inc(dietimes[-xu]);
      end;
    end;//end if die
  end;//end with
end;
procedure hurt_tank(n,harm,ht,fromwho:longint);
begin
  if n>0 then hurt_tank(ai[n],harm,ht,fromwho)
   else if n=0 then exit
    else if n<0 then hurt_tank(player[-n],harm,ht,fromwho);
end;

procedure checkdie(var who:Ttank);
var i,n,t,w,j:longint;
begin
  with who do
   if living and (hp<=0) then
   begin
     if (nam='Ai') and (occup=0) then bosstime:=false;
     if (nam='Player') then
       playmusic('music/player_death.wav','0');
     living:=false;
     dec(lives);
     gt(ldt);
     print_auto(zb);
   end;//end with
end;
procedure checkdie;
var i:longint;
begin
  //for i:=1 to maxmob do checkdie(mob[i]);
  for i:=1 to maxai do checkdie(ai[i]);
  for i:=1 to setting.playernum do checkdie(player[i]);
end;

procedure fire(var who:Ttank;fangxiang,amt:longint);
var i,n,t:longint;
begin
  with who do
  begin
    fx:=fangxiang;
    print_tank(who);
    repeat
      gt(lft[amt]);
      t:=new_mob(zb.x{+gox[fx]},zb.y{+goy[fx]},fx,amt,xu);
    until true;
    gt(lft[amt]);
    if nam='Player' then
     if (amt<>1) and (god=false) then dec(profile.ammo[amt]);
    case amt of
      1:playmusic('music\fire_bullet.wav','0');
      2:playmusic('music\fire_laser.wav','0');
      3:playmusic('music\fire_bomb.wav','0');
    end;
  end;//end with
end;

function canfire(who:Ttank;amt:longint):boolean;
var i,n,t:longint;
begin
  with who do
  begin
    if occup=2 then
    begin
      if tick-lft[amt].tick<firespeed[id,occup,amt] div (2+random(2)) then exit(false);
    end
     else if tick-lft[amt].tick<firespeed[id,occup,amt] then exit(false);
    if (id=0) and (amt<>1) and (god=false) and (profile.ammo[amt]<=0) then exit(false);
  end;//end with
  exit(true);
end;

procedure move(var who:Ttank;dfx:longint);
var i,n,t:longint;
    ox,oy:longint;
begin
  with who do
  begin
    ox:=zb.x;
    oy:=zb.y;
    inc(zb.x,gox[dfx]);
    inc(zb.y,goy[dfx]);
    fx:=dfx;
    gt(lmt);
    print_auto(ox,oy);
    print_tank(who);
    hitbox[ox][oy]:=0;
    hitbox[zb.x][zb.y]:=0;
  end;//end with
end;

function canmove(who:Ttank;dfx:longint):boolean;
var i,n,t:longint;
    xx,yy:longint;
begin
  with who do
  begin
    if tick-lmt.tick<speed then exit(false);
    if (occup=2) and (skillusing) then exit(false);
    if fx=-1 then exit(false);
    xx:=zb.x+gox[dfx];
    yy:=zb.y+goy[dfx];
    if nam='Mob' then
      exit(can(xx,yy,2));
    exit(can(xx,yy,1));
  end;//end with
end;

procedure print_tank(who:Ttank);
var i,tcc,tbc:longint;
    s:string;
begin
  with who do
  begin
    if living=false then exit;
    if mm.map[zb.x,zb.y].id in donotprintblock_tank then exit;
    if unbreakble and (tick mod unbreakbleblinklast>=unbreakbleblinklast div 2) then exit;
    tbc:=tankbackground[id];
    tcc:=color(hp,maxhp);
    if nam='Player' then
    begin
      if xu=-2 then tbc:=player2color;
      tcc:=15;
      if skillusing then
       if xu=-1 then tcc:=13
        else tcc:=9;
      if tick-skill.stop.tick<occupskilltime[occup,1] then tcc:=8;
    end;
    s:=tankchar[id,occup,fx];

     with newsc[zb.x,zb.y] do
     begin
       bg:=tbc;
       col:=tcc;
       ch:=s;
     end;//end with
  {  gotoxy(zb.x*2+1,zb.y+1);
    tc();
    write(tankchar[id,occup,fx]);  }
  end;
end;
procedure print_tank(n:longint);
begin
  if (n>=1) and (n<=maxai) then
  begin
    print_tank(ai[n]);
  end
   else if (-n>=1) and (-n<=maxplayer) then
   begin
     print_tank(player[-n]);
   end;
end;

procedure print_mob(who:Tmob);
var i,tcc,tbc:longint;
    s:string;
begin
  with who do
  begin
    if living=false then exit;
  //  gotoxy(zb.x*2+1,zb.y+1);
    if mm.map[zb.x,zb.y].id in donotprintblock_mob then exit;
    tbc:=blockbackground[mm.map[zb.x,zb.y].id];
    tcc:=mobcolor[id];
    if id=4 then
    begin
      if (tick-lst.tick) mod TNTblinklast<TNTblinklast div 2 then tbc:=7
       else begin
         tbc:=6;
         tcc:=0;
       end;
    end;
    s:=mobchar[id,max(fx,0)];
     with newsc[zb.x,zb.y] do
     begin
       bg:=tbc;
       col:=tcc;
       ch:=s;
     end;//end with
  end;
end;
procedure print_mob(n:longint);
begin
  if (n<1) or (n>maxmob) then exit;
  print_mob(mob[n]);
end;

procedure print_block(x,y:longint);
begin
  if inmap(x,y)=false then
  begin
    clrscr;tc(15);tb(0);
    writeln('Error!');
    writeln('Wrong x or y in procedure print_block');
    writeln('x=',x,'  y=',y);
    delay(2000);
    halt;
  end;
  with mm.map[x,y] do
    print(x,y,blockbackground[id],blockcolor[id],blockchar[id,fx]);
end;
procedure print_block(x:Tpos);
begin
  print_block(x.x,x.y);
end;

procedure print_auto(x,y:longint);
var n:longint;
begin
  print_block(x,y);
  n:=whichmob(x,y);
  if n<>-1 then
  begin
    print_mob(mob[n]);
  end;
  n:=whichtank(x,y);
  if n>0 then
  begin
    print_tank(ai[n]);
  end
   else if n<0 then
   begin
     print_tank(player[-n]);
   end;
end;
procedure print_auto(zb:Tpos);
begin
  print_auto(zb.x,zb.y);
end;

procedure print_game_info;
var i,j,t,n:longint;
    playern,propn:longint;
    s:string;

   procedure printflagstatus(what:Tflag);
   var i,x:longint;
   begin
     with what do
     begin
       if lthp=hp then exit;
       tb(blockbackground[id]);tc(15);
       write(blockchar[id,0]);
       tb(0);tc(15);write(':');
       x:=wherex;
       tc(color(hp,maxhp));
       tb(0);write(hp);
       x:=wherex-x;for i:=1 to 3-x do write(' ');
       tc(15);write('/',maxhp);
      // for i:=1 to 10-y do write(' ');
     end;//end with
   end;

begin
  for playern:=1 to setting.playernum do
   with player[playern] do
   begin
     if ltl[playern]<>lives then
     begin
       gotoxy(15,maxy+3);if playern=2 then gotoxy(wherex,wherey+1);
       tb(bkbg);tc(15);
       tc(color(lives,maxlives));
       write(lives);
       str(lives,s);
       for i:=1 to 4-length(s) do
       begin
         tb(bkbg);tc(bkcl);
         write(' ');
       end;
     end;
     if lthp[playern]<>hp then
     repeat
       gotoxy(22,maxy+3);if playern=2 then gotoxy(wherex,wherey+1);
       tb(bkbg);tc(color(hp,maxhp));
       write(hp);
       str(hp,s);
       for i:=1 to 4-length(s) do
       begin
         tb(bkbg);tc(bkcl);
         write(' ');
       end;
       if hp>lthp[playern] then break;
       n:=random(3)+1;
       s:='music\hit'+chr(n+ord('0'))+'.wav';
       playmusic(s,'0');
      // write(s);
     until true;
     for propn:=1 to maxproptype do
      if ltprop[playern,propn]<>profile.prop[propn] then
      begin
        gotoxy(40+(propn-1)*10,maxy+3);if playern=2 then gotoxy(wherex,wherey+1);
        tb(bkbg);tc(15);
        write(profile.prop[propn]);
        str(profile.prop[propn],s);
        for i:=1 to 3-length(s) do
        begin
          tb(bkbg);tc(bkcl);
          write(' ');
        end;
      end;
   end;//end with

  gotoxy(maxx*2-6,maxy+3);
  printflagstatus(playerflag);
  gotoxy(maxx*2-6,maxy+4);
  printflagstatus(aiflag);

  tb(bkbg);tc(15);
  gotoxy(maxx*2-9,maxy+2);WRITE('Tick:',tick);

  gt(fpsn);
  if td(fpsb,fpsn)>=1000 then
  begin
    gotoxy(73,1);tb(bkbg);write('       ');
    gotoxy(80-length('Tps:'+inttostr(fpsn.tick-fpsb.tick))+1,1);tb(bkbg);tc(7);if fpsn.tick-fpsb.tick>=1000 div ticklast then tc(15);write('Tps:',fpsn.tick-fpsb.tick);
    fpsb:=fpsn;
  end;

        for i:=1 to setting.playernum do
         with player[i] do
         begin
           lthp[i]:=hp;
           for j:=1 to maxproptype do
             ltprop[i,j]:=profile.prop[j];
         end;
         playerflag.lthp:=playerflag.hp;aiflag.lthp:=aiflag.hp;
end;

procedure print_screen(j,i:longint);
var x1,x2,y1,y2:longint;
    s:string;
begin
  if (oldsc[j,i].ch<>newsc[j,i].ch) or (oldsc[j,i].bg<>newsc[j,i].bg) or (oldsc[j,i].col<>newsc[j,i].col) then
   with newsc[j,i] do
   begin
     gotoxy(j*2+1,i+1);
     tb(bg);tc(col);
     if ch<>'  ' then write(ch)
      else begin
        x1:=windminx;x2:=windmaxx;y1:=windminy;y2:=windmaxy;
        windminx:=j*2+x1;windmaxx:=j*2+length(ch)+x1-1;windminy:=i+y1;windmaxy:=i+y1;
        clrscr;
        windminx:=x1;windmaxx:=x2;windminy:=y1;windmaxy:=y2;
      end;
     oldsc[j,i]:=newsc[j,i];
   end;//end with
end;

procedure print_screen(opt:longint);
var i,j,x,y,cnt:longint;
    vst:array[1..maxx,1..maxy] of boolean;
begin
  fillchar(vst,sizeof(vst),false);
  if (opt=1) then
  begin
    case random(4) of
      0:for i:=1 to maxx do
         for j:=1 to maxy do
           print_screen(i,j);
      1:for i:=maxx downto 1do
         for j:=1 to maxy do
           print_screen(i,j);
      2:for i:=1 to maxy do
         for j:=1 to maxx do
           print_screen(j,i);
      3:for i:=maxy downto 1 do
         for j:=1 to maxx do
           print_screen(j,i);
    end;
    exit;
  end
  else if (opt=2) then
  begin
    for i:=1 to maxx*maxy do
    begin
      repeat
        x:=random(maxx)+1;
        y:=random(maxy)+1;
      until vst[x][y]=false;
      vst[x][y]:=true;
      print_screen(x,y);
    end;
    exit;
  end;
  for i:=-maxy to maxx+maxy do
  begin
    x:=i;
    y:=0;
    if (opt mod 2=1) then inc(x,maxy);
    for j:=1 to maxy do
    begin
      if opt mod 2=0 then inc(x)
      else dec(x);    
      inc(y);
      if (x>=1) and (x<=maxx) and (y>=1) and (y<=maxy) then
      begin
        if (vst[x][y]=false) then print_screen(x,y);
        vst[x][y]:=true;
      end;
    end;
    x:=maxx+maxy-i;
    if (opt mod 4>=2) then dec(x,maxy);
    y:=0;
    for j:=1 to maxy do
    begin
      if opt mod 4<2 then inc(x)
      else dec(x); 
      inc(y);
      if (x>=1) and (x<=maxx) and (y>=1) and (y<=maxy) then
      begin
        if (vst[x][y]=false) then print_screen(x,y);
        vst[x][y]:=true;
      end;
    end;
  end;
 // oldsc:=newsc;
end;
procedure print_screen;
begin
  print_screen(random(7));
end;

procedure print_map;
var i,j,t,n:longint;
begin
  tb(0);
  clrscr;
  tb(bkbg);
  tc(bkcl);
  write('╔');
  for i:=1 to maxx do write('═');
  write('╗');
  tb(bkbg);
  writeln;
  for i:=1 to maxy do
  begin
    gotoxy(1,i+1);
    tb(bkbg);
    tc(bkcl);
    write('║');
    for j:=1 to maxx do
     with mm.map[j,i] do
     begin
       print_auto(j,i);
     end;
    gotoxy(79,i+1);
    tb(bkbg);
    tc(bkcl);
    writeln('║');
  end;
  gotoxy(1,maxy+2);
  write('╚');
  for i:=1 to maxx do write('═');
  write('╝');
  writeln;

  gotoxy(20,1);
  tb(bkbg);tc(11);
  write(mm.nam);

  tb(bkbg);tc(7);
  gotoxy(maxx*2-25,1);
  write('关卡:');
  tc(15);
  write(lenlimit(mm.filenam,15));

  for i:=1 to setting.playernum do
  begin
    gotoxy(1,maxy+3+i-1);
    if i=1 then tb(tankbackground[0]) else tb(player2color);tc(15);write(tankchar[0,1,0]);    // gotoxy(wherex+4,wherey);
    tb(0);tc(7);write(' ',occupnam[0,player[i].occup],' ');
    tc(15);tb(0);{write(#3,'=');}write('Lives:');

    gotoxy(19,wherey);write('HP:');
    for j:=1 to maxproptype do
    begin
      gotoxy(35+(j-1)*10,wherey);
      write(propnam[j],':',profile.prop[j]);
    end;
  end;
  print_game_info;
  print_screen;
end;

procedure clear_tip;
var i,n,t:longint;
begin
  gotoxy(3,maxy+2);
  tc(bkcl);tb(bkbg);
  for i:=1 to maxtiplength div 2 do write('═');
end;

procedure clear_mob(var who:Tmob);
var i,j,n,t,w:longint;
begin
  with who do
  begin
    maxhp:=0;hp:=0;
    fx:=0;
    living:=false;
    lmt.tick:=-1000;
    ldt.tick:=-1000;
    lst.tick:=-1000;
    zb.x:=-1;zb.y:=-1;
    id:=255;
  end;
end;

procedure clear_tank(var who:Ttank);
var i,j,n,t,w:longint;
begin
  with who do
  begin
    maxhp:=0;hp:=0;
    fx:=0;
    living:=false;
    lmt.tick:=-1000;
    for i:=1 to maxammotype do lft[i].tick:=-1000;
    ldt.tick:=-1000;
    lst.tick:=-1000;
    zb.x:=-1;zb.y:=-1;
    id:=255;
    ljn:=0;
    skillusing:=false;
  end;
end;

procedure clear_map;
var i,j,n,t,w:longint;
begin
  for i:=1 to maxx do
   for j:=1 to maxy do
    with mm.map[i,j] do
    begin
      id:=0;
      hard:=0;
      maxhard:=0;
      fj:=0;
      fx:=0;
      lrt.tick:=0;
      unbreakble:=false;
    end;
end;

procedure end_game;
var i,j,n,t:longint;
begin
  tb(0);clrscr;
  windminx:=1;windmaxx:=setting.smaxx;
  windminy:=1;windmaxy:=setting.smaxy;
  print_program_info;
  windmaxy:=setting.smaxy-3;
  gaming:=false;

  for i:=1 to setting.playernum do
  begin
    inc(dietimes[0],dietimes[i]);
    for j:=1 to maxoccup do
      inc(killnum[0,j],killnum[i,j]);
  end;
  for i:=1 to maxoccup do
    inc(killnum[0,0],killnum[0,i]);
  if ismainlevel then t:=levelwinprize[nowlevel] else t:=0;
  if ismainlevel then n:=nowlevel else n:=3;
  score:=(500*n+(t div 100+killnum[0,0])*(setting.gamehard*5+1)) div max(dietimes[0]+1-(nowlevel div 4),1);
  score:=round(score*(system.random/2+0.75));

  if ismainlevel and gamewin  then
  begin
    for assess:=1 to maxassess do
     if gameendtick<=levelbesttime[nowlevel,assess] then break;
  end
   else if gamelose then assess:=maxassess
    else assess:=round(maxassess*0.75);
end;

procedure print_program_info;
var i,j:longint;
begin
  gotoxy(setting.smaxx-length('程序版本:'+Version)+1,setting.smaxy-2);                 tc(7);  write('程序版本:',Version);
  gotoxy(setting.smaxx-length('适用地图版本:'+ApplicationVersion)+1,setting.smaxy-1);  tc(7);  write('适用地图版本:',ApplicationVersion);
  gotoxy(setting.smaxx-15,setting.smaxy);                                              tc(8);  write('By ');  tc(15);  write('Fallen_Breath');
end;

procedure print_profile;
var i,n,t,x,y:longint;
begin
  clrscr;
  tb(0);
  with profile do
  begin
    tc(12);write('账号:');tc(15);writeln(usernam);
    tc(14);write('金钱:');tc(15);writeln(money);
    writeln;
    tc(11);writeln('弹药');
    for i:=1 to maxammotype do
    begin
      tc(7);write(ammonam[i],':');
      tc(15);
      if i=1 then writeln('∞')
       else writeln(ammo[i]);
    end;
    tc(11);writeln('道具');
    for i:=1 to maxproptype do
    begin
      tc(7);write(propnam[i],':');
      tc(15);writeln(prop[i]);
    end;
    writeln;
    tc(11);writeln('关卡状态');
    for i:=1 to mainlevelnum do
    begin
      tc(7);write('Level-',i,':');
      if levelunlock[i] then
      begin
        tc(15);write('已解锁');
      end
       else begin
        tc(8);write('未解锁');
       end;
      write(' ');
      if levelfinish[i] then
      begin
        tc(15);write('已通过');
      end
       else begin
        tc(8);write('未通过');
       end;
      if (i<>mainlevelnum) then writeln;
    end;
    writeln;
    gotoxy((windmaxx+windminx) div 2,windminy);
    x:=wherex; y:=wherey;
    tc(11);write('职业状态');
    for i:=0 to maxoccup do
    begin
      inc(y);
      gotoxy(x,y);
      tc(7);write(occupnam[0][i],':');
      if profile.occupown[i] then
      begin
        tc(15);write('已拥有');
      end
       else begin
        tc(8);write('未获得');
       end;
    end;
  end;//end with
  readkey;
end;

procedure save;
var i,j,n:longint;
    wj:text;
begin
  if logged=false then exit;
  assign(wj,'save/'+profile.filenam);
  rewrite(wj);
  writeln(wj,Version);
  with profile do
  begin
    writeln(wj,'PassWord=',password);
    writeln(wj,'Money=',money);
    for i:=1 to mainlevelnum do
    begin
      writeln(wj,'Level',i,'UnLock=',levelunlock[i]);
    end;
    for i:=1 to mainlevelnum do
    begin
      writeln(wj,'Level',i,'Finish=',levelfinish[i]);
    end;
    for i:=1 to maxammotype do
    begin
      writeln(wj,'Ammo',i,'=',ammo[i]);
    end;
    for i:=1 to maxproptype do
    begin
      writeln(wj,'Prop',i,'=',prop[i]);
    end;
    for i:=0 to maxoccup do
    begin
      writeln(wj,'Occup',i,'Own=',occupown[i]);
    end;
  end;//end with
  close(wj);
end;

function load(mode:longint):boolean;
var choose,i,n,t:longint;
    s:string;
    res:findfilesres;

   procedure fileread(fn:ansistring);
   var wj:text;
       s,s1,s2,s3,e:string;
       i,j,n,t:longint;
       next,b:boolean;
      function fr(var s:string):string;
      begin
        if next then exit('');
        readln(wj,s);
        fr:=s;
        if pos('=',s)=0 then exit;
        while (length(s)>=1) and (s[1]<>'=') do delete(s,1,1);
        delete(s,1,1);
      end;
      function fr:string;
      var s:string;
      begin
        readln(wj,s);
        s1:='';s2:='';s3:='';
        if pos('=',s)=0 then exit(s);
        while (length(s)>1) and (s[1] in ['0'..'9','=']=false) do
        begin
          s1:=s1+s[1];
          delete(s,1,1);
        end;
        while (length(s)>1) and (s[1] in ['0'..'9']) do
        begin
          s2:=s2+s[1];
          delete(s,1,1);
        end;
        while (length(s)>1) and (s[1]<>'=') do
        begin
          s3:=s3+s[1];
          delete(s,1,1);
        end;
        if (length(s)>1) and (s[1]='=') then delete(s,1,1);
        exit(s);
      end;
   begin
     assign(wj,'save/'+fn);
     reset(wj);
     next:=false;
     with profile do
     begin
       fillchar(levelunlock,sizeof(levelunlock),false);levelunlock[1]:=true;levelunlock[2]:=true;
       fillchar(levelfinish,sizeof(levelfinish),false);
       fillchar(occupown,sizeof(occupown),false);occupown[0]:=true;
       fillchar(ammo,sizeof(ammo),0);
       fillchar(prop,sizeof(prop),0);

       filenam:=fn;
       usernam:=copy(fn,1,length(fn)-9);
       e:=fr(password);
       if e=password then fr(password);
       fr(s);val(s,money);
       while not eof(wj) do
       begin
         s:=fr;
         val(s2,n);
         if s1='Level' then
         begin
           if s3='UnLock' then
           begin
             if (n>=1) and (n<=mainlevelnum) then levelunlock[n]:=s='TRUE';
           end//end if s3='Unlock'
           else if s3='Finish' then
           begin
             if (n>=1) and (n<=mainlevelnum) then levelfinish[n]:=s='TRUE';
           end;//end if s3='Finish'
         end//end if s1='Level'

         else if s1='Ammo' then
         begin
           if (n>=1) and (n<=maxammotype) then val(s,ammo[n]);
         end//end if s1='Ammo'

         else if s1='Prop' then
         begin
           if (n>=1) and (n<=maxproptype) then val(s,prop[n]);
         end//end if s1='Prop'

         else if s1='Occup' then
         begin
           if (s3='Own') then
           begin
             if (n>=0) and (n<=maxoccup) then occupown[n]:=s='TRUE';
           end;
         end;//end if s1='Occup'
       end;//end while
       if (levelunlock[mainlevelnum]=false) and (levelfinish[mainlevelnum]=false) then
       begin
         levelunlock[mainlevelnum]:=true;
         for i:=1 to mainlevelnum-1 do
          if (levelfinish[i]=false) then levelunlock[mainlevelnum]:=false;
       end;//end if
     end;//end with
     close(wj);
   end;

begin
  load:=false;
  repeat//=============================================================
    if mode=0 then
    begin
      clrscr;
      gotoxy_mid(getastr(max(length('登录'),length('游客'))+6),1);
                   choose:=chooseone('登录'+ln+
                                     '游客');
      if choose=2 then exit(false);
    end;
    repeat
      clrscr;
      gotoxy_mid(getastr(max(length('载入存档'),max(length('新建存档'),length('返回')))+6),1);
      choose:=chooseone('载入存档'+ln+
                        '新建存档'+ln+
                        '返回');
      clrscr;
      if choose=3 then break;
      clrscr;
      case choose of
        1:begin
            gotoxy_mid('Loading...',1);tb(0);tc(7);write('Loading...');
            findfiles('save/*.savedata',res);
            s:='';
            for i:=1 to res.filenum do
              s:=s+copy(res.filenam[i],1,length(res.filenam[i])-9)+ln;
            if length(s)=0 then
            begin
              gotoxy_mid('无存档',2);tc(4);tb(0);write('无存档');
              delay(500);
              continue;
            end;
            s:=s+'返回';
            clrscr;
            gotoxy_mid('存档列表',1);tb(0);tc(15);write('存档列表');
            gotoxy_mid(getastr(max(res.maxlen-9,length('返回'))+6),2);choose:=chooseone(s);
            if choose=res.filenum+1 then continue;
            s:=res.filenam[choose];
            fileread(s);
            i:=0;
            repeat
              clrscr;
              gotoxy_mid('请输入密码',1);tb(0);tc(7);write('请输入密码');
              gotoxy_mid(getastr(maxlengthofpassword),2);inputpassword(s);
              if s=profile.password then break;
              gotoxy_mid('密码错误',3);tb(0);tc(4);write('密码错误');
              inc(i);
              delay(300);
            until i=5;
            if i=5 then continue;
            gotoxy_mid('登录成功',3);tb(0);tc(12);write('登录成功');
            delay(500);
          end;//end case 1
        2:begin
            i:=0;
            repeat
              clrscr;
              gotoxy_mid('账号名:',1);tb(0);tc(15);write('账号名:');
              cursoron;
              gotoxy_mid(getastr(maxlengthofusernam),2);tb(0);tc(7);readln(s);
              cursoroff;
              if length(s) in [minlengthofusernam..maxlengthofusernam]=false then continue;
              if fsearch('save\'+s+'.savedata','\')='' then break;
              gotoxy_mid('该账号已存在',3);    tb(0);tc(4); write('该账号已存在');
              delay(75);
              gotoxy_mid('是否覆盖该账号',4);  tb(0);tc(15);write('是否覆盖该账号');
              delay(75);
              gotoxy_mid(getastr(max(length('否'),length('是'))+6),5);tb(0);tc(7);choose:=chooseone('否'+ln+
                                                                                                  '是');
              if choose=2 then break;
              inc(i);
              delay(300);
            until i=5;
            if i=5 then continue;
            with profile do
            begin
              filenam:=s+'.savedata';
              usernam:=s;
              repeat
                i:=0;
                repeat
                  clrscr;
                  gotoxy_mid('请输入密码',1);  tc(15);tb(0);  write('请输入密码');
                  gotoxy_mid(getastr(maxlengthofpassword),2);tc(7);tb(0);inputpassword(s);
                  if length(s) in [minlengthofpassword..maxlengthofpassword] then break;
                  gotoxy_mid('密码过短',3);    tc(4);tb(0);   write('密码过短');delay(300);
                  inc(i);
                until i=5;
                if i=5 then break;
                clrscr;
                gotoxy_mid('请再次输入密码',1);  tc(15);tb(0);  write('请再次输入密码');
                gotoxy_mid(getastr(maxlengthofpassword),2);tc(7);tb(0);inputpassword(password);
                if password=s then break;
                gotoxy_mid('密码错误',3);        tc(4);tb(0);   write('密码错误');delay(500);
              until false;
              if i=5 then continue;

              money:=1000;
              ammo[2]:=100;
              ammo[3]:=10;
              prop[1]:=10;
            end;//end with
            logged:=true;
            clrscr;
            gotoxy_mid('Loading...',1);      tb(0);tc(7);   write('Loading...');
            save;
            clrscr;
            gotoxy_mid('创建新存档成功',1);  tb(0);tc(12);  write('创建新存档成功');
            delay(700);
          end;//end case 1
      end;//end case
      exit(true);
    until false;
    if mode=1 then exit(false);
  until false;//=============================================================
end;

procedure init_program;
var i,j,n,t:longint;
    s:ansistring;

   procedure levelread(s:string;var mm:Tlevel);
   var i,j:longint;
       wjin:text;
   begin
     with mm do
     begin
       for i:=length(s)-10 downto 1 do
        if s[i]='\' then break;
       filenam:=copy(s,i+1,length(s)-i-10);
       ismainlevel:=false;
       if copy(s,1,i)='bin\' then ismainlevel:=true;

       assign(wjin,s);
       reset(wjin);
       readln(wjin,s);delete(s,1,pos('=',s));nam:=s;
       for i:=1 to maxx do
       begin
         for j:=1 to maxy do
          with mm.map[i,j] do
          begin
            read(wjin,id,hard,maxhard);
            if eoln(wjin)=false then read(wjin,fx,fj);
            readln(wjin);
          end;
       end;
readln(wjin);
       readln(wjin,playerflagmaxhp,aiflagmaxhp);
       readln(wjin,playerspawnpointnum);
       for i:=1 to playerspawnpointnum do
        with playerspawnpoint[i] do
         readln(wjin,x,y);

       for i:=1 to maxoccup do
         read(wjin,aispawnpointnum[i]);readln(wjin);
       for i:=1 to maxoccup do
       begin
         for j:=1 to aispawnpointnum[i] do
          with aispawnpoint[i,j] do
           readln(wjin,x,y);
       end;
       aispawnpointnum[0]:=playerspawnpointnum;
       for i:=1 to playerspawnpointnum do aispawnpoint[0][i]:=playerspawnpoint[i];
readln(wjin);
       readln(wjin,startspawntick);
       for i:=1 to maxoccup do
         readln(wjin,startspawnainum[i]);
       for i:=1 to maxoccup do
         readln(wjin,spawnprobability[i]);
       close(wjin);
     end;//end with
   end;

   procedure init_save;
   var i,j:longint;
   begin
     with profile do
     begin
       password:='';
       usernam:='';
       filenam:='';
       fillchar(ammo,sizeof(ammo),0);
       fillchar(prop,sizeof(prop),0);
       fillchar(levelunlock,sizeof(levelunlock),false);
       levelunlock[1]:=true;
       levelunlock[2]:=true;
       occupown[0]:=true;
       money:=1000;
       ammo[2]:=100;
       ammo[3]:=10;
       prop[1]:=10;
       fillchar(levelfinish,sizeof(levelfinish),false);
     end;
   end;

   procedure levelread(path:string);
   var r:findfilesres;
       i,j,n:longint;
   begin
     gotoxy(1,1);clreol;
     gotoxy_mid('Finding Level in Path "'+path+'"...',1);tc(7);write('Finding Level in Path "',path,'"...');
     findfiles(path+'*.leveldata',r);
     with r do
     begin
       for i:=1 to filenum do
       begin
         inc(levelnum);
         gotoxy(1,1);clreol;
         gotoxy_mid('Reading Level "'+filenam[i]+'"...',1);tc(7);write('Reading Level"',filenam[i],'"...');
         levelread(path+filenam[i],level[levelnum]);
       end;
       maxlevelnamlen:=max(maxlevelnamlen,r.maxlen-10);
       maxlevelnamlen:=min(maxlevelnamlen,setting.smaxx-6);
     end;//end with
   end;

begin
  //createwin(800,600);
  //settitle('坦克大战');
  cursoroff;
  randomize;
  checkbreak:=false;
  gaming:=false;
  logged:=false;
  setting.smaxx:=windmaxx;
  setting.smaxy:=windmaxy;
  print_program_info;
  dec(windmaxy,3);

  for i:=1 to maxplayer do
   with player[i] do
   begin
     xu:=-i;
     nam:='Player';
   end;//end with
  for i:=1 to maxai do
   with ai[i] do
   begin
     xu:=i;
     nam:='Ai';
   end;
  with noai do
  begin
    xu:=-1;
  end;//end with

  if directoryexists('bin')        =false then mkdir('bin');
  if directoryexists('save')       =false then mkdir('save');
  if directoryexists('level')      =false then mkdir('level');
  if directoryexists('screenshot') =false then mkdir('screenshot');

  gotoxy(1,1);clreol;gotoxy_mid('Reading "+SettingFileNam+"...',1);tc(7);write('Reading "',SettingFileNam,'"...');
  with setting do
  begin
    if fsearch(SettingFileNam,'\')<>'' then
    begin
      assign(wjin,SettingFileNam);
      reset(wjin);
      readln(wjin,s);while (s[1]<>'=') and (length(s)<>0) do delete(s,1,1);delete(s,1,1);val(s,gamehard,t);if (t<>0) or (gamehard>maxgamehard) or (gamehard<0) then gamehard:=1;
      readln(wjin,s);while (s[1]<>'=') and (length(s)<>0) do delete(s,1,1);delete(s,1,1);val(s,gamemode,t);if (t<>0) or (gamemode>maxgamemode) or (gamehard<0) then gamemode:=0;
      if gamemode=1 then god:=true;
      if eof(wjin)=false then
      begin
        readln(wjin,s);while (s[1]<>'=') and (length(s)<>0) do delete(s,1,1);delete(s,1,1);val(s,playernum,t);if (t<>0) or (playernum>maxplayer) or (playernum<0) then playernum:=1;
        if (eof(wjin)=false) then
        begin
          readln(wjin,s);while (s[1]<>'=') and (length(s)<>0) do delete(s,1,1);delete(s,1,1);val(s,musicon,t);if (t<>0) or (musicon>1) or (musicon<0) then musicon:=1;
        end;
      end
       else begin
         playernum:=gamemode;
         musicon:=1;
         gamemode:=0;
       end;
      close(wjin)
    end//end if fsearch(SettingFileNam,'\')<>''
     else begin
       gamehard:=1;
       gamemode:=0;
       playernum:=1;
       musicon:=1;
     end;
    assign(wjout,SettingFileNam);
    rewrite(wjout);
    writeln(wjout,'GameHard=',gamehard);
    writeln(wjout,'GameMode=',gamemode);
    writeln(wjout,'Player=',playernum);
    writeln(wjout,'Music=',musicon);
    close(wjout);
  end;//end with
  gotoxy(1,1);clreol;

  levelnum:=0;
  maxlevelnamlen:=0;
  levelread('bin\');
  levelread('level\');
 { for i:=1 to levelnum do
  begin
    n:=(maxlevelnamlen-length(level[i].filenam)) div 2;
    for j:=1 to n do
      level[i].filenam:=' '+level[i].filenam;
  end;           }
  init_save;
end;

procedure init_prop(dx,dy,did,dwhos:longint);
var i,n,t:longint;
begin
  case did of
    1:begin
        with mm.map[dx,dy] do
        begin
          id:=11;
          fj:=dwhos;
          fx:=0;
          maxhard:=blockmaxhard[id];
          hard:=maxhard;
        end;
        print_auto(dx,dy);
      end;
  end;//end case
end;

procedure init_tank(var who:Ttank;d_id,docc:longint; _pos:Tpos);
const didnotuse=-1000;
var i,j,n,t,w:longint;
    b:boolean;
    spawn:Tpos;
begin
  with who do
  begin
    case d_id of
      0:begin
          b:=false;
          for j:=1 to mm.playerspawnpointnum do
           if can(mm.playerspawnpoint[j],1) then b:=true;
          if b=false then exit;

          lmt.tick:=didnotuse;
          with skill do
          begin
            start.tick:=didnotuse;
            stop.tick:=didnotuse;
            use.tick:=didnotuse;
          end;

          repeat
            spawn:=mm.playerspawnpoint[random(mm.playerspawnpointnum)+1];
          until can(spawn.x,spawn.y,1);
          zb:=spawn;
          unbreakble:=true;
          for i:=1 to maxammotype do lft[i].tick:=0;
        end;
      1:begin

          maxlives:=1;
          lives:=maxlives;

          for i:=1 to maxammotype do
          begin
            gt(lft[i]);
            lft[i].tick:=tick+50-setting.gamehard*20;
          end;
          if docc in canbfsoccup then lmt.tick:=tick+50-setting.gamehard*20
           else lmt.tick:=didnotuse;
          ljn:=0;

          zb:=_pos;
        end;
    end;//end case
    living:=true;
    skillusing:=false;
    fx:=0;
    id:=d_id;
    occup:=docc;
    gt(lmt);
    gt(lst);
    speed:=tankspeed[d_id,docc];
    maxhp:=tankmaxhp[d_id,docc];
    hp:=maxhp;
    hitbox[zb.x][zb.y]:=tick*2;
    print_tank(who);
  end; //end with
end;
procedure init_tank(var who:Ttank;d_id,docc:longint);
var pos:Tpos;
begin
  pos.x:=-1;
  pos.y:=-1;
  init_tank(who,d_id,docc,pos);
end;

procedure init_mob(nn,dx,dy,dfx,d_id,dwhos:longint);
var i,j,n,w:longint;
begin
  if (dx=-1) or (dy=-1) then exit;
  with mob[nn] do
  begin
    id:=d_id;fx:=dfx;whos:=dwhos;
    nam:='Mob';
    speed:=mobspeed[d_id];
    zb.x:=dx;zb.y:=dy;
    living:=true;
    rfx:=false;
    gt(lmt);//inc(lmt.tick);
    gt(lst);
    maxhp:=mobmaxhp[d_id];
    hp:=maxhp;
  //  work_mob;
    if living=false then exit;

    //print(zb.x,zb.y,-1,15,mobchar[id,fx]);
   { if nn>t then
    begin
      t:=nn;
      gotoxy(1,1);write(t);
    end;       }
  end;
end;

function new_mob(dx,dy,dfx,d_id,dwhos:longint):longint;
var i,j,n,t,w:longint;
begin
  if inmap(dx,dy)=false then exit(-1);
  if d_id=0 then exit;
  for i:=1 to maxmob do
   with mob[i] do
    if living=false then
    begin
   //   if (id in [0]) and (tick-ldt.tick<=TNTexplodelast) then continue;
      init_mob(i,dx,dy,dfx,d_id,dwhos);
      exit(i);
    end;
  exit(-1);
end;

function new_ai(d_id,docc:longint;spawn:Tpos):longint;
var i,j,n,t,w:longint;
    b:boolean;
begin
  if (spawn.x=-1) then
  begin
    b:=false;
    for j:=1 to mm.aispawnpointnum[docc] do
     if can(mm.aispawnpoint[docc,j],1) then b:=true;
    if b=false then exit(-1);
    repeat
      spawn:=mm.aispawnpoint[docc,random(mm.aispawnpointnum[docc])+1];
      for j:=1 to maxplayer do
       if player[j].living then
        if ju(spawn,player[j].zb)<=5 then exit;
    until can(spawn.x,spawn.y,1);
  end;
  for i:=1 to maxai do
   with ai[i] do
    if living=false then
    begin
      if tick-ldt.tick<=dyinglast then continue;
      init_tank(ai[i],d_id,docc,spawn);
      if (docc=0) and (ai[i].living) then bosstime:=true;
      exit(i);
    end;
  exit(-1);
end;  
function new_ai(d_id,docc:longint):longint;
var spawn:Tpos;
begin
  spawn.x:=-1;
  spawn.y:=-1;
  exit(new_ai(d_id,docc,spawn));
end;

procedure init_game;
var i,j,n,t,w:longint;

   procedure p1(var x:Tscreen);
   var i:longint;
   begin
     with x do
     begin
       ch:=chr(0);
       col:=0;bg:=0;
     end;
   end;

begin
  Tick:=0;
  gameendtick:=-1;
  clrscr;
  t:=(setting.smaxx-80) div 2;
  windminx:=t+1;windmaxx:=80+t;
  t:=(setting.smaxy-25) div 2;
  windminy:=t+1;windmaxy:=25+t;
  fillchar(hitbox,sizeof(hitbox),0);
///////////////Clear Tank///////////////
  for i:=1 to maxai do
    clear_tank(ai[i]);
  for i:=1 to setting.playernum do
    clear_tank(player[i]);
  for i:=1 to maxmob do
    clear_mob(mob[i]);

  for i:=1 to maxoccup do
   for j:=1 to mm.startspawnainum[i] do
     new_ai(1,i);
  if (mm.nam='What''s that?!') and ismainlevel then
  with mm do
  begin
    aispawnpointnum[0]:=4;
    aispawnpoint[0][1].x:=29; aispawnpoint[0][1].y:=4;
    aispawnpoint[0][2].x:=29; aispawnpoint[0][2].y:=5;
    aispawnpoint[0][3].x:=30; aispawnpoint[0][3].y:=4;
    aispawnpoint[0][4].x:=30; aispawnpoint[0][4].y:=5;
    new_ai(1,0);
    aispawnpointnum[0]:=playerspawnpointnum;
    for i:=1 to playerspawnpointnum do aispawnpoint[0][i]:=playerspawnpoint[i];
  end;
  for i:=1 to maxx do
   for j:=1 to maxy do
   begin
     p1(oldsc[i,j]);
     p1(newsc[i,j]);
   end;

  with playerflag do
  begin
    zb.x:=findblock(4,0).x;
    zb.y:=findblock(4,0).y;
    id:=4;
    maxhp:=mm.playerflagmaxhp;
    hp:=maxhp;
  end;
  with aiflag do
  begin
    zb.x:=findblock(5,0).x;
    zb.y:=findblock(5,0).y;
    id:=5;
    maxhp:=mm.aiflagmaxhp;
    hp:=maxhp;
  end;

  livingnum:=0;
  gaming:=true;
  gamewin:=false;
  gamelose:=false;
  bosstime:=false; 
  cmdused:=false;
  cmdmemcnt:=0;

  for i:=1 to setting.playernum do
    init_tank(player[i],0,player[i].occup);
  playerflag.lthp:=-1;aiflag.lthp:=-1;
  for i:=1 to maxplayer do
   with player[i] do
   begin
     lthp[i]:=-1;
     ammotype:=1;
     maxlives:=playermaxlives;
     lives:=maxlives;
   end;
  fillchar(ltl,sizeof(ltl),255);
///////////////Clear Tips///////////////
  with tip do
  begin
    twn:=0;
    for i:=1 to maxtip do
     with tipwaiting[i] do
     begin
       st:='';
       color:=7;
       gt(starttime);
       lastfor:=0;
     end;//end with&for
    gt(lasttipendtime);
  end;

  fillchar(killnum,sizeof(killnum),0);
  fillchar(dietimes,sizeof(dietimes),0);
end;

procedure work_mob(i:longint);
const block8harm:array[0..5] of longint=(15,9,6,4,2,1);
      number:array[0..9] of string=('0','1','2','3','4','5','6','7','8','9');
var j,k,n,t,w,xx,yy,ox,oy:longint;
    ain:longint;

   procedure workblock8(var who:Tmob);
   var h,i,j,n,t:longint;
   begin
     with who do
     begin
       if (rfx=false) then explode(zb.x,zb.y,TNTexplodehard,whos,0)
       else explode(zb.x,zb.y,TNTexplodehard,whos,1);
     end;
   end;

   procedure workmob3(var who:Tmob);
   var h,i,j,n,t:longint;
   begin
     with who do
     begin
       if (rfx=false) then explode(zb.x,zb.y,mob3explodehard,whos,0)
       else explode(zb.x,zb.y,mob3explodehard,whos,1);
     end;
   end;

   procedure hurttank(var mob:Tmob;mode:longint);
   var n,h:longint;
   begin
     with mob do
     begin
       h:=mobharm[id];
       n:=whichtank(zb.x,zb.y);
       if n=0 then exit;
       if (whos=n) and (rfx=false) then exit;
       if mode=1 then
       begin
         if n>0 then begin if ai[n].lmt.tick<>tick-1 then exit;end
          else if n<0 then if player[-n].lmt.tick<>tick-1 then exit;
       end;//end if
       if (rfx) or (whos<>n) then hurt_tank(n,h,getmobharmtype(id),whos);
       dec(hp);
       if n>0 then
        if ai[n].occup in [0,2] then hp:=0;
       if n<0 then
        if player[-n].occup in [2] then hp:=0;
     end;
   end;

   procedure checking(nn:longint);
   var i,j,n,h:longint;
   begin
     with mob[nn] do
     begin
       h:=mobharm[id];

       n:=mm.map[zb.x,zb.y].id;
       if n in cangoblock_mob then
       begin
         if n in donotprintblock_mob=false then print_mob(mob[nn])
          else print_block(zb);
       end
       else if n in candestroyblock[getmobharmtype(id)] then
       begin
         if (id<>2) or (mm.map[zb.x,zb.y].hard<=h) then dec(hp,mm.map[zb.x,zb.y].hard)
          else hp:=0;
         destroy(zb.x,zb.y,zb.x,zb.y,h,getmobharmtype(id));
       end
        else hp:=0;
       if n in cannotpierceblock then
       begin
         hp:=0;
       end;
       hurttank(mob[nn],0);
       if hp<=0 then living:=false;
     end;//end with
   end;

begin
  with mob[i] do
   if id=4 then
   begin
     if living=false then exit;
     if lst.tick=tick then exit;
     if tick-lst.tick<=TNTexplodelast then
     repeat
       if tick-lmt.tick<speed then break;
       if fx=-1 then break;
       gt(lmt);
       xx:=zb.x+gox[fx];yy:=zb.y+goy[fx];
       ox:=zb.x;oy:=zb.y;
       if inmap(xx,yy) then
        if (whichtank(xx,yy)=0) and ((mm.map[xx,yy].id in cangoblock_mob)) then
       begin
         zb.x:=xx;
         zb.y:=yy;
         print_auto(ox,oy);
         if ((tick-lst.tick) mod 3=0) and (random(2)=0) then speed:=round(speed*(system.random*1.5+0.5));
         if (speed<=0) and (random(7)<=1) then inc(speed);
       end
        else speed:=maxlongint;
     until true;
     if tick-lst.tick>TNTexplodelast then
     begin
       living:=false;
     end;
     print_auto(zb);
     if living=false then
      workblock8(mob[i]);
   end
   else if living then
   begin
     if inmap(zb)=false then living:=false;
     if living=false then exit;
     t:=tick-lmt.tick;
     if t>=speed then
     repeat
       hurttank(mob[i],1);
       if living=false then break;
       gt(lmt);
       ox:=zb.x;oy:=zb.y;
       inc(zb.x,gox[fx]);
       inc(zb.y,goy[fx]);
       print_auto(ox,oy);
       if inmap(zb)=false then
       begin
         living:=false;
         continue;
       end;
      until true;//end if t>=speed
     if inmap(zb) then
     begin
       checking(i);
       print_auto(zb);
     end;
     if (living=false) and (id=3) then workmob3(mob[i]);
   end; //end with
end;
procedure work_mob;
var i:longint;
begin
  for i:=1 to maxmob do work_mob(i);
  checkdie;
end;

procedure work_ai;
const occup5harm:array[0..3] of longint=(10,5,2,1);
      maxtrytime=50;
      maxdeep=50;
var i,j,k,n,t,w,xx,yy,ox,oy,trytime,safede,ain:longint;
    dosth,b,bfsok,playeralive:boolean;
    lj:Tlj;
    gotowhere:array[1..maxblock] of Tpos;
    cannotgo:array[0..maxoccup,1..maxx,1..maxy] of boolean;
    gwn:longint;
    bb:array[-1..3] of boolean;

   function firesafe(ain,x,y,de,ju:longint):boolean;
   var i,j,n,t:longint;
   begin
     i:=0;
     t:=1;
     repeat
       inc(i);
       dec(ju);
       inc(x,gox[de]);
       inc(y,goy[de]);
       if inmap(x,y)=false then break;
       if mm.map[x,y].id in [5,8] then exit(false);

       if mm.map[x,y].hard>=0 then dec(t,mm.map[x,y].hard);
       if (t<=0) and ((ju<0) or (ju>1000)) then break; // 子弹经过后,才被拦截
       if ju<=0 then
        if ai[ain].occup in [0,2,3,4] then exit(true);//无视玩家后面的状况

       if (ju>=0) and (mm.map[x,y].id in [2,14,15]) then exit(false);//与敌方之间有xxx
       if (mm.map[x,y].id=16) and (mm.map[x,y].fx<>de) then exit(false);
       if (mm.map[x,y].id=17) and (mm.map[x,y].fx<>(de+2) mod maxfx) then exit(false);

       n:=whichtank(x,y);
       if n>0 then
       repeat
         if (ai[n].id<>0) and (ai[n].occup in [2,3]) and (ai[ain].occup in [1]) then exit(false);//前方的自己人不会躲避
       //  if (ai[n].id<>0) and (i=1) and (ai[ain].id<>2) then exit(false);  //前面紧挨着自己人
       until true;
     until false;
     exit(true);
   end;

   function heresafe(x,y,de,view:longint):boolean;
   var i,j,n,t,xx,yy,ox,oy:longint;
       b:boolean;
   begin
     ox:=x;oy:=y;
     while inmap(x,y) and (mm.map[x,y].id<>2) do
     begin
       inc(x,gox[de]);
       inc(y,goy[de]);
       n:=whichmob(x,y);
       if n<>-1 then
       begin
         with mob[n] do
          if fx=(de+2) mod 4 then
          repeat
            b:=true;
            xx:=x;yy:=y;
            t:=1;//mob_id[1].maxhp
            repeat
              xx:=xx+gox[(de+2) mod 4];
              yy:=yy+goy[(de+2) mod 4];
              dec(t,mm.map[xx,yy].hard);
              if mm.map[xx,yy].hard=-1 then dec(t);
              if (t<=0) or (mm.map[xx,yy].id=2) then
              begin
                b:=false;
                break;
              end;
            until (xx=ox) and (yy=oy);
            if b then exit(false);
          until true;  //end if fx=(de+2) mod 4
       end;   //end if n<>-1
       dec(view);
       if (view=0) then break;;
     end;
     exit(true);
   end;

   procedure readyfire(ain,de,v:longint);
   var i,j,n,t:longint;
   begin
     with ai[ain] do
     begin
       for i:=1 to maxammotype do
        if (tick-lft[i].tick>=firespeed[id,occup,i]) and (firespeed[id,occup,i]<>maxlongint) then
        begin
          if firesafe(ain,zb.x,zb.y,de,v) then
          begin
            fire(ai[ain],de,i);
            dosth:=true;
          end;
        end;
     end;//end with
   end;

   procedure workoccup5(ain:longint);
   var i,j,n,t,x,y,h:longint;
   begin
     with ai[ain] do
       explode(zb,aioccup5explodehard,ain,1);
   end;

   function finishgoing(x,y:longint):boolean;
   var i:longint;
   begin
     for i:=1 to gwn do
      if (gotowhere[i].x=x) and (gotowhere[i].y=y) then exit(true);
     exit(false);
   end;

   function bfs(x,y,ain:longint):boolean;
   var i,n,xx,yy,cnt:longint;
       q:array[1..2,1..maxqueue] of record
                                      x,y,pre:longint;
                                    end;
       head,tail:array[1..2] of longint;
       went:array[1..maxx,1..maxy] of longint;

      function finish(n,x,y:longint):longint;
      var i:longint;
      begin
        if n=1 then n:=2
         else n:=1;
        for i:=1 to tail[n] do
         if (x=q[n,i].x) and (y=q[n,i].y) then exit(i);
        exit(0);
      end;

      function kz(n:longint;var head,tail:longint):longint;
      var i,j,ii,t,tot,xx,yy:longint;
          b:array[0..3] of boolean;

         procedure print(n,d:longint);
         begin
           if n=1 then
            if q[n,d].pre<>0 then print(n,q[n,d].pre);
           inc(tot);
           ai[ain].lj.zb[tot].x:=q[n,d].x;
           ai[ain].lj.zb[tot].y:=q[n,d].y;
           if n=2 then
            if q[n,d].pre<>0 then print(n,q[n,d].pre);
         end;

      begin
        inc(head);
        fillchar(b,sizeof(b),true);
        for ii:=0 to 3 do
        begin
          repeat
            i:=random(4);
          until b[i];
          b[i]:=false;
          xx:=q[n,head].x+gox[i];
          yy:=q[n,head].y+goy[i];
          if ai[ain].occup in [4,5] then if (ju(x,y,xx,yy)>(setting.gamehard+1)*16) then continue;
          if can(xx,yy,1)  and (cannotgo[ai[ain].occup,xx,yy]=false) then
          repeat
            if n=1 then if went[xx,yy]>0 then break;
            if n=2 then if went[xx,yy]<0 then break;
            inc(tail);
            q[n,tail].x:=xx;q[n,tail].y:=yy;q[n,tail].pre:=head;
            t:=went[xx,yy];
            if ((n=1) and (t<0)) or ((n=2) and (t>0)) then
            begin
              tot:=0;
              if n=2 then print(n mod 2+1,abs(t));
              print(n,tail);dec(tot);
              if n=1 then  print(n mod 2+1,abs(t));
              ai[ain].lj.tot:=tot;
              ai[ain].lj.zb[tot+1].x:=-1;
              exit(1);
            end;
            if n=1 then went[xx,yy]:=tail;
            if n=2 then went[xx,yy]:=-tail;
          until true;//end if can
        end;// end for
        exit(0);
      end;

   begin
     fillchar(went,sizeof(went),false);
     head[1]:=0;head[2]:=0;
     tail[1]:=1;tail[2]:=gwn;
     went[x,y]:=1;
     q[1,1].x:=x;q[1,1].y:=y;q[1,1].pre:=0;
     for i:=1 to gwn do
      with q[2,i] do
      begin
        x:=gotowhere[i].x;
        y:=gotowhere[i].y;
        went[x,y]:=-i;
        pre:=0;
      end;
     while true do
     begin
       inc(bfscnt);
       if (head[1]>=tail[1]) or (head[2]>=tail[2]) then
       begin
         for xx:=1 to maxx do
          for yy:=1 to maxy do
          begin
            if (head[1]>=tail[1]) and (went[xx,yy]>0) then cannotgo[ai[ain].occup,xx,yy]:=true;
            if (head[2]>=tail[2]) and (went[xx,yy]<0) then cannotgo[ai[ain].occup,xx,yy]:=true;
          end;
         exit(false);
       end;
       if tail[1]<tail[2] then n:=kz(1,head[1],tail[1])
        else n:=kz(2,head[2],tail[2]);
       if n=1 then exit(true);
     end; //end while
   end;//end bfs

begin
  fillchar(cannotgo,sizeof(cannotgo),false);
  bfscnt:=0;
  for i:=1 to maxai do
   with ai[i] do
   begin
     if living then
     begin
       repeat
         dosth:=false;
         ain:=i;

         //TRY GO
         if occup in [0,3,4,5] then
         repeat
           if bfscnt>100000 then break;
           playeralive:=false;for j:=1 to maxplayer do if player[j].living then playeralive:=true;  
           t:=maxlongint;mubiao:=0;
           for j:=1 to setting.playernum do
            with player[j] do
             if living then
              if (ju(zb,ai[ain].zb)<t) and (ju(zb,ai[ain].zb)<=(setting.gamehard+1)*16) then
              begin
                t:=ju(zb,ai[ain].zb);
                ai[ain].mubiao:=j;
              end;
           if (occup in [4,5]) and (mubiao=0) then break;

           fillchar(gotowhere,sizeof(gotowhere),0);
           if occup in [4,5] then
           begin
             if (tick-player[ai[ain].mubiao].lmt.tick<=5-setting.gamehard) then break;
           end;
          // gotoxy(1,1); tc(random(16)); write(playeralive,' ');
           gwn:=0;
           if (occup=3) or ((occup=0) and ((playeralive=false) or (mubiao=0))) then
           begin
             for j:=0 to 3 do
             begin
               xx:=playerflag.zb.x;
               yy:=playerflag.zb.y;
               while inmap(xx,yy) do
               begin
                 if mm.map[xx,yy].id in [2,5,8,14,15] then break;
                 if (mm.map[xx,yy].id=16) and (mm.map[xx,yy].fx<>(j+2) mod maxfx) then break;
                 if (mm.map[xx,yy].id=17) and (mm.map[xx,yy].fx<>j) then break;
           {      t:=whichtank(xx,yy);
                 if (t>0) and (t<>ain) then
                  if ai[t].occup=3 then break;    }
                 inc(xx,gox[j]);
                 inc(yy,goy[j]);
                 if can(xx,yy,1) or ((ai[ain].zb.x=xx) and (ai[ain].zb.y=yy)) then
                 begin
                   inc(gwn);
                   gotowhere[gwn].x:=xx;
                   gotowhere[gwn].y:=yy;
                 end;
               end;//end while
             end;//end for
           end//end 3
         else if (occup=4) or (occup=0) then
         begin
           if playeralive=false then break;
           for j:=0 to 3 do
           begin
             xx:=player[mubiao].zb.x;
             yy:=player[mubiao].zb.y;
             while inmap(xx,yy) do
             begin
               if mm.map[xx,yy].id in [2,5,8,14,15] then break;
               if (mm.map[xx,yy].id=16) and (mm.map[xx,yy].fx<>(j+2) mod maxfx) then break;
               if (mm.map[xx,yy].id=17) and (mm.map[xx,yy].fx<>j) then break;
              { t:=whichtank(xx,yy);
               if (t<>-1) and (t<>ain) then
                if ai[t].occup=4 then break;  }
               inc(xx,gox[j]);
               inc(yy,goy[j]);
               if can(xx,yy,1) or ((ai[ain].zb.x=xx) and (ai[ain].zb.y=yy)) then
               begin
                 inc(gwn);
                 gotowhere[gwn].x:=xx;
                 gotowhere[gwn].y:=yy;
               end;
             end;//end while
           end;//end for
         end //end 4
         else if (occup=5) then
         begin
           if playeralive=false then break;

            for j:=player[mubiao].zb.x-1 to player[mubiao].zb.x+1 do
             for k:=player[mubiao].zb.y-1 to player[mubiao].zb.y+1 do
              if can(j,k,1) or ((j=zb.x) and (k=zb.y)) then
              repeat
                if setting.gamehard>=2 then
                 if ju(j,k,player[mubiao].zb)=2 then break;
                inc(gwn);
                gotowhere[gwn].x:=j;
                gotowhere[gwn].y:=k;
              until true;//end for
         end;  //end case 5
           if tick-lmt.tick<tankspeed[id,occup] then break;
           if finishgoing(zb.x,zb.y) then break;
           bfsok:=false;
           repeat
             if ai[15+random(3)].living then
              if (tick-lst.tick-ain) mod tankspeed[0,1]<>0 then break;
            // if (tick-lst.tick) mod 5<>0 then break;
             {if occup in [4,5] then
              if (player[mubiao].lmt.tick<>tick-1) and (ljn<>0) then break;      }
             bfsok:=bfs(zb.x,zb.y,ain);
             if bfsok=false then break;
             ljn:=1;
           until true;
           {if (tick-lst.tick-ain) mod tankspeed[0,1]<>0 then
            if ai[20+random(3)].living=false then break;}
           if ljn=0 then break;
           if can(lj.zb[ljn+1],1)=false then break;
           if ju(lj.zb[ljn+1],zb)<>1 then break;
           {if ljn=lj.tot+1 then
           begin
             ljn:=lj.tot;
             break;
           end;     }
           inc(ljn);
           move(ai[ain],getfx(zb,lj.zb[ljn]));
           dosth:=true;
         until true;//end TRY GO

         //CHECK SAFE               
         if occup in [0,1,3,4,5] then
         repeat
           case setting.gamehard of
             0:if occup in [0]=false then break;
             1:if occup in [0,1]=false then break;
             2:if occup in [0,1,4]=false then break;
             3:if occup in [0,1,3,4,5]=false then break;
           end;
           if (occup=1) and (system.random<=1/(setting.gamehard+1)) then break;
           trytime:=0;safede:=0;j:=-1;
           repeat //CHECK SAFE
              if tick-lmt.tick<tankspeed[id,occup] then break;
              inc(trytime);
              j:=(j+1) mod maxfx;
              if heresafe(zb.x,zb.y,j,4+setting.gamehard) then inc(safede)
               else safede:=0;
              if heresafe(zb.x,zb.y,j,4+setting.gamehard)=false then
              begin
                t:=0;
                if random(2)=0 then k:=(j+1) mod maxfx
                 else k:=(j+3) mod maxfx;
                repeat
                  inc(t);
                  xx:=zb.x+gox[k];
                  yy:=zb.y+goy[k];
                  if can(xx,yy,1) and (whichmob(xx,yy)=-1) then
                  begin
                    move(ai[ain],k);
                    dosth:=true;
                    break;
                  end;
                  k:=(k+2) mod maxfx;
                until t=2;
                t:=j;
              end;//end if heresafe(zb.x,zb.y,j,4+setting.gamehard*2)=false
           until (trytime=maxtrytime) or (safede=maxfx);
           if (trytime=maxtrytime) then
           repeat
             t:=(t+2) mod maxfx;
             if canmove(ai[ain],t) then move(ai[ain],t);
           until true;
         until true;//CHECK SAFE
         
         //RANDOM MOVE
         if occup in [0,1,3,4,5] then
         repeat
           if tick-lmt.tick<tankspeed[id,occup] then break;
           if (occup=0) and (dosth) then break;
           if (occup in [1]) then
           begin
             if (random(20)<>0) then break;
           end
            else if random(75)<>0 then break;
           if occup in [0,3,5] then
            if finishgoing(zb.x,zb.y) then break;
          b:=false;if occup in [4] then
            for j:=1 to maxplayer do
             if player[j].living then b:=true;if b then break;

           if occup in [1] then for j:=1 to maxplayer do
            if player[j].living then
             if (zb.x=player[j].zb.x) or (zb.y=player[j].zb.y) then
             begin
               b:=false;
               if player[j].zb.x=zb.x then
               begin
                 t:=abs(player[j].zb.y-zb.y);
                 if player[j].zb.y>zb.y then b:=firesafe(ain,zb.x,zb.y,2,t)
                  else b:=firesafe(ain,zb.x,zb.y,0,t);
               end
                else if player[j].zb.y=zb.y then
                begin
                  t:=abs(player[j].zb.x-zb.x);
                  if player[j].zb.x>zb.x then b:=firesafe(ain,zb.x,zb.y,1,t)
                   else b:=firesafe(ain,zb.x,zb.y,3,t);
                end;
               if b then break;
             end;//end for
           if b then break;
           k:=0;
           fillchar(bb,sizeof(bb),false);
           for k:=1 to maxfx do
           repeat
             repeat
               t:=random(4);
             until bb[t]=false;
             bb[t]:=true;
             xx:=zb.x+gox[t];yy:=zb.y+goy[t];
             if (heresafe(xx,yy,(t+1) mod 4,12)=false) or (heresafe(xx,yy,(t+3) mod 4,12)=false) then continue;
             if canmove(ai[ain],t) then
             begin
               move(ai[ain],t);
               dosth:=true;
               break;
             end;
           until true;
         until true;//end RANDOM MOVE

         //TRY ATTACK
         if occup in [0,1,2,3,4] then
          for t:=1 to 2 do
          repeat
            repeat
              j:=random(maxplayer)+1;
              if player[j].living=false then break;
              if (occup in [3]) and (t=1) then break;
              if (occup in [0]) and (random(2)=0) then break;
              if player[j].zb.x=zb.x then
              begin
                if player[j].zb.y>zb.y then readyfire(ain,2,abs(player[j].zb.y-zb.y))
                 else readyfire(ain,0,abs(player[j].zb.y-zb.y));
              end
               else if player[j].zb.y=zb.y then
               begin
                 if player[j].zb.x>zb.x then readyfire(ain,1,abs(player[j].zb.x-zb.x))
                  else readyfire(ain,3,abs(player[j].zb.x-zb.x));
               end;
            until true;
            if playerflag.zb.x=zb.x then
            begin
              if playerflag.zb.y>zb.y then readyfire(ain,2,abs(playerflag.zb.y-zb.y))
               else readyfire(ain,0,abs(playerflag.zb.y-zb.y));
            end
             else if playerflag.zb.y=zb.y then
             begin
               if playerflag.zb.x>zb.x then readyfire(ain,1,abs(playerflag.zb.x-zb.x))
                else readyfire(ain,3,abs(playerflag.zb.x-zb.x));
             end;
          until true;//end TRY ATTACK

         //RANDOM ATTACK
         if occup in [1] then
         repeat
           if random(200)<>0 then break;
           fillchar(bb,sizeof(bb),true);
           for j:=0 to 3 do
           begin
             repeat
               t:=random(4);
             until bb[t];
             bb[t]:=false;
             readyfire(ain,t,maxlongint);
             bb[-1]:=false;
             for t:=1 to maxammotype do
              if lft[t].tick=tick then bb[-1]:=true;
             if bb[-1] then break;
           end;
         until true;//end RANDOM ATTACK

         if occup in [5] then
         repeat
           if mubiao=0 then break;
           if tick-lmt.tick<trunc((1-setting.gamehard/maxgamehard)*tankspeed[id,occup]) then break;
           if finishgoing(zb.x,zb.y)=false then break;
           workoccup5(ain);
           dosth:=true;
         until true;
         if dosth then print_tank(ai[ain]);
       until true;//main
     end //end if living
      else if tick-ldt.tick<dyinglast then
      repeat
        if mm.map[zb.x,zb.y].id in [9] then break;
        if (tick-ldt.tick) mod dyingblinklast<=dyingblinklast div 2 then print_auto(zb)
         else print(zb,tankbackground[id],color(hp,maxhp),tankchar[id,occup,fx]);
      until true
       else if tick-ldt.tick=dyinglast then
       begin
         print_auto(zb);
         clear_tank(ai[i]);
       end;
   end;//end with
end;

procedure work_tip;
var i,j,n,t:longint;
begin
  with tip do
   if twn<>0 then
   repeat
     t:=tick-tipwaiting[1].starttime.tick;
     if t<tipwaiting[1].lastfor then break;

     if t=tipwaiting[1].lastfor then
     begin
       gt(lasttipendtime);
       for i:=1 to twn-1 do
         tipwaiting[i]:=tipwaiting[i+1];
       dec(twn);
     end;//end if
     if (twn=0) or (t=tipwaiting[1].lastfor) then
     begin
       clear_tip;
       break;
     end;//end if
     if tick-lasttipendtime.tick<tipbreak then break;

     with tipwaiting[1] do
       print_tip(st,color);
     gt(tipwaiting[1].starttime);
   until true; //end with
end;

procedure work_block;
const didnotuse=-1000;
var i,n,t,firebreak:longint;
    nx,ny:longint;
    changed:array[1..maxmob] of boolean;

    function getmob(x,y:longint):longint;
    var i,n:longint;
    begin
      n:=-1;
      for i:=1 to maxmob do
       if (mob[i].living) and (mob[i].zb.x=x) and (mob[i].zb.y=y) and (changed[i]=false) then
       begin
         n:=i;
         changed[i]:=true;
         break;
       end;
      exit(n);
    end;

    procedure wm(n:longint);
    begin
      with mob[n] do
      begin
        if id=4 then speed:=maxlongint
         else if (id<>2) or (mm.map[nx,ny].hard<=mobharm[id]) then dec(hp,mm.map[nx,ny].hard)
          else hp:=0;
        destroy(nx,ny,nx,ny,mobharm[id],getmobharmtype(id));
        work_mob(n);
      end;//end with
    end;

begin
  fillchar(changed,sizeof(changed),false);
  for nx:=1 to maxx do
   for ny:=1 to maxy do
    with mm.map[nx,ny] do
     case id of
       10:begin
         case fj of
           1..4:firebreak:=block10firebreak[fj];
           else firebreak:=maxlongint;
         end;
         if tick-lrt.tick>=firebreak then
         begin
           new_mob(nx+gox[fx],ny+goy[fx],fx,fj,0);
           gt(lrt);
           if fj in [4]=false then
            if random(2)=0 then inc(lrt.tick,random(3)-1);
         end;
       end;//end case 10
       11:repeat
         n:=whichtank(nx,ny);
         if n=0 then
         begin
           lrt.tick:=didnotuse;
           break;
         end;
         if lrt.tick=didnotuse then gt(lrt);
         if n=fj then break;
         if tick-lrt.tick<=block11explodewait then break;
         id:=0;
         print_block(nx,ny);
         explode(nx,ny,block11explodehard,fj,0);
       until true;//end case 11
        14:repeat
          repeat
            n:=getmob(nx,ny);
            if n=-1 then break;
            with mob[n] do
            begin
              rfx:=true;
              if (fx=(mm.map[nx,ny].fx+0) mod maxfx) or (fx=(mm.map[nx,ny].fx+1) mod maxfx) then
              begin
                wm(n);
                break;
              end;//end if
              if      fx=(mm.map[nx,ny].fx+2) mod maxfx then fx:=(mm.map[nx,ny].fx+1) mod maxfx
              else if fx=(mm.map[nx,ny].fx+3) mod maxfx then fx:=(mm.map[nx,ny].fx) mod maxfx;
              inc(zb.x,gox[fx]);
              inc(zb.y,goy[fx]);
              inc(lmt.tick);
            end;//end with
          until false;//end repeat
        until true;//end case 14
        15:repeat
          repeat
            n:=getmob(nx,ny);
            if n=-1 then break;
            with mob[n] do
            begin
              rfx:=true;
              if ((mm.map[nx,ny].fx=0) and (fx in [1,3]))
              or ((mm.map[nx,ny].fx=1) and (fx in [0,2])) then
              begin
                wm(n);
                break;
              end;//end if
              case mm.map[nx,ny].fx of
                0,1:fx:=(fx+2) mod maxfx;
                2:case fx of
                  0:fx:=3;1:fx:=2;2:fx:=1;3:fx:=0;
                end;
                3:case fx of
                  0:fx:=1;1:fx:=0;2:fx:=3;3:fx:=2;
                end;
              end;
              inc(zb.x,gox[fx]);
              inc(zb.y,goy[fx]);
              inc(lmt.tick);
            end;//end with
          until false;//end repeat
        until true;//end case 15
        16,17:repeat
          repeat
            n:=getmob(nx,ny);
            if n=-1 then break;
            with mob[n] do
            begin
              if id=4 then
               if (mm.map[nx,ny].id=17)
               or ((mm.map[nx,ny].id=16) and (fx<>mm.map[nx,ny].fx)) then
               begin
                 speed:=maxlongint;
                 inc(zb.x,gox[(fx+2) mod maxfx]);
                 inc(zb.y,goy[(fx+2) mod maxfx]);
                 if inmap(zb)=false then
                 begin
                   inc(zb.x,gox[fx]);
                   inc(zb.y,goy[fx]);
                 end;
                 continue;
               end;//end if id=4
              if ((mm.map[nx,ny].id=16) and (fx<>mm.map[nx,ny].fx))                        //是单向穿透且方向不对
              or ((mm.map[nx,ny].id=17) and (fx<>(mm.map[nx,ny].fx+2) mod maxfx)) then     //是单向破坏且方向不对
              begin
                hp:=0;
                work_mob(n);
                continue;
              end;
              if mm.map[nx,ny].id=16 then break;

              wm(n);
              destroy(nx,ny,nx,ny,mobharm[id],getmobharmtype(id));
              work_mob(n);
            end;//end with
          until false;//end repeat
        until true;//end case 16,17
     end;//end case
end;

procedure work_occupskill(var player:Ttank);
var i,j,n,t,x,y:longint;

   function firesafe(x,y,de:longint):boolean;
   var n,t:longint;
   begin
     t:=1;
     repeat
       inc(x,gox[de]);
       inc(y,goy[de]);
       if inmap(x,y)=false then break;
       if mm.map[x,y].id in [4,8] then exit(false);
       if mm.map[x,y].hard>0 then break;

       n:=whichtank(x,y);
       if n<0 then exit(false);
     until false;
     exit(true);
   end;

   procedure catchmob(x,y:longint);
   var head,tail:longint;
       fx,xx,yy,t:longint;
       q:Array[1..maxqueue] of record
                                 x,y,dis:longint;
                               end;
   begin
     head:=0;
     tail:=1;
     q[tail].x:=x;
     q[tail].y:=y;
     q[tail].dis:=0;
     repeat
       inc(head);
       with q[head] do
       repeat
         if dis>=playeroccup1skillcatchdis then break;
         for fx:=0 to maxfx-1 do
         begin
           xx:=x+gox[fx];
           yy:=y+goy[fx];
           if can(xx,yy,2)=false then continue;
           inc(tail);
           with q[tail] do
           repeat
             x:=xx;
             y:=yy;
             dis:=q[head].dis+1;
             t:=whichmob(xx,yy);
             if t=-1 then break;
             if mob[t].whos=player.xu then break;
             with mob[t] do
             begin
               whos:=player.xu;
               fx:=player.fx;
               xx:=zb.x;yy:=zb.y;
               zb:=player.zb;
               if inmap(zb.x,zb.y)=false then living:=false;
               print_auto(xx,yy);
             end;
           until true;//end with
         end;  //end for
       until true;//end with
     until head=tail;
   end;

begin
  with player do
  begin
    if living=false then exit;
    if skillusing=false then exit;
    if (god=false) and ((tick-skill.start.tick>=occupskilltime[occup,2]) or (tick-skill.stop.tick<occupskilltime[occup,1])) then
    begin
      if (tick-skill.start.tick>=occupskilltime[occup,2]) then
      begin
        gt(skill.stop);
        if (occup=2) then playmusic('music\skill2_end.wav','0');
      end;
      skillusing:=false;
      exit;
    end;
    if tick-skill.use.tick<occupskilltime[occup,3] then exit;
    if tick=skill.start.tick+1 then
    case occup of
      2:playmusic('music\skill2_start.wav','0');
    end;
    gt(skill.use);
    case occup of
      0:repeat
          for i:=1 to maxammotype do
            if canfire(player,i) then
              fire(player,fx,i);
        until true;
      1:repeat
         { for i:=1 to maxammotype do
           if canfire(player,i) then fire(player,fx,i);
          for i:=0 to maxfx-1 do
           if firesafe(zb.x,zb.y,i) then
             new_mob(zb.x,zb.y,i,playerskillfiretype[occup],xu);   }
          catchmob(zb.x,zb.y);
          if random(15)<>0 then break;
          i:=0;
          repeat
            inc(i);
            n:=random(maxai)+1;
          until ai[n].living or (i=maxai*3);
          if ai[n].living=false then break;
          if (god=false) and (profile.ammo[playerskillfiretype[occup]]<3) then break;
          if (god=false) then dec(profile.ammo[playerskillfiretype[occup]],3);
          for i:=0 to maxfx-1 do
           with ai[n].zb do
            for j:=1 to 2 do
            begin
              t:=new_mob(x+(random(2)+1)*gox[i],y+(random(2)+1)*goy[i],(i+2) mod maxfx,playerskillfiretype[occup],xu);
              if t<>-1 then
              begin
                inc(mob[t].lmt.tick,playeroccup1skillwait);
                mob[t].hp:=3;
              end;
            end;
        until true;
      2:begin
        end;
      3:repeat
          if tick=skill.start.tick+1 then
          begin
            if (god=false) and (profile.ammo[3]<5) then break;
            if (god=false) then dec(profile.ammo[3],5);
            for i:=10 to 30 do
            if (i>20) or (random(3)<>0) then
             begin
               t:=new_mob(zb.x,zb.y,fx,playerskillfiretype[occup],xu);
               if t=-1 then continue;
               mob[t].speed:=TNTexplodelast div i;
             end;
          end;
          if tick-skill.start.tick>=TNTexplodelast+1 then
          begin   
            if (god=false) and (profile.ammo[3]<5) then break;
            if (god=false) then dec(profile.ammo[3],1);
            t:=new_mob(zb.x,zb.y,fx,playerskillfiretype[occup],xu);
            if t=-1 then break;
            mob[t].speed:=random(3);
            mob[t].speed:=random(mob[t].speed);
          end;
        until true;
      4:repeat              
          if (god=false) and (profile.ammo[playerskillfiretype[occup]]<=0) then break;
          if (god=false) and ((tick mod 5)>1) then dec(profile.ammo[playerskillfiretype[occup]]);
          x:=random(maxfx)+1;
          for i:=1 to x do
          begin
            t:=random(maxfx);
            x:=new_mob(zb.x+gox[t],zb.y+goy[t],fx,playerskillfiretype[occup],xu);
            mob[x].hp:=2;
          end;
        until true;
      5:repeat
          if (god=false) and (profile.prop[1]<1) then break;
          if (god=false) then dec(profile.prop[1],1);
          explode(zb.x,zb.y,playeroccup5explodehard,xu,0);
          for i:=1 to maxfx do
          begin
            t:=random(maxfx);
            explode(zb.x+gox[t],zb.y+goy[t],playeroccup5explodehard,xu,0,1);
          end;
          if random(2)=0 then hurt_tank(player,1,1,0);
          if living=false then explode(zb,TNTexplodehard,xu,0,1);
        until true;
    end;//end case
  end;//end with
end;

procedure savescreenshot;
var wj:text;
    i,j:longint;
    c:string;
    s:ansistring;
    year,month,day,wday,hour,minute,second,s100:word;
begin
  s:='screenshot\Screenshot ';
  dos.getdate(year,month,day,wday);
  dos.gettime(hour,minute,second,s100);
  s:=s+inttostr(year)+'_'+inttostr(month)+'_'+inttostr(day)+'_'+inttostr(hour)+'_'+inttostr(minute)+'_'+inttostr(second)+'_';
  if s100<10 then s:=s+'0';
  s:=s+inttostr(s100);
  i:=0;
  if fsearch(s+c+'.screenshotdata','\')<>'' then
  repeat
    if i=maxlongint then exit;
    inc(i);
    str(i,c);
  until fsearch(s+'('+c+').screenshotdata','\')='';
  if i<>0 then s:=s+'('+c+')';
  s:=s+'.screenshotdata';
  assign(wj,s);
  rewrite(wj);
  for i:=1 to maxx do
   for j:=1 to maxy do
    with newsc[i,j] do
    begin
      writeln(wj,col,' ',bg,' ',ord(ch[1]),' ',ord(ch[2]));
    end;//end with
  close(wj);
end;

procedure print_ammo;
var i,j,ii:longint;
    s:string;
begin
  tb(0);
  for ii:=1 to setting.playernum do
   with player[ii] do
   begin
     if lamt[ii]<>ammotype then
     for i:=1 to maxammotype do oammo[ii,i]:=-255;
     i:=ammotype;

     with profile do
     begin
     // if oammo[i]=num then continue;
       oammo[ii,i]:=ammo[i];lamt[ii]:=ai[ii].ammotype;
       tc(8);if i=ammotype then tc(15);gotoxy(26,maxy+3);if ii=2 then gotoxy(wherex,wherey+1);
       write(ammonam[i],':');if i=1 then write('∞ ')else write(ammo[i]);
       str(ammo[i],s);if i=1 then s:='∞';
       for j:=1 to 3-length(s) do
         write(' ');
      end;//end with&for
   end;
end;

procedure work_command;
const startx=41;
      starty=23;
      maxlen=24;
var i,l,n,t,x,y,z,id,typ,nowmem,a,b:longint;
    s:string;
    st:array[1..100] of string;
    c:char;
    p:Tpos;
    isend,reprt:boolean;
begin           
  isend:=false;
  repeat
    tb(0); tc(7);
    cursoroff;
    gotoxy(startx,starty);
    for i:=1 to maxlen do write(' ');
    l:=0; s:='';
    nowmem:=cmdmemcnt+1;
    gotoxy(startx,starty);
    cursoron;
    repeat //start read
      c:=readkey;
      case c of
        'a'..'z',' ','-','0'..'9','A'..'Z','_':
        begin
          if (l<maxlen-1) then
          begin
            inc(l);
            s:=s+c;
            write(c);
          end;
        end;
        #8:
        begin
          if (l>0) then
          begin
            dec(l);
            delete(s,length(s),1);
            gotoxy(wherex-1,wherey);
            write(' ');              
            gotoxy(wherex-1,wherey);
          end;
        end;
        #27:
        begin
          isend:=true;
          break;
        end;
        #13:
        begin
          isend:=l=0;
          break;
        end;
        #0:
        begin
          c:=readkey;
          reprt:=false;
          case c of
            #72: //up
            begin
              if (nowmem>1) then 
              begin
                dec(nowmem); 
                reprt:=true;
              end;
            end;
            #80: //down
            begin
              if (nowmem<=cmdmemcnt) then 
              begin
                inc(nowmem); 
                reprt:=true;
              end;
            end;
            #28:    
            begin
              isend:=l=0;
              break;
            end;
          end;
          if reprt then
          begin
            cursoroff;
            tb(0); tc(7);
            gotoxy(startx,starty);
            write(cmdmem[nowmem]);
            for i:=length(cmdmem[nowmem])+1 to maxlen do write(' ');
            gotoxy(wherex-maxlen+length(cmdmem[nowmem]),wherey);
            s:=cmdmem[nowmem];
            l:=length(s);
            cursoron;
          end;
        end;//end #0
      end;
    until false;//end read
    if (isend) then break;
    n:=0;
    if (cmdmemcnt<maxcmdmem) then
    begin
      inc(cmdmemcnt);
      cmdmem[cmdmemcnt]:=s;
    end;   
    s:=upcase(s);
    while (pos(' ',s)<>0) do
    begin
      t:=pos(' ',s);
      inc(n);
      st[n]:=copy(s,1,t-1);
      delete(s,1,t);
    end;
    inc(n);
    st[n]:=s;
    if (st[1]='SUMMON_ENEMY') or (st[1]='SUMMONENEMY') or (st[1]='SE') then
    repeat
      if (n<2) then break;
      val(st[2],z,t);if (t<>0) then break;
      if (z<0) or (z>maxoccup) then break;
      x:=-1;
      y:=-1;
      if (n=4) then
      begin
        val(st[3],x,t);if (t<>0) then break;
        val(st[4],y,t);if (t<>0) then break;
        if (x<1) or (x>maxx) or (y<1) or (y>maxy) then break;
      end;
      p.x:=x;
      p.y:=y;
      id:=new_ai(1,z,p);
      if (id<>-1) then
      begin
        print_tank(ai[id]);
        print_screen(ai[id].zb.x,ai[id].zb.y);
      end;
      cmdused:=true;
    until true
    else if (st[1]='SET_BLOCK') or (st[1]='SETBLOCK') or (st[1]='SB') then
    repeat
      if (n<4) then break;
      val(st[2],x,t);if (t<>0) then break;
      val(st[3],y,t);if (t<>0) then break;
      val(st[4],typ,t);if (t<>0) then break;                             
      if (x<1) or (x>maxx) or (y<1) or (y>maxy) then break;
      if (typ<0) or (typ>maxblocktype) or (typ in [4,5]) then break;
      a:=0; b:=0;
      if (n=6) then
      begin
        val(st[5],a,t);if (t<>0) then break;
        val(st[6],b,t);if (t<>0) then break;
      end;
      with mm.map[x,y] do
      begin
        if (id in [4,5]) then break;
        id:=typ;
        fx:=a; fj:=b;
        hard:=blockmaxhard[typ];
        maxhard:=blockmaxhard[typ];
        unbreakble:=false;
      end; //end with
      print_block(x,y);
      print_screen(x,y);
      cmdused:=true;
    until true
    else if (st[1]='HEAL') or (st[1]='HE') then
    begin               
      cmdused:=true;
      for i:=1 to setting.playernum do
        if player[i].living then
          player[i].hp:=player[i].maxhp;
    end
    else if (st[1]='CLEAR_CD') or (st[1]='CC') then
    begin          
      cmdused:=true;
      for i:=1 to setting.playernum do
        if player[i].living then
          with player[i].skill do
          begin
            start.tick:=-1000;
            stop.tick:=-1000;
            use.tick:=-1000;
          end;
    end
    else if (st[1]='KILL_ALL') or (st[1]='KA') then
    begin               
      cmdused:=true;
      for i:=1 to maxai do
        if (ai[i].living) then
          hurt_tank(ai[i],ai[i].hp,1,0);
    end
    else if (st[1]='EXPLODE') or (st[1]='EX') then
    begin
      if (n<4) then break;
      val(st[2],x,t);if (t<>0) then break;
      val(st[3],y,t);if (t<>0) then break;
      val(st[4],z,t);if (t<>0) or (z<0) or (z>maxexplodehard) then break;
      a:=0;
      b:=0;
      if (n>=5) then
      begin
        val(st[5],a,t);if (t<>0) then break;
        if (n>=6) then
        begin           
          val(st[6],b,t);if (t<>0) or ((b<>0) and (b<>1)) then break;
        end;
      end;           
      cmdused:=true;
      explode(x,y,z,a,b,0);
    end;
  until isend;
  gotoxy(41,23);
  tb(0); tc(7);
  for i:=1 to maxlen div 2 do write('═');
  cursoroff;
end;

function work_keypressed:longint;
var c:char;
    t:longint;
   procedure usingskill(var player:Ttank);
   begin
     with player do
     begin
       skillusing:=not skillusing;
       if skillusing then gt(skill.start)
        else gt(skill.stop);
       if occup=2 then
       begin
         if skillusing=false then playmusic('music\skill2_end.wav','0');
         gt(lmt);
         inc(lmt.tick,-tankspeed[0,2]+occupskilltime[2,3]);
       end;
     end;
   end;
begin
  if keypressed=false then exit(0);
  c:=upcase(readkey);
  case c of
    'W':gof[1]:=0;
    'A':gof[1]:=3;
    'S':gof[1]:=2;
    'D':gof[1]:=1;
    'I':if setting.playernum=1 then firef[1]:=0;
    'J':if setting.playernum=1 then firef[1]:=3;
    'K':if setting.playernum=1 then firef[1]:=2;
    'L':if setting.playernum=1 then firef[1]:=1
      else if setting.playernum=2 then gof[2]:=3;
    ' ':usingskill(player[1]);
    'T':if setting.playernum=2 then firef[1]:=0;
    'F':if setting.playernum=2 then firef[1]:=3;
    'G':if setting.playernum=2 then firef[1]:=2;
    'H':if setting.playernum=2 then firef[1]:=1;
    'P':if setting.playernum=2 then gof[2]:=0;
    ';':if setting.playernum=2 then gof[2]:=2;
    '''':if setting.playernum=2 then gof[2]:=1;
    #9:begin
         player[1].ammotype:=(player[1].ammotype mod maxammotype)+1;
         print_ammo;
       end;
    'O':if setting.playernum=2 then
        begin
          player[2].ammotype:=(player[2].ammotype mod maxammotype)+1;
          print_ammo;
        end;
    '`','1'..'5':with player[1] do
             begin
               if (c='`') then t:=0
               else val(c,t);
               if living then
               repeat
                 if t>maxproptype then break;
                 if mm.map[zb.x,zb.y].id<>0 then break;
                 if t>maxproptype then break;
                 if profile.prop[t]<=0 then break;
                 dec(profile.prop[t]);
                 init_prop(zb.x,zb.y,t,-1);
               until true
                else repeat
                  if (profile.occupown[t]=false) then break;
                  occup:=t;
                  init_tip('玩家1职业更改为:'+occupnam[0][t],7,changeoccuptipshowlast);
                until true;
             end;//end case
    '7','8','9','0','-','=':with player[2] do
                         if setting.playernum>1 then
                         begin
                           case c of
                             '7':t:=0;
                             '8':t:=1;
                             '9':t:=2;
                             '0':t:=3;
                             '-':t:=4;
                             '=':t:=5;
                           end;
                           if living then
                           repeat
                             if t>maxproptype then break;
                             if mm.map[zb.x,zb.y].id<>0 then break;
                             if t>maxproptype then break;
                             if profile.prop[t]=0 then break;
                             dec(profile.prop[t]);
                             init_prop(zb.x,zb.y,t,-2);
                           until true//end case
                            else repeat
                              if (profile.occupown[t]=false) then break;
                              occup:=t;
                              init_tip('玩家2职业更改为:'+occupnam[0][t],7,changeoccuptipshowlast);
                            until true;//end case
                         end;//end case
    #0:begin
         c:=readkey;
         case c of
           'H':if setting.playernum=2 then firef[2]:=0;
           'K':if setting.playernum=2 then firef[2]:=3;
           'P':if setting.playernum=2 then firef[2]:=2;
           'M':if setting.playernum=2 then firef[2]:=1;
           ']':if setting.playernum=2 then usingskill(player[2]);
           #83:if player[1].living then
               repeat
                 t:=new_mob(player[1].zb.x,player[1].zb.y,player[1].fx,4,-1);
                 if t=-1 then break;
                 mob[t].speed:=0;
               until true;
           #60:savescreenshot;
         end;//end case
       end;//end #0:
    #27:begin
          close(f_usedtime);
          if gamewin or gamelose then exit(1)
           else exit(2);
        end;
    #8:begin
         while readkey<>#13 do;
       end;
    '/':begin
          work_command;
        end;
  end;//end case
end;

function play:longint;
var oldtime,newtime,bt,ct,ov,nv,oz,nz:Ttime;
    i,playern,n,w,t,d,de,tt:longint;
    c:string;
    worked:boolean;

   procedure beforetickwait;
   var i,j,n,t,playern:longint;
   begin
     if (gamewin=false) and (gamelose=false) then
     begin
       gamelose:=true;
       for i:=1 to setting.playernum do
        if player[i].lives>0 then gamelose:=false;
       if gamelose and (gameendtick=-1) then gameendtick:=tick;
     end;
     for playern:=1 to setting.playernum do
      with player[playern] do
      repeat
        if living=false then
        begin
          if tick>=ldt.tick+dyinglast then
          begin
            if tick=ldt.tick+dyinglast then print_auto(zb);
            if (tick>ldt.tick+dyinglast+spawnwait) and (lives>0) then
            begin
              init_tank(player[playern],0,player[playern].occup);
              gotoxy(4,maxy+2+playern);tb(0);tc(7);write(occupnam[0,occup]);
            end;
          end
           else repeat
             if mm.map[zb.x,zb.y].id in [9] then break;
             if (tick-ldt.tick) mod dyingblinklast<=dyingblinklast div 2 then print(zb,-1,15,'  ')
              else if playern=1 then print(zb,tankbackground[0],15,tankchar[0,occup,fx])
               else if playern=2 then print(zb,3,15,tankchar[0,occup,fx]);
           until true;
        end;//end if living=false
      until true;//end with
   end;

   procedure aftertickwait;
   var i,j,n,t,playern:longint;
       d,ox,oy,xx,yy:longint;
   begin
     for playern:=1 to setting.playernum do
      with player[playern] do if living then
      begin
        d:=fx;ox:=zb.x;oy:=zb.y;

        if gof[playern]<>-1 then
         if canmove(player[playern],gof[playern]) then move(player[playern],gof[playern]);
        if unbreakble and (tick mod unbreakbleblinklast>=unbreakbleblinklast div 2) then
        begin
          print_block(zb);
          print_mob(whichmob(zb));
        end
         else print_tank(player[playern]);
        if tick-lst.tick=unbreakblelast+1 then unbreakble:=false;

        if (firef[playern]<>-1) and (firef[playern]<>fx) then
        begin
          fx:=firef[playern];
          print_tank(player[playern]);
        end;
        i:=0;
        if firef[playern]<>-1 then
        repeat
          inc(i);
          if canfire(player[playern],ammotype) then fire(player[playern],fx,ammotype);

        until true;
        print_ammo;
      end;//end for&with
   end;

begin
  gt(fpsb);
  print_map;
  print_ammo;     assign(f_usedtime,'UsedTime.log');rewrite(f_usedtime);
  fillchar(lamt,sizeof(lamt),255);
  if upcase(mm.nam)='LOGO' then delay(5000);

  repeat{******************************************************************}

    gt(oz);gt(ov);{-------}
    tick:=tick+1;write(f_usedtime,'Tick',tick,': ');    
    if ((profile.ammo[1]>999) or (profile.ammo[2]>999)) and (random(2)=0) and (tick mod 1000=0) and (tick>0) and (bosstime=false) then new_ai(1,0);
    if tick>=round(mm.startspawntick/spawnadd[setting.gamehard]) then
    begin
      for i:=1 to maxoccup do
       if mm.spawnprobability[i]<>maxlongint then
        if random(round(mm.spawnprobability[i]/spawnadd[setting.gamehard]))=0 then
          new_ai(1,i);
    end; //end if tick>=startspawntick

    gt(oldtime);c:='';{-------}
    fillchar(gof,sizeof(gof),255);
    fillchar(firef,sizeof(firef),255);
    worked:=false;
    repeat//================================================================================
      if worked=false then
      begin
                                                                      gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        beforetickwait;                                               gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        print_screen(1);                                              gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        work_tip;                                                     gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        work_block;                                                   gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        for i:=1 to setting.playernum do work_occupskill(player[i]);  gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        work_mob;                                                     gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        work_ai;                                                      gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        print_game_info;                                              gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        worked:=true;
      end;
      t:=work_keypressed;
      case t of
        0:       ;
        1:exit(0);
        2:exit(1);
      end;
      gt(newtime);
      if setting.gamemode=2 then break;
    until td(oldtime,newtime)>=ticklast;//================================================================================
    gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
    aftertickwait;

    gt(nv);write(f_usedtime,td(ov,nv),' ');{-------}
    gt(nz);writeln(f_usedtime,td(oz,nz));{-------}
  until false;{******************************************************************}
  tc(7);tb(0);
end;

function chooseoccup:longint;
var playern,cnt:longint;
    n,i,maxlen:longint;
    a:array[1..maxoccup+1] of longint;
    s:string;
begin
  for playern:=1 to setting.playernum do
  begin
    clrscr;
    gotoxy_mid('选择职业',1);tb(0);tc(15);write('选择职业');
    gotoxy_mid('Player'+inttostr(playern),wherey+1);tb(0);tc(14);write('Player'+inttostr(playern));
    s:='';
    maxlen:=4;
    cnt:=0;
    for i:=0 to maxoccup do
      if (profile.occupown[i]) then
      begin
        inc(cnt);
        a[cnt]:=i;
        s:=s+occupnam[0,i]+ln;
        maxlen:=max(maxlen,length(occupnam[0,i]));
      end;
    s:=s+'返回';
    gotoxy_mid(getastr(maxlen+6),wherey+1);
    n:=chooseone(s);
    if n=cnt+1 then exit(1);
    player[playern].occup:=a[n];
  end;
  exit(0);
end;

procedure work_game;
const interval:array[1..2] of longint=(0,13);
var i,playern,occup,n,t,x,y:longint;
    s:ansistring;
    playexit:longint;
    ot,nt:Ttime;

   procedure print_score(x,y,n:longint);
   var i,d:longint;
   begin
     for i:=0 to n-1 do
     begin
       gotoxy(x,y);
       write(i);
       crt.delay(max(trunc(500/n),1));
       if keypressed then break;
     end;
     gotoxy(x,y);
     write(n);
     while keypressed do readkey;
   end;

   procedure print_assess(x,y,cl:longint;s:string);
   const maxc=2;
         maxa=255;
         wait=200;
         c:array[1..maxc] of longint=(8,7);
   var i,n,j,max:longint;
       a:array[1..maxa] of longint;
   begin
     max:=maxc+1;
     for i:=1 to maxc do
      if cl=c[i] then
      begin
        max:=i;
        break;
      end;
     for i:=1 to maxa do
       a[i]:=-i+1;
     repeat
       for j:=1 to maxa do a[j]:=min(max,a[j]+1);
       gotoxy(x,y);
       for j:=1 to length(s) do
       begin
         if a[j]<=0 then continue
          else if a[j]<max then tc(c[a[j]])
           else tc(cl);
         write(s[j]);
       end;//end for j
       crt.delay(wait);
       if a[length(s)]=max then break;
       if keypressed then break;
     until false;
     gotoxy(x,y);
     tc(cl);write(s);
     while keypressed do readkey;
   end;

begin
  clear_map;
  clrscr;
  s:='';
  for i:=1 to levelnum do
    s:=s+level[i].filenam+ln;
  s:=s+'返回';
  maxlevelnamlen:=max(maxlevelnamlen,length('返回'));
  repeat
    clrscr;
    gotoxy_mid('选择关卡',1);tc(15);tb(0);write('选择关卡');
    gotoxy_mid(getastr(maxlevelnamlen+6),2);nowlevel:=chooseone(s);
    if nowlevel=levelnum+1 then exit;
    ismainlevel:=false;
    if level[nowlevel].ismainlevel then
    begin
      if profile.levelunlock[nowlevel]=false then
      begin
        //clrscr;
        gotoxy(1,1);clreol;
        gotoxy_mid('关卡未解锁',1);tb(0);tc(12);write('关卡未解锁');
        delay(500);
        gotoxy(1,nowlevel+1);clreol;
        gotoxy(1,levelnum+3);clreol;
        continue;
      end;
      ismainlevel:=true;
    end;
    break;
  until false;
  mm:=level[nowlevel];

  n:=chooseoccup;
  if n=1 then exit;
  {■■■■}
  init_game;
  playexit:=play;
  end_game;
  {■■■■}
  if playexit=1 then
  begin
    gotoxy_mid('Saving...',1);tb(0);tc(7);write('Saving...');
    save;
    exit;
  end;
  if gamewin then
  begin
    gotoxy_mid('胜利',windmaxy-3);tc(12);tb(0);write('胜利');
    playmusic('music\gamewin.wav','0');
    with profile do
    repeat
      if nowlevel>mainlevelnum then break;
      if levelfinish[nowlevel]=false then
       for i:=1 to mainlevelnum-1 do
        if levelunlock[i] and (levelunlock[i+1]=false) then
        begin
          levelunlock[i+1]:=true;
          delay(400);
          gotoxy_mid('关卡'+inttostr(i+1)+'解锁',wherey+1);tb(0);tc(14);write('关卡',i+1,'解锁');
          break;
        end;
      levelfinish[nowlevel]:=true;
      if (god=false) and (cmdused=false) then
      begin
        inc(money,levelwinprize[nowlevel]);
        gotoxy_mid('金钱增加'+inttostr(levelwinprize[nowlevel]),wherey+1); tb(0); tc(14); write('金钱增加',levelwinprize[nowlevel]);
      end;
    until true;//end with
  end
  else if gamelose then
  begin
    gotoxy_mid('失败',windmaxy-1);
    tc(10);tb(0);write('失败');
    playmusic('music\gameover.wav','0');
    with profile do
    begin
    end;//end with
  end
  else begin
    gotoxy_mid('和局',windmaxy-1);
    tc(7);tb(0);write('和局');
  end;
  
  gotoxy(1,1);
  gotoxy_mid('当前关卡 '+level[nowlevel].filenam); tb(0); tc(8); write('当前关卡 '); tc(15); writeln(level[nowlevel].filenam);
  gotoxy_mid('胜负决出于 Tick '+inttostr(gameendtick),wherey);tb(0);tc(8);write('胜负决出于 Tick ');tc(15);write(gameendtick);
  gotoxy_mid('杀敌数目',wherey+2);tc(11);tb(0);write('杀敌数目');
  x:=windmaxx div 2-2;y:=wherey+1;if setting.playernum=2 then x:=windmaxx div 2-8;
  for i:=1 to setting.playernum do
  begin
    tb(0);tc(15);gotoxy(x+interval[i]-1,y);write(player[i].nam,i);
  end;
  for occup:=1 to maxoccup do
  begin
    for playern:=1 to setting.playernum do
    begin
      gotoxy(x+interval[playern],y+occup);tb(tankbackground[1]);tc(color(random(101),100));write(tankchar[1,occup,0]);
      tb(0);tc(7);write(':');
      tb(0);tc(7);print_score(wherex,wherey,killnum[playern,occup]);
    end;//end for
  end;//end for occup

  gotoxy_mid('死亡次数',wherey+2);tb(0);tc(4);write('死亡次数');
  gotoxy(wherex,wherey+1);
  for playern:=1 to setting.playernum do
  begin
    gotoxy(x+interval[playern],wherey);tb(tankbackground[0]);if playern=2 then tb(player2color);tc(tankcolor[0]);write(tankchar[0,1,0]);
    tb(0);tc(7);write(':');
    tb(0);tc(7);print_score(wherex,wherey,dietimes[playern]);
  end;
  gotoxy_mid('得分',wherey+2); tb(0);tc(15);                  write('得分');
  gotoxy_mid(inttostr(score)+' ',wherey+1); tb(0);tc(7);          print_score(wherex,wherey,score);
  if ismainlevel then
  begin
    gotoxy_mid('评价',wherey+1);    tb(0);tc(15);   write('评价');
                                    tb(0);          print_assess((windmaxx-length(assesschar[assess])-1) div 2,wherey+1,assesscolor[assess],assesschar[assess]);
  end;

  gt(ot);
  save;
  repeat
    gt(nt);
  until td(ot,nt)>=100;
  readkey;
end;

procedure shop;
var i,n,t,choose,cnt,mxl:longint;
    a:array[1..maxoccup] of longint;
    s,ss:string;
begin
  clrscr;
  gotoxy_mid('商店',1);tb(0);tc(11);write('商店');
  windminy:=2;
  repeat
    clrscr;
    gotoxy_mid('弹药'+getastr(6),1);
    tb(0);tc(7);choose:=chooseone('弹药'+ln+
                                  '道具'+ln+
                                  '职业'+ln+
                                  '返回');
    if choose=4 then break;
    clrscr;
    case choose of
      1:begin
          s:='';
          for i:=2 to maxammotype do
            s:=s+ammonam[i]+ln;
          s:=s+'返回';
          gotoxy_mid(getastr(10),1);tb(0);tc(7);choose:=chooseone(s)+1;
          if choose=maxammotype+1 then continue;
          clrscr;
          i:=0;
          repeat
            clrscr;
            gotoxy_mid('金钱:'+inttostr(profile.money),1);                                    tc(7);tb(0);  write('金钱:',profile.money);
            gotoxy_mid(ammonam[choose]+inttostr(ammoprice[choose])+'元/发',2);             tc(7);tb(0);  write(ammonam[choose],ammoprice[choose],'元/发');
            gotoxy_mid('请输入要购买的数量'+'(已有'+inttostr(profile.ammo[choose])+'发)',3);  tc(7);tb(0);  write('请输入要购买的数量'+'(已有'+inttostr(profile.ammo[choose])+'发)');

            n:=0;
            gotoxy(1,4);clreol;
            tb(7);tb(0);gotoxy(38,4);inputint(n,min(999-profile.ammo[choose],profile.money div ammoprice[choose]),0);
            if n=0 then
            begin
              i:=5;
              break;
            end;

            if (n+profile.ammo[choose]<=999) and (profile.money>=n*ammoprice[choose]) then break;
            if profile.money<n*ammoprice[choose] then
            begin
              gotoxy_mid('金钱不足',wherey+1);tc(4);tb(0);write('金钱不足');
            end;
            if n+profile.ammo[choose]>999 then
            begin
              gotoxy_mid('超出数量限制(999)',wherey+1);tc(4);tb(0);write('超出数量限制(999)');
            end;
            delay(500);
            inc(i);
          until i=5;
          if i=5 then continue;
          with profile do
          begin
            inc(ammo[choose],n);
            dec(money,n*ammoprice[choose]);
          end;
        end;//end case 1
      2:begin
          s:='';
          for i:=1 to maxproptype do
            s:=s+propnam[i]+ln;
          s:=s+'返回';
          gotoxy_mid(getastr(10),1);tb(0);tc(7);choose:=chooseone(s);
          if choose=maxproptype+1 then continue;
          clrscr;
          i:=0;
          repeat
            clrscr;
            gotoxy_mid('金钱:'+inttostr(profile.money),1);                                    tc(7);tb(0);  write('金钱:',profile.money);
            gotoxy_mid(propnam[choose]+inttostr(propprice[choose])+'元/个',2);             tc(7);tb(0);  write(propnam[choose],propprice[choose],'元/个');
            gotoxy_mid('请输入要购买的数量'+'(已有'+inttostr(profile.prop[choose])+'个)',3);  tc(7);tb(0);  write('请输入要购买的数量'+'(已有'+inttostr(profile.prop[choose])+'个)');
                                                                                           tc(8);tb(0);  write('(已有',profile.prop[choose],'个)');
            n:=0;
            gotoxy(1,4);clreol;
            tb(7);tb(0);gotoxy(38,4);inputint(n,min(999-profile.prop[choose],profile.money div propprice[choose]),0);
            if n=0 then
            begin
              i:=5;
              break;
            end;

            if (n+profile.prop[choose]<=999) and (profile.money>=n*propprice[choose]) then break;
            if profile.money<n*propprice[choose] then
            begin
              gotoxy_mid('金钱不足',wherey+1);tc(4);tb(0);write('金钱不足');
            end;
            if n+profile.prop[choose]>999 then
            begin
              gotoxy_mid('超出数量限制(999)',wherey+1);tc(4);tb(0);write('超出数量限制(999)');
            end;
            delay(500);
            inc(i);
          until i=5;
          if i=5 then continue;
          with profile do
          begin
            inc(prop[choose],n);
            dec(money,n*propprice[choose]);
          end;
        end;
      3:begin
          s:='';
          cnt:=0;
          mxl:=4;
          for i:=0 to maxoccup do
           if (profile.occupown[i]=false) then
           begin
             ss:=occupnam[0][i]+' (售价:'+inttostr(occupprice[i])+')';
             mxl:=max(mxl,length(ss));
             s:=s+ss+ln;
             inc(cnt);
             a[cnt]:=i;
           end;
          s:=s+'返回';
          gotoxy_mid(mxl+6,1);tb(0);tc(7);choose:=chooseone(s);
          if choose=cnt+1 then continue;
          choose:=a[choose];
          if (profile.money<occupprice[choose]) then
          begin                          
            clrscr;
            gotoxy_mid('金钱不足',wherey+1);tc(4);tb(0);write('金钱不足');    
            delay(500);
            continue;
          end;
          with profile do
          begin
            dec(money,occupprice[choose]);
            occupown[choose]:=true;
          end;
        end;
    end;//end case
    gotoxy_mid('购买成功',wherey+1);tc(12);tb(0);write('购买成功');
    gotoxy_mid('剩余金钱:'+inttostr(profile.money),wherey+1);tc(7);tb(0);write('剩余金钱:',profile.money);
    readkey;
  until false;
  save;
  windminy:=1;
end;

procedure setsetting;
var i,n,t:longint;
    s:string;
begin
  clrscr;
  s:='设置将在游戏重启后生效';
  gotoxy_mid(s);tb(0);tc(7);write(s);
  exec('notepad.exe',path+'\'+settingfilenam);
  readkey;
end;

procedure print_text(fn:string);
var f:text;
    s,ss:string;
    i,l:longint;
    fst:boolean;
   function trans(c:char):longint;
   begin
     c:=upcase(c);
     if (c in ['0'..'9']) then trans:=ord(c)-ord('0')
     else trans:=ord(c)-ord('A')+10;
   end;
begin
  clrscr;
  if (fsearch(fn,'\')='') then exit;
  assign(f,fn);
  reset(f);
  l:=0;
  fst:=true;
  while (eof(f)=false) do
  begin
    readln(f,s);
    if (length(s)>=2) and (s[1]='\') and (s[2]='\') then
    begin
      readkey;
      fst:=true;
      clrscr;
    end
    else begin       
      if fst then l:=length(s);
      if (length(s)>=2) and (s[1]='\') and (s[2]='l') then l:=length(s)-2;
      tb(0); tc(7);
      i:=1;
      ss:='';
      if fst=false then writeln;
      gotoxy_mid(l);
      fst:=false;
      while (i<=length(s)) do
      begin
        if (s[i]='\') then
        repeat
          if (s[i+1]='l') then
          begin
            inc(i);
            break;
          end;
          tb(trans(s[i+1]));
          tc(trans(s[i+2]));
          inc(i,2);
        until true
        else ss:=ss+s[i];
        if (length(ss)=2) or (ord(ss[1])<128) then
        begin
          write(ss);
          ss:='';
        end;
        inc(i);
      end; //end while i
    end;
    tb(0); tc(7);
  end;
  close(f);
  readkey;
end;

procedure help;
var s:string;
    i,j,cnt,choose:longint;
begin
  clrscr;
  gotoxy_mid('帮助&图鉴',1);tb(0);tc(11);write('帮助&图鉴');
  windminy:=2;
  repeat
    clrscr;
    gotoxy_mid('游戏目标'+getastr(6));
    choose:=chooseone('游戏目标'+ln+
                      '键位说明'+ln+
                      '方块类型'+ln+
                      '实体类型'+ln+
                      '敌人种类'+ln+
                      '职业介绍'+ln+
                      '设置参数'+ln+
                      '指令详情'+ln+
                      '其他信息'+ln+
                      '返回'        );
    case choose of
      1:print_text('bin\help_gamegoal.txt');
      2:print_text('bin\help_keyboard.txt');
      3:print_text('bin\help_block.txt');
      4:print_text('bin\help_entity.txt');
      5:print_text('bin\help_enemy.txt');
      6:print_text('bin\help_occupation.txt');
      7:print_text('bin\help_setting.txt');
      8:print_text('bin\help_command.txt');
      9:print_text('bin\help_other.txt');
      10:break;
    end;
    clrscr;
  until false;
  windminy:=1;
end;

procedure work_main;
var i,n,t,choose:longint;
begin
  repeat
    clrscr;
    gotoxy_mid('帮助&图鉴'+getastr(6),windminy);
    if logged then choose:=chooseone('开始游戏'  +ln+
                                     '商店'      +ln+
                                     '账号信息'  +ln+
                                     '帮助&图鉴'+ln+
                                     '设置'      +ln+
                                     '退出'          )
              else choose:=chooseone('开始游戏'  +ln+
                                     '商店'      +ln+
                                     '登录'      +ln+
                                     '帮助&图鉴'+ln+
                                     '设置'      +ln+
                                     '退出'          );
    case choose of
      1:begin
          work_game;
        end;
      2:shop;
      3:if logged then print_profile
         else logged:=load(1);
      4:help;
      5:setsetting;
      6:begin
          tc(0); tb(0);
          break;
        end;
    end;//end case
  until false;
end;

BEGIN
  clrscr;gotoxy_mid('Loading...',1);tb(0);tc(7);write('Loading...');
  getdir(byt,path);
  init_program;
  logged:=load(0);
  work_main;
END.

 

方亦欧在2018-02-10 20:12:10追加了内容

刚刚发的没高亮,重发一遍。 

PROGRAM The_War_of_Tank_____By_Fallen_Breath;

{$M 1000000000,0,maxlongint}
{$inline on}

USES Crt,Dos,SysUtils,Math,Windows,BetterInput,MmSystem;

CONST
/////////////////////////Program Information/////////////////////////

      AppName                  = '坦克大战';
      Version                  = 'V1.0.0_build7';
      ApplicationVersion       = 'Beta 1.0.0+';
      Date                     = '2017.4.10';

{$I 定义.inc}

procedure F4;
begin
  write('Press F4 here!');
  explode(maxx div 2,maxy div 2,maxexplodehard,0,1);
end;

function gettick:int64;
var t:SYSTEMTIME;
    u,x,y:int64;
begin
  GetLocalTime(t);
  u:=1;
  with t do
  begin
    gettick:=u*wMilliseconds+u*1000*wSecond+u*1000*60*wMinute;
    gettick:=gettick+u*1000*60*60*wHour+u*1000*60*60*24*wDay;
  end;
end;

procedure gt(var n:Ttime);inline;
begin
  n.time:=gettick;
  if gaming then n.tick:=tick;
end;

function td(o,n:Ttime):int64;
begin
  exit(n.time-o.time);
end;

function color(now,max:longint):longint;
var i:longint;
begin
  if (now<0) or (max=0) then exit(12);
  case trunc(now/max*100) of
    0..25:color:=12;
    26..50:color:=14;
    51..75:color:=11;
    76..100:color:=10;
  end;
end;

procedure delay(x:longint);
var st:longint;
begin
  st:=getmscount;
  while (getmscount-st<x) and (keypressed=false) do;
  if keypressed then readkey;
end;

function lenlimit(s:string;max:longint):string;
var l,r,i:longint;
begin
  if length(s)<=max then exit(s);
  l:=1;r:=length(s);
  exit(copy(s,1,r-4-(r-max))+'..'+copy(s,r-1,2));
end;

function getastr(len:longint):string;
var i:longint;
begin
  getastr:='';
  for i:=1 to len do
    getastr:=getastr+chr(random(256));
end;

procedure runmusic;
var i:longint;
    s:ansistring;m:string;
begin
  s:=musicparameter;
  musicthreadok:=true;
  exec(musicplayerprogramnam,s);

 { s:=musicparameter[1];
  m:=musicparameter[2];
  if length(s)=0 then exitthread(0);
  if length(m)=0 then m:='0';
  case m[1] of
    '0':sndplaysound(pchar(s),SND_ASYNC);//播放一次
    '1':begin
          sndplaysound(pchar(s),SND_LOOP);//播放多次
          while FileExists(pchar('stopplaymucsic'))=false do;
        end;
  end;
  musicparameter[1]:='';musicparameter[2]:=''; }
  exitthread(0);
end;

procedure playmusic(s,m:string);//inline;
var f:text;
    ff:file;
begin
  if (setting.musicon=0) then exit;
  musicparameter:=s+' '+m;
  {s:=s1;
  musicparameter[1]:=s;
  musicparameter[2]:=m;  }
  musicthreadok:=false;
  if (createthread(nil,0,@runmusic,nil,0,tid)=0) then exit;
  while (musicthreadok=false) do;
  //sndplaysound(pchar(s),SND_ASYNC);
  exit;
end;

function chooseone(s:ansistring):longint;
begin
  chooseone:=betterinput.chooseone(s);
  playmusic('music/click.wav','0');
end;

procedure findfiles(fn:ansistring;var res:findfilesres);
var wjin,wjout:text;
    i,j:longint;
    r:tsearchrec;
    s:string;

   procedure qsort(l,r:longint);
   var i,j:longint;
       x,y:string;
   begin
     i:=l;
     j:=r;
     x:=res.filenam[(l+r)div 2];
     repeat
       while res.filenam[i]<x do inc(i);
       while res.filenam[j]>x do dec(j);
       if i<=j then
       begin
         y:=res.filenam[i];
         res.filenam[i]:=res.filenam[j];
         res.filenam[j]:=y;
         inc(i);
         dec(j);
       end;
     until i>j;
     if i<r then qsort(i,r);
     if l<j then qsort(l,j);
   end;

begin
  with res do
  begin
    filenum:=0;
    maxlen:=0;
    i:=sysutils.findfirst(fn,faanyfile,r);
    while I=0 do
    begin
      inc(filenum);
      filenam[filenum]:=r.name;
      maxlen:=max(maxlen,length(filenam[filenum]));
      i:=sysutils.findnext(r);
    end;
    sysutils.findclose(r);
  end;
  if res.filenum=0 then exit;
  qsort(1,res.filenum);
end;

function getfx(x1,y1,x2,y2:longint):longint;
begin
  if x2=x1 then
  begin
    if y2>y1 then exit(2)
     else exit(0);
  end
   else if y1=y2 then
   begin
     if x2>x1 then exit(1)
      else exit(3);
   end;

  if x1>x2 then
  begin
    if y1>y2 then
    begin
      if (y1-y2)>(x1-x2) then exit(0)
       else exit(3);
    end
     else begin
       if (y2-y1)>(x1-x2) then exit(2)
        else exit(3);
     end;
  end
   else begin
     if y1>y2 then
     begin
       if (y1-y2)>=(x2-x1) then exit(0)
        else exit(1);
     end
      else begin
        if (y2-y1)>=(x2-x1) then exit(2)
         else exit(1);
      end;
   end;
end;
function getfx(x1,x2:Tpos):longint;
begin
  exit(getfx(x1.x,x1.y,x2.x,x2.y));
end;
function getfx(x1:Tpos;x2,y2:longint):longint;
begin
  exit(getfx(x1.x,x1.y,x2,y2));
end;
function getfx(x1,y1:longint;x2:Tpos):longint;
begin
  exit(getfx(x1,y1,x2.x,x2.y));
end;

function getmobharmtype(id:longint):longint;
begin
  case id of
    1,3:exit(1);
    2:exit(2);
    4:exit(3);
  end;
end;
function getmobharmtype(who:Ttank):longint;
begin
  exit(getmobharmtype(who.id));
end;

procedure print(x,y,tbc,tcc:longint;st:string);
var i:longint;
begin
  if inmap(x,y)=false then
  begin
    clrscr;tc(15);tb(0);
    writeln('Error!');
    writeln('Wrong x or y in procedure print');
    writeln('x=',x,'  y=',y);
    delay(2000);
    halt;
  end;
  if tbc=-1 then tbc:=blockbackground[mm.map[x,y].id];

   with newsc[x,y] do
   begin
    // gotoxy(x*2+1,y+1);
     bg:=tbc;col:=tcc;
     ch:=st;
   end;//end with
end;
procedure print(zb:Tpos;tbc,tcc:longint;st:string);
begin
  print(zb.x,zb.y,tbc,tcc,st);
end;

function inmap(x,y:longint):boolean;
begin
  if (x<1) or (x>maxx) or (y<1) or (y>maxy) then exit(false);
  exit(true);
end;
function inmap(zb:Tpos):boolean;
begin
  exit(inmap(zb.x,zb.y));
end;

function can(x,y,typ:longint):boolean; //typ:1:坦克 2:mob
var i:longint;
begin
  if inmap(x,y)=false then exit(false);
  with mm.map[x,y] do
  begin
    if typ=2 then exit(id in cangoblock_mob);
    if (hitbox[x][y]>=tick*2) and (tick>0) then
    begin
      if (hitbox[x][y]=tick*2) then exit(false);
      exit(true);
    end;
    hitbox[x][y]:=tick*2;
    for i:=1 to maxai do
     with ai[i] do
      if (zb.x=x)and (zb.y=y) then
      begin
        if living then exit(false)
      //   else if tick-ldt.tick<dyinglast then exit(false);
      end;
    for i:=1 to setting.playernum do
     with player[i] do
      if (zb.x=x)and (zb.y=y) then
      begin
        if living then exit(false)
       //  else if tick-ldt.tick<dyinglast then exit(false);
      end;
    if id in cangoblock_tank=false then exit(false);
  end;
  if (tick>0) then hitbox[x][y]:=tick*2+1;
  exit(true);
end;
function can(zb:Tpos;typ:longint):boolean;
begin
  exit(can(zb.x,zb.y,typ));
end;

function whichmob(x,y:longint):longint;{exit -1:no}
var i,j,n,t,w:longint;
    a:array[1..maxmob] of longint;
begin
  n:=0;
  for i:=1 to maxmob do
   with mob[i] do
    if living then
      if (zb.x=x) and (zb.y=y) then
      begin
        inc(n);
        a[n]:=i;
      end;
  if n=0 then exit(-1);
  exit(a[random(n)+1]);
end;
function whichmob(zb:Tpos):longint;
begin
  exit(whichmob(zb.x,zb.y));
end;

function whichtank(x,y:longint):longint;{exit 0:no}
var i,j,n,t,w:longint;
begin
  for i:=1 to maxai do
   with ai[i] do
    if (zb.x=x) and (zb.y=y) then
     if living{ or (((tick-ldt.tick) mod dyingblinklast<=dyingblinklast div 2) and (tick<=ldt.tick+dyinglast)) }then exit(i);
  for i:=1 to maxplayer do
   with player[i] do
    if (zb.x=x) and (zb.y=y) then
     if living {or (((tick-ldt.tick) mod dyingblinklast<=dyingblinklast div 2) and (tick<=ldt.tick+dyinglast))} then exit(-i);
  exit(0);
end;
function whichtank(zb:Tpos):longint;
begin
  exit(whichtank(zb.x,zb.y));
end;

function ju(x1,y1,x2,y2:longint):longint;
begin
  exit(abs(x1-x2)+abs(y1-y2));
end;
function ju(a,b:Tpos):longint;
begin
  exit(ju(a.x,a.y,b.x,b.y));
end;
function ju(a:Tpos;x,y:longint):longint;
begin
  exit(ju(a.x,a.y,x,y));
end;
function ju(x,y:longint;a:Tpos):longint;
begin
  exit(ju(x,y,a.x,a.y));
end;

function findblock(did,isrnd:longint):Tpos;//idrnd 1:random
var i,j,n:longint;
    a:array[0..maxblock] of Tpos;
begin
  n:=0;
  a[0].x:=-1;
  a[0].y:=-1;
  for i:=1 to maxx do
   for j:=1 to maxy do
    if mm.map[i,j].id=did then
    begin
      inc(n);
      a[n].x:=i;
      a[n].y:=j;
    end;
  if n=0 then exit(a[0]);
  if isrnd=0 then exit(a[1]);
  exit(a[random(n)+1]);
end;



procedure destroy(x,y,fromx,fromy,harm,ht:longint);
var i,j,n,t,w:longint;
    zb:Tpos;
begin
  if inmap(x,y)=false then
  begin
    clrscr;tc(15);tb(0);
    writeln('Error!');
    writeln('Wrong x or y in procedure destroy');
    writeln('x=',x,'  y=',y);
    delay(2000);
    halt;
  end;
  with mm.map[x,y] do
  begin
    if unbreakble then exit;
    if ht<>0 then
     if id in candestroyblock[ht]=false then exit;
   { if id in [10] then
     if ht=3 then exit;}
    dec(hard,harm);
    if id=4 then
     with playerflag do
       dec(hp,harm);
    if id=5 then
     with aiflag do
       dec(hp,harm);
    if ht<>3 then
    case id of
      1,2,6,7:playmusic('music\stone'+chr(random(4)+1+ord('0'))+'.wav','0');
      4,5:playmusic('music\wood'+chr(random(4)+1+ord('0'))+'.wav','0');
      8:playmusic('music\fuse.wav','0');
    end;
    if hard<=0 then
    begin
      case id of
        4:repeat
            gamelose:=true;gameendtick:=tick;
            init_tip('游戏失败',10,gamefinishtipshowlast);
            zb:=findblock(5,0);
            if zb.x=-1 then break;
            mm.map[zb.x,zb.y].unbreakble:=true;
          until true;
        5:repeat
            gamewin:=true;gameendtick:=tick;
            init_tip('游戏胜利',12,gamefinishtipshowlast);
            zb:=findblock(4,0);
            if zb.x=-1 then break;
            mm.map[zb.x,zb.y].unbreakble:=true;
          until true;
        8:repeat
            if (harm>TNTgenerateharmlimit) then break;
            t:=new_mob(x,y,-1,4,0);
            if ht=3 then
            begin
              mob[t].lst.tick:=tick-(random(6)+1)*TNTblinklast div 2+random(3)-1;
              mob[t].fx:=getfx(fromx,fromy,x,y);
            end
             else mob[t].speed:=maxlongint;
          until true;
      end;//end case
     // if id in candestroyblock[ht] then
      begin
        id:=0;
        print(x,y,blockbackground[id],15,blockchar[id,fx]);
      end;
    end;//end if destroyed
  end;
end;

procedure explode(mx,my,hard,fromwho,hurtfrom,nomusic:longint); //hard:1~15
var maxju,i,tmp:longint;
    explodeed:array[1..maxx,1..maxy] of boolean;
    candes:boolean;

   procedure bfs(x,y,hard:longint);
   type dl=record
             x,y,pre,h:longint;
           end;
   var i,ii,j,xx,yy,n,head,tail:longint;
       q:array[1..10000] of dl;
       b:array[0..3] of boolean;

      procedure work(x,y,harm:longint);
      begin
        explodeed[x,y]:=true;
        hurt_mob(whichmob(x,y),mx,my,harm,3,fromwho);
        if candes=true then
         if inmap(mx,my) then
          if mm.map[mx,my].id in [3]=false then
          begin
            tmp:=whichtank(x,y);
            if (fromwho<>tmp) or (hurtfrom=1) then hurt_tank(tmp,harm,3,fromwho);
            destroy(x,y,mx,my,harm,3);
          end;
      end;

   begin;

     head:=0;tail:=1;
     q[tail].x:=x;q[tail].y:=y;q[tail].pre:=0;q[tail].h:=hard;
     if inmap(x,y) then
     begin
       work(x,y,explodeharm[hard]);
     end;
     while head<>tail do
     begin
       inc(head);
       fillchar(b,sizeof(b),true);
       for ii:=0 to 3 do
       begin
      //   write(candes);
         repeat
           i:=random(4);
         until b[i];
         b[i]:=false;
         xx:=q[head].x+gox[i];
         yy:=q[head].y+goy[i];
         if inmap(xx,yy)=false then continue;
         if explodeed[xx,yy] then continue;
         if (mm.map[xx,yy].hard>explodeharm[q[head].h]) or (mm.map[xx,yy].id in [0]+candestroyblock[3]-[3]=false)
         or ((candes=false) and (mm.map[xx,yy].id in cangoblock_mob=false)) then
         begin
           work(xx,yy,explodeharm[q[tail].h]);
           continue;
         end;
         if (q[head].h>1) then
         begin
           inc(tail);
           q[tail].x:=xx;q[tail].y:=yy;q[tail].pre:=head;q[tail].h:=q[head].h-1;
           work(xx,yy,explodeharm[q[tail].h]);
           if (mm.map[xx,yy].id in [0]=false) then q[tail].h:=q[head].h-mm.map[xx,yy].hard div 3-1;
         end;//end if can
       end;// end for
     end; //end while
   end;//end bfs

begin
  if (nomusic=0) then playmusic('music\boom'+chr(random(4)+1+ord('0'))+'.wav','0');
  hard:=min(hard,maxexplodehard);
  hard:=max(hard,0);
  fillchar(explodeed,sizeof(explodeed),false);
  candes:=true;
  if inmap(mx,my) then
   if mm.map[mx,my].id in [3] then candes:=false;
  bfs(mx,my,hard);
end;    
procedure explode(mx,my,hard,fromwho,hurtfrom:longint);
begin
  explode(mx,my,hard,fromwho,hurtfrom,0);
end;
procedure explode(m:Tpos;hard,fromwho,hurtfrom,nomusic:longint);
begin
  explode(m.x,m.y,hard,fromwho,hurtfrom,nomusic);
end;
procedure explode(m:Tpos;hard,fromwho,hurtfrom:longint);
begin
  explode(m.x,m.y,hard,fromwho,hurtfrom,0);
end;

procedure print_tip(s:string;color:longint);
var i,j,t:longint;
begin
  gotoxy(maxtiplength div 2-(length(s) div 2)+3,maxy+2);
  tc(color);tb(8);write(s);
end;

procedure init_tip(s:string;c,lf:longint);
var i,j,t:longint;
begin
  with tip do
  begin
    if twn=maxtip then exit;
    inc(twn);
    with tipwaiting[twn] do
    begin
      st:=s;
      color:=c;
      lastfor:=lf;
      if twn>1 then exit;
      gt(starttime);
      print_tip(st,color);
    end;//end with
  end;//end with
end;

procedure hurt_mob(var who:Tmob;fromx,fromy,harm,ht,fromwho:longint);
var i,n,gf:longint;
begin
  with who do
  begin
    if living=false then exit;
    if getmobharmtype(id) in [2] then exit;
    if (fromx=zb.x) and (fromy=zb.y) then exit;
    gf:=getfx(fromx,fromy,zb.x,zb.y);
    repeat
      if fx=-1 then break;
      if abs(gf-fx)=2 then
      begin
        speed:=max(speed,10-harm);
        if speed<0 then
        begin
          fx:=gf;
          speed:=-speed;
        end;
      end
       else if gf=fx then
       begin
         dec(speed,harm div 2+1);
       end;
    until true;
    if speed=maxlongint then speed:=10-harm;
   // speed:=max(speed,0);

    if harm>2 then fx:=gf;
    whos:=fromwho;
    print_mob(who);
  end;//end with
end;
procedure hurt_mob(n,fromx,fromy,harm,ht,fromwho:longint);
begin
  if n<1 then exit;
  hurt_mob(mob[n],fromx,fromy,harm,ht,fromwho);
end;

procedure hurt_tank(var who:Ttank;harm,ht,fromwho:longint);
var i,n:longint;
begin
  with who do
  begin
    if living=false then exit;
    if (nam='Player') and god then exit;
    if unbreakble then exit;

    if (occup<>2) or (skillusing=false) then dec(hp,harm)
     else begin
       dec(hp,harm div 10);
       if system.random<=harm mod 10/10 then dec(hp,1);
       playmusic('music\hitiron'+chr(random(4)+1+ord('0'))+'.wav','0');
     end;
    print_tank(who);
    checkdie(who);

    if living=false then
    begin
      if nam='Ai' then
       if (fromwho<0) and (god=false) and (cmdused=false) then
       begin
         init_tip('金钱增加'+inttostr(killaiprize[occup]),14,killaitipshowlast);
         inc(profile.money,killaiprize[occup]);
         inc(killnum[-fromwho,occup]);
         if ((setting.gamehard<2) or (player[-fromwho].occup=0)) and (player[-fromwho].occup in [0,1,3,4]) and (player[-fromwho].living) and (random(setting.gamehard+1)=0) then player[-fromwho].hp:=min(player[-fromwho].hp+1,player[-fromwho].maxhp);
         playmusic('music\kill.wav','0');
       end;
      if nam='Player' then
      begin
        inc(dietimes[-xu]);
      end;
    end;//end if die
  end;//end with
end;
procedure hurt_tank(n,harm,ht,fromwho:longint);
begin
  if n>0 then hurt_tank(ai[n],harm,ht,fromwho)
   else if n=0 then exit
    else if n<0 then hurt_tank(player[-n],harm,ht,fromwho);
end;

procedure checkdie(var who:Ttank);
var i,n,t,w,j:longint;
begin
  with who do
   if living and (hp<=0) then
   begin
     if (nam='Ai') and (occup=0) then bosstime:=false;
     if (nam='Player') then
       playmusic('music/player_death.wav','0');
     living:=false;
     dec(lives);
     gt(ldt);
     print_auto(zb);
   end;//end with
end;
procedure checkdie;
var i:longint;
begin
  //for i:=1 to maxmob do checkdie(mob[i]);
  for i:=1 to maxai do checkdie(ai[i]);
  for i:=1 to setting.playernum do checkdie(player[i]);
end;

procedure fire(var who:Ttank;fangxiang,amt:longint);
var i,n,t:longint;
begin
  with who do
  begin
    fx:=fangxiang;
    print_tank(who);
    repeat
      gt(lft[amt]);
      t:=new_mob(zb.x{+gox[fx]},zb.y{+goy[fx]},fx,amt,xu);
    until true;
    gt(lft[amt]);
    if nam='Player' then
     if (amt<>1) and (god=false) then dec(profile.ammo[amt]);
    case amt of
      1:playmusic('music\fire_bullet.wav','0');
      2:playmusic('music\fire_laser.wav','0');
      3:playmusic('music\fire_bomb.wav','0');
    end;
  end;//end with
end;

function canfire(who:Ttank;amt:longint):boolean;
var i,n,t:longint;
begin
  with who do
  begin
    if occup=2 then
    begin
      if tick-lft[amt].tick<firespeed[id,occup,amt] div (2+random(2)) then exit(false);
    end
     else if tick-lft[amt].tick<firespeed[id,occup,amt] then exit(false);
    if (id=0) and (amt<>1) and (god=false) and (profile.ammo[amt]<=0) then exit(false);
  end;//end with
  exit(true);
end;

procedure move(var who:Ttank;dfx:longint);
var i,n,t:longint;
    ox,oy:longint;
begin
  with who do
  begin
    ox:=zb.x;
    oy:=zb.y;
    inc(zb.x,gox[dfx]);
    inc(zb.y,goy[dfx]);
    fx:=dfx;
    gt(lmt);
    print_auto(ox,oy);
    print_tank(who);
    hitbox[ox][oy]:=0;
    hitbox[zb.x][zb.y]:=0;
  end;//end with
end;

function canmove(who:Ttank;dfx:longint):boolean;
var i,n,t:longint;
    xx,yy:longint;
begin
  with who do
  begin
    if tick-lmt.tick<speed then exit(false);
    if (occup=2) and (skillusing) then exit(false);
    if fx=-1 then exit(false);
    xx:=zb.x+gox[dfx];
    yy:=zb.y+goy[dfx];
    if nam='Mob' then
      exit(can(xx,yy,2));
    exit(can(xx,yy,1));
  end;//end with
end;

procedure print_tank(who:Ttank);
var i,tcc,tbc:longint;
    s:string;
begin
  with who do
  begin
    if living=false then exit;
    if mm.map[zb.x,zb.y].id in donotprintblock_tank then exit;
    if unbreakble and (tick mod unbreakbleblinklast>=unbreakbleblinklast div 2) then exit;
    tbc:=tankbackground[id];
    tcc:=color(hp,maxhp);
    if nam='Player' then
    begin
      if xu=-2 then tbc:=player2color;
      tcc:=15;
      if skillusing then
       if xu=-1 then tcc:=13
        else tcc:=9;
      if tick-skill.stop.tick<occupskilltime[occup,1] then tcc:=8;
    end;
    s:=tankchar[id,occup,fx];

     with newsc[zb.x,zb.y] do
     begin
       bg:=tbc;
       col:=tcc;
       ch:=s;
     end;//end with
  {  gotoxy(zb.x*2+1,zb.y+1);
    tc();
    write(tankchar[id,occup,fx]);  }
  end;
end;
procedure print_tank(n:longint);
begin
  if (n>=1) and (n<=maxai) then
  begin
    print_tank(ai[n]);
  end
   else if (-n>=1) and (-n<=maxplayer) then
   begin
     print_tank(player[-n]);
   end;
end;

procedure print_mob(who:Tmob);
var i,tcc,tbc:longint;
    s:string;
begin
  with who do
  begin
    if living=false then exit;
  //  gotoxy(zb.x*2+1,zb.y+1);
    if mm.map[zb.x,zb.y].id in donotprintblock_mob then exit;
    tbc:=blockbackground[mm.map[zb.x,zb.y].id];
    tcc:=mobcolor[id];
    if id=4 then
    begin
      if (tick-lst.tick) mod TNTblinklast<TNTblinklast div 2 then tbc:=7
       else begin
         tbc:=6;
         tcc:=0;
       end;
    end;
    s:=mobchar[id,max(fx,0)];
     with newsc[zb.x,zb.y] do
     begin
       bg:=tbc;
       col:=tcc;
       ch:=s;
     end;//end with
  end;
end;
procedure print_mob(n:longint);
begin
  if (n<1) or (n>maxmob) then exit;
  print_mob(mob[n]);
end;

procedure print_block(x,y:longint);
begin
  if inmap(x,y)=false then
  begin
    clrscr;tc(15);tb(0);
    writeln('Error!');
    writeln('Wrong x or y in procedure print_block');
    writeln('x=',x,'  y=',y);
    delay(2000);
    halt;
  end;
  with mm.map[x,y] do
    print(x,y,blockbackground[id],blockcolor[id],blockchar[id,fx]);
end;
procedure print_block(x:Tpos);
begin
  print_block(x.x,x.y);
end;

procedure print_auto(x,y:longint);
var n:longint;
begin
  print_block(x,y);
  n:=whichmob(x,y);
  if n<>-1 then
  begin
    print_mob(mob[n]);
  end;
  n:=whichtank(x,y);
  if n>0 then
  begin
    print_tank(ai[n]);
  end
   else if n<0 then
   begin
     print_tank(player[-n]);
   end;
end;
procedure print_auto(zb:Tpos);
begin
  print_auto(zb.x,zb.y);
end;

procedure print_game_info;
var i,j,t,n:longint;
    playern,propn:longint;
    s:string;

   procedure printflagstatus(what:Tflag);
   var i,x:longint;
   begin
     with what do
     begin
       if lthp=hp then exit;
       tb(blockbackground[id]);tc(15);
       write(blockchar[id,0]);
       tb(0);tc(15);write(':');
       x:=wherex;
       tc(color(hp,maxhp));
       tb(0);write(hp);
       x:=wherex-x;for i:=1 to 3-x do write(' ');
       tc(15);write('/',maxhp);
      // for i:=1 to 10-y do write(' ');
     end;//end with
   end;

begin
  for playern:=1 to setting.playernum do
   with player[playern] do
   begin
     if ltl[playern]<>lives then
     begin
       gotoxy(15,maxy+3);if playern=2 then gotoxy(wherex,wherey+1);
       tb(bkbg);tc(15);
       tc(color(lives,maxlives));
       write(lives);
       str(lives,s);
       for i:=1 to 4-length(s) do
       begin
         tb(bkbg);tc(bkcl);
         write(' ');
       end;
     end;
     if lthp[playern]<>hp then
     repeat
       gotoxy(22,maxy+3);if playern=2 then gotoxy(wherex,wherey+1);
       tb(bkbg);tc(color(hp,maxhp));
       write(hp);
       str(hp,s);
       for i:=1 to 4-length(s) do
       begin
         tb(bkbg);tc(bkcl);
         write(' ');
       end;
       if hp>lthp[playern] then break;
       n:=random(3)+1;
       s:='music\hit'+chr(n+ord('0'))+'.wav';
       playmusic(s,'0');
      // write(s);
     until true;
     for propn:=1 to maxproptype do
      if ltprop[playern,propn]<>profile.prop[propn] then
      begin
        gotoxy(40+(propn-1)*10,maxy+3);if playern=2 then gotoxy(wherex,wherey+1);
        tb(bkbg);tc(15);
        write(profile.prop[propn]);
        str(profile.prop[propn],s);
        for i:=1 to 3-length(s) do
        begin
          tb(bkbg);tc(bkcl);
          write(' ');
        end;
      end;
   end;//end with

  gotoxy(maxx*2-6,maxy+3);
  printflagstatus(playerflag);
  gotoxy(maxx*2-6,maxy+4);
  printflagstatus(aiflag);

  tb(bkbg);tc(15);
  gotoxy(maxx*2-9,maxy+2);WRITE('Tick:',tick);

  gt(fpsn);
  if td(fpsb,fpsn)>=1000 then
  begin
    gotoxy(73,1);tb(bkbg);write('       ');
    gotoxy(80-length('Tps:'+inttostr(fpsn.tick-fpsb.tick))+1,1);tb(bkbg);tc(7);if fpsn.tick-fpsb.tick>=1000 div ticklast then tc(15);write('Tps:',fpsn.tick-fpsb.tick);
    fpsb:=fpsn;
  end;

        for i:=1 to setting.playernum do
         with player[i] do
         begin
           lthp[i]:=hp;
           for j:=1 to maxproptype do
             ltprop[i,j]:=profile.prop[j];
         end;
         playerflag.lthp:=playerflag.hp;aiflag.lthp:=aiflag.hp;
end;

procedure print_screen(j,i:longint);
var x1,x2,y1,y2:longint;
    s:string;
begin
  if (oldsc[j,i].ch<>newsc[j,i].ch) or (oldsc[j,i].bg<>newsc[j,i].bg) or (oldsc[j,i].col<>newsc[j,i].col) then
   with newsc[j,i] do
   begin
     gotoxy(j*2+1,i+1);
     tb(bg);tc(col);
     if ch<>'  ' then write(ch)
      else begin
        x1:=windminx;x2:=windmaxx;y1:=windminy;y2:=windmaxy;
        windminx:=j*2+x1;windmaxx:=j*2+length(ch)+x1-1;windminy:=i+y1;windmaxy:=i+y1;
        clrscr;
        windminx:=x1;windmaxx:=x2;windminy:=y1;windmaxy:=y2;
      end;
     oldsc[j,i]:=newsc[j,i];
   end;//end with
end;

procedure print_screen(opt:longint);
var i,j,x,y,cnt:longint;
    vst:array[1..maxx,1..maxy] of boolean;
begin
  fillchar(vst,sizeof(vst),false);
  if (opt=1) then
  begin
    case random(4) of
      0:for i:=1 to maxx do
         for j:=1 to maxy do
           print_screen(i,j);
      1:for i:=maxx downto 1do
         for j:=1 to maxy do
           print_screen(i,j);
      2:for i:=1 to maxy do
         for j:=1 to maxx do
           print_screen(j,i);
      3:for i:=maxy downto 1 do
         for j:=1 to maxx do
           print_screen(j,i);
    end;
    exit;
  end
  else if (opt=2) then
  begin
    for i:=1 to maxx*maxy do
    begin
      repeat
        x:=random(maxx)+1;
        y:=random(maxy)+1;
      until vst[x][y]=false;
      vst[x][y]:=true;
      print_screen(x,y);
    end;
    exit;
  end;
  for i:=-maxy to maxx+maxy do
  begin
    x:=i;
    y:=0;
    if (opt mod 2=1) then inc(x,maxy);
    for j:=1 to maxy do
    begin
      if opt mod 2=0 then inc(x)
      else dec(x);    
      inc(y);
      if (x>=1) and (x<=maxx) and (y>=1) and (y<=maxy) then
      begin
        if (vst[x][y]=false) then print_screen(x,y);
        vst[x][y]:=true;
      end;
    end;
    x:=maxx+maxy-i;
    if (opt mod 4>=2) then dec(x,maxy);
    y:=0;
    for j:=1 to maxy do
    begin
      if opt mod 4<2 then inc(x)
      else dec(x); 
      inc(y);
      if (x>=1) and (x<=maxx) and (y>=1) and (y<=maxy) then
      begin
        if (vst[x][y]=false) then print_screen(x,y);
        vst[x][y]:=true;
      end;
    end;
  end;
 // oldsc:=newsc;
end;
procedure print_screen;
begin
  print_screen(random(7));
end;

procedure print_map;
var i,j,t,n:longint;
begin
  tb(0);
  clrscr;
  tb(bkbg);
  tc(bkcl);
  write('╔');
  for i:=1 to maxx do write('═');
  write('╗');
  tb(bkbg);
  writeln;
  for i:=1 to maxy do
  begin
    gotoxy(1,i+1);
    tb(bkbg);
    tc(bkcl);
    write('║');
    for j:=1 to maxx do
     with mm.map[j,i] do
     begin
       print_auto(j,i);
     end;
    gotoxy(79,i+1);
    tb(bkbg);
    tc(bkcl);
    writeln('║');
  end;
  gotoxy(1,maxy+2);
  write('╚');
  for i:=1 to maxx do write('═');
  write('╝');
  writeln;

  gotoxy(20,1);
  tb(bkbg);tc(11);
  write(mm.nam);

  tb(bkbg);tc(7);
  gotoxy(maxx*2-25,1);
  write('关卡:');
  tc(15);
  write(lenlimit(mm.filenam,15));

  for i:=1 to setting.playernum do
  begin
    gotoxy(1,maxy+3+i-1);
    if i=1 then tb(tankbackground[0]) else tb(player2color);tc(15);write(tankchar[0,1,0]);    // gotoxy(wherex+4,wherey);
    tb(0);tc(7);write(' ',occupnam[0,player[i].occup],' ');
    tc(15);tb(0);{write(#3,'=');}write('Lives:');

    gotoxy(19,wherey);write('HP:');
    for j:=1 to maxproptype do
    begin
      gotoxy(35+(j-1)*10,wherey);
      write(propnam[j],':',profile.prop[j]);
    end;
  end;
  print_game_info;
  print_screen;
end;

procedure clear_tip;
var i,n,t:longint;
begin
  gotoxy(3,maxy+2);
  tc(bkcl);tb(bkbg);
  for i:=1 to maxtiplength div 2 do write('═');
end;

procedure clear_mob(var who:Tmob);
var i,j,n,t,w:longint;
begin
  with who do
  begin
    maxhp:=0;hp:=0;
    fx:=0;
    living:=false;
    lmt.tick:=-1000;
    ldt.tick:=-1000;
    lst.tick:=-1000;
    zb.x:=-1;zb.y:=-1;
    id:=255;
  end;
end;

procedure clear_tank(var who:Ttank);
var i,j,n,t,w:longint;
begin
  with who do
  begin
    maxhp:=0;hp:=0;
    fx:=0;
    living:=false;
    lmt.tick:=-1000;
    for i:=1 to maxammotype do lft[i].tick:=-1000;
    ldt.tick:=-1000;
    lst.tick:=-1000;
    zb.x:=-1;zb.y:=-1;
    id:=255;
    ljn:=0;
    skillusing:=false;
  end;
end;

procedure clear_map;
var i,j,n,t,w:longint;
begin
  for i:=1 to maxx do
   for j:=1 to maxy do
    with mm.map[i,j] do
    begin
      id:=0;
      hard:=0;
      maxhard:=0;
      fj:=0;
      fx:=0;
      lrt.tick:=0;
      unbreakble:=false;
    end;
end;

procedure end_game;
var i,j,n,t:longint;
begin
  tb(0);clrscr;
  windminx:=1;windmaxx:=setting.smaxx;
  windminy:=1;windmaxy:=setting.smaxy;
  print_program_info;
  windmaxy:=setting.smaxy-3;
  gaming:=false;

  for i:=1 to setting.playernum do
  begin
    inc(dietimes[0],dietimes[i]);
    for j:=1 to maxoccup do
      inc(killnum[0,j],killnum[i,j]);
  end;
  for i:=1 to maxoccup do
    inc(killnum[0,0],killnum[0,i]);
  if ismainlevel then t:=levelwinprize[nowlevel] else t:=0;
  if ismainlevel then n:=nowlevel else n:=3;
  score:=(500*n+(t div 100+killnum[0,0])*(setting.gamehard*5+1)) div max(dietimes[0]+1-(nowlevel div 4),1);
  score:=round(score*(system.random/2+0.75));

  if ismainlevel and gamewin  then
  begin
    for assess:=1 to maxassess do
     if gameendtick<=levelbesttime[nowlevel,assess] then break;
  end
   else if gamelose then assess:=maxassess
    else assess:=round(maxassess*0.75);
end;

procedure print_program_info;
var i,j:longint;
begin
  gotoxy(setting.smaxx-length('程序版本:'+Version)+1,setting.smaxy-2);                 tc(7);  write('程序版本:',Version);
  gotoxy(setting.smaxx-length('适用地图版本:'+ApplicationVersion)+1,setting.smaxy-1);  tc(7);  write('适用地图版本:',ApplicationVersion);
  gotoxy(setting.smaxx-15,setting.smaxy);                                              tc(8);  write('By ');  tc(15);  write('Fallen_Breath');
end;

procedure print_profile;
var i,n,t,x,y:longint;
begin
  clrscr;
  tb(0);
  with profile do
  begin
    tc(12);write('账号:');tc(15);writeln(usernam);
    tc(14);write('金钱:');tc(15);writeln(money);
    writeln;
    tc(11);writeln('弹药');
    for i:=1 to maxammotype do
    begin
      tc(7);write(ammonam[i],':');
      tc(15);
      if i=1 then writeln('∞')
       else writeln(ammo[i]);
    end;
    tc(11);writeln('道具');
    for i:=1 to maxproptype do
    begin
      tc(7);write(propnam[i],':');
      tc(15);writeln(prop[i]);
    end;
    writeln;
    tc(11);writeln('关卡状态');
    for i:=1 to mainlevelnum do
    begin
      tc(7);write('Level-',i,':');
      if levelunlock[i] then
      begin
        tc(15);write('已解锁');
      end
       else begin
        tc(8);write('未解锁');
       end;
      write(' ');
      if levelfinish[i] then
      begin
        tc(15);write('已通过');
      end
       else begin
        tc(8);write('未通过');
       end;
      if (i<>mainlevelnum) then writeln;
    end;
    writeln;
    gotoxy((windmaxx+windminx) div 2,windminy);
    x:=wherex; y:=wherey;
    tc(11);write('职业状态');
    for i:=0 to maxoccup do
    begin
      inc(y);
      gotoxy(x,y);
      tc(7);write(occupnam[0][i],':');
      if profile.occupown[i] then
      begin
        tc(15);write('已拥有');
      end
       else begin
        tc(8);write('未获得');
       end;
    end;
  end;//end with
  readkey;
end;

procedure save;
var i,j,n:longint;
    wj:text;
begin
  if logged=false then exit;
  assign(wj,'save/'+profile.filenam);
  rewrite(wj);
  writeln(wj,Version);
  with profile do
  begin
    writeln(wj,'PassWord=',password);
    writeln(wj,'Money=',money);
    for i:=1 to mainlevelnum do
    begin
      writeln(wj,'Level',i,'UnLock=',levelunlock[i]);
    end;
    for i:=1 to mainlevelnum do
    begin
      writeln(wj,'Level',i,'Finish=',levelfinish[i]);
    end;
    for i:=1 to maxammotype do
    begin
      writeln(wj,'Ammo',i,'=',ammo[i]);
    end;
    for i:=1 to maxproptype do
    begin
      writeln(wj,'Prop',i,'=',prop[i]);
    end;
    for i:=0 to maxoccup do
    begin
      writeln(wj,'Occup',i,'Own=',occupown[i]);
    end;
  end;//end with
  close(wj);
end;

function load(mode:longint):boolean;
var choose,i,n,t:longint;
    s:string;
    res:findfilesres;

   procedure fileread(fn:ansistring);
   var wj:text;
       s,s1,s2,s3,e:string;
       i,j,n,t:longint;
       next,b:boolean;
      function fr(var s:string):string;
      begin
        if next then exit('');
        readln(wj,s);
        fr:=s;
        if pos('=',s)=0 then exit;
        while (length(s)>=1) and (s[1]<>'=') do delete(s,1,1);
        delete(s,1,1);
      end;
      function fr:string;
      var s:string;
      begin
        readln(wj,s);
        s1:='';s2:='';s3:='';
        if pos('=',s)=0 then exit(s);
        while (length(s)>1) and (s[1] in ['0'..'9','=']=false) do
        begin
          s1:=s1+s[1];
          delete(s,1,1);
        end;
        while (length(s)>1) and (s[1] in ['0'..'9']) do
        begin
          s2:=s2+s[1];
          delete(s,1,1);
        end;
        while (length(s)>1) and (s[1]<>'=') do
        begin
          s3:=s3+s[1];
          delete(s,1,1);
        end;
        if (length(s)>1) and (s[1]='=') then delete(s,1,1);
        exit(s);
      end;
   begin
     assign(wj,'save/'+fn);
     reset(wj);
     next:=false;
     with profile do
     begin
       fillchar(levelunlock,sizeof(levelunlock),false);levelunlock[1]:=true;levelunlock[2]:=true;
       fillchar(levelfinish,sizeof(levelfinish),false);
       fillchar(occupown,sizeof(occupown),false);occupown[0]:=true;
       fillchar(ammo,sizeof(ammo),0);
       fillchar(prop,sizeof(prop),0);

       filenam:=fn;
       usernam:=copy(fn,1,length(fn)-9);
       e:=fr(password);
       if e=password then fr(password);
       fr(s);val(s,money);
       while not eof(wj) do
       begin
         s:=fr;
         val(s2,n);
         if s1='Level' then
         begin
           if s3='UnLock' then
           begin
             if (n>=1) and (n<=mainlevelnum) then levelunlock[n]:=s='TRUE';
           end//end if s3='Unlock'
           else if s3='Finish' then
           begin
             if (n>=1) and (n<=mainlevelnum) then levelfinish[n]:=s='TRUE';
           end;//end if s3='Finish'
         end//end if s1='Level'

         else if s1='Ammo' then
         begin
           if (n>=1) and (n<=maxammotype) then val(s,ammo[n]);
         end//end if s1='Ammo'

         else if s1='Prop' then
         begin
           if (n>=1) and (n<=maxproptype) then val(s,prop[n]);
         end//end if s1='Prop'

         else if s1='Occup' then
         begin
           if (s3='Own') then
           begin
             if (n>=0) and (n<=maxoccup) then occupown[n]:=s='TRUE';
           end;
         end;//end if s1='Occup'
       end;//end while
       if (levelunlock[mainlevelnum]=false) and (levelfinish[mainlevelnum]=false) then
       begin
         levelunlock[mainlevelnum]:=true;
         for i:=1 to mainlevelnum-1 do
          if (levelfinish[i]=false) then levelunlock[mainlevelnum]:=false;
       end;//end if
     end;//end with
     close(wj);
   end;

begin
  load:=false;
  repeat//=============================================================
    if mode=0 then
    begin
      clrscr;
      gotoxy_mid(getastr(max(length('登录'),length('游客'))+6),1);
                   choose:=chooseone('登录'+ln+
                                     '游客');
      if choose=2 then exit(false);
    end;
    repeat
      clrscr;
      gotoxy_mid(getastr(max(length('载入存档'),max(length('新建存档'),length('返回')))+6),1);
      choose:=chooseone('载入存档'+ln+
                        '新建存档'+ln+
                        '返回');
      clrscr;
      if choose=3 then break;
      clrscr;
      case choose of
        1:begin
            gotoxy_mid('Loading...',1);tb(0);tc(7);write('Loading...');
            findfiles('save/*.savedata',res);
            s:='';
            for i:=1 to res.filenum do
              s:=s+copy(res.filenam[i],1,length(res.filenam[i])-9)+ln;
            if length(s)=0 then
            begin
              gotoxy_mid('无存档',2);tc(4);tb(0);write('无存档');
              delay(500);
              continue;
            end;
            s:=s+'返回';
            clrscr;
            gotoxy_mid('存档列表',1);tb(0);tc(15);write('存档列表');
            gotoxy_mid(getastr(max(res.maxlen-9,length('返回'))+6),2);choose:=chooseone(s);
            if choose=res.filenum+1 then continue;
            s:=res.filenam[choose];
            fileread(s);
            i:=0;
            repeat
              clrscr;
              gotoxy_mid('请输入密码',1);tb(0);tc(7);write('请输入密码');
              gotoxy_mid(getastr(maxlengthofpassword),2);inputpassword(s);
              if s=profile.password then break;
              gotoxy_mid('密码错误',3);tb(0);tc(4);write('密码错误');
              inc(i);
              delay(300);
            until i=5;
            if i=5 then continue;
            gotoxy_mid('登录成功',3);tb(0);tc(12);write('登录成功');
            delay(500);
          end;//end case 1
        2:begin
            i:=0;
            repeat
              clrscr;
              gotoxy_mid('账号名:',1);tb(0);tc(15);write('账号名:');
              cursoron;
              gotoxy_mid(getastr(maxlengthofusernam),2);tb(0);tc(7);readln(s);
              cursoroff;
              if length(s) in [minlengthofusernam..maxlengthofusernam]=false then continue;
              if fsearch('save\'+s+'.savedata','\')='' then break;
              gotoxy_mid('该账号已存在',3);    tb(0);tc(4); write('该账号已存在');
              delay(75);
              gotoxy_mid('是否覆盖该账号',4);  tb(0);tc(15);write('是否覆盖该账号');
              delay(75);
              gotoxy_mid(getastr(max(length('否'),length('是'))+6),5);tb(0);tc(7);choose:=chooseone('否'+ln+
                                                                                                  '是');
              if choose=2 then break;
              inc(i);
              delay(300);
            until i=5;
            if i=5 then continue;
            with profile do
            begin
              filenam:=s+'.savedata';
              usernam:=s;
              repeat
                i:=0;
                repeat
                  clrscr;
                  gotoxy_mid('请输入密码',1);  tc(15);tb(0);  write('请输入密码');
                  gotoxy_mid(getastr(maxlengthofpassword),2);tc(7);tb(0);inputpassword(s);
                  if length(s) in [minlengthofpassword..maxlengthofpassword] then break;
                  gotoxy_mid('密码过短',3);    tc(4);tb(0);   write('密码过短');delay(300);
                  inc(i);
                until i=5;
                if i=5 then break;
                clrscr;
                gotoxy_mid('请再次输入密码',1);  tc(15);tb(0);  write('请再次输入密码');
                gotoxy_mid(getastr(maxlengthofpassword),2);tc(7);tb(0);inputpassword(password);
                if password=s then break;
                gotoxy_mid('密码错误',3);        tc(4);tb(0);   write('密码错误');delay(500);
              until false;
              if i=5 then continue;

              money:=1000;
              ammo[2]:=100;
              ammo[3]:=10;
              prop[1]:=10;
            end;//end with
            logged:=true;
            clrscr;
            gotoxy_mid('Loading...',1);      tb(0);tc(7);   write('Loading...');
            save;
            clrscr;
            gotoxy_mid('创建新存档成功',1);  tb(0);tc(12);  write('创建新存档成功');
            delay(700);
          end;//end case 1
      end;//end case
      exit(true);
    until false;
    if mode=1 then exit(false);
  until false;//=============================================================
end;

procedure init_program;
var i,j,n,t:longint;
    s:ansistring;

   procedure levelread(s:string;var mm:Tlevel);
   var i,j:longint;
       wjin:text;
   begin
     with mm do
     begin
       for i:=length(s)-10 downto 1 do
        if s[i]='\' then break;
       filenam:=copy(s,i+1,length(s)-i-10);
       ismainlevel:=false;
       if copy(s,1,i)='bin\' then ismainlevel:=true;

       assign(wjin,s);
       reset(wjin);
       readln(wjin,s);delete(s,1,pos('=',s));nam:=s;
       for i:=1 to maxx do
       begin
         for j:=1 to maxy do
          with mm.map[i,j] do
          begin
            read(wjin,id,hard,maxhard);
            if eoln(wjin)=false then read(wjin,fx,fj);
            readln(wjin);
          end;
       end;
readln(wjin);
       readln(wjin,playerflagmaxhp,aiflagmaxhp);
       readln(wjin,playerspawnpointnum);
       for i:=1 to playerspawnpointnum do
        with playerspawnpoint[i] do
         readln(wjin,x,y);

       for i:=1 to maxoccup do
         read(wjin,aispawnpointnum[i]);readln(wjin);
       for i:=1 to maxoccup do
       begin
         for j:=1 to aispawnpointnum[i] do
          with aispawnpoint[i,j] do
           readln(wjin,x,y);
       end;
       aispawnpointnum[0]:=playerspawnpointnum;
       for i:=1 to playerspawnpointnum do aispawnpoint[0][i]:=playerspawnpoint[i];
readln(wjin);
       readln(wjin,startspawntick);
       for i:=1 to maxoccup do
         readln(wjin,startspawnainum[i]);
       for i:=1 to maxoccup do
         readln(wjin,spawnprobability[i]);
       close(wjin);
     end;//end with
   end;

   procedure init_save;
   var i,j:longint;
   begin
     with profile do
     begin
       password:='';
       usernam:='';
       filenam:='';
       fillchar(ammo,sizeof(ammo),0);
       fillchar(prop,sizeof(prop),0);
       fillchar(levelunlock,sizeof(levelunlock),false);
       levelunlock[1]:=true;
       levelunlock[2]:=true;
       occupown[0]:=true;
       money:=1000;
       ammo[2]:=100;
       ammo[3]:=10;
       prop[1]:=10;
       fillchar(levelfinish,sizeof(levelfinish),false);
     end;
   end;

   procedure levelread(path:string);
   var r:findfilesres;
       i,j,n:longint;
   begin
     gotoxy(1,1);clreol;
     gotoxy_mid('Finding Level in Path "'+path+'"...',1);tc(7);write('Finding Level in Path "',path,'"...');
     findfiles(path+'*.leveldata',r);
     with r do
     begin
       for i:=1 to filenum do
       begin
         inc(levelnum);
         gotoxy(1,1);clreol;
         gotoxy_mid('Reading Level "'+filenam[i]+'"...',1);tc(7);write('Reading Level"',filenam[i],'"...');
         levelread(path+filenam[i],level[levelnum]);
       end;
       maxlevelnamlen:=max(maxlevelnamlen,r.maxlen-10);
       maxlevelnamlen:=min(maxlevelnamlen,setting.smaxx-6);
     end;//end with
   end;

begin
  //createwin(800,600);
  //settitle('坦克大战');
  cursoroff;
  randomize;
  checkbreak:=false;
  gaming:=false;
  logged:=false;
  setting.smaxx:=windmaxx;
  setting.smaxy:=windmaxy;
  print_program_info;
  dec(windmaxy,3);

  for i:=1 to maxplayer do
   with player[i] do
   begin
     xu:=-i;
     nam:='Player';
   end;//end with
  for i:=1 to maxai do
   with ai[i] do
   begin
     xu:=i;
     nam:='Ai';
   end;
  with noai do
  begin
    xu:=-1;
  end;//end with

  if directoryexists('bin')        =false then mkdir('bin');
  if directoryexists('save')       =false then mkdir('save');
  if directoryexists('level')      =false then mkdir('level');
  if directoryexists('screenshot') =false then mkdir('screenshot');

  gotoxy(1,1);clreol;gotoxy_mid('Reading "+SettingFileNam+"...',1);tc(7);write('Reading "',SettingFileNam,'"...');
  with setting do
  begin
    if fsearch(SettingFileNam,'\')<>'' then
    begin
      assign(wjin,SettingFileNam);
      reset(wjin);
      readln(wjin,s);while (s[1]<>'=') and (length(s)<>0) do delete(s,1,1);delete(s,1,1);val(s,gamehard,t);if (t<>0) or (gamehard>maxgamehard) or (gamehard<0) then gamehard:=1;
      readln(wjin,s);while (s[1]<>'=') and (length(s)<>0) do delete(s,1,1);delete(s,1,1);val(s,gamemode,t);if (t<>0) or (gamemode>maxgamemode) or (gamehard<0) then gamemode:=0;
      if gamemode=1 then god:=true;
      if eof(wjin)=false then
      begin
        readln(wjin,s);while (s[1]<>'=') and (length(s)<>0) do delete(s,1,1);delete(s,1,1);val(s,playernum,t);if (t<>0) or (playernum>maxplayer) or (playernum<0) then playernum:=1;
        if (eof(wjin)=false) then
        begin
          readln(wjin,s);while (s[1]<>'=') and (length(s)<>0) do delete(s,1,1);delete(s,1,1);val(s,musicon,t);if (t<>0) or (musicon>1) or (musicon<0) then musicon:=1;
        end;
      end
       else begin
         playernum:=gamemode;
         musicon:=1;
         gamemode:=0;
       end;
      close(wjin)
    end//end if fsearch(SettingFileNam,'\')<>''
     else begin
       gamehard:=1;
       gamemode:=0;
       playernum:=1;
       musicon:=1;
     end;
    assign(wjout,SettingFileNam);
    rewrite(wjout);
    writeln(wjout,'GameHard=',gamehard);
    writeln(wjout,'GameMode=',gamemode);
    writeln(wjout,'Player=',playernum);
    writeln(wjout,'Music=',musicon);
    close(wjout);
  end;//end with
  gotoxy(1,1);clreol;

  levelnum:=0;
  maxlevelnamlen:=0;
  levelread('bin\');
  levelread('level\');
 { for i:=1 to levelnum do
  begin
    n:=(maxlevelnamlen-length(level[i].filenam)) div 2;
    for j:=1 to n do
      level[i].filenam:=' '+level[i].filenam;
  end;           }
  init_save;
end;

procedure init_prop(dx,dy,did,dwhos:longint);
var i,n,t:longint;
begin
  case did of
    1:begin
        with mm.map[dx,dy] do
        begin
          id:=11;
          fj:=dwhos;
          fx:=0;
          maxhard:=blockmaxhard[id];
          hard:=maxhard;
        end;
        print_auto(dx,dy);
      end;
  end;//end case
end;

procedure init_tank(var who:Ttank;d_id,docc:longint; _pos:Tpos);
const didnotuse=-1000;
var i,j,n,t,w:longint;
    b:boolean;
    spawn:Tpos;
begin
  with who do
  begin
    case d_id of
      0:begin
          b:=false;
          for j:=1 to mm.playerspawnpointnum do
           if can(mm.playerspawnpoint[j],1) then b:=true;
          if b=false then exit;

          lmt.tick:=didnotuse;
          with skill do
          begin
            start.tick:=didnotuse;
            stop.tick:=didnotuse;
            use.tick:=didnotuse;
          end;

          repeat
            spawn:=mm.playerspawnpoint[random(mm.playerspawnpointnum)+1];
          until can(spawn.x,spawn.y,1);
          zb:=spawn;
          unbreakble:=true;
          for i:=1 to maxammotype do lft[i].tick:=0;
        end;
      1:begin

          maxlives:=1;
          lives:=maxlives;

          for i:=1 to maxammotype do
          begin
            gt(lft[i]);
            lft[i].tick:=tick+50-setting.gamehard*20;
          end;
          if docc in canbfsoccup then lmt.tick:=tick+50-setting.gamehard*20
           else lmt.tick:=didnotuse;
          ljn:=0;

          zb:=_pos;
        end;
    end;//end case
    living:=true;
    skillusing:=false;
    fx:=0;
    id:=d_id;
    occup:=docc;
    gt(lmt);
    gt(lst);
    speed:=tankspeed[d_id,docc];
    maxhp:=tankmaxhp[d_id,docc];
    hp:=maxhp;
    hitbox[zb.x][zb.y]:=tick*2;
    print_tank(who);
  end; //end with
end;
procedure init_tank(var who:Ttank;d_id,docc:longint);
var pos:Tpos;
begin
  pos.x:=-1;
  pos.y:=-1;
  init_tank(who,d_id,docc,pos);
end;

procedure init_mob(nn,dx,dy,dfx,d_id,dwhos:longint);
var i,j,n,w:longint;
begin
  if (dx=-1) or (dy=-1) then exit;
  with mob[nn] do
  begin
    id:=d_id;fx:=dfx;whos:=dwhos;
    nam:='Mob';
    speed:=mobspeed[d_id];
    zb.x:=dx;zb.y:=dy;
    living:=true;
    rfx:=false;
    gt(lmt);//inc(lmt.tick);
    gt(lst);
    maxhp:=mobmaxhp[d_id];
    hp:=maxhp;
  //  work_mob;
    if living=false then exit;

    //print(zb.x,zb.y,-1,15,mobchar[id,fx]);
   { if nn>t then
    begin
      t:=nn;
      gotoxy(1,1);write(t);
    end;       }
  end;
end;

function new_mob(dx,dy,dfx,d_id,dwhos:longint):longint;
var i,j,n,t,w:longint;
begin
  if inmap(dx,dy)=false then exit(-1);
  if d_id=0 then exit;
  for i:=1 to maxmob do
   with mob[i] do
    if living=false then
    begin
   //   if (id in [0]) and (tick-ldt.tick<=TNTexplodelast) then continue;
      init_mob(i,dx,dy,dfx,d_id,dwhos);
      exit(i);
    end;
  exit(-1);
end;

function new_ai(d_id,docc:longint;spawn:Tpos):longint;
var i,j,n,t,w:longint;
    b:boolean;
begin
  if (spawn.x=-1) then
  begin
    b:=false;
    for j:=1 to mm.aispawnpointnum[docc] do
     if can(mm.aispawnpoint[docc,j],1) then b:=true;
    if b=false then exit(-1);
    repeat
      spawn:=mm.aispawnpoint[docc,random(mm.aispawnpointnum[docc])+1];
      for j:=1 to maxplayer do
       if player[j].living then
        if ju(spawn,player[j].zb)<=5 then exit;
    until can(spawn.x,spawn.y,1);
  end;
  for i:=1 to maxai do
   with ai[i] do
    if living=false then
    begin
      if tick-ldt.tick<=dyinglast then continue;
      init_tank(ai[i],d_id,docc,spawn);
      if (docc=0) and (ai[i].living) then bosstime:=true;
      exit(i);
    end;
  exit(-1);
end;  
function new_ai(d_id,docc:longint):longint;
var spawn:Tpos;
begin
  spawn.x:=-1;
  spawn.y:=-1;
  exit(new_ai(d_id,docc,spawn));
end;

procedure init_game;
var i,j,n,t,w:longint;

   procedure p1(var x:Tscreen);
   var i:longint;
   begin
     with x do
     begin
       ch:=chr(0);
       col:=0;bg:=0;
     end;
   end;

begin
  Tick:=0;
  gameendtick:=-1;
  clrscr;
  t:=(setting.smaxx-80) div 2;
  windminx:=t+1;windmaxx:=80+t;
  t:=(setting.smaxy-25) div 2;
  windminy:=t+1;windmaxy:=25+t;
  fillchar(hitbox,sizeof(hitbox),0);
///////////////Clear Tank///////////////
  for i:=1 to maxai do
    clear_tank(ai[i]);
  for i:=1 to setting.playernum do
    clear_tank(player[i]);
  for i:=1 to maxmob do
    clear_mob(mob[i]);

  for i:=1 to maxoccup do
   for j:=1 to mm.startspawnainum[i] do
     new_ai(1,i);
  if (mm.nam='What''s that?!') and ismainlevel then
  with mm do
  begin
    aispawnpointnum[0]:=4;
    aispawnpoint[0][1].x:=29; aispawnpoint[0][1].y:=4;
    aispawnpoint[0][2].x:=29; aispawnpoint[0][2].y:=5;
    aispawnpoint[0][3].x:=30; aispawnpoint[0][3].y:=4;
    aispawnpoint[0][4].x:=30; aispawnpoint[0][4].y:=5;
    new_ai(1,0);
    aispawnpointnum[0]:=playerspawnpointnum;
    for i:=1 to playerspawnpointnum do aispawnpoint[0][i]:=playerspawnpoint[i];
  end;
  for i:=1 to maxx do
   for j:=1 to maxy do
   begin
     p1(oldsc[i,j]);
     p1(newsc[i,j]);
   end;

  with playerflag do
  begin
    zb.x:=findblock(4,0).x;
    zb.y:=findblock(4,0).y;
    id:=4;
    maxhp:=mm.playerflagmaxhp;
    hp:=maxhp;
  end;
  with aiflag do
  begin
    zb.x:=findblock(5,0).x;
    zb.y:=findblock(5,0).y;
    id:=5;
    maxhp:=mm.aiflagmaxhp;
    hp:=maxhp;
  end;

  livingnum:=0;
  gaming:=true;
  gamewin:=false;
  gamelose:=false;
  bosstime:=false; 
  cmdused:=false;
  cmdmemcnt:=0;

  for i:=1 to setting.playernum do
    init_tank(player[i],0,player[i].occup);
  playerflag.lthp:=-1;aiflag.lthp:=-1;
  for i:=1 to maxplayer do
   with player[i] do
   begin
     lthp[i]:=-1;
     ammotype:=1;
     maxlives:=playermaxlives;
     lives:=maxlives;
   end;
  fillchar(ltl,sizeof(ltl),255);
///////////////Clear Tips///////////////
  with tip do
  begin
    twn:=0;
    for i:=1 to maxtip do
     with tipwaiting[i] do
     begin
       st:='';
       color:=7;
       gt(starttime);
       lastfor:=0;
     end;//end with&for
    gt(lasttipendtime);
  end;

  fillchar(killnum,sizeof(killnum),0);
  fillchar(dietimes,sizeof(dietimes),0);
end;

procedure work_mob(i:longint);
const block8harm:array[0..5] of longint=(15,9,6,4,2,1);
      number:array[0..9] of string=('0','1','2','3','4','5','6','7','8','9');
var j,k,n,t,w,xx,yy,ox,oy:longint;
    ain:longint;

   procedure workblock8(var who:Tmob);
   var h,i,j,n,t:longint;
   begin
     with who do
     begin
       if (rfx=false) then explode(zb.x,zb.y,TNTexplodehard,whos,0)
       else explode(zb.x,zb.y,TNTexplodehard,whos,1);
     end;
   end;

   procedure workmob3(var who:Tmob);
   var h,i,j,n,t:longint;
   begin
     with who do
     begin
       if (rfx=false) then explode(zb.x,zb.y,mob3explodehard,whos,0)
       else explode(zb.x,zb.y,mob3explodehard,whos,1);
     end;
   end;

   procedure hurttank(var mob:Tmob;mode:longint);
   var n,h:longint;
   begin
     with mob do
     begin
       h:=mobharm[id];
       n:=whichtank(zb.x,zb.y);
       if n=0 then exit;
       if (whos=n) and (rfx=false) then exit;
       if mode=1 then
       begin
         if n>0 then begin if ai[n].lmt.tick<>tick-1 then exit;end
          else if n<0 then if player[-n].lmt.tick<>tick-1 then exit;
       end;//end if
       if (rfx) or (whos<>n) then hurt_tank(n,h,getmobharmtype(id),whos);
       dec(hp);
       if n>0 then
        if ai[n].occup in [0,2] then hp:=0;
       if n<0 then
        if player[-n].occup in [2] then hp:=0;
     end;
   end;

   procedure checking(nn:longint);
   var i,j,n,h:longint;
   begin
     with mob[nn] do
     begin
       h:=mobharm[id];

       n:=mm.map[zb.x,zb.y].id;
       if n in cangoblock_mob then
       begin
         if n in donotprintblock_mob=false then print_mob(mob[nn])
          else print_block(zb);
       end
       else if n in candestroyblock[getmobharmtype(id)] then
       begin
         if (id<>2) or (mm.map[zb.x,zb.y].hard<=h) then dec(hp,mm.map[zb.x,zb.y].hard)
          else hp:=0;
         destroy(zb.x,zb.y,zb.x,zb.y,h,getmobharmtype(id));
       end
        else hp:=0;
       if n in cannotpierceblock then
       begin
         hp:=0;
       end;
       hurttank(mob[nn],0);
       if hp<=0 then living:=false;
     end;//end with
   end;

begin
  with mob[i] do
   if id=4 then
   begin
     if living=false then exit;
     if lst.tick=tick then exit;
     if tick-lst.tick<=TNTexplodelast then
     repeat
       if tick-lmt.tick<speed then break;
       if fx=-1 then break;
       gt(lmt);
       xx:=zb.x+gox[fx];yy:=zb.y+goy[fx];
       ox:=zb.x;oy:=zb.y;
       if inmap(xx,yy) then
        if (whichtank(xx,yy)=0) and ((mm.map[xx,yy].id in cangoblock_mob)) then
       begin
         zb.x:=xx;
         zb.y:=yy;
         print_auto(ox,oy);
         if ((tick-lst.tick) mod 3=0) and (random(2)=0) then speed:=round(speed*(system.random*1.5+0.5));
         if (speed<=0) and (random(7)<=1) then inc(speed);
       end
        else speed:=maxlongint;
     until true;
     if tick-lst.tick>TNTexplodelast then
     begin
       living:=false;
     end;
     print_auto(zb);
     if living=false then
      workblock8(mob[i]);
   end
   else if living then
   begin
     if inmap(zb)=false then living:=false;
     if living=false then exit;
     t:=tick-lmt.tick;
     if t>=speed then
     repeat
       hurttank(mob[i],1);
       if living=false then break;
       gt(lmt);
       ox:=zb.x;oy:=zb.y;
       inc(zb.x,gox[fx]);
       inc(zb.y,goy[fx]);
       print_auto(ox,oy);
       if inmap(zb)=false then
       begin
         living:=false;
         continue;
       end;
      until true;//end if t>=speed
     if inmap(zb) then
     begin
       checking(i);
       print_auto(zb);
     end;
     if (living=false) and (id=3) then workmob3(mob[i]);
   end; //end with
end;
procedure work_mob;
var i:longint;
begin
  for i:=1 to maxmob do work_mob(i);
  checkdie;
end;

procedure work_ai;
const occup5harm:array[0..3] of longint=(10,5,2,1);
      maxtrytime=50;
      maxdeep=50;
var i,j,k,n,t,w,xx,yy,ox,oy,trytime,safede,ain:longint;
    dosth,b,bfsok,playeralive:boolean;
    lj:Tlj;
    gotowhere:array[1..maxblock] of Tpos;
    cannotgo:array[0..maxoccup,1..maxx,1..maxy] of boolean;
    gwn:longint;
    bb:array[-1..3] of boolean;

   function firesafe(ain,x,y,de,ju:longint):boolean;
   var i,j,n,t:longint;
   begin
     i:=0;
     t:=1;
     repeat
       inc(i);
       dec(ju);
       inc(x,gox[de]);
       inc(y,goy[de]);
       if inmap(x,y)=false then break;
       if mm.map[x,y].id in [5,8] then exit(false);

       if mm.map[x,y].hard>=0 then dec(t,mm.map[x,y].hard);
       if (t<=0) and ((ju<0) or (ju>1000)) then break; // 子弹经过后,才被拦截
       if ju<=0 then
        if ai[ain].occup in [0,2,3,4] then exit(true);//无视玩家后面的状况

       if (ju>=0) and (mm.map[x,y].id in [2,14,15]) then exit(false);//与敌方之间有xxx
       if (mm.map[x,y].id=16) and (mm.map[x,y].fx<>de) then exit(false);
       if (mm.map[x,y].id=17) and (mm.map[x,y].fx<>(de+2) mod maxfx) then exit(false);

       n:=whichtank(x,y);
       if n>0 then
       repeat
         if (ai[n].id<>0) and (ai[n].occup in [2,3]) and (ai[ain].occup in [1]) then exit(false);//前方的自己人不会躲避
       //  if (ai[n].id<>0) and (i=1) and (ai[ain].id<>2) then exit(false);  //前面紧挨着自己人
       until true;
     until false;
     exit(true);
   end;

   function heresafe(x,y,de,view:longint):boolean;
   var i,j,n,t,xx,yy,ox,oy:longint;
       b:boolean;
   begin
     ox:=x;oy:=y;
     while inmap(x,y) and (mm.map[x,y].id<>2) do
     begin
       inc(x,gox[de]);
       inc(y,goy[de]);
       n:=whichmob(x,y);
       if n<>-1 then
       begin
         with mob[n] do
          if fx=(de+2) mod 4 then
          repeat
            b:=true;
            xx:=x;yy:=y;
            t:=1;//mob_id[1].maxhp
            repeat
              xx:=xx+gox[(de+2) mod 4];
              yy:=yy+goy[(de+2) mod 4];
              dec(t,mm.map[xx,yy].hard);
              if mm.map[xx,yy].hard=-1 then dec(t);
              if (t<=0) or (mm.map[xx,yy].id=2) then
              begin
                b:=false;
                break;
              end;
            until (xx=ox) and (yy=oy);
            if b then exit(false);
          until true;  //end if fx=(de+2) mod 4
       end;   //end if n<>-1
       dec(view);
       if (view=0) then break;;
     end;
     exit(true);
   end;

   procedure readyfire(ain,de,v:longint);
   var i,j,n,t:longint;
   begin
     with ai[ain] do
     begin
       for i:=1 to maxammotype do
        if (tick-lft[i].tick>=firespeed[id,occup,i]) and (firespeed[id,occup,i]<>maxlongint) then
        begin
          if firesafe(ain,zb.x,zb.y,de,v) then
          begin
            fire(ai[ain],de,i);
            dosth:=true;
          end;
        end;
     end;//end with
   end;

   procedure workoccup5(ain:longint);
   var i,j,n,t,x,y,h:longint;
   begin
     with ai[ain] do
       explode(zb,aioccup5explodehard,ain,1);
   end;

   function finishgoing(x,y:longint):boolean;
   var i:longint;
   begin
     for i:=1 to gwn do
      if (gotowhere[i].x=x) and (gotowhere[i].y=y) then exit(true);
     exit(false);
   end;

   function bfs(x,y,ain:longint):boolean;
   var i,n,xx,yy,cnt:longint;
       q:array[1..2,1..maxqueue] of record
                                      x,y,pre:longint;
                                    end;
       head,tail:array[1..2] of longint;
       went:array[1..maxx,1..maxy] of longint;

      function finish(n,x,y:longint):longint;
      var i:longint;
      begin
        if n=1 then n:=2
         else n:=1;
        for i:=1 to tail[n] do
         if (x=q[n,i].x) and (y=q[n,i].y) then exit(i);
        exit(0);
      end;

      function kz(n:longint;var head,tail:longint):longint;
      var i,j,ii,t,tot,xx,yy:longint;
          b:array[0..3] of boolean;

         procedure print(n,d:longint);
         begin
           if n=1 then
            if q[n,d].pre<>0 then print(n,q[n,d].pre);
           inc(tot);
           ai[ain].lj.zb[tot].x:=q[n,d].x;
           ai[ain].lj.zb[tot].y:=q[n,d].y;
           if n=2 then
            if q[n,d].pre<>0 then print(n,q[n,d].pre);
         end;

      begin
        inc(head);
        fillchar(b,sizeof(b),true);
        for ii:=0 to 3 do
        begin
          repeat
            i:=random(4);
          until b[i];
          b[i]:=false;
          xx:=q[n,head].x+gox[i];
          yy:=q[n,head].y+goy[i];
          if ai[ain].occup in [4,5] then if (ju(x,y,xx,yy)>(setting.gamehard+1)*16) then continue;
          if can(xx,yy,1)  and (cannotgo[ai[ain].occup,xx,yy]=false) then
          repeat
            if n=1 then if went[xx,yy]>0 then break;
            if n=2 then if went[xx,yy]<0 then break;
            inc(tail);
            q[n,tail].x:=xx;q[n,tail].y:=yy;q[n,tail].pre:=head;
            t:=went[xx,yy];
            if ((n=1) and (t<0)) or ((n=2) and (t>0)) then
            begin
              tot:=0;
              if n=2 then print(n mod 2+1,abs(t));
              print(n,tail);dec(tot);
              if n=1 then  print(n mod 2+1,abs(t));
              ai[ain].lj.tot:=tot;
              ai[ain].lj.zb[tot+1].x:=-1;
              exit(1);
            end;
            if n=1 then went[xx,yy]:=tail;
            if n=2 then went[xx,yy]:=-tail;
          until true;//end if can
        end;// end for
        exit(0);
      end;

   begin
     fillchar(went,sizeof(went),false);
     head[1]:=0;head[2]:=0;
     tail[1]:=1;tail[2]:=gwn;
     went[x,y]:=1;
     q[1,1].x:=x;q[1,1].y:=y;q[1,1].pre:=0;
     for i:=1 to gwn do
      with q[2,i] do
      begin
        x:=gotowhere[i].x;
        y:=gotowhere[i].y;
        went[x,y]:=-i;
        pre:=0;
      end;
     while true do
     begin
       inc(bfscnt);
       if (head[1]>=tail[1]) or (head[2]>=tail[2]) then
       begin
         for xx:=1 to maxx do
          for yy:=1 to maxy do
          begin
            if (head[1]>=tail[1]) and (went[xx,yy]>0) then cannotgo[ai[ain].occup,xx,yy]:=true;
            if (head[2]>=tail[2]) and (went[xx,yy]<0) then cannotgo[ai[ain].occup,xx,yy]:=true;
          end;
         exit(false);
       end;
       if tail[1]<tail[2] then n:=kz(1,head[1],tail[1])
        else n:=kz(2,head[2],tail[2]);
       if n=1 then exit(true);
     end; //end while
   end;//end bfs

begin
  fillchar(cannotgo,sizeof(cannotgo),false);
  bfscnt:=0;
  for i:=1 to maxai do
   with ai[i] do
   begin
     if living then
     begin
       repeat
         dosth:=false;
         ain:=i;

         //TRY GO
         if occup in [0,3,4,5] then
         repeat
           if bfscnt>100000 then break;
           playeralive:=false;for j:=1 to maxplayer do if player[j].living then playeralive:=true;  
           t:=maxlongint;mubiao:=0;
           for j:=1 to setting.playernum do
            with player[j] do
             if living then
              if (ju(zb,ai[ain].zb)<t) and (ju(zb,ai[ain].zb)<=(setting.gamehard+1)*16) then
              begin
                t:=ju(zb,ai[ain].zb);
                ai[ain].mubiao:=j;
              end;
           if (occup in [4,5]) and (mubiao=0) then break;

           fillchar(gotowhere,sizeof(gotowhere),0);
           if occup in [4,5] then
           begin
             if (tick-player[ai[ain].mubiao].lmt.tick<=5-setting.gamehard) then break;
           end;
          // gotoxy(1,1); tc(random(16)); write(playeralive,' ');
           gwn:=0;
           if (occup=3) or ((occup=0) and ((playeralive=false) or (mubiao=0))) then
           begin
             for j:=0 to 3 do
             begin
               xx:=playerflag.zb.x;
               yy:=playerflag.zb.y;
               while inmap(xx,yy) do
               begin
                 if mm.map[xx,yy].id in [2,5,8,14,15] then break;
                 if (mm.map[xx,yy].id=16) and (mm.map[xx,yy].fx<>(j+2) mod maxfx) then break;
                 if (mm.map[xx,yy].id=17) and (mm.map[xx,yy].fx<>j) then break;
           {      t:=whichtank(xx,yy);
                 if (t>0) and (t<>ain) then
                  if ai[t].occup=3 then break;    }
                 inc(xx,gox[j]);
                 inc(yy,goy[j]);
                 if can(xx,yy,1) or ((ai[ain].zb.x=xx) and (ai[ain].zb.y=yy)) then
                 begin
                   inc(gwn);
                   gotowhere[gwn].x:=xx;
                   gotowhere[gwn].y:=yy;
                 end;
               end;//end while
             end;//end for
           end//end 3
         else if (occup=4) or (occup=0) then
         begin
           if playeralive=false then break;
           for j:=0 to 3 do
           begin
             xx:=player[mubiao].zb.x;
             yy:=player[mubiao].zb.y;
             while inmap(xx,yy) do
             begin
               if mm.map[xx,yy].id in [2,5,8,14,15] then break;
               if (mm.map[xx,yy].id=16) and (mm.map[xx,yy].fx<>(j+2) mod maxfx) then break;
               if (mm.map[xx,yy].id=17) and (mm.map[xx,yy].fx<>j) then break;
              { t:=whichtank(xx,yy);
               if (t<>-1) and (t<>ain) then
                if ai[t].occup=4 then break;  }
               inc(xx,gox[j]);
               inc(yy,goy[j]);
               if can(xx,yy,1) or ((ai[ain].zb.x=xx) and (ai[ain].zb.y=yy)) then
               begin
                 inc(gwn);
                 gotowhere[gwn].x:=xx;
                 gotowhere[gwn].y:=yy;
               end;
             end;//end while
           end;//end for
         end //end 4
         else if (occup=5) then
         begin
           if playeralive=false then break;

            for j:=player[mubiao].zb.x-1 to player[mubiao].zb.x+1 do
             for k:=player[mubiao].zb.y-1 to player[mubiao].zb.y+1 do
              if can(j,k,1) or ((j=zb.x) and (k=zb.y)) then
              repeat
                if setting.gamehard>=2 then
                 if ju(j,k,player[mubiao].zb)=2 then break;
                inc(gwn);
                gotowhere[gwn].x:=j;
                gotowhere[gwn].y:=k;
              until true;//end for
         end;  //end case 5
           if tick-lmt.tick<tankspeed[id,occup] then break;
           if finishgoing(zb.x,zb.y) then break;
           bfsok:=false;
           repeat
             if ai[15+random(3)].living then
              if (tick-lst.tick-ain) mod tankspeed[0,1]<>0 then break;
            // if (tick-lst.tick) mod 5<>0 then break;
             {if occup in [4,5] then
              if (player[mubiao].lmt.tick<>tick-1) and (ljn<>0) then break;      }
             bfsok:=bfs(zb.x,zb.y,ain);
             if bfsok=false then break;
             ljn:=1;
           until true;
           {if (tick-lst.tick-ain) mod tankspeed[0,1]<>0 then
            if ai[20+random(3)].living=false then break;}
           if ljn=0 then break;
           if can(lj.zb[ljn+1],1)=false then break;
           if ju(lj.zb[ljn+1],zb)<>1 then break;
           {if ljn=lj.tot+1 then
           begin
             ljn:=lj.tot;
             break;
           end;     }
           inc(ljn);
           move(ai[ain],getfx(zb,lj.zb[ljn]));
           dosth:=true;
         until true;//end TRY GO

         //CHECK SAFE               
         if occup in [0,1,3,4,5] then
         repeat
           case setting.gamehard of
             0:if occup in [0]=false then break;
             1:if occup in [0,1]=false then break;
             2:if occup in [0,1,4]=false then break;
             3:if occup in [0,1,3,4,5]=false then break;
           end;
           if (occup=1) and (system.random<=1/(setting.gamehard+1)) then break;
           trytime:=0;safede:=0;j:=-1;
           repeat //CHECK SAFE
              if tick-lmt.tick<tankspeed[id,occup] then break;
              inc(trytime);
              j:=(j+1) mod maxfx;
              if heresafe(zb.x,zb.y,j,4+setting.gamehard) then inc(safede)
               else safede:=0;
              if heresafe(zb.x,zb.y,j,4+setting.gamehard)=false then
              begin
                t:=0;
                if random(2)=0 then k:=(j+1) mod maxfx
                 else k:=(j+3) mod maxfx;
                repeat
                  inc(t);
                  xx:=zb.x+gox[k];
                  yy:=zb.y+goy[k];
                  if can(xx,yy,1) and (whichmob(xx,yy)=-1) then
                  begin
                    move(ai[ain],k);
                    dosth:=true;
                    break;
                  end;
                  k:=(k+2) mod maxfx;
                until t=2;
                t:=j;
              end;//end if heresafe(zb.x,zb.y,j,4+setting.gamehard*2)=false
           until (trytime=maxtrytime) or (safede=maxfx);
           if (trytime=maxtrytime) then
           repeat
             t:=(t+2) mod maxfx;
             if canmove(ai[ain],t) then move(ai[ain],t);
           until true;
         until true;//CHECK SAFE
         
         //RANDOM MOVE
         if occup in [0,1,3,4,5] then
         repeat
           if tick-lmt.tick<tankspeed[id,occup] then break;
           if (occup=0) and (dosth) then break;
           if (occup in [1]) then
           begin
             if (random(20)<>0) then break;
           end
            else if random(75)<>0 then break;
           if occup in [0,3,5] then
            if finishgoing(zb.x,zb.y) then break;
          b:=false;if occup in [4] then
            for j:=1 to maxplayer do
             if player[j].living then b:=true;if b then break;

           if occup in [1] then for j:=1 to maxplayer do
            if player[j].living then
             if (zb.x=player[j].zb.x) or (zb.y=player[j].zb.y) then
             begin
               b:=false;
               if player[j].zb.x=zb.x then
               begin
                 t:=abs(player[j].zb.y-zb.y);
                 if player[j].zb.y>zb.y then b:=firesafe(ain,zb.x,zb.y,2,t)
                  else b:=firesafe(ain,zb.x,zb.y,0,t);
               end
                else if player[j].zb.y=zb.y then
                begin
                  t:=abs(player[j].zb.x-zb.x);
                  if player[j].zb.x>zb.x then b:=firesafe(ain,zb.x,zb.y,1,t)
                   else b:=firesafe(ain,zb.x,zb.y,3,t);
                end;
               if b then break;
             end;//end for
           if b then break;
           k:=0;
           fillchar(bb,sizeof(bb),false);
           for k:=1 to maxfx do
           repeat
             repeat
               t:=random(4);
             until bb[t]=false;
             bb[t]:=true;
             xx:=zb.x+gox[t];yy:=zb.y+goy[t];
             if (heresafe(xx,yy,(t+1) mod 4,12)=false) or (heresafe(xx,yy,(t+3) mod 4,12)=false) then continue;
             if canmove(ai[ain],t) then
             begin
               move(ai[ain],t);
               dosth:=true;
               break;
             end;
           until true;
         until true;//end RANDOM MOVE

         //TRY ATTACK
         if occup in [0,1,2,3,4] then
          for t:=1 to 2 do
          repeat
            repeat
              j:=random(maxplayer)+1;
              if player[j].living=false then break;
              if (occup in [3]) and (t=1) then break;
              if (occup in [0]) and (random(2)=0) then break;
              if player[j].zb.x=zb.x then
              begin
                if player[j].zb.y>zb.y then readyfire(ain,2,abs(player[j].zb.y-zb.y))
                 else readyfire(ain,0,abs(player[j].zb.y-zb.y));
              end
               else if player[j].zb.y=zb.y then
               begin
                 if player[j].zb.x>zb.x then readyfire(ain,1,abs(player[j].zb.x-zb.x))
                  else readyfire(ain,3,abs(player[j].zb.x-zb.x));
               end;
            until true;
            if playerflag.zb.x=zb.x then
            begin
              if playerflag.zb.y>zb.y then readyfire(ain,2,abs(playerflag.zb.y-zb.y))
               else readyfire(ain,0,abs(playerflag.zb.y-zb.y));
            end
             else if playerflag.zb.y=zb.y then
             begin
               if playerflag.zb.x>zb.x then readyfire(ain,1,abs(playerflag.zb.x-zb.x))
                else readyfire(ain,3,abs(playerflag.zb.x-zb.x));
             end;
          until true;//end TRY ATTACK

         //RANDOM ATTACK
         if occup in [1] then
         repeat
           if random(200)<>0 then break;
           fillchar(bb,sizeof(bb),true);
           for j:=0 to 3 do
           begin
             repeat
               t:=random(4);
             until bb[t];
             bb[t]:=false;
             readyfire(ain,t,maxlongint);
             bb[-1]:=false;
             for t:=1 to maxammotype do
              if lft[t].tick=tick then bb[-1]:=true;
             if bb[-1] then break;
           end;
         until true;//end RANDOM ATTACK

         if occup in [5] then
         repeat
           if mubiao=0 then break;
           if tick-lmt.tick<trunc((1-setting.gamehard/maxgamehard)*tankspeed[id,occup]) then break;
           if finishgoing(zb.x,zb.y)=false then break;
           workoccup5(ain);
           dosth:=true;
         until true;
         if dosth then print_tank(ai[ain]);
       until true;//main
     end //end if living
      else if tick-ldt.tick<dyinglast then
      repeat
        if mm.map[zb.x,zb.y].id in [9] then break;
        if (tick-ldt.tick) mod dyingblinklast<=dyingblinklast div 2 then print_auto(zb)
         else print(zb,tankbackground[id],color(hp,maxhp),tankchar[id,occup,fx]);
      until true
       else if tick-ldt.tick=dyinglast then
       begin
         print_auto(zb);
         clear_tank(ai[i]);
       end;
   end;//end with
end;

procedure work_tip;
var i,j,n,t:longint;
begin
  with tip do
   if twn<>0 then
   repeat
     t:=tick-tipwaiting[1].starttime.tick;
     if t<tipwaiting[1].lastfor then break;

     if t=tipwaiting[1].lastfor then
     begin
       gt(lasttipendtime);
       for i:=1 to twn-1 do
         tipwaiting[i]:=tipwaiting[i+1];
       dec(twn);
     end;//end if
     if (twn=0) or (t=tipwaiting[1].lastfor) then
     begin
       clear_tip;
       break;
     end;//end if
     if tick-lasttipendtime.tick<tipbreak then break;

     with tipwaiting[1] do
       print_tip(st,color);
     gt(tipwaiting[1].starttime);
   until true; //end with
end;

procedure work_block;
const didnotuse=-1000;
var i,n,t,firebreak:longint;
    nx,ny:longint;
    changed:array[1..maxmob] of boolean;

    function getmob(x,y:longint):longint;
    var i,n:longint;
    begin
      n:=-1;
      for i:=1 to maxmob do
       if (mob[i].living) and (mob[i].zb.x=x) and (mob[i].zb.y=y) and (changed[i]=false) then
       begin
         n:=i;
         changed[i]:=true;
         break;
       end;
      exit(n);
    end;

    procedure wm(n:longint);
    begin
      with mob[n] do
      begin
        if id=4 then speed:=maxlongint
         else if (id<>2) or (mm.map[nx,ny].hard<=mobharm[id]) then dec(hp,mm.map[nx,ny].hard)
          else hp:=0;
        destroy(nx,ny,nx,ny,mobharm[id],getmobharmtype(id));
        work_mob(n);
      end;//end with
    end;

begin
  fillchar(changed,sizeof(changed),false);
  for nx:=1 to maxx do
   for ny:=1 to maxy do
    with mm.map[nx,ny] do
     case id of
       10:begin
         case fj of
           1..4:firebreak:=block10firebreak[fj];
           else firebreak:=maxlongint;
         end;
         if tick-lrt.tick>=firebreak then
         begin
           new_mob(nx+gox[fx],ny+goy[fx],fx,fj,0);
           gt(lrt);
           if fj in [4]=false then
            if random(2)=0 then inc(lrt.tick,random(3)-1);
         end;
       end;//end case 10
       11:repeat
         n:=whichtank(nx,ny);
         if n=0 then
         begin
           lrt.tick:=didnotuse;
           break;
         end;
         if lrt.tick=didnotuse then gt(lrt);
         if n=fj then break;
         if tick-lrt.tick<=block11explodewait then break;
         id:=0;
         print_block(nx,ny);
         explode(nx,ny,block11explodehard,fj,0);
       until true;//end case 11
        14:repeat
          repeat
            n:=getmob(nx,ny);
            if n=-1 then break;
            with mob[n] do
            begin
              rfx:=true;
              if (fx=(mm.map[nx,ny].fx+0) mod maxfx) or (fx=(mm.map[nx,ny].fx+1) mod maxfx) then
              begin
                wm(n);
                break;
              end;//end if
              if      fx=(mm.map[nx,ny].fx+2) mod maxfx then fx:=(mm.map[nx,ny].fx+1) mod maxfx
              else if fx=(mm.map[nx,ny].fx+3) mod maxfx then fx:=(mm.map[nx,ny].fx) mod maxfx;
              inc(zb.x,gox[fx]);
              inc(zb.y,goy[fx]);
              inc(lmt.tick);
            end;//end with
          until false;//end repeat
        until true;//end case 14
        15:repeat
          repeat
            n:=getmob(nx,ny);
            if n=-1 then break;
            with mob[n] do
            begin
              rfx:=true;
              if ((mm.map[nx,ny].fx=0) and (fx in [1,3]))
              or ((mm.map[nx,ny].fx=1) and (fx in [0,2])) then
              begin
                wm(n);
                break;
              end;//end if
              case mm.map[nx,ny].fx of
                0,1:fx:=(fx+2) mod maxfx;
                2:case fx of
                  0:fx:=3;1:fx:=2;2:fx:=1;3:fx:=0;
                end;
                3:case fx of
                  0:fx:=1;1:fx:=0;2:fx:=3;3:fx:=2;
                end;
              end;
              inc(zb.x,gox[fx]);
              inc(zb.y,goy[fx]);
              inc(lmt.tick);
            end;//end with
          until false;//end repeat
        until true;//end case 15
        16,17:repeat
          repeat
            n:=getmob(nx,ny);
            if n=-1 then break;
            with mob[n] do
            begin
              if id=4 then
               if (mm.map[nx,ny].id=17)
               or ((mm.map[nx,ny].id=16) and (fx<>mm.map[nx,ny].fx)) then
               begin
                 speed:=maxlongint;
                 inc(zb.x,gox[(fx+2) mod maxfx]);
                 inc(zb.y,goy[(fx+2) mod maxfx]);
                 if inmap(zb)=false then
                 begin
                   inc(zb.x,gox[fx]);
                   inc(zb.y,goy[fx]);
                 end;
                 continue;
               end;//end if id=4
              if ((mm.map[nx,ny].id=16) and (fx<>mm.map[nx,ny].fx))                        //是单向穿透且方向不对
              or ((mm.map[nx,ny].id=17) and (fx<>(mm.map[nx,ny].fx+2) mod maxfx)) then     //是单向破坏且方向不对
              begin
                hp:=0;
                work_mob(n);
                continue;
              end;
              if mm.map[nx,ny].id=16 then break;

              wm(n);
              destroy(nx,ny,nx,ny,mobharm[id],getmobharmtype(id));
              work_mob(n);
            end;//end with
          until false;//end repeat
        until true;//end case 16,17
     end;//end case
end;

procedure work_occupskill(var player:Ttank);
var i,j,n,t,x,y:longint;

   function firesafe(x,y,de:longint):boolean;
   var n,t:longint;
   begin
     t:=1;
     repeat
       inc(x,gox[de]);
       inc(y,goy[de]);
       if inmap(x,y)=false then break;
       if mm.map[x,y].id in [4,8] then exit(false);
       if mm.map[x,y].hard>0 then break;

       n:=whichtank(x,y);
       if n<0 then exit(false);
     until false;
     exit(true);
   end;

   procedure catchmob(x,y:longint);
   var head,tail:longint;
       fx,xx,yy,t:longint;
       q:Array[1..maxqueue] of record
                                 x,y,dis:longint;
                               end;
   begin
     head:=0;
     tail:=1;
     q[tail].x:=x;
     q[tail].y:=y;
     q[tail].dis:=0;
     repeat
       inc(head);
       with q[head] do
       repeat
         if dis>=playeroccup1skillcatchdis then break;
         for fx:=0 to maxfx-1 do
         begin
           xx:=x+gox[fx];
           yy:=y+goy[fx];
           if can(xx,yy,2)=false then continue;
           inc(tail);
           with q[tail] do
           repeat
             x:=xx;
             y:=yy;
             dis:=q[head].dis+1;
             t:=whichmob(xx,yy);
             if t=-1 then break;
             if mob[t].whos=player.xu then break;
             with mob[t] do
             begin
               whos:=player.xu;
               fx:=player.fx;
               xx:=zb.x;yy:=zb.y;
               zb:=player.zb;
               if inmap(zb.x,zb.y)=false then living:=false;
               print_auto(xx,yy);
             end;
           until true;//end with
         end;  //end for
       until true;//end with
     until head=tail;
   end;

begin
  with player do
  begin
    if living=false then exit;
    if skillusing=false then exit;
    if (god=false) and ((tick-skill.start.tick>=occupskilltime[occup,2]) or (tick-skill.stop.tick<occupskilltime[occup,1])) then
    begin
      if (tick-skill.start.tick>=occupskilltime[occup,2]) then
      begin
        gt(skill.stop);
        if (occup=2) then playmusic('music\skill2_end.wav','0');
      end;
      skillusing:=false;
      exit;
    end;
    if tick-skill.use.tick<occupskilltime[occup,3] then exit;
    if tick=skill.start.tick+1 then
    case occup of
      2:playmusic('music\skill2_start.wav','0');
    end;
    gt(skill.use);
    case occup of
      0:repeat
          for i:=1 to maxammotype do
            if canfire(player,i) then
              fire(player,fx,i);
        until true;
      1:repeat
         { for i:=1 to maxammotype do
           if canfire(player,i) then fire(player,fx,i);
          for i:=0 to maxfx-1 do
           if firesafe(zb.x,zb.y,i) then
             new_mob(zb.x,zb.y,i,playerskillfiretype[occup],xu);   }
          catchmob(zb.x,zb.y);
          if random(15)<>0 then break;
          i:=0;
          repeat
            inc(i);
            n:=random(maxai)+1;
          until ai[n].living or (i=maxai*3);
          if ai[n].living=false then break;
          if (god=false) and (profile.ammo[playerskillfiretype[occup]]<3) then break;
          if (god=false) then dec(profile.ammo[playerskillfiretype[occup]],3);
          for i:=0 to maxfx-1 do
           with ai[n].zb do
            for j:=1 to 2 do
            begin
              t:=new_mob(x+(random(2)+1)*gox[i],y+(random(2)+1)*goy[i],(i+2) mod maxfx,playerskillfiretype[occup],xu);
              if t<>-1 then
              begin
                inc(mob[t].lmt.tick,playeroccup1skillwait);
                mob[t].hp:=3;
              end;
            end;
        until true;
      2:begin
        end;
      3:repeat
          if tick=skill.start.tick+1 then
          begin
            if (god=false) and (profile.ammo[3]<5) then break;
            if (god=false) then dec(profile.ammo[3],5);
            for i:=10 to 30 do
            if (i>20) or (random(3)<>0) then
             begin
               t:=new_mob(zb.x,zb.y,fx,playerskillfiretype[occup],xu);
               if t=-1 then continue;
               mob[t].speed:=TNTexplodelast div i;
             end;
          end;
          if tick-skill.start.tick>=TNTexplodelast+1 then
          begin   
            if (god=false) and (profile.ammo[3]<5) then break;
            if (god=false) then dec(profile.ammo[3],1);
            t:=new_mob(zb.x,zb.y,fx,playerskillfiretype[occup],xu);
            if t=-1 then break;
            mob[t].speed:=random(3);
            mob[t].speed:=random(mob[t].speed);
          end;
        until true;
      4:repeat              
          if (god=false) and (profile.ammo[playerskillfiretype[occup]]<=0) then break;
          if (god=false) and ((tick mod 5)>1) then dec(profile.ammo[playerskillfiretype[occup]]);
          x:=random(maxfx)+1;
          for i:=1 to x do
          begin
            t:=random(maxfx);
            x:=new_mob(zb.x+gox[t],zb.y+goy[t],fx,playerskillfiretype[occup],xu);
            mob[x].hp:=2;
          end;
        until true;
      5:repeat
          if (god=false) and (profile.prop[1]<1) then break;
          if (god=false) then dec(profile.prop[1],1);
          explode(zb.x,zb.y,playeroccup5explodehard,xu,0);
          for i:=1 to maxfx do
          begin
            t:=random(maxfx);
            explode(zb.x+gox[t],zb.y+goy[t],playeroccup5explodehard,xu,0,1);
          end;
          if random(2)=0 then hurt_tank(player,1,1,0);
          if living=false then explode(zb,TNTexplodehard,xu,0,1);
        until true;
    end;//end case
  end;//end with
end;

procedure savescreenshot;
var wj:text;
    i,j:longint;
    c:string;
    s:ansistring;
    year,month,day,wday,hour,minute,second,s100:word;
begin
  s:='screenshot\Screenshot ';
  dos.getdate(year,month,day,wday);
  dos.gettime(hour,minute,second,s100);
  s:=s+inttostr(year)+'_'+inttostr(month)+'_'+inttostr(day)+'_'+inttostr(hour)+'_'+inttostr(minute)+'_'+inttostr(second)+'_';
  if s100<10 then s:=s+'0';
  s:=s+inttostr(s100);
  i:=0;
  if fsearch(s+c+'.screenshotdata','\')<>'' then
  repeat
    if i=maxlongint then exit;
    inc(i);
    str(i,c);
  until fsearch(s+'('+c+').screenshotdata','\')='';
  if i<>0 then s:=s+'('+c+')';
  s:=s+'.screenshotdata';
  assign(wj,s);
  rewrite(wj);
  for i:=1 to maxx do
   for j:=1 to maxy do
    with newsc[i,j] do
    begin
      writeln(wj,col,' ',bg,' ',ord(ch[1]),' ',ord(ch[2]));
    end;//end with
  close(wj);
end;

procedure print_ammo;
var i,j,ii:longint;
    s:string;
begin
  tb(0);
  for ii:=1 to setting.playernum do
   with player[ii] do
   begin
     if lamt[ii]<>ammotype then
     for i:=1 to maxammotype do oammo[ii,i]:=-255;
     i:=ammotype;

     with profile do
     begin
     // if oammo[i]=num then continue;
       oammo[ii,i]:=ammo[i];lamt[ii]:=ai[ii].ammotype;
       tc(8);if i=ammotype then tc(15);gotoxy(26,maxy+3);if ii=2 then gotoxy(wherex,wherey+1);
       write(ammonam[i],':');if i=1 then write('∞ ')else write(ammo[i]);
       str(ammo[i],s);if i=1 then s:='∞';
       for j:=1 to 3-length(s) do
         write(' ');
      end;//end with&for
   end;
end;

procedure work_command;
const startx=41;
      starty=23;
      maxlen=24;
var i,l,n,t,x,y,z,id,typ,nowmem,a,b:longint;
    s:string;
    st:array[1..100] of string;
    c:char;
    p:Tpos;
    isend,reprt:boolean;
begin           
  isend:=false;
  repeat
    tb(0); tc(7);
    cursoroff;
    gotoxy(startx,starty);
    for i:=1 to maxlen do write(' ');
    l:=0; s:='';
    nowmem:=cmdmemcnt+1;
    gotoxy(startx,starty);
    cursoron;
    repeat //start read
      c:=readkey;
      case c of
        'a'..'z',' ','-','0'..'9','A'..'Z','_':
        begin
          if (l<maxlen-1) then
          begin
            inc(l);
            s:=s+c;
            write(c);
          end;
        end;
        #8:
        begin
          if (l>0) then
          begin
            dec(l);
            delete(s,length(s),1);
            gotoxy(wherex-1,wherey);
            write(' ');              
            gotoxy(wherex-1,wherey);
          end;
        end;
        #27:
        begin
          isend:=true;
          break;
        end;
        #13:
        begin
          isend:=l=0;
          break;
        end;
        #0:
        begin
          c:=readkey;
          reprt:=false;
          case c of
            #72: //up
            begin
              if (nowmem>1) then 
              begin
                dec(nowmem); 
                reprt:=true;
              end;
            end;
            #80: //down
            begin
              if (nowmem<=cmdmemcnt) then 
              begin
                inc(nowmem); 
                reprt:=true;
              end;
            end;
            #28:    
            begin
              isend:=l=0;
              break;
            end;
          end;
          if reprt then
          begin
            cursoroff;
            tb(0); tc(7);
            gotoxy(startx,starty);
            write(cmdmem[nowmem]);
            for i:=length(cmdmem[nowmem])+1 to maxlen do write(' ');
            gotoxy(wherex-maxlen+length(cmdmem[nowmem]),wherey);
            s:=cmdmem[nowmem];
            l:=length(s);
            cursoron;
          end;
        end;//end #0
      end;
    until false;//end read
    if (isend) then break;
    n:=0;
    if (cmdmemcnt<maxcmdmem) then
    begin
      inc(cmdmemcnt);
      cmdmem[cmdmemcnt]:=s;
    end;   
    s:=upcase(s);
    while (pos(' ',s)<>0) do
    begin
      t:=pos(' ',s);
      inc(n);
      st[n]:=copy(s,1,t-1);
      delete(s,1,t);
    end;
    inc(n);
    st[n]:=s;
    if (st[1]='SUMMON_ENEMY') or (st[1]='SUMMONENEMY') or (st[1]='SE') then
    repeat
      if (n<2) then break;
      val(st[2],z,t);if (t<>0) then break;
      if (z<0) or (z>maxoccup) then break;
      x:=-1;
      y:=-1;
      if (n=4) then
      begin
        val(st[3],x,t);if (t<>0) then break;
        val(st[4],y,t);if (t<>0) then break;
        if (x<1) or (x>maxx) or (y<1) or (y>maxy) then break;
      end;
      p.x:=x;
      p.y:=y;
      id:=new_ai(1,z,p);
      if (id<>-1) then
      begin
        print_tank(ai[id]);
        print_screen(ai[id].zb.x,ai[id].zb.y);
      end;
      cmdused:=true;
    until true
    else if (st[1]='SET_BLOCK') or (st[1]='SETBLOCK') or (st[1]='SB') then
    repeat
      if (n<4) then break;
      val(st[2],x,t);if (t<>0) then break;
      val(st[3],y,t);if (t<>0) then break;
      val(st[4],typ,t);if (t<>0) then break;                             
      if (x<1) or (x>maxx) or (y<1) or (y>maxy) then break;
      if (typ<0) or (typ>maxblocktype) or (typ in [4,5]) then break;
      a:=0; b:=0;
      if (n=6) then
      begin
        val(st[5],a,t);if (t<>0) then break;
        val(st[6],b,t);if (t<>0) then break;
      end;
      with mm.map[x,y] do
      begin
        if (id in [4,5]) then break;
        id:=typ;
        fx:=a; fj:=b;
        hard:=blockmaxhard[typ];
        maxhard:=blockmaxhard[typ];
        unbreakble:=false;
      end; //end with
      print_block(x,y);
      print_screen(x,y);
      cmdused:=true;
    until true
    else if (st[1]='HEAL') or (st[1]='HE') then
    begin               
      cmdused:=true;
      for i:=1 to setting.playernum do
        if player[i].living then
          player[i].hp:=player[i].maxhp;
    end
    else if (st[1]='CLEAR_CD') or (st[1]='CC') then
    begin          
      cmdused:=true;
      for i:=1 to setting.playernum do
        if player[i].living then
          with player[i].skill do
          begin
            start.tick:=-1000;
            stop.tick:=-1000;
            use.tick:=-1000;
          end;
    end
    else if (st[1]='KILL_ALL') or (st[1]='KA') then
    begin               
      cmdused:=true;
      for i:=1 to maxai do
        if (ai[i].living) then
          hurt_tank(ai[i],ai[i].hp,1,0);
    end
    else if (st[1]='EXPLODE') or (st[1]='EX') then
    begin
      if (n<4) then break;
      val(st[2],x,t);if (t<>0) then break;
      val(st[3],y,t);if (t<>0) then break;
      val(st[4],z,t);if (t<>0) or (z<0) or (z>maxexplodehard) then break;
      a:=0;
      b:=0;
      if (n>=5) then
      begin
        val(st[5],a,t);if (t<>0) then break;
        if (n>=6) then
        begin           
          val(st[6],b,t);if (t<>0) or ((b<>0) and (b<>1)) then break;
        end;
      end;           
      cmdused:=true;
      explode(x,y,z,a,b,0);
    end;
  until isend;
  gotoxy(41,23);
  tb(0); tc(7);
  for i:=1 to maxlen div 2 do write('═');
  cursoroff;
end;

function work_keypressed:longint;
var c:char;
    t:longint;
   procedure usingskill(var player:Ttank);
   begin
     with player do
     begin
       skillusing:=not skillusing;
       if skillusing then gt(skill.start)
        else gt(skill.stop);
       if occup=2 then
       begin
         if skillusing=false then playmusic('music\skill2_end.wav','0');
         gt(lmt);
         inc(lmt.tick,-tankspeed[0,2]+occupskilltime[2,3]);
       end;
     end;
   end;
begin
  if keypressed=false then exit(0);
  c:=upcase(readkey);
  case c of
    'W':gof[1]:=0;
    'A':gof[1]:=3;
    'S':gof[1]:=2;
    'D':gof[1]:=1;
    'I':if setting.playernum=1 then firef[1]:=0;
    'J':if setting.playernum=1 then firef[1]:=3;
    'K':if setting.playernum=1 then firef[1]:=2;
    'L':if setting.playernum=1 then firef[1]:=1
      else if setting.playernum=2 then gof[2]:=3;
    ' ':usingskill(player[1]);
    'T':if setting.playernum=2 then firef[1]:=0;
    'F':if setting.playernum=2 then firef[1]:=3;
    'G':if setting.playernum=2 then firef[1]:=2;
    'H':if setting.playernum=2 then firef[1]:=1;
    'P':if setting.playernum=2 then gof[2]:=0;
    ';':if setting.playernum=2 then gof[2]:=2;
    '''':if setting.playernum=2 then gof[2]:=1;
    #9:begin
         player[1].ammotype:=(player[1].ammotype mod maxammotype)+1;
         print_ammo;
       end;
    'O':if setting.playernum=2 then
        begin
          player[2].ammotype:=(player[2].ammotype mod maxammotype)+1;
          print_ammo;
        end;
    '`','1'..'5':with player[1] do
             begin
               if (c='`') then t:=0
               else val(c,t);
               if living then
               repeat
                 if t>maxproptype then break;
                 if mm.map[zb.x,zb.y].id<>0 then break;
                 if t>maxproptype then break;
                 if profile.prop[t]<=0 then break;
                 dec(profile.prop[t]);
                 init_prop(zb.x,zb.y,t,-1);
               until true
                else repeat
                  if (profile.occupown[t]=false) then break;
                  occup:=t;
                  init_tip('玩家1职业更改为:'+occupnam[0][t],7,changeoccuptipshowlast);
                until true;
             end;//end case
    '7','8','9','0','-','=':with player[2] do
                         if setting.playernum>1 then
                         begin
                           case c of
                             '7':t:=0;
                             '8':t:=1;
                             '9':t:=2;
                             '0':t:=3;
                             '-':t:=4;
                             '=':t:=5;
                           end;
                           if living then
                           repeat
                             if t>maxproptype then break;
                             if mm.map[zb.x,zb.y].id<>0 then break;
                             if t>maxproptype then break;
                             if profile.prop[t]=0 then break;
                             dec(profile.prop[t]);
                             init_prop(zb.x,zb.y,t,-2);
                           until true//end case
                            else repeat
                              if (profile.occupown[t]=false) then break;
                              occup:=t;
                              init_tip('玩家2职业更改为:'+occupnam[0][t],7,changeoccuptipshowlast);
                            until true;//end case
                         end;//end case
    #0:begin
         c:=readkey;
         case c of
           'H':if setting.playernum=2 then firef[2]:=0;
           'K':if setting.playernum=2 then firef[2]:=3;
           'P':if setting.playernum=2 then firef[2]:=2;
           'M':if setting.playernum=2 then firef[2]:=1;
           ']':if setting.playernum=2 then usingskill(player[2]);
           #83:if player[1].living then
               repeat
                 t:=new_mob(player[1].zb.x,player[1].zb.y,player[1].fx,4,-1);
                 if t=-1 then break;
                 mob[t].speed:=0;
               until true;
           #60:savescreenshot;
         end;//end case
       end;//end #0:
    #27:begin
          close(f_usedtime);
          if gamewin or gamelose then exit(1)
           else exit(2);
        end;
    #8:begin
         while readkey<>#13 do;
       end;
    '/':begin
          work_command;
        end;
  end;//end case
end;

function play:longint;
var oldtime,newtime,bt,ct,ov,nv,oz,nz:Ttime;
    i,playern,n,w,t,d,de,tt:longint;
    c:string;
    worked:boolean;

   procedure beforetickwait;
   var i,j,n,t,playern:longint;
   begin
     if (gamewin=false) and (gamelose=false) then
     begin
       gamelose:=true;
       for i:=1 to setting.playernum do
        if player[i].lives>0 then gamelose:=false;
       if gamelose and (gameendtick=-1) then gameendtick:=tick;
     end;
     for playern:=1 to setting.playernum do
      with player[playern] do
      repeat
        if living=false then
        begin
          if tick>=ldt.tick+dyinglast then
          begin
            if tick=ldt.tick+dyinglast then print_auto(zb);
            if (tick>ldt.tick+dyinglast+spawnwait) and (lives>0) then
            begin
              init_tank(player[playern],0,player[playern].occup);
              gotoxy(4,maxy+2+playern);tb(0);tc(7);write(occupnam[0,occup]);
            end;
          end
           else repeat
             if mm.map[zb.x,zb.y].id in [9] then break;
             if (tick-ldt.tick) mod dyingblinklast<=dyingblinklast div 2 then print(zb,-1,15,'  ')
              else if playern=1 then print(zb,tankbackground[0],15,tankchar[0,occup,fx])
               else if playern=2 then print(zb,3,15,tankchar[0,occup,fx]);
           until true;
        end;//end if living=false
      until true;//end with
   end;

   procedure aftertickwait;
   var i,j,n,t,playern:longint;
       d,ox,oy,xx,yy:longint;
   begin
     for playern:=1 to setting.playernum do
      with player[playern] do if living then
      begin
        d:=fx;ox:=zb.x;oy:=zb.y;

        if gof[playern]<>-1 then
         if canmove(player[playern],gof[playern]) then move(player[playern],gof[playern]);
        if unbreakble and (tick mod unbreakbleblinklast>=unbreakbleblinklast div 2) then
        begin
          print_block(zb);
          print_mob(whichmob(zb));
        end
         else print_tank(player[playern]);
        if tick-lst.tick=unbreakblelast+1 then unbreakble:=false;

        if (firef[playern]<>-1) and (firef[playern]<>fx) then
        begin
          fx:=firef[playern];
          print_tank(player[playern]);
        end;
        i:=0;
        if firef[playern]<>-1 then
        repeat
          inc(i);
          if canfire(player[playern],ammotype) then fire(player[playern],fx,ammotype);

        until true;
        print_ammo;
      end;//end for&with
   end;

begin
  gt(fpsb);
  print_map;
  print_ammo;     assign(f_usedtime,'UsedTime.log');rewrite(f_usedtime);
  fillchar(lamt,sizeof(lamt),255);
  if upcase(mm.nam)='LOGO' then delay(5000);

  repeat{******************************************************************}

    gt(oz);gt(ov);{-------}
    tick:=tick+1;write(f_usedtime,'Tick',tick,': ');    
    if ((profile.ammo[1]>999) or (profile.ammo[2]>999)) and (random(2)=0) and (tick mod 1000=0) and (tick>0) and (bosstime=false) then new_ai(1,0);
    if tick>=round(mm.startspawntick/spawnadd[setting.gamehard]) then
    begin
      for i:=1 to maxoccup do
       if mm.spawnprobability[i]<>maxlongint then
        if random(round(mm.spawnprobability[i]/spawnadd[setting.gamehard]))=0 then
          new_ai(1,i);
    end; //end if tick>=startspawntick

    gt(oldtime);c:='';{-------}
    fillchar(gof,sizeof(gof),255);
    fillchar(firef,sizeof(firef),255);
    worked:=false;
    repeat//================================================================================
      if worked=false then
      begin
                                                                      gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        beforetickwait;                                               gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        print_screen(1);                                              gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        work_tip;                                                     gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        work_block;                                                   gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        for i:=1 to setting.playernum do work_occupskill(player[i]);  gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        work_mob;                                                     gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        work_ai;                                                      gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        print_game_info;                                              gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
        worked:=true;
      end;
      t:=work_keypressed;
      case t of
        0:       ;
        1:exit(0);
        2:exit(1);
      end;
      gt(newtime);
      if setting.gamemode=2 then break;
    until td(oldtime,newtime)>=ticklast;//================================================================================
    gt(nv);write(f_usedtime,td(ov,nv),' ');gt(ov);{-------}
    aftertickwait;

    gt(nv);write(f_usedtime,td(ov,nv),' ');{-------}
    gt(nz);writeln(f_usedtime,td(oz,nz));{-------}
  until false;{******************************************************************}
  tc(7);tb(0);
end;

function chooseoccup:longint;
var playern,cnt:longint;
    n,i,maxlen:longint;
    a:array[1..maxoccup+1] of longint;
    s:string;
begin
  for playern:=1 to setting.playernum do
  begin
    clrscr;
    gotoxy_mid('选择职业',1);tb(0);tc(15);write('选择职业');
    gotoxy_mid('Player'+inttostr(playern),wherey+1);tb(0);tc(14);write('Player'+inttostr(playern));
    s:='';
    maxlen:=4;
    cnt:=0;
    for i:=0 to maxoccup do
      if (profile.occupown[i]) then
      begin
        inc(cnt);
        a[cnt]:=i;
        s:=s+occupnam[0,i]+ln;
        maxlen:=max(maxlen,length(occupnam[0,i]));
      end;
    s:=s+'返回';
    gotoxy_mid(getastr(maxlen+6),wherey+1);
    n:=chooseone(s);
    if n=cnt+1 then exit(1);
    player[playern].occup:=a[n];
  end;
  exit(0);
end;

procedure work_game;
const interval:array[1..2] of longint=(0,13);
var i,playern,occup,n,t,x,y:longint;
    s:ansistring;
    playexit:longint;
    ot,nt:Ttime;

   procedure print_score(x,y,n:longint);
   var i,d:longint;
   begin
     for i:=0 to n-1 do
     begin
       gotoxy(x,y);
       write(i);
       crt.delay(max(trunc(500/n),1));
       if keypressed then break;
     end;
     gotoxy(x,y);
     write(n);
     while keypressed do readkey;
   end;

   procedure print_assess(x,y,cl:longint;s:string);
   const maxc=2;
         maxa=255;
         wait=200;
         c:array[1..maxc] of longint=(8,7);
   var i,n,j,max:longint;
       a:array[1..maxa] of longint;
   begin
     max:=maxc+1;
     for i:=1 to maxc do
      if cl=c[i] then
      begin
        max:=i;
        break;
      end;
     for i:=1 to maxa do
       a[i]:=-i+1;
     repeat
       for j:=1 to maxa do a[j]:=min(max,a[j]+1);
       gotoxy(x,y);
       for j:=1 to length(s) do
       begin
         if a[j]<=0 then continue
          else if a[j]<max then tc(c[a[j]])
           else tc(cl);
         write(s[j]);
       end;//end for j
       crt.delay(wait);
       if a[length(s)]=max then break;
       if keypressed then break;
     until false;
     gotoxy(x,y);
     tc(cl);write(s);
     while keypressed do readkey;
   end;

begin
  clear_map;
  clrscr;
  s:='';
  for i:=1 to levelnum do
    s:=s+level[i].filenam+ln;
  s:=s+'返回';
  maxlevelnamlen:=max(maxlevelnamlen,length('返回'));
  repeat
    clrscr;
    gotoxy_mid('选择关卡',1);tc(15);tb(0);write('选择关卡');
    gotoxy_mid(getastr(maxlevelnamlen+6),2);nowlevel:=chooseone(s);
    if nowlevel=levelnum+1 then exit;
    ismainlevel:=false;
    if level[nowlevel].ismainlevel then
    begin
      if profile.levelunlock[nowlevel]=false then
      begin
        //clrscr;
        gotoxy(1,1);clreol;
        gotoxy_mid('关卡未解锁',1);tb(0);tc(12);write('关卡未解锁');
        delay(500);
        gotoxy(1,nowlevel+1);clreol;
        gotoxy(1,levelnum+3);clreol;
        continue;
      end;
      ismainlevel:=true;
    end;
    break;
  until false;
  mm:=level[nowlevel];

  n:=chooseoccup;
  if n=1 then exit;
  {■■■■}
  init_game;
  playexit:=play;
  end_game;
  {■■■■}
  if playexit=1 then
  begin
    gotoxy_mid('Saving...',1);tb(0);tc(7);write('Saving...');
    save;
    exit;
  end;
  if gamewin then
  begin
    gotoxy_mid('胜利',windmaxy-3);tc(12);tb(0);write('胜利');
    playmusic('music\gamewin.wav','0');
    with profile do
    repeat
      if nowlevel>mainlevelnum then break;
      if levelfinish[nowlevel]=false then
       for i:=1 to mainlevelnum-1 do
        if levelunlock[i] and (levelunlock[i+1]=false) then
        begin
          levelunlock[i+1]:=true;
          delay(400);
          gotoxy_mid('关卡'+inttostr(i+1)+'解锁',wherey+1);tb(0);tc(14);write('关卡',i+1,'解锁');
          break;
        end;
      levelfinish[nowlevel]:=true;
      if (god=false) and (cmdused=false) then
      begin
        inc(money,levelwinprize[nowlevel]);
        gotoxy_mid('金钱增加'+inttostr(levelwinprize[nowlevel]),wherey+1); tb(0); tc(14); write('金钱增加',levelwinprize[nowlevel]);
      end;
    until true;//end with
  end
  else if gamelose then
  begin
    gotoxy_mid('失败',windmaxy-1);
    tc(10);tb(0);write('失败');
    playmusic('music\gameover.wav','0');
    with profile do
    begin
    end;//end with
  end
  else begin
    gotoxy_mid('和局',windmaxy-1);
    tc(7);tb(0);write('和局');
  end;
  
  gotoxy(1,1);
  gotoxy_mid('当前关卡 '+level[nowlevel].filenam); tb(0); tc(8); write('当前关卡 '); tc(15); writeln(level[nowlevel].filenam);
  gotoxy_mid('胜负决出于 Tick '+inttostr(gameendtick),wherey);tb(0);tc(8);write('胜负决出于 Tick ');tc(15);write(gameendtick);
  gotoxy_mid('杀敌数目',wherey+2);tc(11);tb(0);write('杀敌数目');
  x:=windmaxx div 2-2;y:=wherey+1;if setting.playernum=2 then x:=windmaxx div 2-8;
  for i:=1 to setting.playernum do
  begin
    tb(0);tc(15);gotoxy(x+interval[i]-1,y);write(player[i].nam,i);
  end;
  for occup:=1 to maxoccup do
  begin
    for playern:=1 to setting.playernum do
    begin
      gotoxy(x+interval[playern],y+occup);tb(tankbackground[1]);tc(color(random(101),100));write(tankchar[1,occup,0]);
      tb(0);tc(7);write(':');
      tb(0);tc(7);print_score(wherex,wherey,killnum[playern,occup]);
    end;//end for
  end;//end for occup

  gotoxy_mid('死亡次数',wherey+2);tb(0);tc(4);write('死亡次数');
  gotoxy(wherex,wherey+1);
  for playern:=1 to setting.playernum do
  begin
    gotoxy(x+interval[playern],wherey);tb(tankbackground[0]);if playern=2 then tb(player2color);tc(tankcolor[0]);write(tankchar[0,1,0]);
    tb(0);tc(7);write(':');
    tb(0);tc(7);print_score(wherex,wherey,dietimes[playern]);
  end;
  gotoxy_mid('得分',wherey+2); tb(0);tc(15);                  write('得分');
  gotoxy_mid(inttostr(score)+' ',wherey+1); tb(0);tc(7);          print_score(wherex,wherey,score);
  if ismainlevel then
  begin
    gotoxy_mid('评价',wherey+1);    tb(0);tc(15);   write('评价');
                                    tb(0);          print_assess((windmaxx-length(assesschar[assess])-1) div 2,wherey+1,assesscolor[assess],assesschar[assess]);
  end;

  gt(ot);
  save;
  repeat
    gt(nt);
  until td(ot,nt)>=100;
  readkey;
end;

procedure shop;
var i,n,t,choose,cnt,mxl:longint;
    a:array[1..maxoccup] of longint;
    s,ss:string;
begin
  clrscr;
  gotoxy_mid('商店',1);tb(0);tc(11);write('商店');
  windminy:=2;
  repeat
    clrscr;
    gotoxy_mid('弹药'+getastr(6),1);
    tb(0);tc(7);choose:=chooseone('弹药'+ln+
                                  '道具'+ln+
                                  '职业'+ln+
                                  '返回');
    if choose=4 then break;
    clrscr;
    case choose of
      1:begin
          s:='';
          for i:=2 to maxammotype do
            s:=s+ammonam[i]+ln;
          s:=s+'返回';
          gotoxy_mid(getastr(10),1);tb(0);tc(7);choose:=chooseone(s)+1;
          if choose=maxammotype+1 then continue;
          clrscr;
          i:=0;
          repeat
            clrscr;
            gotoxy_mid('金钱:'+inttostr(profile.money),1);                                    tc(7);tb(0);  write('金钱:',profile.money);
            gotoxy_mid(ammonam[choose]+inttostr(ammoprice[choose])+'元/发',2);             tc(7);tb(0);  write(ammonam[choose],ammoprice[choose],'元/发');
            gotoxy_mid('请输入要购买的数量'+'(已有'+inttostr(profile.ammo[choose])+'发)',3);  tc(7);tb(0);  write('请输入要购买的数量'+'(已有'+inttostr(profile.ammo[choose])+'发)');

            n:=0;
            gotoxy(1,4);clreol;
            tb(7);tb(0);gotoxy(38,4);inputint(n,min(999-profile.ammo[choose],profile.money div ammoprice[choose]),0);
            if n=0 then
            begin
              i:=5;
              break;
            end;

            if (n+profile.ammo[choose]<=999) and (profile.money>=n*ammoprice[choose]) then break;
            if profile.money<n*ammoprice[choose] then
            begin
              gotoxy_mid('金钱不足',wherey+1);tc(4);tb(0);write('金钱不足');
            end;
            if n+profile.ammo[choose]>999 then
            begin
              gotoxy_mid('超出数量限制(999)',wherey+1);tc(4);tb(0);write('超出数量限制(999)');
            end;
            delay(500);
            inc(i);
          until i=5;
          if i=5 then continue;
          with profile do
          begin
            inc(ammo[choose],n);
            dec(money,n*ammoprice[choose]);
          end;
        end;//end case 1
      2:begin
          s:='';
          for i:=1 to maxproptype do
            s:=s+propnam[i]+ln;
          s:=s+'返回';
          gotoxy_mid(getastr(10),1);tb(0);tc(7);choose:=chooseone(s);
          if choose=maxproptype+1 then continue;
          clrscr;
          i:=0;
          repeat
            clrscr;
            gotoxy_mid('金钱:'+inttostr(profile.money),1);                                    tc(7);tb(0);  write('金钱:',profile.money);
            gotoxy_mid(propnam[choose]+inttostr(propprice[choose])+'元/个',2);             tc(7);tb(0);  write(propnam[choose],propprice[choose],'元/个');
            gotoxy_mid('请输入要购买的数量'+'(已有'+inttostr(profile.prop[choose])+'个)',3);  tc(7);tb(0);  write('请输入要购买的数量'+'(已有'+inttostr(profile.prop[choose])+'个)');
                                                                                           tc(8);tb(0);  write('(已有',profile.prop[choose],'个)');
            n:=0;
            gotoxy(1,4);clreol;
            tb(7);tb(0);gotoxy(38,4);inputint(n,min(999-profile.prop[choose],profile.money div propprice[choose]),0);
            if n=0 then
            begin
              i:=5;
              break;
            end;

            if (n+profile.prop[choose]<=999) and (profile.money>=n*propprice[choose]) then break;
            if profile.money<n*propprice[choose] then
            begin
              gotoxy_mid('金钱不足',wherey+1);tc(4);tb(0);write('金钱不足');
            end;
            if n+profile.prop[choose]>999 then
            begin
              gotoxy_mid('超出数量限制(999)',wherey+1);tc(4);tb(0);write('超出数量限制(999)');
            end;
            delay(500);
            inc(i);
          until i=5;
          if i=5 then continue;
          with profile do
          begin
            inc(prop[choose],n);
            dec(money,n*propprice[choose]);
          end;
        end;
      3:begin
          s:='';
          cnt:=0;
          mxl:=4;
          for i:=0 to maxoccup do
           if (profile.occupown[i]=false) then
           begin
             ss:=occupnam[0][i]+' (售价:'+inttostr(occupprice[i])+')';
             mxl:=max(mxl,length(ss));
             s:=s+ss+ln;
             inc(cnt);
             a[cnt]:=i;
           end;
          s:=s+'返回';
          gotoxy_mid(mxl+6,1);tb(0);tc(7);choose:=chooseone(s);
          if choose=cnt+1 then continue;
          choose:=a[choose];
          if (profile.money<occupprice[choose]) then
          begin                          
            clrscr;
            gotoxy_mid('金钱不足',wherey+1);tc(4);tb(0);write('金钱不足');    
            delay(500);
            continue;
          end;
          with profile do
          begin
            dec(money,occupprice[choose]);
            occupown[choose]:=true;
          end;
        end;
    end;//end case
    gotoxy_mid('购买成功',wherey+1);tc(12);tb(0);write('购买成功');
    gotoxy_mid('剩余金钱:'+inttostr(profile.money),wherey+1);tc(7);tb(0);write('剩余金钱:',profile.money);
    readkey;
  until false;
  save;
  windminy:=1;
end;

procedure setsetting;
var i,n,t:longint;
    s:string;
begin
  clrscr;
  s:='设置将在游戏重启后生效';
  gotoxy_mid(s);tb(0);tc(7);write(s);
  exec('notepad.exe',path+'\'+settingfilenam);
  readkey;
end;

procedure print_text(fn:string);
var f:text;
    s,ss:string;
    i,l:longint;
    fst:boolean;
   function trans(c:char):longint;
   begin
     c:=upcase(c);
     if (c in ['0'..'9']) then trans:=ord(c)-ord('0')
     else trans:=ord(c)-ord('A')+10;
   end;
begin
  clrscr;
  if (fsearch(fn,'\')='') then exit;
  assign(f,fn);
  reset(f);
  l:=0;
  fst:=true;
  while (eof(f)=false) do
  begin
    readln(f,s);
    if (length(s)>=2) and (s[1]='\') and (s[2]='\') then
    begin
      readkey;
      fst:=true;
      clrscr;
    end
    else begin       
      if fst then l:=length(s);
      if (length(s)>=2) and (s[1]='\') and (s[2]='l') then l:=length(s)-2;
      tb(0); tc(7);
      i:=1;
      ss:='';
      if fst=false then writeln;
      gotoxy_mid(l);
      fst:=false;
      while (i<=length(s)) do
      begin
        if (s[i]='\') then
        repeat
          if (s[i+1]='l') then
          begin
            inc(i);
            break;
          end;
          tb(trans(s[i+1]));
          tc(trans(s[i+2]));
          inc(i,2);
        until true
        else ss:=ss+s[i];
        if (length(ss)=2) or (ord(ss[1])<128) then
        begin
          write(ss);
          ss:='';
        end;
        inc(i);
      end; //end while i
    end;
    tb(0); tc(7);
  end;
  close(f);
  readkey;
end;

procedure help;
var s:string;
    i,j,cnt,choose:longint;
begin
  clrscr;
  gotoxy_mid('帮助&图鉴',1);tb(0);tc(11);write('帮助&图鉴');
  windminy:=2;
  repeat
    clrscr;
    gotoxy_mid('游戏目标'+getastr(6));
    choose:=chooseone('游戏目标'+ln+
                      '键位说明'+ln+
                      '方块类型'+ln+
                      '实体类型'+ln+
                      '敌人种类'+ln+
                      '职业介绍'+ln+
                      '设置参数'+ln+
                      '指令详情'+ln+
                      '其他信息'+ln+
                      '返回'        );
    case choose of
      1:print_text('bin\help_gamegoal.txt');
      2:print_text('bin\help_keyboard.txt');
      3:print_text('bin\help_block.txt');
      4:print_text('bin\help_entity.txt');
      5:print_text('bin\help_enemy.txt');
      6:print_text('bin\help_occupation.txt');
      7:print_text('bin\help_setting.txt');
      8:print_text('bin\help_command.txt');
      9:print_text('bin\help_other.txt');
      10:break;
    end;
    clrscr;
  until false;
  windminy:=1;
end;

procedure work_main;
var i,n,t,choose:longint;
begin
  repeat
    clrscr;
    gotoxy_mid('帮助&图鉴'+getastr(6),windminy);
    if logged then choose:=chooseone('开始游戏'  +ln+
                                     '商店'      +ln+
                                     '账号信息'  +ln+
                                     '帮助&图鉴'+ln+
                                     '设置'      +ln+
                                     '退出'          )
              else choose:=chooseone('开始游戏'  +ln+
                                     '商店'      +ln+
                                     '登录'      +ln+
                                     '帮助&图鉴'+ln+
                                     '设置'      +ln+
                                     '退出'          );
    case choose of
      1:begin
          work_game;
        end;
      2:shop;
      3:if logged then print_profile
         else logged:=load(1);
      4:help;
      5:setsetting;
      6:begin
          tc(0); tb(0);
          break;
        end;
    end;//end case
  until false;
end;

BEGIN
  clrscr;gotoxy_mid('Loading...',1);tb(0);tc(7);write('Loading...');
  getdir(byt,path);
  init_program;
  logged:=load(0);
  work_main;
END.

 

方亦欧在2018-02-10 20:13:31追加了内容

呃好像不行,你就这样看吧。

0
0
我要回答