{ TROFF II --- UFP Software --- 1990 }

uses
    Graph,
    Crt;

label 1, 2, 3, 4;

const
    TLCor = 1;  Hor = 5;
    TRCor = 2;  Ver = 6;
    BLCor = 3;
    BRCor = 4;
    ML = 1;  IBML = 2;  W = 3;  MW = 4; Bl = 5;
    SB = 1;  LB = 2;  PS = 3;   Sp = 0;
    You = 1; IBM = 2; incr = 1; decr =2;

type
    PlayField = array[0..78,0..48] of byte;

var
    { Images }
    LineIm    : array[1..4,1..6] of pointer;
    BallIm    : array[1..2,1..4]  of pointer;
    Sib, Null :                 pointer;
    Note      :                 pointer;
    Numbers   : array[0..9]  of pointer;

    PF        : PlayField; { Playfield }
    Gd, Gm    : integer;   { EGAsetup }
    OldPal    : PaletteType;
    Scr,Bonus : array[1..2] of longint;
    Lng,Lplus : array[1..2] of integer;
    Trn       : array[1..2] of byte;
    Pntr      : array[1..2] of integer;
    Snk       : array[1..2,1..200] of record x:byte; y:byte ;end;
    MaxTrn, Code, OldCode, OldestCode, SaveCode : byte;
    Xdir,Ydir : array[1..2] of integer;
    Ch        : char;
    ObN       : byte;
    ShowTurnsFlag   : boolean;
    ShowScoreFlag, ShowLenFlag : array[1..2] of boolean;
    Gold      : array[1..3] of
                record
                 Class : byte;
                    gx : byte;
                    gy : byte;
                  Size : byte;
                   Dir : byte;
                end; { Gold }
    MoveWallFlag : boolean;
    Mow          : array[1..35] of record
                                   mwx : byte;
                                   mwy : byte;
                    end; { Mow }
    MWInfo       : record    mwxdir : integer;
                             mwydir : integer;
                             mwleng : byte;
                             mwpntr : byte;
                    end; { MWData }
    Tune,Counter : byte;
    MaxCounter   : byte;
    ToggleSound  : boolean;
    Message      : array[1..20] of string;
    MessageFlag  : integer;
    Speed        : byte;
    EndFlag      : array[1..2] of boolean;
    EnemyToggle  : boolean;
    MWallToggle  : integer;
    LenToWin     : byte;
    g            : integer;
    GameNo       : byte;
    Hisco,Losco  : longint;
    HiPla,Lopla  : byte;
    FirstGameFlag: boolean;
    QuitFlag     : boolean;
    ExitFlag     : boolean;

procedure GetImages;
  var i, j, x, c1, c2 :integer;
      size : word;
  begin
  for i:=0 to 15 do SetPalette(i,0);
  { Numbers }
  SetColor(Red);
  Line(3,1,6,1);Line(3,18,6,18);Line(2,2,2,3);Line(7,2,7,3);
  Line(1,4,1,15);Line(8,4,8,15);Line(2,16,2,17);Line(7,16,7,17);
  Line(4,5,5,5);Line(4,14,5,14); {0}
  MoveTo(16,1);LineTo(16,15);LineTo(18,15);LineTo(18,18);
  LineTo(11,18);LineTo(11,15);LineTo(13,15);LineTo(13,5);LineTo(11,7);
  LineTo(11,3);LineTo(12,2);LineTo(13,2);LineTo(13,1);LineTo(16,1); {1}
  MoveTo(21,3);LineTo(23,1);LineTo(26,1);LineTo(28,3);LineTo(28,10);
  LineTo(24,14);LineTo(24,15);LineTo(28,15);LineTo(28,18);LineTo(21,18);
  LineTo(21,14);LineTo(25,10);LineTo(25,4);LineTo(23,4);LineTo(21,6);
  LineTo(21,3); {2}
  MoveTo(31,6);LineTo(31,3);LineTo(33,1);LineTo(36,1);LineTo(38,3);
  LineTo(38,8);Line(37,9,37,10);MoveTo(38,11);LineTo(38,16);LineTo(36,18);
  LineTo(33,18);LineTo(31,16);LineTo(31,13);LineTo(33,15);LineTo(34,15);LineTo(35,14);
  LineTo(35,11);LineTo(33,10);LineTo(33,9);LineTo(35,8);LineTo(35,5);
  LineTo(34,4);LineTo(33,4);LineTo(31,6); {3}
  MoveTo(48,1);LineTo(48,18);LineTo(45,18);LineTo(45,11);LineTo(41,11);
  LineTo(41,5);LineTo(45,1);LineTo(48,1);MoveTo(45,5);LineTo(45,8);
  LineTo(43,8);LineTo(43,6);LineTo(45,5); {4}
  MoveTo(58,1);LineTo(51,1);LineTo(51,10);LineTo(55,10);LineTo(55,15);
  LineTo(54,15);LineTo(51,12);LineTo(51,15);LineTo(54,18);LineTo(55,18);
  LineTo(58,15);LineTo(58,9);LineTo(56,7);LineTo(54,7);LineTo(54,4);
  LineTo(58,4);LineTo(58,1); {5}
  MoveTo(68,1);LineTo(63,1);LineTo(61,3);LineTo(61,17);LineTo(62,18);
  LineTo(66,18);LineTo(68,16);LineTo(68,9);LineTo(66,7);LineTo(64,7);
  LineTo(64,4);LineTo(68,4);LineTo(68,1);Rectangle(63,10,66,15); {6}
  MoveTo(71,1);LineTo(78,1);LineTo(78,7);LineTo(76,9);LineTo(76,18);
  LineTo(73,18);LineTo(73,9);LineTo(75,7);LineTo(75,4);LineTo(73,4);
  LineTo(73,6);LineTo(71,6);LineTo(71,1); {7}
  MoveTo(83,1);LineTo(86,1);LineTo(88,3);LineTo(88,7);LineTo(86,9);
  LineTo(88,11);LineTo(88,16);LineTo(86,18);LineTo(83,18);LineTo(81,16);
  LineTo(81,11);LineTo(83,9);LineTo(81,7);LineTo(81,3);LineTo(83,1);
  MoveTo(83,5);LineTo(84,4);LineTo(85,4);LineTo(86,5);LineTo(85,6);
  LineTo(84,6);MoveTo(84,12);LineTo(85,12);LineTo(86,13);LineTo(86,14);
  LineTo(85,15);LineTo(84,15);LineTo(83,14);LineTo(83,13); {8}
  MoveTo(93,1);LineTo(97,1);LineTo(98,2);LineTo(98,16);LineTo(96,18);
  LineTo(91,18);LineTo(91,15);LineTo(95,15);LineTo(95,12);LineTo(93,12);
  LineTo(91,10);LineTo(91,3);LineTo(93,1);Rectangle(93,4,96,9); {9}
  SetColor(Yellow);
  Line(2,4,2,15);Line(3,2,3,17);Line(6,2,6,17);Line(7,4,7,15);
  SetFillStyle(SolidFill,Yellow);Bar(4,2,5,4);Bar(4,15,5,17);
  SetFillStyle(SolidFill,Yellow);FloodFill(14,2,Red);FloodFill(22,3,Red);
  FloodFill(32,3,Red);FloodFill(45,2,Red);FloodFill(57,2,Red);
  FloodFill(67,2,Red);Line(63,10,63,15);Line(66,10,66,15);
  FloodFill(72,2,Red);FloodFill(83,2,Red);
  FloodFill(97,2,Red);Line(93,4,93,9);Line(96,4,96,9);
  { Snakes & Walls }
  for i:=1 to 4 do
    begin
    x:=i*30-30;
    case i of
   1 : begin c1:=LightGreen;c2:=Green;end; 2 : begin c1:=LightMagenta;c2:=Magenta;end;
   3 : begin c1:=LightBlue;c2:=Blue;end; 4 : begin c1:=LightGray;c2:=DarkGray;end;
      end; {case i}
    SetColor(c2);
    MoveTo(x+2,30); LineTo(x+18,30); LineTo(x+20,32); LineTo(x+20,48);
    LineTo(x+18,50); LineTo(x+2,50); LineTo(x,48); LineTo(x,32);
    LineTo(x+2,30); Rectangle(x+6,36,x+14,44);
    for j:=0 to 8 do
      begin
      Line(x+3+j*2,31,x+3+j*2,30); Line(x+3+j*2,49,x+3+j*2,50);
      Line(x+1,33+j*2,x,33+j*2);   Line(x+19,33+j*2,x+20,33+j*2);
      end;
    for j:=0 to 5 do
      begin
      Line(x+5+j*2,35,x+5+j*2,35); Line(x+5+j*2,45,x+5+j*2,45);
      Line(x+5,35+j*2,x+5,35+j*2); Line(x+15,35+j*2,x+15,35+j*2);
      end;
    Line(x+1,33,x+3,31); Line(x+17,31,x+19,33);
    Line(x+1,47,x+3,49); Line(x+17,49,x+19,47);
    SetFillStyle(SolidFill,c1);FloodFill(x+4,31,c2);
    SetColor(c1);
    Line(x+1,32,x+2,31);Line(x+18,31,x+19,32);
    Line(x+1,48,x+2,49);Line(x+18,49,x+19,48);
    end;
  { Golds }
  for i:=0 to 1 do
    begin
    case i of
    0 : begin c1:=LightCyan;c2:=Cyan;end;
    1 : begin c1:=White;c2:=LightGray;end;
    end; {case i} SetFillStyle(SolidFill,c1);
    SetColor(c2);Line(3,92+i*10,3,94+i*10);Line(2,93+i*10,4,93+i*10);PutPixel(3,93+10*i,c1);
    SetColor(c1);Bar(12,92+10*i,14,94+10*i);SetColor(c2);
    MoveTo(13,91+i*10);LineTo(15,93+i*10);LineTo(13,95+i*10);LineTo(11,93+i*10);LineTo(13,91+i*10);
    MoveTo(23,90+i*10);LineTo(26,93+i*10);LineTo(23,96+i*10);LineTo(20,93+i*10);LineTo(23,90+i*10);
    FloodFill(23,91+i*10,c2);
    Line(30,92+i*10,32,90+i*10);Line(34,90+i*10,36,92+i*10);Line(30,94+i*10,32,96+i*10);Line(34,96+i*10,36,94+i*10);
    SetColor(c1);MoveTo(30,93+i*10);LineTo(33,90+i*10);LineTo(36,93+i*10);
    LineTo(33,96+i*10);LineTo(30,93+i*10);FloodFill(33,93+i*10,c1);
    end;
  SetColor(Yellow);MoveTo(0,111);LineTo(1,110);LineTo(5,110);LineTo(6,111);LineTo(6,115);
  LineTo(5,116);LineTo(1,116);LineTo(0,115);LineTo(0,111);Line(2,110,2,116);
  PutPixel(1,113,Yellow);PutPixel(4,112,Yellow);
  { Get Images }
  for i:=0 to 9 do
    begin
    Size:=ImageSize(10*i,0,10*i+9,19);GetMem(Numbers[i],Size);
    GetImage(10*i,0,10*i+9,19,Numbers[i]^); end;
  Size:=ImageSize(0,30,6,36);
  for i:=1 to 4 do
    begin
    x:=30*i-30;
    for j:=1 to 6 do GetMem(LineIm[i,j],Size);
    GetImage(x,30,x+6,36,LineIm[i,TLCor]^);
    GetImage(x+14,30,x+20,36,LineIm[i,TRCor]^);
    GetImage(x,44,x+6,50,LineIm[i,BLCor]^);
    GetImage(x+14,44,x+20,50,LineIm[i,BRCor]^);
    GetImage(x+7,30,x+13,36,LineIm[i,Hor]^);
    GetImage(x,37,x+6,43,LineIm[i,Ver]^);
    end;
  for i:=1 to 2 do
    begin
    for j:=1 to 4 do
      begin
      GetMem(BallIm[i,j],Size);
      x:=10*j-10;
      GetImage(x,80+i*10,x+6,86+i*10,BallIm[i,j]^);
      end;
    end;
  GetMem(Null,Size);GetMem(Sib,Size);
  GetImage(0,70,6,76,Null^);GetImage(0,110,6,116,Sib^);
  SetColor(LightGray);
  Line(631,9,631,11);
  for i:=632 to 634 do Line(i,8,i,12);
  for i:=635 to 636 do Line(i,0,i,11);
  MoveTo(637,0);LineTo(639,0);LineTo(639,1);
  MoveTo(637,3);LineTo(639,3);LineTo(639,4);
  GetMem(Note,ImageSize(631,0,639,12));
  GetImage(631,0,639,12,Note^);
  end;

