Skip to content

Instantly share code, notes, and snippets.

@benbek
Created December 9, 2016 22:32
Show Gist options
  • Save benbek/a6182518e43e16b4d4b80d54005b9340 to your computer and use it in GitHub Desktop.
Save benbek/a6182518e43e16b4d4b80d54005b9340 to your computer and use it in GitHub Desktop.
Game of Life homework project, February 2003
{ ָ ¾ ´ × © ° ± ² ³ µ ¶ · ¸ ¹ ÷ » ¼ ½ ¿ ְ ֱ ֲ ֳ ִ ֵ ֶ ַ ֹ ֺ ֻ ּ
ֽ ־ ֿ ׀ ׁ ׂ ׃ װ ױ ײ ׳ ״        }
Program Life;
Uses CRT;
Const MAXGEN = 25 ;
Const MATSIZE = 8 ;
Const GENTIME = 750;
Const BlockCursor = $000A;
{ ִִִִִִִִִִִִִִִִִ´ Consts for playing music ֳִִִִִִִִִִִִִִִִִִִ }
Const s = 50; o = 100; q = 200; tq = 300; h = 400; th = 500; w = 800;
{ sixteenth,eighth,quarter,half,whole }
lC = 262; lD = 294; lE = 330; lF = 350; lG = 392; lA = 440; lB = 494;
lCs= 277; lDs= 311; lFs= 370; lGs= 415; lAs= 466;
C = 523; D = 587; E = 659; F = 698; G = 784; A = 880; B = 988;
Cs = 554; Ds = 622; Fs = 740; Gs = 830; As = 932;
hC = 1046; { two octaves } { constants for Play procedure }
{ ִִִִִִִִִ´ End of 'consts for playing music' section ֳִִִִִִִִִִ }
Var Board : Array [1..MATSIZE,1..MATSIZE] Of Boolean;
Board_Temp : Array[1..MATSIZE,1..MATSIZE] Of Boolean;
KeyPress : Char;
cgen, CurrentR, CurrentC, Living, Changes, neighbors : Integer;
OldCursor : Word; {For the "no-cursor" environment}
flag, gStatus : Boolean;
TimeDisplay : Real;
Procedure DrawBorder(BorderType : Integer; xTop : Integer; yTop : Integer; xBot : Integer; yBot : Integer);
{ Proc: DrawBorder
Purpose: Drawing a border, creating a frame
In: BorderType - Line's type (whatever ³ (1-Single) or ÷ (2-Double)
xTop & yTop - Coordinates of the left-topmost spot of the border
xBot & yBot - Coordinates of the right-bottommost spot of the border
Out:Nothing }
Var Count : Integer;
Begin
If BorderType=1 Then
Begin
GotoXY(xTop, yTop);
Write('');
For Count:=1 To (xBot-xTop) Do
Begin
GotoXY(xTop+Count,yTop);
Write('ִ');
End;
GotoXY(xBot,yTop);
Write('¿');
For Count:=1 To (yBot-yTop) Do
Begin
GotoXY(xTop,yTop+Count);
Write('³');
End;
GotoXY(xTop,yBot);
Write('ְ');
For Count:=1 To (xBot-xTop) Do
Begin
GotoXY(xTop+Count,yBot);
Write('ִ');
End;
For Count:=1 To (yBot-yTop) Do
Begin
GotoXY(xBot,yTop+Count);
Write('³');
End;
GotoXY(xBot,yBot);
Write('');
End
Else
Begin
GotoXY(xTop, yTop);
Write('ֹ');
For Count:=1 To (xBot-xTop) Do
Begin
GotoXY(xTop+count,yTop);
Write('ֽ');
End;
GotoXY(xBot,yTop);
Write('»');
For Count:=1 To (yBot-yTop) Do
Begin
GotoXY(xTop,yTop+count);
Write('÷');
End;
GotoXY(xTop,yBot);
Write('ָ');
For Count:=1 To (xBot-xTop) Do
Begin
GotoXY(xTop+count,yBot);
Write('ֽ');
End;
For Count:=1 To (yBot-yTop) Do
Begin
GotoXY(xBot,yTop+count);
Write('÷');
End;
GotoXY(xBot,yBot);
Write('¼');
End;
End;
Procedure Center (Text : String; Coloum : Integer);
Begin
{ Centers the text on the screen }
GotoXY((80-Length(Text)) DIV 2, Coloum);
Write(Text);
End;
Procedure DrawMain (startX : Integer; startY : Integer);
Var count, count2 : Integer;
Begin
{ This procedure draws the main board }
GotoXY(startX-3,startY);
Write('');
count:=1;
While count<((MATSIZE*4)-3) Do
{For count:=1 To ((MATSIZE*4)-3) Do}
Begin
GotoXY(startX+count,startY);
Write('ֲ');
count:=count+4; {Increases by 4 every cycle of the loop}
End;
GotoXY(startX+count,startY);
Write('¿');
GotoXY(startX-2,startY);
Write('ִִִ');
For count:=2 To MATSIZE*4-3 Do
Begin
GotoXY(startX+count,startY);
Write('ִִִ');
count:=count+3;
End;
For count:=1 To ((MATSIZE*2)-1) Do
Begin
GotoXY(startX-3,startY+count);
Write('³');
End;
count:=2;
While count<(MATSIZE*2) Do
{For count:=2 To 16 Do}
Begin
GotoXY(startX-3, startY+count);
Write('ֳ');
count:=count+2; {Increases by 2 every cycle of the loop}
End;
GotoXY(startX-3,startY+count);
Write('ְ');
count:=1;
While count<(MATSIZE*4) Do
{For count:=1 To MATSIZE*4 Do}
Begin
For count2:=1 To (MATSIZE*2) Do
Begin
GotoXY(startX+count,startY+count2);
Write('³');
End;
count:=count+4;
End;
count:=-2;
While count<((MATSIZE*4)-3) Do
{For count:=-2 To MATSIZE*4-3 Do}
Begin
count2:=2;
While count2<((MATSIZE*2)+1) Do
{For count2:=2 To 17 Do}
Begin
GotoXY(startX+count,startY+count2);
Write('ִִִ');
count2:=count2+2;
End;
count:=count+4;
End;
count:=1;
While count<((MATSIZE*4)-3) Do
{For count:=1 To MATSIZE*4-3 Do}
Begin
count2:=2;
While count2<(MATSIZE*2) Do
{For count2:=2 To 16 Do}
Begin
GotoXY(startX+count,startY+count2);
Write('ֵ');
count2:=count2+2;
End;
count:=count+4;
End;
count:=2;
While count<(MATSIZE*2) Do
{For count:=2 To 16 Do}
Begin
GotoXY(MATSIZE*4+2, startY+count);
Write('´');
count:=count+2;
End;
count:=1;
While count<((MATSIZE*4)-3) Do
{For count:=1 To MATSIZE*4-3 Do}
Begin
GotoXY(startX+count,MATSIZE*2+2);
Write('ֱ');
count:=count+4;
End;
GotoXY(startX+count,MATSIZE*2+2);
Write('');
End;
Procedure DrawCreatures;
{ Draws the creatures on the board }
Begin
For CurrentR:=1 To MATSIZE Do
Begin
For CurrentC:=1 To MATSIZE Do
Begin
GotoXY(CurrentR*4,CurrentC*2+1);
If Not Board[CurrentR,CurrentC] Then
Write(' ')
Else
Begin
TextColor(YELLOW);
Write('*');
End;
End;
End;
End;
Function Progress : Boolean;
{ This is the kernel of the program, consists of
progression in the generations }
Var neighbors : Integer;
Begin
{ Moving to the next generation
Out: 1 = Moving successful
0 = End of game }
Changes:=0;
For CurrentR:=1 To MATSIZE Do
Begin
For CurrentC:=1 To MATSIZE Do
Begin
neighbors:=0;
{Count neighbors}
If Board[CurrentR+1,CurrentC] Then Inc(neighbors);
If Board[CurrentR-1,CurrentC] Then Inc(neighbors);
If Board[CurrentR,CurrentC+1] Then Inc(neighbors);
If Board[CurrentR,CurrentC-1] Then Inc(neighbors);
If Board[CurrentR+1,CurrentC+1] Then Inc(neighbors);
If Board[CurrentR-1,CurrentC-1] Then Inc(neighbors);
If Board[CurrentR+1,CurrentC-1] Then Inc(neighbors);
If Board[CurrentR-1,CurrentC+1] Then Inc(neighbors);
{Check for birth}
If (Not Board[CurrentR,CurrentC]) And (neighbors=3) Then
Begin
{Check for margins}
If ((CurrentR<>1) And (CurrentR<>MATSIZE)) And ((CurrentC<>1) And (CurrentC<>MATSIZE)) Then
Begin
Board_Temp[CurrentR,CurrentC]:=True;
Inc(Changes);
Inc(Living);
End;
End;
{Check for margins}
If ((Board[CurrentR,CurrentC])) And (((CurrentR=1) Or (CurrentR=MATSIZE))
Or ((CurrentC=1) Or (CurrentC=MATSIZE)))
Then
Begin
Board_Temp[CurrentR,CurrentC]:=False;
Inc(Changes);
Dec(Living);
End
Else
{Check for bore and crowdness}
If (Board[CurrentR,CurrentC]) And (neighbors<2) Then
Begin
Board_Temp[CurrentR,CurrentC]:=False;
Inc(Changes);
Dec(Living);
End
Else If (Board[CurrentR,CurrentC]) And (neighbors>3) Then
Begin
Board_Temp[CurrentR,CurrentC]:=False;
Inc(Changes);
Dec(Living);
End;
End;
End;
For CurrentR:=1 To MATSIZE Do
For CurrentC:=1 To MATSIZE Do
Board[CurrentR,CurrentC]:=Board_Temp[CurrentR,CurrentC];
{Check for End-Of-Game}
TextColor(12);
GotoXY(40,7); Write('Changes: ',Changes,'; Living Creatures: ',Living,' ');
If Living<=0 Then
Begin
DrawBorder(2,38,10,73,14);
TextColor(GREEN); GotoXY(40,10); Write('¹ End Of Game ּ');
GotoXY(39,11); Write('There are no more living creatures');
GotoXY(39,12); Write('any longer. Therefore, the game ');
GotoXY(39,13); Write('has been discontinued. ');
TextColor(CYAN); GotoXY(50,3); Write(' END OF GAME ');
TextColor(LIGHTGREEN); Center('Would you like to play again (Y/N)?',22);
gStatus:=False;
End;
If Changes<=0 Then
Begin
DrawBorder(2,38,10,73,14);
TextColor(GREEN); GotoXY(40,10); Write('¹ End Of Game ּ');
GotoXY(39,11); Write('No changes were made during the ');
GotoXY(39,12); Write('generation change. Therefore, the ');
GotoXY(39,13); Write('game has been discontinued. ');
TextColor(CYAN); GotoXY(50,3); Write(' END OF GAME ');
TextColor(LIGHTGREEN); Center('Would you like to play again (Y/N)?',22);
gStatus:=False;
End;
{If (Living>0) And (Changes>0) Then
Begin}
gStatus:=(Living>0) And (Changes>0);
{End;}
If cgen=MAXGEN Then
Begin
DrawBorder(2,38,10,73,14);
TextColor(GREEN);
GotoXY(40,10); Write('¹ End Of Game ּ');
GotoXY(39,11); Write('The maximum number of generations ');
GotoXY(39,12); Write('has just been reached. Therefore, ');
GotoXY(39,13); Write('the game has been discontinued. ');
TextColor(CYAN); GotoXY(50,3); Write(' END OF GAME ');
TextColor(LIGHTGREEN); Center('Would you like to play again (Y/N)?',22);
gStatus:=False;
End;
Progress:=gStatus;
End;
Procedure HideCursor;
{ Purpose: Hides the cursor, for the sanity of esthetics }
Begin
ASM
{ Save the old Cursor type }
mov ah,03h
mov bh,01h { Screen page }
int 10h
mov word ptr OldCursor,cx
{ Set new cursor type }
mov ah,01h
mov cx,0FFFFh
int 10h
End;
End;
Procedure ShowCursor;
{ Purpose: Restores and then shows the cursor }
Begin
ASM
{ Restore the old Cursor type }
mov ah,01h
mov cx,OldCursor
int 10h
End;
End;
Procedure SolidCursor;
{ Purpose: Shows a block-solid cursor }
Begin
ASM
Mov AH,1
Mov BH,0
Mov CX,BlockCursor
Int $10
End;
End;
Procedure DeadTune;
{ Purpose: Plays the dead tune using the internal speaker }
Begin
Sound(220); { Beep }
Delay(200); { For 200 ms }
Sound(320);
Delay(200);
Sound(500);
Delay(200);
NoSound; { Relief! }
End;
Procedure Play(Note, Value : Integer);
{ Purpose: Plays the specified note and then waits the specified time }
Begin
Sound (Note);
Delay (Value);
NoSound;
Delay (20);
End;
Procedure StartTune;
{ Purpose: Plays a nice tune via the internal speaker }
Begin
Play (lG,q);
Play (lD,q); Play (lG,q); Play (lB,tq); Play (C,o);
Play (lB,q); Play (lA,h); Play (lA,q);
Play (lD,q); Play (lFs,q); Play (lA,tq); Play (lB,o);
Play (lA,q); Play (lG,h); Play (lG,q);
Play (lD,q); Play (lG,q); Play (lB,tq); Play (c,o);
Play (lB,q); Play (lA,h); Play (lA,q);
Play (D,q); Play (D,q); Play (C,q); Play (lA,q);
Play (lG,th);
End;
Procedure Beep;
{ Purpose: Beeps the user }
Begin
Sound(600);
Delay(100);
NoSound;
End;
Procedure ChangeTune;
{ Purpose: Plays a tune when a generation change occurs }
Begin
Sound(800);
Delay(40);
NoSound;
End;
Begin { Of the main program }
KeyPress:=Chr(1); {Initialize it here, before the main loop, so that
it won't be initialized in every cycle of the loop}
Repeat { Main loop }
{Initialization of variants}
cgen:=0; CurrentR:=1; CurrentC:=1; Living:=0; Changes:=0; neighbors:=0; Flag:=True; TimeDisplay:=GENTIME/1000;
For CurrentR:=1 To MATSIZE Do
For CurrentC:=1 To MATSIZE Do
Board[CurrentR,CurrentC]:=False;
TextBackground(BLACK);
ClrScr;
HideCursor;
TextColor(5); {textbackground(1);}
DrawBorder(1,1,1,80,24); {Maximum frame size}
TextColor(6); TextBackground(1);
Center('´ T H E G A M E O F L I F E ֳ',1);
TextColor(1); TextBackground(0);
GotoXY(3,3); Write('By Ben Bekerman and Assaf Zaltsman February 2003');
TextColor(9);
Center('The Life Game describes the natural evolving of a popolation in a given',6);
Center('area, on a few generations. This evolving is affected by births, deaths',7);
GotoXY(4,8); Write('and various enviroment conditions (for example, crowdness and');
GotoXY(4,9); Write('lonliness).');
TextColor(2);
DrawBorder(2,4,11,77,22);
Center('¹ RULES OF PLAYING ּ',11);
TextColor(15);
GotoXY(6,12); Write('- Each field on the board can carry one of two values:');
GotoXY(6,13); Write(' 1 = Living creature (represented by an *);'); GotoXY(47,13); TextColor(14); Write('*'); TextColor(15);
GotoXY(6,14); Write(' 0 = Dead creature (represented by an empty field).');
GotoXY(6,15); Write('- The neighbors'' number of a given field is the living fields'' number');
GotoXY(6,16); Write(' which are near that field (maximum of 8 neighbors).');
GotoXY(6,17); Write('- Continuing to the next generation is done by these rules:');
GotoXY(6,18); Write(' *If the field is located in the margins, no new creature will be born');
GotoXY(6,19); Write(' there. If a living creature is in the field - it''ll die.');
GotoXY(6,20); Write(' *If a living creature has less than two living neighbors, it''ll die');
GotoXY(6,21); Write(' (out of bore).');
TextColor(9); GotoXY(62,23); Write(' Next Page '); TextColor(YELLOW + BLINK); GotoXY(73,23); Write('');
If KeyPress<>'Y' Then StartTune;
ReadKey;
ClrScr;
TextColor(5);
DrawBorder(1,1,1,80,24);
TextColor(6); TextBackground(1);
Center('´ T H E G A M E O F L I F E ֳ',1);
TextColor(1); TextBackground(0);
GotoXY(3,3); Write('By Ben Bekerman and Assaf Zaltsman February 2003');
TextColor(9);
Center('The Life Game describes the natural evolving of a popolation in a given',6);
Center('area, on a few generations. This evolving is affected by births, deaths',7);
GotoXY(4,8); Write('and various enviroment conditions (for example, crowdness and');
GotoXY(4,9); Write('lonliness).');
TextColor(2);
DrawBorder(2,4,11,77,22);
Center('¹ RULES OF PLAYING ּ',11);
TextColor(15);
GotoXY(6,12); Write(' *If a living creature has more than three neighbors, it''ll die');
GotoXY(6,13); Write(' (out of crowdness).');
GotoXY(6,14); Write(' *If a living creature has two or three neighbors, it''ll keep on the');
GotoXY(6,15); Write(' living.');
GotoXY(6,16); Write(' *If an empty field has precisly three neighbors - a new creature will');
GotoXY(6,17); Write(' be born there.');
GotoXY(6,18); Write('- The game ends when one of the following occurs:');
GotoXY(6,19); Write(' *There are no more living creatures.');
GotoXY(6,20); Write(' *No changes were made during the generation switches (static mode).');
GotoXY(6,21); Write(' *The given number of generations has been finally reached.');
TextColor(9); GotoXY(49,23); Write(' Press any key to continue...');
ReadKey;
ClrScr;
TextColor(5); TextBackground(1);
DrawBorder(2,1,1,80,24);
TextColor(11); TextBackground(0);
Center('¹ T H E G A M E O F L I F E ּ',1);
TextColor(15);
DrawMain(5,2); {Draw main board}
CurrentR:=1;
CurrentC:=1;
TextColor(CYAN);
GotoXY(40,3); Write('Starting the Game');
GotoXY(40,4); Write('~~~~~~~~~~~~~~~~~');
TextColor(LIGHTGRAY);
GotoXY(40,6); Write('Move in the fields by the arrow keys.');
GotoXY(40,7); Write('While in a field press 1 (for a living');
TextColor(YELLOW); GotoXY(63,7); Write('1'); TextColor(LIGHTGRAY);
GotoXY(40,8); Write('creature) or 0 (for a dead one).'); TextColor(YELLOW); GotoXY(53,8); Write('0'); TextColor(LIGHTGRAY);
GotoXY(40,9); Write('You can also press SpaceBar to switch');
TextColor(YELLOW); GotoXY(59,9); Write('SpaceBar'); TextColor(LIGHTGRAY);
GotoXY(40,10); Write('a living creature by a dead one and');
GotoXY(40,11); Write('vice versa.');
TextColor(GREEN);
GotoXY(40,13); Write('When you''re finished, press ִ (Enter).');
TextColor(YELLOW); GotoXY(68,13); Write('ִ'); GotoXY(73,13); Write('Enter'); TextColor(LIGHTGRAY);
SolidCursor;
GotoXY(4,3);
Repeat
While Not KeyPressed Do; { do nothing }
KeyPress:=ReadKey;
If Ord(KeyPress)<>0 Then
Begin
Case Ord(KeyPress) Of
49: Begin
Board[CurrentR,CurrentC]:=True;
Board_Temp[CurrentR,CurrentC]:=True;
TextColor(14); Write('*'); TextColor(LightBlue);
GotoXY(CurrentR*4,CurrentC*2+1);
End;
48: Begin
Board[CurrentR,CurrentC]:=False;
Board_Temp[CurrentR,CurrentC]:=False;
TextColor(LightBlue) {Same as TextColor(9)}; Write(' ');
GotoXY(CurrentR*4,CurrentC*2+1);
End;
32: Begin
Board[CurrentR,CurrentC]:=Not Board[CurrentR,CurrentC]; {Invert}
Board_Temp[CurrentR,CurrentC]:=Not Board_Temp[CurrentR,CurrentC];
If Not Board[CurrentR,CurrentC] Then
Begin
{Board[CurrentR,CurrentC]:=False;
Board_Temp[CurrentR,CurrentC]:=False;}
TextColor(LightBlue) {Same as TextColor(9)}; Write(' ');
GotoXY(CurrentR*4,CurrentC*2+1);
End
Else
Begin
{Board[CurrentR,CurrentC]:=True;
Board_Temp[CurrentR,CurrentC]:=True;}
TextColor(YELLOW); Write('*'); TextColor(LightBlue);
GotoXY(CurrentR*4,CurrentC*2+1);
End;
End;
13:
flag:=False;
End;
TextColor(LightBlue);
End
Else
Begin
KeyPress:=ReadKey;
Case Ord(KeyPress) Of {72 Up key; 80 Down key; 75 Left; 77 Right}
72: Begin
If CurrentC<>1 Then
Begin
Dec(CurrentC);
GotoXY(CurrentR*4,CurrentC*2+1);
End
Else Beep;
End;
80: Begin
If CurrentC<>MATSIZE Then
Begin
Inc(CurrentC);
GotoXY(CurrentR*4,CurrentC*2+1);
End
Else Beep;
End;
75: Begin
If CurrentR<>1 Then
Begin
Dec(CurrentR);
GotoXY(CurrentR*4,CurrentC*2+1);
End
Else Beep;
End;
77: Begin
If CurrentR<>MATSIZE Then
Begin
Inc(CurrentR);
GotoXY(CurrentR*4,CurrentC*2+1);
End
Else Beep;
End;
End;
TextColor(LightBlue);
End;
TextColor(LightBlue);
Until flag=False;
ClrScr;
TextColor(5); TextBackground(1);
DrawBorder(2,1,1,80,24);
TextColor(11); TextBackground(0);
Center('¹ T H E G A M E O F L I F E ּ',1);
TextColor(15);
DrawMain(5,2); {Draw main board}
DrawCreatures; {Draw the creatures}
HideCursor;
TextColor(CYAN);
GotoXY(50,3); Write('GAME IN PROGRESS');
GotoXY(4,19); Write('M A I N B O A R D');
{Counting the living creatures}
For CurrentR:=1 To MATSIZE Do
For CurrentC:=1 To MATSIZE Do
If Board[CurrentR,CurrentC] Then Inc(Living);
Inc(cgen);
TextColor(RED);
GotoXY(45,5); Write('Generation: ',cgen,' out of ',MAXGEN);
DrawBorder(1,5,21,75,23);
TextColor(LIGHTGREEN); GotoXY(15,22); Write(' Moving on to the next generation in ');
Write(TimeDisplay:0:1,' seconds... ');
Delay(GENTIME);
{TextColor(LIGHTGREEN); Center('Press any key to move on to the next generation...',22);
ReadKey;}
Center(' Moving... ',22);
ChangeTune;
While Progress Do
Begin
DrawCreatures;
Inc(cgen);
TextColor(RED);
GotoXY(45,5); Write('Generation: ',cgen,' out of ',MAXGEN);
DrawBorder(1,5,21,75,23);
TextColor(LIGHTGREEN); GotoXY(15,22); Write(' Moving on to the next generation in ');
Write(TimeDisplay:0:1,' seconds... ');
Delay(GENTIME);
{TextColor(LIGHTGREEN); Center('Press any key to move on to the next generation...',22);
ReadKey;}
Center(' Moving... ',22);
ChangeTune;
End;
DeadTune;
While Not KeyPressed Do;
Repeat
KeyPress:=UpCase(ReadKey);
Until (KeyPress='Y') Or (KeyPress='N');
Until KeyPress='N';
GotoXY(80,24);
TextColor(LightGray);
ShowCursor;
NormVideo;
End.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment