Uses Crt, Dos;

Var
{ var for game}
 C            : Char;
 yanX ,  yanY ,
 ameX ,  ameY ,
 gunY ,   gunX : byte;
 ameDir       : ShortInt;
 mscore         : Word;
 yboo, gboo, gstart : Boolean;
{ var for time}
 h1,m1,s1,hund1 ,
 h2,m2,s2,hund2 : Word;
 mboo : Boolean;

Const
    yann =char(5 );
    amee =char(2 );
    gunn =char(94);
    blakk=char(0 );

{ assembly code form swag support team }
Procedure HideCursor; Assembler;
Asm
  MOV   ax,$0100
  MOV   cx,$2607
  INT   $10
end;

Procedure ShowCursor; Assembler;
Asm
  MOV   ax,$0100
  MOV   cx,$0506
  INT   $10
end;

{++++++++++ TIME +++++++++++}
Procedure TimeGameStart;
 begin
    if mboo=true then
     begin
     Gettime(h1,m1,s1,hund1);
     mboo:=false;
     end;
 end;

Procedure DoWhenAtLimit;
 begin
     Repeat
          mboo:=true;
        Gotoxy (12,21);
        Write(' Press `Q` to Exit or Press `C` to Continue');
          c:=Readkey;
           if (c='Q') or (c='q') then
             Halt;
     Until (c='C') or (c='c');
        Gotoxy (12,21);
        Write( '                                           ' );
 end;

Procedure Time_Con_Or_Exit( MyTimeLimit:byte );
 begin
 if (ameX=39) or (ameX=40) then begin
    Gettime(h2,m2,s2,hund2);
     if m2>m1 then
      if m2-m1>=MyTimeLimit then
        begin
           doWhenAtLimit;
        end;

     if h1<>h2 then
      if m2>=1 then
        begin
           doWhenAtLimit;
        end;
 end;
 end;

{++++++++++ Score +++++++++++}
Procedure writeScore;
 begin
   mscore:=mscore+100;
   Gotoxy (55,22); Write( '                  ' );
   Gotoxy (55,22); Write( 'score : ' ,mscore);
 end;

{+++++++ Game-Simbol ++++++++}
Procedure Yan;
 begin Write( yann); end;

Procedure Ame;
 begin Write( amee);  end;

Procedure Gun;
 begin Write( gunn); end;

Procedure Blank;
 begin Write( blakk); end;

Procedure iline;
 var
     myi : byte;
 begin
     for myi :=1 to 24 do BEGIN
     Gotoxy (80,myi); Write( 'x' );
     Gotoxy (1 ,myi); Write( 'x' ); END;
 end;

{+++++++++ Game-Run ++++++++++}
Procedure YanStart;
 var
  i : byte;
 begin
     For i:=1 To 3 Do
       begin
           Gotoxy ( 40, 16);
            TextColor(10+i);
           yan;
          Delay (350);
       end;
           Gotoxy ( 40, 16);
            TextColor(7);
           yan;
  end; { write yan color and Gotoxy=40,16}

Procedure ameRan;
 begin
     Randomize;
          ameX:=Random( 76)+3;
          ameY:=Random( 8)+5;
        ameDir:=Random(  2);

    if (ameDir=0) then
          ameDir:=-1     else
   if (ameDir=1) then
          ameDir:=1;
 end;

Procedure runAme;
 begin
   if gboo=false then
      Delay (50);

          if ameX=yanX then
              begin
                 Gotoxy ( ameX, ameY);
                  blank;       ameran;
              end;

            if ameX=79 then
             ameDir:=-1    else
            if ameX=2  then
             ameDir:=1;

               ameX:= ameX+ameDir;
          Gotoxy ( ameX,        ameY);    ame;
          Gotoxy ( ameX-ameDir, ameY);  blank;
          Delay  (50);
  end; { run Ame }