procedure DrawScoreWindow;
  begin
  SetColor(Magenta);
  MoveTo(565,0);LineTo(629,0);LineTo(634,10);LineTo(634,329);LineTo(629,339);
  LineTo(565,339);LineTo(560,329);LineTo(560,10);LineTo(565,0);
  SetFillStyle(InterleaveFill,Magenta);FloodFill(566,1,Magenta);
  SetColor(Red);
  MoveTo(634,329);LineTo(629,339);LineTo(634,349);LineTo(639,339);LineTo(634,329);
  SetFillStyle(SolidFill,Brown);FloodFill(634,339,Red);
  SetColor(Brown);
  MoveTo(629,0);LineTo(639,20);LineTo(639,339);LineTo(634,329);LineTo(634,10);
  MoveTo(560,329);LineTo(570,349);LineTo(634,349);LineTo(629,339);LineTo(565,339);
  SetFillStyle(InterleaveFill,Brown);FloodFill(635,20,Brown);FloodFill(570,340,Brown);
  SetColor(Black);SetFillStyle(InterleaveFill,DarkGray);Bar(565,270,626,291);Bar(565,300,626,321);
  Bar(565,58,590,263);Bar(601,58,626,263);Bar(565,19,590,50);Bar(601,19,626,50);
  SetColor(Brown);
  MoveTo(565,50);LineTo(565,19);LineTo(590,19);
  MoveTo(601,50);LineTo(601,19);LineTo(626,19);
  Line(565,20,590,20);Line(601,20,626,20);
  MoveTo(565,263);LineTo(565,58);LineTo(590,58);Line(565,59,590,59);
  MoveTo(601,263);LineTo(601,58);LineTo(626,58);Line(601,59,626,59);
  MoveTo(565,291);LineTo(565,270);LineTo(626,270);Line(565,271,626,271);
  MoveTo(565,321);LineTo(565,300);LineTo(626,300);Line(565,301,626,301);
  SetFillStyle(SolidFill,Black);SetColor(Magenta);
  FillEllipse(577,10,5,5);FillEllipse(613,10,5,5);FillEllipse(596,330,5,5);
  end;

procedure DrawPlayField;
  var i,j,Room,Barrier : integer;
  procedure DW(ax,by,img : byte);
    begin
    PutImage(7*ax,7*by,LineIm[W,img]^,NormalPut);
    PF[ax,by]:=W;
    end;
  begin
   if trn[1]+1=MaxTrn then begin
     SetFillStyle(SolidFill,LightGreen);FloodFill(577,10,Magenta);end;
   if trn[2]+1=MaxTrn then begin
     SetFillStyle(SolidFill,LightRed);FloodFill(613,10,Magenta);end;
  for i:=0 to 78 do for j:=0 to 48 do PF[i,j]:=Sp;
  for i:=0 to 78 do begin pf[i,0]:=W;pf[i,48]:=W;PutImage(7*i,0,LineIm[W,Hor]^,NormalPut);
                          PutImage(7*i,336,LineIm[W,Hor]^,NormalPut);end;
  for j:=1 to 47 do begin pf[0,j]:=W;pf[78,j]:=w;PutImage(0,7*j,LineIm[W,Ver]^,NormalPut);
                          PutImage(546,7*j,LineIm[W,Ver]^,NormalPut);end;
  PutImage(0,0,LineIm[W,TLCor]^,NormalPut);PutImage(546,0,LineIm[W,TRCor]^,NormalPut);
  PutImage(0,336,LineIm[W,BLCor]^,NormalPut);PutImage(546,336,LineIm[W,BRCor]^,NormalPut);
  Barrier:=Random(5)+1;
  repeat
    Room:=Random(11)+1;Barrier:=Barrier-1;
    case Room of
      1: begin
         DW(1,1,BRCor); DW(77,1,BLCor); DW(1,47,TRCor); DW(77,47,TLCor);
         end;
      2: begin
         for i:=35 to 43 do begin DW(i,1,Hor); DW(i,47,Hor); end;
         end;
      3: begin
         for i:=21 to 27 do begin DW(1,i,Ver); DW(77,i,Ver); end;
         end;
      4: begin
         for i:=11 to 14 do begin DW(i,5,Hor); DW(i,43,Hor); end;
         for i:=64 to 67 do begin DW(i,5,Hor); DW(i,43,Hor); end;
         for i:=6  to 9  do begin DW(10,i,Ver); DW(68,i,Ver); end;
         for i:=39 to 42 do begin DW(10,i,Ver); DW(68,i,Ver); end;
         DW(10,5,TLCor); DW(68,5,TRCor);
         DW(10,43,BLCor); DW(68,43,BRCor);
         end;
      5: begin
         for i:=15 to 19 do begin DW(i,5,Hor); DW(i,43,Hor); end;
         for i:=59 to 63 do begin DW(i,5,Hor); DW(i,43,Hor); end;
         for i:=10 to 14 do begin DW(10,i,Ver); DW(68,i,Ver); end;
         for i:=34 to 38 do begin DW(10,i,Ver); DW(68,i,Ver); end;
         end;
      6: begin
         for i:=21 to 27 do DW(39,i,Ver);
         end;
      7: begin
         for i:=16 to 20 do DW(39,i,Ver);
         for i:=28 to 32 do DW(39,i,Ver);
         end;
      8: begin
         for i:=35 to 43 do DW(i,24,Hor);
         end;
      9: begin
         for i:=30 to 34 do DW(i,24,Hor);
         for i:=44 to 48 do DW(i,24,Hor);
         end;
     10: begin
         for i:=35 to 43 do begin DW(i,7,Hor); DW(i,41,Hor); end;
         end;
     11: begin
         for i:=30 to 34 do begin DW(i,7,Hor); DW(i,41,Hor); end;
         for i:=44 to 48 do begin DW(i,7,Hor); DW(i,41,Hor); end;
         end;
      end; { case Room }
    until Barrier=0;
  end;

