问题标题: 大家有什么编程小游戏?

0
0
已解决
尤博扬
尤博扬
初级光能
初级光能

大家有什么编程小游戏?

当这里是个交流站

谁的游戏被点赞最多

拿走这20豆~

豆少请见谅~~


0
已采纳
刘英杰
刘英杰
新手天翼
新手天翼

这是一个小游戏

我们称之为:《坦克大战》

游戏可玩性非常高

但是酷町问答显然不能发布配套的文件

所以要想玩这个游戏的完整版本

请加本人微信:liuyingjie071202

0
尤博扬
尤博扬
初级光能
初级光能

大家有什么编程小游戏?

当这里是个交流站

谁的游戏被点赞最多

拿走这20豆~

豆少请见谅~~

0
刘英杰
刘英杰
新手天翼
新手天翼

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.
 

0
刘英杰
刘英杰
新手天翼
新手天翼

这是一个小游戏

我们称之为:《坦克大战》

游戏可玩性非常高

但是酷町问答显然不能发布配套的文件

所以要想玩这个游戏的完整版本

请加本人微信:liuyingjie071202

0
曲天歌
曲天歌
高级光能
高级光能

好好学习吧,别天天玩游戏了,童鞋。→_→

0
0
我要回答