Procedure RunGun;
 begin
  IF gboo=true THEN
   BEGIN

    if gstart=true then
      begin
      { define GunX=YanX and define GunY=YanY-2 At First}
          gunX:=yanX;
          gunY:=yanY-2;
          gstart:=false;
      end;

           Dec (gunY);
           Gotoxy (gunX, gunY  );   gun;
           Gotoxy (gunX, gunY+1); blank;
           Delay (50);

        if (gunY<=ameY) then
          begin
              Gotoxy ( gunX, gunY);
               blank;
              gboo:=false;
          end;

         if (gunY=ameY) and (gunX=ameX) then
            begin
                Gotoxy ( ameX,ameY);
                TextColor (11);
                      Write ( '*' );  { write Boom}
                TextColor ( 7);
                Delay (75);
            writeScore;
            end;
   END;
 end;

Procedure RunYan;
 begin
    IF yboo=true THEN
     BEGIN
        if (c=#75) And (yanX>=4 ) then BEGIN
        { when press arrow left AND yanX more than 2}
             yanX := yanX-2;
           Gotoxy  ( yanX, yanY);    yan;
           Gotoxy  ( yanX+2, yanY); blank;
             Delay ( 25);
                                        END
        else
        if (c=#77) And (yanX<=77) then BEGIN
        { when press arrow right AND yanX less than 79}
            yanX := yanX+2;
           Gotoxy  ( yanX, yanY);    yan;
           Gotoxy  ( yanX-2, yanY); blank;
             Delay ( 25);
                                        END;
       yboo:=false;
    END;
  end; { RunYan}

begin Clrscr;
  HideCursor;
    yanstart;
     ameran;
     iline;
     yanX := 40;
     yanY := 16;      
       gstart:=false;
       gboo:=false;
       yboo:=false;
       mboo:=true;
      {start}

     while c<>#27 do
       Begin
         c:=readkey;
         IF c=#0 THEN
          BEGIN
             c:=readkey;
            if (c=#75) xor (c=#77) then
              begin
                 yboo :=true;
              end           
         else
         if c=#72 then
              begin
                gboo  :=true;
                gstart :=true;
              end;
           REPEAT
            rungun;
            runame;
            runyan;
            timeGameStart;
            time_Con_Or_Exit(3);
           UNTIL KeyPressed;
          END;

       End;

  ShowCursor;{end}
end.

โปรแกรมนี้เริ่มต้นที่ การเรียกใช้ unit CRT และ DOS

จากนั้นก็ประกาศตัวแปร
c เป็นตัวแปรสำหรับ รับค่า scan code
yanX yanY เป็นตัวแปรตำแหน่งของ ยาน
ameX ameY เป็นตัวแปรตำแหน่งของ ยานฝ่ายตรงข้าม
gunX gunY เป็นตัวแปรตำแหน่ง ของกระสุน
ameDir เป็นตัวแปร สำหรับกำหนดทิศทางซ้ายขวา
mscore เป็นตัวแปรเก็บ คะแนน
yboo gboo gstart เป็นตัวแปร boolean
yboo ทำหน้าที่ ควบคุมให้ ยาน ทำงานหรือหยุดทำงาน
gboo ทำหน้าที่ ควบคุมให้ กระสุน ทำงานหรือหยุดทำงาน
gstart ทำหน้าที่ กำหนด ตำแหน่งแรกของกระสุน เมื่อสั่งให้ยิง

h1 m1 s1 hund1 h2 m2 s2 hund2
เป็นตัวแปรเก็บค่าเกี่ยวกับเวลา ชั่วโมง นาที วินาที และมิลลิวินาที
โดยที่ h1 m1 s1 hund1 เก็บเวลาเริ่มต้น
และ   h2 m2 s2 hund2 เก็บเวลาปัจจุบัน เกมจะหยุดทำงาน
เมื่อเวลาปัจจุบันมากกว่า เวลาเริ่มต้น ตามระยะเวลาที่กำหนด
mboo เป็นตัวควบคุม ให้นับเวลา เริ่มต้นเดิม
หรือ นับเวลาเริ่มต้น เป็นเวลาใหม่

ประกาศค่าคงที่
 yann เป็น รูป ใบโพธิ์
 amee เป็น รูป หน้ายิ้ม
 gunn เป็นรูป ตัวยก
 blakk เป็นรูปช่องว่าง


HideCursor;  สั่งให้  ซ่อน cursor 
ShowCursor; สั่งให้  แสดง cursor







TimeGameStart;
ถ้า mboo= true 
( ทำการ นับเวลาเริ่มต้น กันใหม่
จากนั้น กำหนด mboo := false )





DoWhenAtLimit;
กำหนด mboo :=true
จากนั้นแสดง ข้อความ
' Press `Q` to Exit or Press `C` to Continue'
ถ้า ผู้เล่น กดปุ่ม q จะเป็นการปิดเกม
ถ้า ผู้เล่น กดปุ่ม c จะเป็นการเล่นเกมต่อ







Time_Con_Or_Exit ( MyTimeLimit : byte );
รับเวลาปัจจุบันมาเก็บ ไว้ในตัวแปร
ถ้า นาทีปัจจุบัน มากกว่า นาทีเริ่มต้น ให้ตรวจสอบ
ว่า นาทีปัจจุบัน มากกว่า นาทีเริ่มต้น เป็นระยะ
มากกว่าหรือเท่ากับ MyTimeLimit หรือเปล่า
ถ้า มากกว่าหรือเท่ากับ ให้ออกตัวคำสั่ง DoWhenAtLimit;

ถ้า ชั่วโมงเริ่มต้น กับ ชั่วโมงปัจจุบัน ไม่เท่ากัน
ให้ตรวจสอบ ถ้า นาทีปัจจุบัน มากกว่า 1
ให้ออกตัวคำสั่ง DoWhenAtLimit;
{ ผมสร้างกรณีตรวจสอบนี้เผื่อ ผู้เล่นเริ่มเล่นตอน นาทีที่ 58, 59
จะทำให้ นาทีปัจจุบันไม่มีทางมากกว่า นาทีเริ่มต้นได้ง่ายๆ
อาจจะทำให้โปรแกรมไม่หยุด ถ้าเกิดไม่กด esc




writeScore;
ทำการแสดง คะแนน
ที่ตำแหน่ง 55,22
ทำการเคลียจอว่างก่อน เผื่อมีตัวเลขอันก่อนๆ
หรือ อะไร ซ้อนทับอ่าน ทำให้ดูไม่ออกว่าเท่าไร



เครื่องหมายของเกม
ส่วนนี้เป็นส่วนแสดง เครื่องหมายของเกม
ที่ผมกำหนดเป็นค่าคงที่ ในส่วนบนไงล่ะ
ส่วน iline; ก็คือ แท่งอักษรตัว x ตำแหน่ง คอลัมภ์ 1 และ 80


















ส่วนการทำงานของเกม
ส่วนนี้ มี procedure อยู่ 5 อันด้วยกัน
1) YanStart;
อันนี้จะทำงานตอนเริ่มต้นเท่านั้น
ก็ไม่มีอะไรมาก เพียงแค่แสดง
ยานรูปใบโพธิ์ เป็นสีๆ ที่ตำแหน่ง 40,14








2) ameRan;
ทำการสุ่ม ตำแหน่งของ ยานฝ่ายตรงข้าม
          ameX:=Random( 76)+3; 
          ameY:=Random( 12)+1;
        ameDir:=Random(  2) ;
ที่ต้องทำการ บวกเพิ่ม เพราะ 
ฟังชั่น random จะเริ่มสุ่มตั้งแต่ [ 0 ถึง ค่าที่กำหนด ]
สำหรับ random( 76) จะหมายถึง สุ่มเลข 0-75 (เลข 76 ตัว)
ผมต้องการสุ่มให้ได้ค่า 3-78  จึงใช้วิธีการเพิ่มเลขอีก 3
เพื่อให้เลขสุ่ม จาก 0-75 กลายเป็น 3-78
random( 8) จะได้เลขสุ่ม 0-7 ผมต้องการเลข 5 ถึง 13
ผมก็ใช้วิธีบวกเพิ่มอีก 5 เพื่อจะได้เลขสุ่มเป็น 5-13
ส่วน ameDir จะสุ่มเลขศูนย์กับ 1 แบบเดิม ไม่มีการเพิ่ม

ถ้า ameDir สุ่มได้เลข 0 ให้กำหนด  ameDir:= -1
ถ้า ameDir สุ่มได้เลข 1 ให้กำหนด  ameDir:= 1



3) runAme;
เป็นคำสั่งเกี่ยวกับ การเคลื่อนที่ ของยานฝ่ายตรงข้าม
ถ้า gboo=false ให้ หน่วงเวลาการทำงาน 0.50 วินาที
( gboo ผมหมายถึงการทำงานของ กระสุน ถ้ากระสุนไม่มีการทำงาน
ผมจะ หน่วงเวลาให้ทำงานช้า * เพราะเวลากระสุนไม่ทำงาน
ยานฝ่ายตรงข้ามจะเคลื่อนที่เพียงอันเดียว ทำให้เคลื่อนไหวเร็ว
ต่างกับเมื่อกระสุนทำงานด้วย ความเร็วจะถูกลดลงครึ่งนึง )

ถ้า ameX = yanX ให้
ให้ไปที่ตำแหน่งยานปัจจุบัน แล้วเขียน ภาพว่าง(สีดำ) 
เพื่อลบภาพยานฝ่ายตรงข้าม ทิ้งไป
จากนั้นทำการสุ่ม ตำแหน่งของยานฝ่ายตรงข้ามใหม่
( ถ้าแนวดิ่งของยานผู้เล่น กับยานฝ่ายตรงข้าม ตรงกัน
ยานฝ่ายตรงข้าม จะย้ายหนี ไปตำแหน่งอื่น )

ถ้า ameX=79 ให้เปลี่ยน ameDir := -1
ถ้า ameX=2  ให้เปลี่ยน ameDir := 1

เปลี่ยนค่า ameX := ameX(อันเดิม)+ ameDir
ไปที่ตำแหน่ง ameX ,ameY เขียน ยานฝ่ายตรงข้าม
โดย ameX กับ ameY ได้ถูกกำหนดโดยการ random มาก่อนแล้ว
ไปที่ตำแหน่ง ameX-ameDir  , ameY เขียน blank
( ทำการลบภาพ ยานฝ่ายตรงข้ามอันเก่า)
หน่วงเวลา 0.50 วินาที สังเกตว่า การหน่วงเวลานี้จะทำงานเสมอ
เมื่อ สั่ง runAme; ทำงาน



4) RunGun;
ถ้า gboo=true ให้เริ่มทำงาน
ให้ตรวจสอบ ถ้า gtart=true ให้
ให้ตำแหน่งแนวดิ่งของกระสุน= ตำแหน่งแนวดิ่งของยานผู้เล่น
ตำแหน่งแนวนอนของกระสุน ให้น้อยกว่าตำแหน่งยาน 2 หน่วย
กำหนด gstart=false เพื่อให้เมื่อยานเคลื่อนที่ วิถีกระสุนจะได้ไม่
เคลื่อนตาม ( คือเมื่อ gstart=false แล้ว คำสั่ง
ภายใน if then อันนี้ จะไม่ ทำงาน )