procedure ClearVariables;
  var i,j : integer;
  begin
  for i:=1 to 2 do
    begin lng[i]:=0; lplus[i]:=20; pntr[i]:=1; EndFlag[i]:=False;
          ydir[i]:=0; xdir[i]:=3-i*2; showturnsflag:=true;
          showscoreflag[i]:=true; showlenflag[i]:=true;
          for j:=1 to 200 do begin snk[i,j].x:=0;snk[i,j].y:=0; end;
          end;
  snk[1,1].y:=24;snk[2,1].y:=24;snk[1,1].x:=8;snk[2,1].x:=70;
  OldCode:=77;OldestCode:=77;Code:=77;
  for i:=1 to 3 do
    with Gold[i] do
      begin class:=0;gx:=0;gy:=0;size:=0;dir:=0; end;
  MoveWallFlag:=False;
  MWInfo.mwxdir:=0; MWInfo.mwydir:=0;
  MWInfo.mwleng:=0; MWInfo.mwpntr:=1;
  for i:=1 to 35 do begin Mow[i].mwx:=0; Mow[i].mwy:=0; end;
  ExitFlag:=False;
  end;

procedure ShowScore;
  var k : longint;
      b : word;
      i : integer;
  procedure WRN(x,y,n : integer);
    begin PutImage(x,y,Numbers[n]^,NormalPut); end;
  begin
    if scr[1]>scr[2] then setfillstyle(1,10) else
    if scr[2]>scr[1] then setfillstyle(1,12) else
                          setfillstyle(1,0);
    FloodFill(596,330,Magenta);
    for i:=1 to 2 do
      begin
     if ShowScoreFlag[i]=True then
      begin
      b:=242+30*i; k:=scr[i];
      if k>999999 then begin k:=k-999999;SetPalette(Yellow,Random(63)+1);end;
      WRN(566,b,k div 100000);k:=k mod 100000;
      WRN(576,b,k div 10000) ;k:=k mod 10000;
      WRN(586,b,k div 1000)  ;k:=k mod 1000;
      WRN(596,b,k div 100)   ;k:=k mod 100;
      WRN(606,b,k div 10)    ;k:=k mod 10;
      WRN(616,b,k);
      ShowScoreFlag[i]:=False;
      end;
     if ShowTurnsFlag=True then
      begin
      b:=569+36*(i-1); k:=trn[i];
      WRN(b-1,26,k div 10);k:=k mod 10;WRN(b+10,26,k);
      if i=2 then ShowTurnsFlag:=False;
      end;
     if ShowLenFlag[i]=True then
      begin
      b:=570+36*(i-1);k:=lng[i];
      if LenToWin=150 then k:=Round(k*1.34);
      if LenToWin=100 then k:=k*2;
      SetFillStyle(InterLeaveFill,DarkGray);Bar(565+(i-1)*36,58,590+(i-1)*36,263);
      SetFillStyle(SolidFill,8+i*2);SetColor(i*2);Bar3D(b,262-k,b+14,262,2,True);
      Line(b+15,262-k,b+15,262);
      ShowLenFlag[i]:=False;
      if (lng[i]<2) and (lplus[i]=0) then EndFlag[i]:=True;
      if lng[i]>LenToWin-1 then EndFlag[3-i]:=True;
      end else delay(8);
     end;
  end;

procedure PauseGame;
  var c : char;
  begin
  nosound;
  SetTextStyle(SmallFont,HorizDir,4);SetColor(White);
  OutTextXY(10,341,'Game Paused --- Press F4 to continue');
  repeat
    if keypressed then c:=readkey;
    if c=#0 then c:=readkey;
  until ord(c)=62;
  SetFillStyle(1,0);SetColor(0);Bar(10,342,225,349);
  end;

procedure Change(ObjNum : byte);
  begin
  with Gold[ObjNum] do
    begin
    if Size=0 then
      begin
      if random(25)=0 then begin Class:=PS; Tune:=10; end else
         if random(2)=0 then Class:=SB else Class:=LB;
      Dir:=incr; Size:=1;
      repeat
        gx:=random(79);gy:=random(49);
      until (PF[gx,gy]=Sp);
      PF[gx,gy]:=Bl;
      if Class<>PS then PutImage(gx*7,gy*7,BallIm[Class,Size]^,NormalPut)
                   else PutImage(gx*7,gy*7,Sib^,NormalPut);
      end
    else
      begin
      if (Size=4) and (Dir=incr) then Dir:=decr;
      if (Size=1) and (Dir=decr) then
        begin Size:=0;if Class=PS then Tune:=11;
        Class:=0;Dir:=0;if PF[gx,gy]=Bl then begin
        PutImage(gx*7,gy*7,Null^,NormalPut);PF[gx,gy]:=Sp;end; end
      else
        begin
        if Dir=incr then Size:=Size+1;
        if Dir=decr then Size:=Size-1;
        if (Class=SB) or (Class=LB) then
             PutImage(gx*7,gy*7,BallIm[Class,Size]^,NormalPut);
        end; {else 2}
      end; {else 1}
    end; {with}
  end;   {proc}

procedure MoveSib(ObjNum : byte);
  var zx,zy : byte;
  begin
  zx:=Gold[ObjNum].gx+(Random(3)-1);
  zy:=Gold[ObjNum].gy+(Random(3)-1);
  if PF[zx,zy]=Sp then
    begin
    PF[Gold[ObjNum].gx,Gold[ObjNum].gy]:=Sp;
    PutImage(Gold[ObjNum].gx*7,Gold[ObjNum].gy*7,Null^,NormalPut);
    Gold[ObjNum].gx:=zx;
    Gold[ObjNum].gy:=zy;
    PutImage(zx*7,zy*7,Sib^,NormalPut);
    PF[zx,zy]:=Bl;
    end;
  end;

procedure MoveYou;
  var nx,ny,ox,oy,tx,ty,c : byte;
      tail : integer;

  procedure GetBall(aa,bb: byte);
    var bonusl,bonuss : byte;
    i, ObN: integer;
    begin
    BonusS:=0; BonusL:=0;
    for i:=1 to 3 do
      with Gold[i] do begin
        if (aa=gx) and (bb=gy) and (size>0) then ObN:=i;
        end;
    with Gold[ObN] do
      begin
      if Class=SB then begin BonusS:=Size*20;
                             BonusL:=0; Tune:=1; end;
      if Class=LB then begin BonusL:=Size*2;
                             BonusS:=0; Tune:=2; end;
      if Class=PS then begin BonusS:=100;
                             BonusL:=10; Tune:=3; end;
      Lplus[You]:=Lplus[You]+BonusL;
      if BonusS>0 then begin scr[You]:=scr[You]+BonusS;
                             ShowScoreFlag[You]:=True; end;
      Gx:=0; Gy:=0; Size:=0; Class:=0;
      end;
    end;

  begin
  OX:=snk[You,Pntr[You]].x; OY:=snk[You,Pntr[You]].y;
  NX:=OX+XDir[1]          ; NY:=OY+YDir[1]          ;
  Tail:=Pntr[You]-lng[You]; if Tail<1 then Tail:=Tail+200;
  TX:=snk[You,Tail].x     ; TY:=snk[You,Tail].y     ;
  case OldestCode of
    72 : if Code=72 then PutImage(OX*7,OY*7,LineIm[ML,Ver]^,NormalPut) else
         if Code=77 then PutImage(OX*7,OY*7,LineIm[ML,TLCor]^,NormalPut) else
         if Code=75 then PutImage(OX*7,OY*7,LineIm[ML,TRCor]^,NormalPut);
    80 : if Code=80 then PutImage(OX*7,OY*7,LineIm[ML,Ver]^,NormalPut) else
         if Code=77 then PutImage(OX*7,OY*7,LineIm[ML,BLCor]^,NormalPut) else
         if Code=75 then PutImage(OX*7,OY*7,LineIm[ML,BRCor]^,NormalPut);
    77 : if Code=72 then PutImage(OX*7,OY*7,LineIm[ML,BRCor]^,NormalPut) else
         if Code=80 then PutImage(OX*7,OY*7,LineIm[ML,TRCor]^,NormalPut) else
         if Code=77 then PutImage(OX*7,OY*7,LineIm[ML,Hor]^,NormalPut);
    75 : if Code=72 then PutImage(OX*7,OY*7,LineIm[ML,BLCor]^,NormalPut) else
         if Code=80 then PutImage(OX*7,OY*7,LineIm[ML,TLCor]^,NormalPut) else
         if Code=75 then PutImage(OX*7,OY*7,LineIm[ML,Hor]^,NormalPut);
    end; { case OldestCode }
  c:=PF[NX,NY];
  if c=Bl then GetBall(nx,ny);
  if (c=W) or (c=MW) or (c=ML) or (c=IBML) then
    begin
    lng[you]:=lng[you]-1;Tune:=7;
    ShowLenFlag[you]:=True;
    end
  else begin
  Pntr[You]:=Pntr[You]+1; if Pntr[You]>200 then Pntr[You]:=1;
  snk[You,Pntr[You]].x:=NX;snk[You,Pntr[You]].y:=NY;
  PF[NX,NY]:=ML;
  if (Code=72) or (Code=80) then PutImage(NX*7,NY*7,LineIm[ML,Ver]^,NormalPut)
    else PutImage(NX*7,NY*7,LineIm[ML,Hor]^,NormalPut);
  end; {else}
  if Lplus[You]>0 then
      begin Lplus[You]:=Lplus[You]-1;Lng[You]:=Lng[You]+1;
        ShowLenFlag[you]:=True; end
  else
    begin
    PF[TX,TY]:=Sp;
    PutImage(TX*7,TY*7,Null^,NormalPut);
    end;
  end;

procedure MoveIBM;
  var ox,oy,nx,ny,tx,ty : byte;
      gex,gey      : byte;
      LoWa              : array[0..3] of byte;
      Dngr              : array[0..3] of boolean;
      j,Tail            : integer;
      IBMFindsGem       : boolean;
      DeadEnd           : boolean;
      NewDir,OldDir     : byte;

  function Best(wx,wy: byte): byte;
    var Up,Down,Left,Right,a,b : integer;
    function Dist(ddx,ddy: integer): byte;
      var ij: integer;
      begin
      ij:=0;
      while (PF[a,b]=Sp) or (PF[a,b]=Bl)
         do begin ij:=ij+1;a:=a+ddx;b:=b+ddy; end;
      Dist:=ij;
      end;
    begin
    a:=wx;b:=wy-1;Up:=Dist(0,-1);
    a:=wx;b:=wy+1;Down:=Dist(0,1);
    a:=wx-1;b:=wy;Left:=Dist(-1,0);
    a:=wx+1;b:=wy;Right:=Dist(1,0);
    if (Up>=Down) and (Up>=Left) and (Up>=Right) then Best:=0;
    if (Down>=Up) and (Down>=Left) and (Down>=Right) then Best:=1;
    if (Left>=Up) and (Left>=Down) and (Left>=Right) then Best:=2;
    if (Right>=Up) and (Right>=Down) and (Right>=Left) then Best:=3;
    end;

  procedure IBMGetsGold(aa,bb : byte);
    var bonusl,bonuss : byte;
    i, ObN : integer;
    begin
    ObN:=0; BonusL:=0; BonusS:=0;
    for i:=1 to 3 do
     if (aa=Gold[i].gx) and (bb=Gold[i].gy) and (Gold[i].size>0) then ObN:=i;
    if ObN>0 then
      begin
      if Gold[ObN].Class=SB then begin BonusS:=Gold[ObN].Size*20;
                             BonusL:=0;Tune:=4;end;
      if Gold[ObN].Class=LB then begin BonusL:=Gold[ObN].Size*2;
                             BonusS:=0;Tune:=5;end;
      if Gold[ObN].Class=PS then begin BonusS:=100;
                             BonusL:=10;Tune:=6;end;
      Lplus[IBM]:=Lplus[IBM]+BonusL;
      if BonusS>0 then begin scr[IBM]:=scr[IBM]+BonusS;
                             ShowScoreFlag[IBM]:=True; end;
      PF[Gold[ObN].gx,Gold[ObN].gy]:=Sp;
      Gold[ObN].size:=0; Gold[ObN].Class:=0;
      end;
    end;

  begin
    OX:=snk[IBM,Pntr[IBM]].x; OY:=snk[IBM,Pntr[IBM]].y;
    Tail:=Pntr[IBM]-lng[IBM]; if Tail<1 then Tail:=Tail+200;
    TX:=snk[IBM,Tail].x;      TY:=snk[IBM,Tail].y;
    if XDir[IBM]=0 then
      if YDir[IBM]=-1 then OldDir:=0 else OldDir:=1;
    if YDir[IBM]=0 then
      if XDir[IBM]=-1 then OldDir:=2 else OldDir:=3;
    LoWa[0]:=PF[ox,oy-1]; LoWa[1]:=PF[ox,oy+1];
    LoWa[2]:=PF[ox-1,oy]; LoWa[3]:=PF[ox+1,oy];
    for j:=0 to 3 do
      if (Lowa[j]=W) or (Lowa[j]=MW) or (Lowa[j]=ML) or (Lowa[j]=IBML)
      then Dngr[j]:=True
      else Dngr[j]:=False;
    if (Dngr[0]=True) and (Dngr[1]=True) and
       (Dngr[2]=True) and (Dngr[3]=True)
    then begin ShowLenFlag[IBM]:=True; DeadEnd:=True; end
    else
      begin
      IBMFindsGem:=False; DeadEnd:=False;
      for j:=1 to 3 do if Gold[j].size>0 then
        begin
        GeX:=Gold[j].gx; Gey:=Gold[j].gy;
        if (OX=Gex) and (OY>Gey) and (Dngr[0]=False)
          then begin NewDir:=0; IBMFindsGem:=True; end;
        if (OX=Gex) and (OY<Gey) and (Dngr[1]=False)
          then begin NewDir:=1; IBMFindsGem:=True; end;
        if (OX>Gex) and (OY=Gey) and (Dngr[2]=False)
          then begin NewDir:=2; IBMFindsGem:=True; end;
        if (OX<Gex) and (OY=Gey) and (Dngr[3]=False)
          then begin NewDir:=3; IBMFindsGem:=True; end;
        end;
      if IBMFindsGem=False then
        if (Random(30)=1) or
           (Dngr[OldDir]=True)
        then
          if Random(7)<>1 then NewDir:=Best(OX,OY)
          else repeat NewDir:=Random(4) until Dngr[NewDir]=False;
      case NewDir of
        0: begin
           case OldDir of
           0: PutImage(OX*7,OY*7,LineIm[IBML,Ver]^,NormalPut);
           2: PutImage(OX*7,OY*7,LineIm[IBML,BLCor]^,NormalPut);
           3: PutImage(OX*7,OY*7,LineIm[IBML,BRCor]^,NormalPut);
              end;
           XDir[IBM]:=0; YDir[IBM]:=-1;
           end;
        1: begin
           case OldDir of
           1: PutImage(OX*7,OY*7,LineIm[IBML,Ver]^,NormalPut);
           2: PutImage(OX*7,OY*7,LineIm[IBML,TLCor]^,NormalPut);
           3: PutImage(OX*7,OY*7,LineIm[IBML,TRCor]^,NormalPut);
              end;
           XDir[IBM]:=0; YDir[IBM]:=1 ;
           end;
        2: begin
           case OldDir of
           0: PutImage(OX*7,OY*7,LineIm[IBML,TRCor]^,NormalPut);
           1: PutImage(OX*7,OY*7,LineIm[IBML,BRCor]^,NormalPut);
           2: PutImage(OX*7,OY*7,LineIm[IBML,Hor]^,NormalPut);
              end;
           XDir[IBM]:=-1;YDir[IBM]:=0 ;
           end;
        3: begin
           case OldDir of
           0: PutImage(OX*7,OY*7,LineIm[IBML,TLCor]^,NormalPut);
           1: PutImage(OX*7,OY*7,LineIm[IBML,BLCor]^,NormalPut);
           3: PutImage(OX*7,OY*7,LineIm[IBML,Hor]^,NormalPut);
              end;
           XDir[IBM]:=1; YDir[IBM]:=0 ;
           end;
        end; { case NewDir }
     if (IBMFindsGem=True) and (Lowa[NewDir]=Bl)
          then IBMGetsGold(OX+XDir[IBM],OY+YDir[IBM]);
    NX:=OX+XDir[IBM]; NY:=OY+YDir[IBM];
    Pntr[IBM]:=Pntr[IBM]+1;if Pntr[IBM]>200 then Pntr[IBM]:=Pntr[IBM]-200;
    snk[IBM,Pntr[IBM]].x:=NX; snk[IBM,Pntr[IBM]].y:=NY;
    PF[NX,NY]:=IBML;
    if XDir[IBM]=0 then PutImage(NX*7,NY*7,LineIm[IBML,Ver]^,NormalPut)
       else PutImage(NX*7,NY*7,LineIm[IBML,Hor]^,NormalPut);
    end; { if no danger }
    if Lplus[IBM]>0 then
      begin Lplus[IBM]:=LPlus[IBM]-1;
            if DeadEnd=False then Lng[IBM]:=Lng[IBM]+1;
            ShowLenFlag[IBM]:=True; end
      else
      begin
      PF[TX,TY]:=sp;
      PutImage(TX*7,TY*7,Null^,NormalPut);
      if DeadEnd=True then begin lng[IBM]:=lng[IBM]-1;Tune:=8;
                                 ShowLenFlag[IBM]:=True;end;
      end;
  end;

procedure SetMoveWall;
  var mwdir : byte;
      x0,y0 : byte;
  begin
  MoveWallFlag:=True; Tune:=9;
  MWInfo.mwpntr:=1;
  MWDir:=random(4);
  if (MWDir=0) and (snk[You,Pntr[You]].y>44) then MWDir:=1;
  if (MWDir=1) and (snk[You,Pntr[You]].y<4 ) then MWDir:=0;
  if (MWDir=2) and (snk[You,Pntr[You]].x<5 ) then MWDir:=3;
  if (MWDir=3) and (snk[You,Pntr[You]].x>73) then MWDir:=2
  ;
  case MWDir of
    0: begin MWInfo.mwxdir:=0 ; MWInfo.mwydir:=-1; end;
    1: begin MWInfo.mwxdir:=0 ; MWInfo.mwydir:=1 ; end;
    2: begin MWInfo.mwxdir:=-1; MWInfo.mwydir:=0 ; end;
    3: begin MWInfo.mwxdir:=1 ; MWInfo.mwydir:=0 ; end;
    end; {case MWDir}
  if MWInfo.mwxdir=0 then MWInfo.mwleng:=Random(22)+3
                     else MWInfo.mwleng:=Random(29)+7;
  case MWDir of
    0: begin x0:=Random(69)+5; y0:=48; end;
    1: begin x0:=Random(69)+5; y0:=0 ; end;
    2: begin x0:=78; y0:=Random(41)+4; end;
    3: begin x0:=0 ; y0:=Random(41)+4; end;
    end; {case MWDir}
  Mow[1].mwx:=x0; Mow[1].mwy:=y0;
  end;

procedure MoveWall;
  var OX,OY,NX,NY,TX,TY,pix : byte;
      Tail,i                : integer;
  begin
  OX:=Mow[MWInfo.mwpntr].mwx; OY:=Mow[MWInfo.mwpntr].mwy;
  NX:=OX+MWInfo.mwxdir    ; NY:=OY+MWInfo.mwydir    ;
  Tail:=MWInfo.mwpntr-MWinfo.mwleng+1;
  if Tail<1 then Tail:=Tail+35;
  if Tail>35 then Tail:=Tail-35;
  TX:=Mow[Tail].mwx         ; TY:=Mow[Tail].mwy         ;
  Pix:=PF[NX,NY];
  if Pix<>Sp then MWInfo.mwleng:=MWInfo.mwleng-1
    else
      begin
      PF[nx,ny]:=MW;
      MWInfo.mwpntr:=MWInfo.mwpntr+1;
      if MWInfo.mwpntr>35 then MWInfo.mwpntr:=1;
      Mow[MWInfo.mwpntr].mwx:=NX;
      Mow[MWInfo.mwpntr].mwy:=NY;
      if MWInfo.mwxdir=0 then PutImage(NX*7,NY*7,LineIm[MW,Ver]^,NormalPut)
                         else PutImage(NX*7,NY*7,LIneIm[MW,Hor]^,NormalPut);
      end;
  if (TX>0) and (TX<78) and (TY>0) and (TY<48) and (PF[tx,ty]=MW) then
    begin
    PF[TX,TY]:=Sp;
    PutImage(TX*7,TY*7,Null^,NormalPut);
    end;
  if MWInfo.mwleng=0 then
    begin
    MoveWallFlag:=False;
    for i:=1 to 30 do begin Mow[i].mwx:=0;Mow[i].mwy:=0;end;
    end;
  end;

procedure Play(Music: byte);
  var i: integer;
  begin
  case Music of
    1: Sound(1000+Counter*100);
    2: Sound(500 +Counter*100);
    3: case Counter of
       0: sound(1000); 1: sound(500); 2: sound(1500);
       3: sound(750);  4: sound(1250);5: sound(1000);
       end;
    4: Sound(1500-Counter*100);
    5: Sound(1000-Counter*100);
    6: case Counter of
       0: sound(500); 1: sound(300); 2: sound(700);
       3: sound(400); 4: sound(600); 5: sound(500);
       end;
    7: sound(300+Random(100));
    8: sound(100+Random(100));
    9: case Counter of 0: sound(100); 1: sound(120); 2: sound(100);
       3: sound(120); 4: sound(100); 5: sound(120); end;
   10: sound(1600+10*Counter);
   11: sound(1650-300*Counter);
   12: case Counter of 0: sound(600); 1: sound(800); 2: sound(400);
       3: sound(800); 4: sound(200); 5: sound(800); 6: sound(750);
       7: sound(700); 8: sound(650); 9: sound(600); end;
   13: case Counter of 0: sound(100); 1: sound(50); 2: sound(100);
       3: sound(50); 4: sound(200); 5: sound(175); 6: sound(150);
       7: sound(125); 8: sound(100); 9: sound(50); end;
  end; { case }
  Counter:=Counter+1;
  if Counter>MaxCounter then begin Counter:=0; Tune:=0; nosound; end;
  end;

procedure GlobalInit;
  begin
  Message[1]:='YOU WILL BE DESTROYED!';
  Message[2]:='TRUST YOUR FEELINGS!';
  Message[3]:='MAY THE FORCE BE WITH YOU!';
  Message[4]:='USE THE FORCE, LUKE!';
  Message[5]:='WAKE UP! IT''S TIME TO DIE!';
  Message[6]:='WORKERS OF ALL COUNTRIES, UNITE!';
  Message[7]:='LIFE IS LIVE, TROFF IS TROFF ...';
  Message[8]:='WELCOME TO MY NIGHTMARE (NIGHTWARE OR SOFTMARE) !';
  Message[9]:='MEOW !';
  Message[10]:='YOU''D BETTER PLAY SIERRA GAMES!';
  Message[11]:='YOU ARE SO BRIGHT!';
  Message[12]:='YOU''LL BE THE HERO OF THE SOVIET UNION!';
  Message[13]:='TRY TO WRITE "TROFF - 3" IF YOU''RE SO CLEVER!';
  Message[14]:='GRATEFUL PEOPLE WILL BUILD A STATUE OF YOU!';
  Message[15]:='SEE YOU LATER. TERMINATOR.';
  Message[16]:='IT''S A CATASTROFF!';
  Message[17]:='HAVE A NICE DEATH!';
  Message[18]:='TROFF IS TOO HARD FOR YOU. TRY TO PLAY CLIPPER';
  Message[19]:='TROFF II IS FOR ABSTINENTS ONLY';
  Message[20]:='NO CHANCE!';
  MessageFlag:=0;
  scr[1]:=0; scr[2]:=0;
  trn[1]:=0; trn[2]:=0;
  Tune:=0; Counter:=0;
  ToggleSound:=True;
  MaxTrn:=3;
  Speed:=30;
  MaxCounter:=5;
  EnemyToggle:=True;
  MWallToggle:=100;
  LenToWin:=200;
  Bonus[1]:=0; Bonus[2]:=0;
  GameNo:=0;
  Hisco:=0; Losco:=0; Hipla:=2; Lopla:=2;
  end;

procedure PrintMessage(MN : byte);
  begin
    SetColor(Cyan);SetTextStyle(SmallFont,HorizDir,4);
    OutTextXY(550-TextWidth(Message[MN]),341,Message[MN]);
  end;

procedure Destroy(Player : byte);
  var p, st, en : byte;
      tail : integer;
  begin
  en:=Pntr[Player];
  Tail:=en-lng[Player]-1;
  if Tail<1 then Tail:=Tail+200;
  st:=Tail;
  p:=st;
  repeat
    p:=p+1; if p>200 then p:=1;
    if ToggleSound=True then sound(Random(500)+Player*500);Delay(10);
    PutImage(snk[Player,p].x*7,snk[Player,p].y*7,Null^,NormalPut);
  until p=en;
  nosound;
  end;

procedure ShowNote;
  begin
  PutImage(631,0,Note^,XORPut);
  end;

procedure DeleteScreen;
  var i : integer;
  begin SetColor(1+Random(15)); nosound;
  for i:=0 to 319 do Rectangle(i,i-145,639-i,494-i);
  SetColor(Black);
  for i:=0 to 319 do Rectangle(i,i-145,639-i,494-i);
  end;

procedure CalcBonus;
  var i : integer;
  begin
  Bonus[1]:=0; Bonus[2]:=0;
  for i:=1 to 2 do if EndFlag[3-i]=True then
    begin
    Bonus[i]:=lng[i];
    case MWallToggle of
      300: Bonus[i]:=Bonus[i]+25;
      100: Bonus[i]:=Bonus[i]+50;
        0: Bonus[i]:=Bonus[i]+100;
        end; {case}
    Bonus[i]:=Bonus[i]+(50-Speed)*4;
    if EnemyToggle=True then Bonus[i]:=Round(Bonus[i]*3);
    end;
  end;

procedure ShowHighScore;
  function st(l:longint):string;
    var s: string;
    begin
    str(l,s);
    case length(s) of
      1: st:='0000000'+s; 2: st:='000000'+s; 3: st:='00000'+s;
      4: st:='0000'+s; 5: st:='000'+s; 6: st:='00'+s; 7: st:='0'+s;
      8: st:=s; end;
    end;
  procedure Pr(xi,yi: word; strn: string; s1,c1,s2,c2: byte; fo,si: word);
    var u,v : integer;
    begin
    SetColor(c1); SetTextStyle(fo,HorizDir,si);
    for u:=xi-s1 to xi+s1 do
      for v:=yi-s1 to yi+s1 do
        OutTextXY(u,v,strn);
    SetColor(c2);
    for u:=xi-s2 to xi do
      for v:=yi-s2 to yi+s2 do
        OutTextXY(u,v,strn);
    end;
  begin
    Pr(235,10,'Troff II',5,LightBlue,4,Blue,SmallFont,15);
    SetFillStyle(SolidFill,Brown);SetColor(Yellow);
    Bar3D(0,10,180,55,5,True); Bar3D(450,10,630,55,5,True);
    SetTextStyle(SmallFont,HorizDir,7);SetColor(LightRed);
    OutTextXY(32,9,'High Score');OutTextXY(490,9,'Low Score');
    SetColor(Yellow);
    OutTextXY(31,10,'High Score');OutTextXY(489,10,'Low Score');
    SetTextStyle(SmallFont,HorizDir,5);
    if Hipla=1 then
      Pr((180-TextWidth(st(Hisco))) div 2 -15,26,st(Hisco),1,0,0,10,1,3)
      else Pr((180-TextWidth(st(Hisco))) div 2 -15,26,st(Hisco),1,0,0,12,1,3);
    if Lopla=1 then
      Pr(455+((180-TextWidth(st(Losco))) div 2),26,st(Losco),1,0,0,10,1,3)
      else Pr(455+((180-TextWidth(st(Losco))) div 2),26,st(Losco),1,0,0,12,1,3);
  end;

