Population(3)
1¡£The problem of human
Programming Project
The game of life is a simulation of population movement and fluctuation developed by
John Conway of Cambridge University. The simulation takes place on a grid of
locations, each of which can contain an ¡°entity¡±. Each such location has eight
¡°neighbours¡±, e.g. N, S, E, W, NE, NW, SE, and SW. The state of each ¡°generation¡± is
determined by the state of the previous one according to the following two rules:
¡¤ An entity in a cell (represented by 1) survives to the next generation if it has either
two or three neighbours; otherwise it dies.
¡¤ An empty cell (represented by 0) that has exactly three neighbours has a new
entity born in it.
For example:
Current Generation Next Generation
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 1 0 0 0 0 1 0 1 1 0
0 0 1 1 1 1 0 0 1 1 0 1 1 0
0 0 1 0 0 0 0 0 1 1 0 1 0 0
0 0 1 0 0 0 0 0 1 1 1 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
You are going to write a program that implements the rules of life for an area, which is
15 by 15. The project consists of three key components, to be completed in three parts:
(i) Initialize a binary (0 or 1 valued) data array of 15 by 15, and print it to the
screen for several generations.
(ii) Display each generation in graphics, in place of printings,
(iii) Enable users to input 1¡¯s and 0¡¯s in the grid cells by using the mouse.
Programming Assignment I [30 marks]
In this assignment, you are to complete part (i) of the programming project.
You must structure your program with procedures.
Specification of Part I of the project:
You will need to set up two 15 x 15 arrays, one which has been initialized with 0¡¯s and
1¡¯s will be the current grid, the other will be the grid into which you place the next
generation. After each iteration you will need to copy the new array into the old one,
print it out, and then start again. Make your program modular by writing procedures that
perform specific well-defined functions. In particular, you must write the following
procedures:
¡¡
call EnterCells; initialize the game of life display Go/Exit buttons; green to Go and red to Exit loop forever wait for a mouse click; if red button pressed, return to DOS; if green button pressed then ¡ call DisplayArray, draws it on the left side of screen; ¡ call NewGeneration; ¡ call DisplayArray; draws it on the right side of screen; end if end loop
¡¡
The new procedures to be written are briefly described below.
1. GetArrayElementIndex:
Each compartment in the grid corresponds to an array element in memory.
This procedure will compute row and column index (
r,c) of thecorresponding array element for a given coordinate (
x,y) in (cx,dx ), andreturn (
r,c) in (bx,si). A value of ¨C1 will be returned in bx if the pixelcoordinate (
x,y) is located outside the grid. [Hint: if (x0,y0) is the left-topcorner of the grid, and each compartment is 8 pixels long, we can
conclude that
c = (x ¨C x0) / 8 and r = (y ¨C y0) / 8. Why?]2. ToggleCell:
This procedure will toggle (switch back and forth) between a ¡®0¡¯ and ¡®1¡¯
of the array element in memory. It receives as input the array index (
r,c) in(
bx,si), and makes changes of the array element from ¡®0¡¯ to ¡®1¡¯, or from¡®1¡¯ to ¡®0¡¯.
3. EnterCells:
Call DisplayArray to display the grid of empty cells. Wait until a mouse
button is clicked. The procedure returns when the right mouse button is
clicked. If a left mouse button is clicked and it is inside the grid, call
GetArrayElementIndex to compute the row and column index (
r,c) of thecorresponding array element, and call ToggleCell to change the value of
the array element from 0 to 1 or 1 to 0, followed by repainting the newly
changed cell only. It is not necessary to repaint the entire grid of cells.
Ignore any mouse clicks outside the grid.
¡¡
2. My Program
TITLE LIFESTYLE DIM EQU 15; CELLSIZE EQU 8; OLDX EQU 0 OLDY EQU 15 NEWX EQU 170 NEWY EQU 15 INPUTX EQU 75 INPUTY EQU 15 REDX EQU 80 REDY EQU 150 GREENX EQU 120 GREENY EQU 150 BOXSIZE EQU 35 DEADCOLOR EQU 01H; WHITE LIVECOLOR EQU 07H; BLUE .DOSSEG .MODEL SMALL .STACK 100H .DATA DIMENSION DB DIM RETURNSTR DB 0AH, 0DH, '$' MSG DB "PRESS RETURN KEY TO ENTER A NEW GENERATION ", "$" COUNTER DB 0; POS DW 0; OLD DB 225 DUP(0); NEW DB 225 DUP(?); .CODE EXTRN ENTERGRAPHIC:NEAR, ENTERTEXT:NEAR, WAITRETURN:NEAR, DRAWBOX:NEAR, FILLGRID:NEAR, DRAWVERLINE:NEAR , DRAWHORLINE:NEAR, DRAWGRID:NEAR, GETCELLINDEX:NEAR, MOUSECLICK:NEAR, MOUSEINIT:NEAR, MOUSESHOW:NEAR, MOUSEHIDE:NEAR START: MOV AX, @DATA MOV DS, AX; CALL SHOWMESSAGE CALL WAITRETURN; CALL ENTERGRAPHIC CALL ENTERCELLS L49: ; FIRST DRAW OLD AT LEFT SIDE CALL MOUSEHIDE MOV AX, OLDX PUSH AX MOV AX, OLDY PUSH AX CALL DRAWALLELEMENTS ; CALL NEWGENERATION ;NOW DRAW ON RIGHT SIDE OF NEW GENERATION MOV AX, NEWX PUSH AX MOV AX, NEWY PUSH AX CALL DRAWALLELEMENTS L47: CALL TESTBUTTON CMP AX, -1; NO HIT JE L47 CMP AX, 0; JNE L48 ; IF IT IS RED CALL MOUSESHOW JMP L49 L48: CALL ENTERTEXT; MOV AX, 4C00H INT 21H ;INTERNAL METHOD TO CHECK IF WITHIN SCOPE ;OUTPUT: AX =1 HIT, AX =0 MISS ;INPUT CX=X, DX=Y, ORIGIN X, Y ,SIZE BY STACK INTERNALTEST PROC NEAR PUSH BP MOV BP, SP MOV AX, [BP+8]; THE ORIGIN X CMP AX, CX JG INTERNALTEST_ ADD AX, [BP+4]; ADD SIZE TO X CMP AX, CX JL INTERNALTEST_ MOV AX, [BP+6]; THE ORIGIN Y CMP AX, DX JG INTERNALTEST_ ADD AX, [BP+4]; ADD SIZE TO Y CMP AX, DX JL INTERNALTEST_ MOV AX, 1; HIT JMP L39 INTERNALTEST_: MOV AX, 0; MISS L39: RET 6 INTERNALTEST ENDP ;FUNCTION: TEST MOUSE TO SEE IF BUTTON IS CLICKED ;INPUT: NONE ;OUTPUT: AX=1 RED CLICKED, AX=0 GREEN CLICK; AX=-1; NO CLICKED TESTBUTTON PROC NEAR PUSH BX PUSH CX PUSH DX L29: CALL MOUSECLICK CMP BX, 01H; TO SEE IF LEFTBUTTON CLICKED; MAY NOT BE NECESSARY JNE L29 TESTGREEN: MOV AX, GREENX PUSH AX MOV AX, GREENY PUSH AX MOV AX, BOXSIZE PUSH AX CALL INTERNALTEST CMP AX, 0; JE TESTRED; MISS MOV AX, 0; AS O INDICATE GREEN JMP TESTBUTTON_ TESTRED: MOV AX, REDX PUSH AX MOV AX, REDY PUSH AX MOV AX, BOXSIZE PUSH AX CALL INTERNALTEST CMP AX, 0; JE NOHIT MOV AX, 1; AS 1 INDICATE RED JMP TESTBUTTON_ NOHIT: MOV AX, -1; TESTBUTTON_: POP DX POP CX POP BX RET TESTBUTTON ENDP ;FUNCTION: DRAW GREEN AND RED BUTTON ;OUTPUT: NONE ;INPUT: NONE DRAWBUTTON PROC NEAR PUSH AX ;PASS PARAM TO CALL DRAWBOX MOV AX, GREENX PUSH AX; X MOV AX, GREENY PUSH AX; Y MOV AX, BOXSIZE PUSH AX; SIZE MOV AX, 02H; GREEN COLOR PUSH AX CALL DRAWBOX MOV AX, REDX PUSH AX MOV AX, REDY PUSH AX MOV AX, BOXSIZE PUSH AX MOV AX, 01H PUSH AX; COLOR RED CALL DRAWBOX POP AX RET DRAWBUTTON ENDP ;FUNCTION: DISPLAY OLD EMPTY GRID UNTIL RIGHTCLICK, INPUT CELL BY TOGGLING. ;OUTPUT: NONE ;INPUT: NONE ENTERCELLS PROC NEAR PUSH AX PUSH BX ;DRAW OLD GRID NOW MOV AX, INPUTX PUSH AX MOV BX, INPUTY PUSH BX CALL DRAWALLELEMENTS CALL DRAWBUTTON ;PASS ORIGIN TO CALL INPUTDATA PUSH AX; STILL INPUTX PUSH BX; STILL INPUTY CALL INPUTDATA POP BX POP AX RET ENTERCELLS ENDP ;FUNCTION: CHANGE VALUE OF ARRAY, AND REPAINT CELL CHANGED ;INPUT: BX=ROW, SI=COL, ;OUTPUT: NONE TOGGLECELL PROC NEAR PUSH AX PUSH CX PUSH DX CMP BX, -1; TO SEE IF OUTSIDE JE TOGGLECELL_ PUSH BX; KEEP OLD PARAM PUSH SI; KEEP OLD PARAM ;FIRST GET VALUE OF ELEMENT IN ARRAY MOV AX, DIM MUL BX; ROW X DIM XOR AX, AX; CLEAR MOV AL, OLD[BX+SI] XOR AL, 1 MOV OLD[BX+SI], AL ;NOW PASS PARAM TO REPAINT CHANGED GRIDCELL MOV CX, OLDX PUSH CX; PASS ORIGIN X MOV CX, OLDY PUSH CX; PASS ORIGIN Y PUSH BX; POS X PUSH SI; POS Y MOV CX, CELLSIZE PUSH CX CMP AL, 00H; 00H MEANS DEAD JE PAINTDIE MOV AL, LIVECOLOR JMP PARAMPASSED PAINTDIE: MOV AL, DEADCOLOR; PARAMPASSED: PUSH AX CALL FILLGRID TOGGLECELL_: POP SI POP BX POP DX POP CX POP AX RET TOGGLECELL ENDP ;FUNCTION: WAIT TO TOGGLE CELL UNTILL RIGHT CLICK ;OUTPUT: NONE ;INPUT: ORIGIN X,Y INPUTDATA PROC NEAR PUSH BP MOV BP, SP PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI WAITCLICK1: CALL MOUSEINIT CALL MOUSESHOW CALL MOUSECLICK CMP BX, 02H; TO SEE IF IT IS RIGHTBUTTON CLICKED JE INPUTDATA_ MOV AX, [BP+6]; THE X ORIGIN PUSH AX MOV AX, [BP+4]; THE Y ORIGIN PUSH AX PUSH CX; THE X POS PUSH DX; THE Y POS MOV AX, DIM PUSH AX; THE DIM OF GRID MOV AX, CELLSIZE PUSH AX CALL GETCELLINDEX CALL TOGGLECELL JMP WAITCLICK1 INPUTDATA_: POP SI POP DX POP CX POP BX POP AX POP BP RET 4 INPUTDATA ENDP ;INPUT: NONE ;OUTPUT: NONE ;FUNCTION: CHANGE NEW LINE CHANGELINE PROC PUSH AX PUSH DX MOV AH, 09H MOV DX, OFFSET RETURNSTR INT 21H POP DX POP AX RET CHANGELINE ENDP ;INPUT: X,Y ;OUTPUT: NONE DRAWALLELEMENTS PROC PUSH BP MOV BP, SP PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI; ; FIRST DRAW GRID MOV AX, [BP+6]; X PUSH AX MOV AX, [BP+4]; Y PUSH AX CALL DRAWGRID MOV BX, OFFSET OLD; BX IS ARRAY, THE OLD ARRAY MOV CX, DIM; CX IS THE COUNTER MOV DX, 0; DX IS THE ROW MOV SI, 0; SI IS THE COL LOCALOUTER: PUSH CX MOV CX, DIM; INITIALIZE INNER COUNTER LOCALINNER: ;PREPAREPARAM ; AS THIS IS PART IS SAME PARAM NO MATTER DIE OR LIVE MOV AX, [BP+6]; X PUSH AX MOV AX, [BP+4]; Y PUSH AX PUSH DX; ROW PUSH SI; COL MOV AX, CELLSIZE; SIZE OF CELL IS 8 PUSH AX MOV AL, [BX]; THIS IS TO SEE IF IT IS LIVE OR DIE CMP AL, 1 JE DRAWLIFE DRAWDIE: MOV AX, DEADCOLOR; WHITE PUSH AX CALL FILLGRID; JMP NEXTINNER DRAWLIFE: MOV AX, LIVECOLOR; COLOR BLUE PUSH AX CALL FILLGRID NEXTINNER: INC SI; COL IS INC INC BX; BX IS NEXT ELEMENT LOOP LOCALINNER ;OUTER LOOP MOV SI, 0; NEW COL START FROM 0 INC DX; NEXT ROW POP CX; RESTORE OUTER COUNTER LOOP LOCALOUTER POP SI POP DX POP CX POP BX POP AX POP BP RET 4; DRAWALLELEMENTS ENDP COUNTNEIGHBORS PROC NEAR PUSH CX; PUSH DX; MOV DX, OFFSET OLD; DX HOLD ARRAY OLD MOV AX, BX; COPY ROW TO AX TO DO MUL MUL DIMENSION ADD AX, SI; NOW AX HOLDS ARRAY INDEX MOV POS, AX; NOW POS HOLD INDEX DURING LOOPING MOV AX, BX; NOW AX HOLDS BX MOV COUNTER, 0; RECORD NEIGHBORS UPLEFT: CMP AX, 0; CHECK IF IT IS FIRST ROW JE UP; CMP SI, 0; CHECK IF IT IS FIRST COL JE UP; MOV BX, POS SUB BX, 16 ADD BX, DX ;BX IS POINTING TO ELEMENT OF ARRAY MOV CL, [BX]; ADD COUNTER,CL UP: CMP AX, 0; CHECK IF IT IS FIRST ROW JE UPRIGHT; MOV BX, POS SUB BX, 15 ADD BX, DX ;BX IS POINTING TO ELEMENT OF ARRAY MOV CL, [BX]; ADD COUNTER,CL UPRIGHT: CMP AX, 0; CHECK IF IT IS FIRST ROW JE RIGHT; CMP SI, 14; CHECK IF IT IS LAST COL JE RIGHT; MOV BX, POS SUB BX, 14 ADD BX, DX MOV CL, [BX]; ADD COUNTER,CL RIGHT: CMP SI, 14 JE DOWNRIGHT MOV BX, POS ADD BX, 1 ADD BX, DX MOV CL, [BX]; ADD COUNTER,CL DOWNRIGHT: CMP SI, 14 JE DOWN CMP AX, 14 JE DOWN MOV BX, POS ADD BX, 16 ADD BX, DX MOV CL, [BX]; ADD COUNTER,CL DOWN: CMP AX, 14 JE DOWNLEFT MOV BX, POS ADD BX, 15 ADD BX, DX MOV CL, [BX]; ADD COUNTER,CL DOWNLEFT: CMP AX, 14 JE LEFT CMP SI, 0 JE LEFT MOV BX, POS ADD BX, 14 ADD BX, DX MOV CL, [BX]; ADD COUNTER,CL LEFT: CMP SI, 0 JE ENDDIR MOV BX, POS SUB BX, 1 ADD BX, DX MOV CL, [BX]; ADD COUNTER,CL ENDDIR: MOV BX, AX MOV AX, 0 MOV AL, COUNTER POP DX POP CX RET COUNTNEIGHBORS ENDP NEWGENERATION PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH BP MOV BP, OFFSET OLD; BP HOLDS OLD ARRAY MOV DX, OFFSET NEW; DX HOLDS NEW ARRAY MOV BX, 1; BX IS ROW COUNTER OR OUTLOOP COUNTER OUTLOOP: CMP BX, 14 JE ENDALLLOOP MOV SI, 1; SI IS COL COUNTER OR INNERLOOP COUNTER INLOOP: CMP SI, 14 JE ENDOUTLOOP XOR AX, AX; CALL COUNTNEIGHBORS MOV COUNTER, AL; COUNTER HOLDS NUM OF NEIGHBORS MOV AX, BX; COPY ROW TO AX TO DO MUL MUL DIMENSION ADD AX, SI ; AX HOLDS INDEX OF ARRAY MOV DI, AX; COPY INDEX OF ARRAY TO DI ADD DI, BP; DI IS POINTING TO ELEMENT OF ARRAY OLD MOV CL, [DI]; USE BP TO DO COM NEXT CMP CL, 0 JE TOBORN; IF THERE IS NO LIFE PREVIOUSLY TODIE: CMP COUNTER, 2 JE LIFE CMP COUNTER, 3 JE LIFE JMP DIE; TOBORN: CMP COUNTER, 3 JE LIFE JMP DIE LIFE: MOV DI, AX; DI HOLDS INDEX OF ARRAY OF NEW ADD DI, DX; DI POINTING TO ELEMENT OF ARRAY OF NEW MOV CL, 1; MOV [DI], CL; JMP ENDINLOOP DIE: MOV DI, AX; ADD DI, DX MOV CL, 0; MOV [DI],CL ENDINLOOP: INC SI; JMP INLOOP ENDOUTLOOP: INC BX; JMP OUTLOOP; ENDALLLOOP: MOV BX, 1; ROWLOOP: CMP BX, 14 JE ENDCOPY; MOV SI, 1 COLLOOP: CMP SI, 14 JE ENDROWLOOP MOV AX, BX; PREPARE MUL MUL DIMENSION ADD AX, SI; AX HOLDS THE INDEX OF ARRAY MOV DI, DX; ADD DI, AX; DI POINTINT TO ELEMENT OF ARRAY NEW MOV CL, [DI]; BP HOLDS VALUE OF NEW MOV DI, BP; ADD DI, AX; DI PINTING TO ELEMENT OF ARRAY OLD MOV [DI], CL; COPY VALUE TO OLD ARRAY INC SI; JMP COLLOOP; ENDROWLOOP: INC BX; JMP ROWLOOP; ENDCOPY: POP BP POP DI POP SI POP DX POP CX POP BX POP AX RET NEWGENERATION ENDP; PRINTARRAY PROC NEAR PUSH AX; PUSH BX; PUSH CX; PUSH DX; MOV BX, OFFSET OLD ;BX IS ARRAY OLD MOV CX, 0; CX IS INNER COUNTER MOV COUNTER, 0; OUTERLOOP: CMP COUNTER, DIM JE ENDLOOP ; MOV CX, 0; INITIALIZE INNER COUNTER TO 0 INNERLOOP: CMP CX, DIM; JE ENDOUTER; MOV AL, [BX] CMP AL, 0 JE PRINTDOT PRINTSTAR: MOV DL, '*' JMP DOPRINTING; PRINTDOT: MOV DL, '.' DOPRINTING: MOV AH, 02H INT 21H PRINTSPACE: MOV DL, 32 MOV AH, 02H INT 21H ENDINNER: INC BX; INC CX; JMP INNERLOOP; ENDOUTER: MOV AH, 09H MOV DX, OFFSET RETURNSTR; INT 21H INC COUNTER; JMP OUTERLOOP; ENDLOOP: POP DX POP CX POP BX POP AX RET PRINTARRAY ENDP ;INPUT: NONE ;OUTPUT: NONE ;FUNCTION: SHOW SOME GARBAGE SHOWMESSAGE PROC PUSH AX PUSH DX MOV AH, 09H MOV DX, OFFSET MSG INT 21H POP DX POP AX RET SHOWMESSAGE ENDP END START
¡¡