ลดค่าของ gunY ลง 1
( สมมุติ gunY:=8 เมื่อ ผ่านคำสั่งนี้ gunY จะมีค่าเหลือ 7)
เราอาจจะใช้คำสั่ง gunY:=gunY-1; แทนคำสั่งนี้ก็ได้
ไปที่ตำแหน่ง gunX, gunY เขียนภาพ กระสุน
ไปที่ตำแหน่ง gunX, gunY เขียนภาพ ช่องว่าง
หน่วงเวลา 0.50 วินาที

ถ้า ตำแหน่งแนวดิ่งของกระสุน น้อยกว่าหรือเท่ากับ
     ตำแหน่งแนวดิ่งของยานฝ่ายตรงข้าม
ให้ไปที่ตำแหน่ง gunX, gunY แล้วลบภาพกระสุนทิ้งไป
กำหนด gboo:=false ( สั่ง กระสุนหยุดทำงานทำงาน)

ถ้า   ตำแหน่งแนวดิ่งของกระสุน=ตำแหน่งแนวดิ่งของยานฝ่ายตรงข้าม
และ ตำแหน่งแนวนอนของกระสุน=ตำแหน่งแนวตั้งของยานฝ่ายตรงข้าม
 ให้ ไปที่ตำแหน่ง ameX, ameY
กำหนดสี (ฟ้า)
 เขียนภาพ ระเบิด
กำหนดสี (เทา)
หน่วงเวลา 0.75 วินาที
แล้วก็เขียน คะแนน



5) RunYan;
ถ้า yboo=true ให้
ตรวจสอบ ถ้า c=#75 ( ปุ่ม left arrow )
และ ตำแหน่งยานผู้เล่นทางแนวนอนมากกว่าหรือเท่ากับ 4 จากนั้น
yanX := yanX-2 ( ลดค่าของ yanX ลง 2 หน่วย )
ไปที่ตำแหน่ง yanX, yanY แล้วเขียนภาพยานผู้เล่น
ไปที่ตำแหน่ง yanX+2, yanY ลบภาพยานภาพเดิมทิ้งไป
หน่วงเวลา 0.25 วินาที

นอกเหนือจากนั้น
ถ้า c=#77 และตำแหน่งยานทางแนวนอน น้อยกว่าหรือเท่ากับ 77
จากนั้นให้
yanX := yanX+2 ( เพิ่มค่าให้ yanX 2 หน่วย )
ไปที่ตำแหน่ง yanX, yanY แล้วเขียนภาพยานผู้เล่น
ไปที่ตำแหน่ง yanX+2, yanY ลบภาพยานภาพเดิมทิ้งไป
หน่วงเวลา 0.25 วินาที
 
เมื่อจบการตรวจสอบ
ให้กำหนด yboo:=false ( เป็นการ ทำให้ยานผู้เล่นหยุดเคลื่อนที่ )


* ส่วนการทำงาน
ล้างหน้าจอ ให้เป็นสีดำทั้งหมด
ทำการ HideCursor;
ทำการ yanStart;
ทำการ iline;
ทำการ ameRan;
กำหนดตำแหน่งยานผู้เล่น แนวนอน ในตอนเริ่มต้น :=40
กำหนดตำแหน่งยานผู้เล่น แนวดิ่ง  ในตอนเริ่มต้น :=14
gstart:=false;  หมายถึงหยุดคำสั่ง if then อันหนึ่ง
ภายใน โพรซีเจอร์ runGun; ไม่ให้ทำงาน
gboo:=false; หมายถึงหยุดไม่ให้ runGun ทำงาน
yboo:=false; หมายถึงหยุดไม่ให้ ยานผู้เล่นเคลื่อนที่
mboo:=true; หมายถึงหยุดไม่ให้ นับเวลาเริ่มต้น เวลาใหม่

ขณะที่ c ไม่เท่ากับ #27 (ปุ่ม esc )
เริ่มทำงาน
รับค่าจาก scancode ของkeyboard เก็บใน c
ถ้า c=#0 (ปุ่มพิเศษนอกเหนือจาก abcdefg 123 ฯลฯ ) จากนั้นให้
รับค่าจาก scancode ของkeyboard เก็บใน c
ถ้า c=#75 ( ปุ่ม left ) หรือ c=#77 (ปุ่ม right )
ให้กำหนด yboo:=true; (หมายถึงให้ยานเคลื่อนที่ได้ )
นอกเหนือจากนั้น ถ้า c=#72 (ปุ่ม up) ให้กำหนด
gboo :=true; หมายถึงให้ยานกระสุนยิงได้
gstart :=true; หมายถึงกำหนด ตำแหน่งเริ่มต้นของกระสุน

เมื่อผ่านการ รับ scancode มาเก็บไว้ที c แล้ว
ให้ทำการวนซ้ำ
rungun;
runame;
runyan;
timeGameStart;
time_Con_Or_Exit(3);
จนกระทั่ง มีการกดปุ่ม keyboard
ซึ่งคำสั่งใดจะทำ งานได้หรือไม่ทำงาน
ก็ขึ้นอยู่กับ ผู้เล่นจะกด ปุ่ม key อันใด

ส่วน timeGameStart;
จะรับค่าเวลาเริ่มต้น
จากนั้นก็จะกำหนด mboo:=false ทำให้ การวนซ้ำครั้งต่อไป
ไม่มีการรับค่าเริ่มต้น อันใหม่
ส่วน time_Con_or_Exit(3)
จะรับเวลาปัจจุบัน ในทุกรอบ และเมื่อ
เวลาปัจจุบันมากกว่าเวลา เริ่มต้น เกิน 3 นาที
โปรแกรมก็จะ แสดงข้อความให้เลือกว่าจะเล่นต่อ
หรือจะออกจากเกมส์

เมื่อใดที่มีการกด esc ก็จะทำการ
ShowCursor; และก็จบโปรแกรม