procedure PressSpaceBar;
  var chch : char;
  begin
  SetTextStyle(SmallFont,HorizDir,4);
  SetUserCharSize(1,1,1,1);
  SetColor(White);
  OutTextXY(522,325,'Press Space Bar ...');
  repeat
    chch:=ReadKey;
  until chch=#32;
  end;

procedure StatusScreen;
  var Mes: array[1..10] of string;
        w: integer;
  function ss1(l:longint):string;
    var s:string;begin str(l,s);
    if length(s)=1 then ss1:='0'+s else ss1:=s;end;
  function ss2(l:longint):string;var s:string;begin str(l,s);ss2:=s;end;
  procedure Pri(xi,yi:word;stri:string;ci1,ci2:word);
    begin
    SetColor(ci2);
    OutTextXY(xi+2,yi-2,stri);OutTextXY(xi+1,yi-1,stri);
    SetColor(ci1);
    OutTextXY(xi,yi,stri);
    end;
  begin
  Mes[1]:='Turns to win'; Mes[2]:='Enemy Snake';
  Mes[3]:='Moving walls'; Mes[4]:='Max.Snake Length';
  Mes[5]:='Speed'       ; Mes[6]:='Sound';
  Mes[7]:='Winner :'    ; Mes[8]:='Score:';
  Mes[9]:='Bonus:'      ; Mes[10]:='Total:';
  ShowHighScore;
  SetLineStyle(0,0,3);
  SetColor(DarkGray); Rectangle(4,62,638,335);
  SetColor(LightGray);Rectangle(0,65,634,338);
  GameNo:=GameNo+1;
  SetTextStyle(SansSerifFont,HorizDir,2);
  pri(280,67,'Game '+ss1(GameNo),Yellow,Brown);
  SetUserCharSize(2,1,1,1);
  pri(140,67,ss1(trn[1]),LightGreen,Green);
  pri(440,67,ss1(trn[2]),LightRed,Red);
  SetUserCharSize(1,1,1,2);
  SetColor(Brown);Line(262,92,382,92);
  SetColor(Yellow);Line(260,94,380,94);
  SetLineStyle(0,0,1);
  for w:=1 to 6 do
    pri(300-TextWidth(Mes[w]),80+w*20,Mes[w],LightGray,DarkGray);
  pri(340,100,ss1(MaxTrn),13,5);
  if EnemyToggle=True then pri(340,120,'On',13,5)
                      else pri(340,120,'Off',13,5);
  case MWallToggle of
    -1: pri(340,140,'Off',13,5);
   300: pri(340,140,'Seldom',13,5);
   100: pri(340,140,'Often',13,5);
     0: pri(340,140,'Always',13,5);
     end;
  pri(340,160,ss1(LenToWin),13,5);
  pri(340,180,ss1(Speed),13,5);
    case Speed of
    0: pri(390,180,'(Madness)',13,5);
    1..10: pri(390,180,'(Very Fast)',13,5);
    11..20: pri(390,180,'(Fast)',13,5);
    21..30: pri(390,180,'(Normal)',13,5);
    31..40: pri(390,180,'(Slow)',13,5);
    41..50: pri(390,180,'(Very Slow)',13,5);
    end;
  if ToggleSound=True then pri(340,200,'On',13,5)
                      else pri(340,200,'Off',13,5);
  SetTextStyle(GothicFont,HorizDir,3);SetUserCharSize(2,1,1,1);
  pri(300-TextWidth(Mes[7]),220,Mes[7],LightCyan,Cyan);
  if EndFlag[IBM]=True then pri(340,220,'You',LightGreen,Green);
  if EndFlag[You]=True then pri(340,220,'mr.Troff',LightRed,Red);
  SetTextStyle(SansSerifFont,HorizDir,3); SetUserCharSize(1,1,1,2);
  for w:=8 to 10 do pri(40,100+w*20,Mes[w],Black,Brown);
  for w:=1 to 2 do begin
    pri(75+175*w,260,ss2(scr[w]),8+2*w,2*w);
    pri(75+175*w,280,ss2(bonus[w]),8+2*w,2*w);
    scr[w]:=scr[w]+bonus[w];
    pri(75+175*w,300,ss2(scr[w]),8+2*w,2*w);
    end;
    PressSpaceBar;
  end;

procedure GameOver;
var i,xj,yj,cj: integer;
    mess : array[1..6] of string;
    hsc,lsc : longint;
    hpl,lpl : byte;
  function ss3(l:longint):string;
    var s:string;
    begin str(l,s);
    if length(s)=1 then ss3:='0'+s else ss3:=s;
    end;
  function ss4(l:longint):string;
    var s,n:string;
    begin str(l,s);
    n:='00000000';
    if length(s)=8 then ss4:=s else
      ss4:=copy(n,1,8-length(s))+s;
    end;
  procedure prin(xl,yl:word;strin:string;cl1,cl2,cl3:word);
    begin
    SetColor(cl3);OutTextXY(xl+2,yl-2,strin);
    SetColor(cl2);OutTextXY(xl+1,yl-1,strin);
    SetColor(cl1);OutTextXY(xl,yl,strin);
    end;
  begin
  mess[1]:='GAME OVER'; mess[2]:='You'; mess[3]:='mr.Troff';
  mess[4]:='The Winner:'; mess[5]:='New High Score'; mess[6]:='New Low Score';
  for i:=0 to 500 do begin cj:=Random(15)+1;SetColor(cj);
    xj:=Random(640);yj:=Random(350);
    if Random(20)=1 then begin Line(xj-2,yj,xj+2,yj);Line(xj,yj-2,xj,yj+2);end;
    if Random(10)=1 then begin Line(xj-1,yj,xj+1,yj);Line(xj,yj-1,xj,yj+1);end;
    PutPixel(xj,yj,cj);end;
  SetTextStyle(SansSerifFont,HorizDir,5);SetColor(Yellow);
  OutTextXY(195,100,mess[1]);
  for i:=1 to 2 do begin SetColor(8+2*i);
    SetTextStyle(TriplexFont,HorizDir,5);
    OutTextXY(220-TextWidth(mess[1+i]),130+40*i,mess[1+i]);
    SetTextStyle(GothicFont,HorizDir,5);
    prin(250,130+40*i,ss3(trn[i]),Yellow,Brown,Red);
    SetTextStyle(SmallFont,HorizDir,12);
    prin(330,135+40*i,ss4(scr[i]),8+2*i,Black,2*i);
    end;
    SetTextStyle(SmallFont,HorizDir,14);
    prin(185,260,mess[4],White,LightGray,DarkGray);
    if Trn[You]=MaxTrn then prin(270,300,mess[2],Cyan,LightCyan,Cyan)
       else prin(220,300,mess[3],Magenta,LightMagenta,Magenta);
    if scr[You]>=scr[IBM] then
      begin hsc:=scr[You]; lsc:=scr[IBM];
            hpl:=You; lpl:=IBM; end
    else
      begin hsc:=scr[IBM]; lsc:=scr[You];
            hpl:=IBM; lpl:=You; end;
    SetTextStyle(SmallFont,HorizDir,4);
    if hsc>=hisco then
      begin hisco:=hsc; hipla:=hpl;
      prin(540,145+42*hpl,mess[5],LightCyan,LightBlue,Blue);end;
    if (FirstGameFlag=True) or (lsc<=losco) then
      begin FirstGameFlag:=False;
      losco:=lsc; lopla:=lpl;
      prin(540,145+42*lpl,mess[6],LightCyan,LightMagenta,Magenta);end;
    ShowHighScore;
    PressSpaceBar;
  end;

procedure SetGameOptions;
  label 224;
  var MS : array[1..8] of string;
       i : integer;
     chx : char;
      cd : byte;
  procedure print(prx,pry:word;prs:string;prc1,prc2:word);
    begin
    SetColor(prc2);
    OutTextXY(prx+3,pry-3,prs); OutTextXY(prx+2,pry-2,prs); OutTextXY(prx+1,pry-1,prs);
    SetColor(prc1);
    OutTextXY(prx,pry,prs);
    end;
  function ss0(l:integer):string;
    var s:string;begin str(l,s);ss0:=s;end;
  procedure enter(fld: byte);
    var j: integer;
    begin
    case fld of
      1: begin SetColor(White);
         for j:=1 to 12 do begin
         Rectangle(240+j*25,84,264+j*25,110);
         if j<=MaxTrn then SetFillStyle(InterLeaveFill,LightRed)
                      else SetFillStyle(InterLeaveFill,DarkGray);
         FloodFill(241+j*25,85,White);
         end; end;
      2: if EnemyToggle=True then
           begin print(290,110,'On',LightRed,Red);
                 print(370,110,'Off',DarkGray,DarkGray);end
         else
           begin print(290,110,'On',DarkGray,DarkGray);
                 print(370,110,'Off',LightRed,Red);end;
      3: begin
         print(290,140,'Off',DarkGray,DarkGray);
         print(370,140,'Easy',DarkGray,DarkGray);
         print(450,140,'Med.',DarkGray,DarkGray);
         print(530,140,'Hard',DarkGray,DarkGray);
         case MWallToggle of
           -1: print(290,140,'Off',LightRed,Red);
          300: print(370,140,'Easy',LightRed,Red);
          100: print(450,140,'Med.',LightRed,Red);
            0: print(530,140,'Hard',LightRed,Red);end;
         end;
      4: for j:=0 to 2 do
           if LenToWin=100+j*50 then
                print(370+80*j,170,ss0(100+50*j),LightRed,Red)
           else print(370+80*j,170,ss0(100+50*j),DarkGray,DarkGray);
      5: begin SetColor(White);SetFillStyle(InterLeaveFill,LightRed);
         Bar(299,207,601,227);Rectangle(299,207,601,227);
         SetFillStyle(InterLeaveFill,DarkGray);
         if Speed>0 then Bar(600-Speed*6,208,600,226);
         end;
      6: if ToggleSound=True then begin
           print(290,230,'On',LightRed,Red);
           print(370,230,'Off',DarkGray,DarkGray); end
         else begin
           print(290,230,'On',DarkGray,DarkGray);
           print(370,230,'Off',LightRed,Red); end;
    end; end;
  procedure Chan(fld:byte);
    begin
    case fld of
      1:begin if (chx=#75) and (MaxTrn>1) then MaxTrn:=MaxTrn-1;
              if (chx=#77) and (MaxTrn<12) then MaxTrn:=MaxTrn+1;end;
      2:EnemyToggle:=not EnemyToggle;
      3:if (chx=#75) then begin
          if MWallToggle=300 then MWallToggle:=-1;
          if MWallToggle=100 then MWallToggle:=300;
          if MWallToggle=0   then MWallToggle:=100; end
        else begin
          if MWallToggle=100 then MWallToggle:=0;
          if MWallToggle=300 then MWallToggle:=100;
          if MWallToggle=-1  then MWallToggle:=300; end;
      4: begin if (chx=#75) and (LenToWin>100) then LenToWin:=LenToWin-50;
          if (chx=#77) and (LenToWin<200) then LenToWin:=LenToWin+50; end;
      5: begin if (chx=#75) and (Speed<50) then Speed:=Speed+1;
          if (chx=#77) and (Speed>0) then Speed:=Speed-1; end;
      6: ToggleSound:=not ToggleSound;
    end;end;
  begin
    ShowHighScore;
    SetFillStyle(InterLeaveFill,DarkGray);SetColor(LightGray);
    Bar3D(0,70,633,349,5,True);
    MS[1]:='Turns To Win';
    MS[2]:='Enemy Snake';
    MS[3]:='Moving Walls';
    MS[4]:='Max.Snake Length';
    MS[5]:='Speed';
    MS[6]:='Sound';
    MS[7]:='Start Game';
    MS[8]:='Quit';
    SetTextStyle(SansSerifFont,HorizDir,4);
    for i:=1 to 8 do print(50,50+i*30,MS[i],LightGray,DarkGray);
    for i:=1 to 8 do enter(i);
    i:=7;
224:print(50,50+i*30,MS[i],LightGreen,Green);
    chx:=ReadKey;
    if chx=#0 then
      begin
      chx:=ReadKey;
      if (chx=#72) or (chx=#80) then print(50,50+i*30,MS[i],LightGray,DarkGray);
      if (chx=#72) and (i>1) then i:=i-1;
      if (chx=#80) and (i<8) then i:=i+1;
      if (chx=#77) or (chx=#75) then begin Chan(i);Enter(i);end;
      end;
    if chx<>#13 then goto 224;
    if i<7 then goto 224;
  if i=8 then QuitFlag:=True;
  end;

  procedure SQ(q1,w1,q2,w2,q3,w3,q4,w4,cc:word);
   var square: array[1..4] of PointType;
   begin square[1].x:=q1;square[1].y:=w1;square[2].x:=q2;square[2].y:=w2;
         square[3].x:=q3;square[3].y:=w3;square[4].x:=q4;square[4].y:=w4;
   SetColor(cc);SetFillStyle(SolidFill,cc);
   FillPoly(sizeof(square) div sizeof(pointtype),square);end;

procedure TroffTitle;
  label 129;
  var i,j: integer;
      chx:char;
   cn,cd: array[1..8] of word;
  procedure LLine(q1,w1,q2,w2,q3,w3,q4,w4,q5,w5,q6,w6:word);
   begin MoveTo(q1,w1);LineTo(q2,w2);LineTo(q3,w3);LineTo(q4,w4);
   LineTo(q5,w5);LineTo(q6,w6);end;
  begin
  cn[1]:=8;cn[2]:=7;cn[3]:=5;cn[4]:=13;cn[5]:=2;cn[6]:=10;cn[7]:=6;cn[8]:=12;
  cd[1]:=57;cd[2]:=59;cd[3]:=57;cd[4]:=1;cd[5]:=57;cd[6]:=59;cd[7]:=57;cd[8]:=1;
  SetLineStyle(0,0,3);SetColor(Blue);
  LLine(220,140,220,200,420,200,420,140,380,140,380,180);
  LLine(380,180,260,180,260,140,220,140,220,140,220,140);
  LLine(273,170,273,130,220,130,220,110,273,110,273,90);
  LLine(273,90,220,90,220,70,313,70,313,170,273,170);
  LLine(327,170,327,70,420,70,420,130,367,130,367,170);
  LLine(367,170,327,170,327,170,327,170,327,170,327,170);
  Circle(380,100,20);Line(380,86,380,115);Line(360,100,380,100);
  Line(390,94,390,96);SetLineStyle(0,0,1);
  SetTextStyle(TriplexFont,Horizdir,4);SetColor(LightBlue);
  OutTextXY(220,200,'UFP software');
  PressSpaceBar;
  cleardevice;
  SetColor(white);SetLineStyle(0,0,3);
  LLine(77,40,107,10,197,10,167,40,152,40,152,115);
  LLine(152,115,137,130,122,115,122,40,77,40,77,40);
  LLine(182,40,212,10,242,10,272,40,272,70,242,100);
  LLine(242,100,272,130,242,130,212,100,167,100,167,70);
  LLine(167,70,227,70,242,55,227,40,182,40,182,40);
  LLine(287,40,317,10,347,10,377,40,377,100,347,130);
  LLine(347,130,317,130,287,100,287,40,287,40,287,40);
  LLine(332,40,347,55,347,85,332,100,317,85,317,55);
  LLine(317,55,332,40,332,40,332,40,332,40,332,40);
  LLine(362,10,437,10,467,40,392,40,362,10,362,10);
  LLine(392,55,422,55,437,70,422,85,392,85,392,55);
  LLine(452,10,527,10,557,40,482,40,452,10,452,10);
  LLine(452,55,512,55,527,70,512,85,482,85,482,115);
  LLine(482,115,467,130,452,115,452,55,452,55,452,55);
  SetLineStyle(0,0,1);
  sq(125,170,155,190,275,190,305,170,White);
  sq(125,260,185,260,215,280,155,280,White);
  sq(215,280,245,260,305,260,275,280,White);
  sq(335,170,515,170,485,190,365,190,White);
  sq(335,260,395,260,425,280,365,280,White);
  sq(425,280,455,260,515,260,485,280,White);
  sq(155,190,215,190,185,210,125,210,Blue);
  sq(215,190,275,190,305,210,245,210,Blue);
  sq(125,300,155,281,275,282,305,300,Blue);
  sq(365,190,425,190,405,210,335,210,Blue);
  sq(425,190,485,190,515,210,445,210,Blue);
  sq(335,300,365,280,485,280,515,300,Blue);
  sq(125,170,155,190,125,210,125,210,Cyan);
  sq(125,260,155,280,125,300,125,300,Cyan);
  sq(185,210,215,190,215,280,185,260,Cyan);
  sq(335,170,365,190,335,210,335,210,Cyan);
  sq(335,260,365,280,335,300,335,300,Cyan);
  sq(395,210,425,190,425,280,395,260,Cyan);
  sq(275,190,305,170,305,210,305,210,LightBlue);
  sq(275,280,305,260,305,300,305,300,LightBlue);
  sq(215,190,245,210,245,260,215,280,LightBlue);
  sq(485,190,515,170,515,210,515,210,LightBlue);
  sq(485,280,515,260,515,300,515,300,LightBlue);
  sq(425,190,455,210,455,260,425,280,LightBlue);
  SetFillStyle(SolidFill,Red);
  FloodFill(137,15,White);FloodFill(227,15,White);
  FloodFill(332,15,White);FloodFill(392,15,White);
  FloodFill(400,60,White);FloodFill(512,15,White);
  FloodFill(467,58,White);SetColor(Yellow);
  SetTextStyle(SmallFont,HorizDir,6);
  OutTextXY(263,217,' Written by');
  OutTextXY(263,234,'N.Soumarokov');
  for i:=1 to 8 do setpalette(cn[i],cd[i]);
  sq(557,20,557,40,562,35,562,35,DarkGray);
  sq(557,40,562,35,577,40,577,40,LightGray);
  sq(557,40,577,40,562,45,562,45,Magenta);
  sq(557,40,562,45,557,70,557,70,LightMagenta);
  sq(557,40,557,70,552,45,552,45,Green);
  sq(557,40,552,45,537,40,537,40,LightGreen);
  sq(557,40,537,40,552,35,552,35,Brown);
  sq(557,40,552,35,557,20,557,20,LightRed);
  129: repeat
  i:=cd[8];
  for j:=8 downto 2 do begin setpalette(cn[j],cd[j-1]); cd[j]:=cd[j-1]; end;
  setpalette(cn[1],i); cd[1]:=i;
  delay(75);
  until keypressed;
  chx:=Readkey; if chx<>' ' then goto 129;
  end;

procedure BossKey;
  label 115;
  var i,j,h:integer;
          s:string;
        chx:char;
  begin
  SetActivePage(1);cleardevice;SetVisualPage(1);nosound;
  if Random(10)>0 then
  begin
  DrawScoreWindow;for i:=1 to 2 do begin SetFillStyle(SolidFill,8+i*2);
  SetColor(i*2);BAR3d(570+36*(i-1),70,584+36*(i-1),262,2,True);
  Line(585+36*(i-1),70,585+36*(i-1),262);end;
  SetColor(White);SetTextStyle(SmallFont,HorizDir,7);
  OutTextXY(568,25,'89');OutTextXY(604,25,'90');
  SetTextStyle(SmallFont,HorizDir,4);
  OutTextXY(573,277,'Business');OutTextXY(573,306,'Graphics');
  for i:=1 to 2 do
  for j:=0 to 11 do begin SetColor(i*2);SetFillStyle(SolidFill,8+i*2);h:=Random(100)+20;
    Bar3d(120-30*i+j*30,200+20*i,145-30*i+j*30,200+20*i-h,20,True);
    SetFillStyle(SolidFill,i*2);
    sq(120-30*i+j*30,200+20*i-h,145-30*i+j*30,200+20*i-h,165-30*i+j*30,185+20*i-h,140-30*i+j*30,185+20*i-h,2*i);
    sq(145-30*i+j*30,200+20*i-h,165-30*i+j*30,185+20*i-h,165-30*i+j*30,185+20*i,145-30*i+j*30,200+20*i,1+2*i);
    SetColor(White);SetTextStyle(SmallFont,VertDir,6);end;
    OutTextXY(67,240,'Jan');OutTextXY(97,240,'Feb');OutTextXY(127,240,'Mar');
    OutTextXY(157,240,'Apr');OutTextXY(187,240,'May');OutTextXY(217,240,'Jun');
    OutTextXY(247,240,'Jul');OutTextXY(277,240,'Aug');OutTextXY(307,240,'Sep');
    OutTextXY(337,240,'Oct');OutTextXY(367,240,'Nov');OutTextXY(397,240,'Dec');
    Line(50,240,50,70);Line(55,80,50,70);Line(50,70,45,80);
    SetColor(Yellow);SetTextStyle(SmallFont,HorizDir,3);h:=(Random(10)+1)*10;
    for i:=0 to 15 do begin Line(48,240-i*10,52,240-i*10);str(h*i,s);
    OutTextXY(30,237-i*10,s);end;
    SetTextStyle(TriplexFont,HorizDir,3);SetColor(random(15)+1);
    if Random(10)=0 then OutTextXY(0,0,'Cats'' Wool Growth') else
    if Random(10)=0 then OutTextXY(0,0,'Poltergeist in the USSR') else
    if Random(10)=0 then OutTextXY(0,0,'Alcohol sale in Sib-Sibiya') else
    if Random(10)=0 then OutTextXY(0,0,'Contacts of the 3d kind growth') else
    if Random(10)=0 then OutTextXY(0,0,'UFP software annual budget') else
    if Random(10)=0 then OutTextXY(0,0,'Number of ghosts catched by Ghostbusters') else
    if Random(10)=0 then OutTextXY(0,0,'Vice in Miami') else
    if Random(10)=0 then OutTextXY(0,0,'Cinetic energy of Darth Vader');
    repeat chx:=ReadKey; until chx=' ';
  end
  else
    begin
    SetTextStyle(TriplexFont,HorizDir,6);SetColor(LightGreen);
    OutTextXY(200,30,'Hey Boss!');SetColor(LightRed);
    OutTextXY(100,80,'C''mon Big Fella!');SetColor(Yellow);
    OutTextXY(150,150,'Do''Ya Wanna');SetColor(White);
    OutTextXY(150,200,'Play TROFF?!');
    h:=1;i:=100;
    115: repeat sound(i); i:=i+h;if (i>2000) or (i<100) then h:=-h;
    until keypressed;
    ch:=ReadKey; if ch<>' ' then goto 115;
    end;
  SetVisualPage(0);SetActivePage(0);nosound;
  end;

begin
  Gd:=EGA; Gm:=EGAHi; InitGraph(Gd,Gm,''); if GraphResult<>grOk then Halt(1);
  FirstGameFlag:=True; QuitFlag:=False;
  SetActivePage(0);SetVisualPage(0);
  GlobalInit;
  GetDefaultPalette(OldPal); Randomize;
  GetImages;
  ClearDevice; SetAllPalette(OldPal); TroffTitle;
  3:scr[1]:=0;scr[2]:=0;trn[1]:=0;trn[2]:=0;
    DeleteScreen;SetAllPalette(Oldpal);SetGameOptions;DeleteScreen;
  if QuitFlag=True then goto 4;
  2: ClearVariables;
  DrawScoreWindow; if ToggleSound=True then ShowNote;
  DrawPlayField;
  1: ShowScore;
  { ******************** Get Command *********************** }
    OldestCode:=OldCode;
    if KeyPressed then
      begin
      ch:=ReadKey;
      if ch=#0 then begin
      ch:=ReadKey;
      SaveCode:=Code;Code:=ord(ch);
      case Code of
      77 : if OldCode<>75 then begin XDir[1]:=1 ;YDir[1]:=0 ;OldCode:=77;end;
      75 : if OldCode<>77 then begin XDir[1]:=-1;YDir[1]:=0 ;OldCode:=75;end;
      72 : if OldCode<>80 then begin XDir[1]:=0 ;YDir[1]:=-1;OldCode:=72;end;
      80 : if OldCode<>72 then begin XDir[1]:=0 ;YDir[1]:=1 ;OldCode:=80;end;
      68 : ExitFlag:=True ;
      59 : begin PauseGame; Code:=SaveCode; end;
      60 : begin ToggleSound:=not ToggleSound; ShowNote;
           nosound; Code:=SaveCode; end;
      61 : begin Bosskey; Code:=SaveCode; end;
      end; { case }
      end; end;
  { ******************************************************** }
  MoveYou;
  if EnemyToggle=True then MoveIBM;
  ObN:=Random(3)+1;
  if (Gold[Obn].Class=PS) and (Gold[Obn].Size>0) then MoveSib(ObN);
  if random(10)=0 then Change(ObN);
  if MoveWallFlag=True then MoveWall;
  if MWallToggle>-1 then if
     (random(MWallToggle)=0) and (MoveWallFlag=False) then SetMoveWall;
  if (Tune>0) and (ToggleSound=True) then play(Tune);
  if ((MessageFlag=0) and (Random(2000)=0))
    then begin PrintMessage(Random(10)+1); MessageFlag:=100; end;
  if MessageFlag>0 then
    begin
    MessageFlag:=MessageFlag-1;
    if MessageFlag=0 then begin SetFillStyle(SolidFill,0);
                          Bar(251,342,550,349); end;
    end;
  delay(Speed);
  if (EndFlag[You]=False) and (EndFlag[IBM]=False)
     and (ExitFlag=False) then GoTo 1;
  if ExitFlag=True then goto 3;
  { ***  End of Turn *** }
    SetFillStyle(SolidFill,0);Bar(251,342,550,349);
    if (EndFlag[You]=True) then if Random(5)=0
       then PrintMessage(Random(5)+16);
    if (EndFlag[You]=False) then if Random(5)=0
       then PrintMessage(Random(5)+11);
    if EndFlag[IBM]=True then Destroy(IBM);
    if EndFlag[You]=True then Destroy(You);
    if ToggleSound=True then begin
    if EndFlag[IBM]=True then begin MaxCounter:=9;
       Counter:=0;repeat Play(12); delay(750); until Counter=0; end;
    if EndFlag[You]=True then begin MaxCounter:=9;
       Counter:=0;repeat Play(13); delay(750); until Counter=0; end;
    nosound;
       end;
    if EndFlag[IBM]=True then Trn[You]:=Trn[You]+1;
    if EndFlag[You]=True then Trn[IBM]:=Trn[IBM]+1;
    ShowTurnsFlag:=True; ShowScore; Delay(500);
    DeleteScreen; CalcBonus;
    StatusScreen; DeleteScreen;
    if (trn[1]<MaxTrn) and (trn[2]<MaxTrn) then GoTo 2;
    GameOver;
    scr[1]:=0;scr[2]:=0;trn[1]:=0;trn[2]:=0;Tune:=0;Counter:=0;GameNo:=0;
    goto 3;
4: CloseGraph; end.