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.
HI
I THINK IT WORKS NOW!
I AM IN LAB AND SEE WHAT HAPPENS. IT IS WINDOWS REFRESHING PROBLEM. IF I WANT TO
WINDOWS TO REPAINT THE MOUSE, I NEED TO HIDE IT FIRST. OTHERWISE WINDOWS WON'T
BE NOTIFIED THAT MOUSE NEED TO REPAINT AND THE AREA COVERED BY MOUSE NEED TO
REPAINT. THAT IS PROBLEM.
BESIDES, THERE IS SOME POINTS I IMPROVED. ACTUALLY IT IS THE ORIGINAL
REQUIREMENT THAT ASKS US TO NEGLECT BOUNDS SITUATION. THAT IS TO SAY CELLS AT
FOUR BOUNDS WON'T BE CONSIDERED UNDER THE RULE OF SURVIVE. NOW I DON'T THINK IT
WILL HARM IF I INCLUDE THOSE CELLS UNDER CALCULATIONS.
HAVE A NICE DAY,
NICK
¡¡
p.s. What moral do we learn? I take it for granted that the mouse initialize function return -1 indicating
errors. But on the contrary, -1 means OK, and 0 means problem! and this cause me a lot of trouble of brain-
torture! Never regard -1 as a bad sign!
2. My Program
TITLE LIFESTYLE
DIM EQU 15;
CELLSIZE EQU 8;
OLDX EQU 0
OLDY EQU 10
NEWX EQU 180
NEWY EQU 10
INPUTX EQU 80
INPUTY EQU 10
REDX EQU 100
REDY EQU 160
GREENX EQU 180
GREENY EQU 160
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, CLEARSCREEN:NEAR, DISPLAYINTEGER:NEAR, RETURN:NEAR,
MOUSERELEASE:NEAR
START:
MOV AX, @DATA
MOV DS, AX;
;CALL SHOWMESSAGE
;CALL WAITRETURN;
CALL MOUSEINIT
CALL ENTERGRAPHIC
CALL CLEARSCREEN
CALL ENTERCELLS
CALL MOUSEHIDE; IF YOU WANT TO SHOW MOUSE CORRECTLY
;YOU HAVE TO HIDE IT FIRST AND SHOW AFTERWARDS
CALL CLEARSCREEN; ONLY CLEAR SCREEN ONCE,
;AS THEY ARE ALL SAME AFTERWARDS
CALL MOUSESHOW;IT IS LIKE REFRESHING
;OTHERWISE YOUR MOUSE DISPLAY MEMORY IS CLEARED
;WITHOUT LETTING WINDOWS NOTIFIED
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
CALL DRAWBUTTON
CALL MOUSESHOW; IT IS TIME TO CALL MOUSE SHOW
L47:
CALL TESTBUTTON
CMP AX, -1; NO HIT
JE L47
CMP AX, 0;
JNE L48 ; IF IT IS RED
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:
POP BP
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:
;DIVIDE BY 2 OF Y OF MOUSE
SHR CX, 1
MOV AX, GREENX
PUSH AX
MOV AX, GREENY
PUSH AX
MOV AX, BOXSIZE
PUSH AX
CALL INTERNALTEST
CMP AX, 0;
JE TESTRED; GREEN MISSED
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, 04H
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
;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
MOV BX, AX
XOR AX, AX; CLEAR
MOV AL, OLD[BX+SI]
XOR AL, 1
MOV OLD[BX+SI], AL
;NOW PASS PARAM TO REPAINT CHANGED GRIDCELL
;NOW RESTORE BX,SI
POP SI
POP BX
MOV CX, INPUTX
PUSH CX; PASS ORIGIN X
MOV CX, INPUTY
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 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
CALL MOUSESHOW
WAITCLICK1:
;CALL MOUSEINIT
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
SHR CX, 1 ; AS MOUSE USES 640X200 INSTEAD OF 320X200
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 MOUSEHIDE
CALL TOGGLECELL
CALL MOUSESHOW
CALL MOUSERELEASE
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
;THIS IS TEST; I AM ENABLING BOUNDS NEIGHBOURS!!!
MOV BX, 0; BX IS ROW COUNTER OR OUTLOOP COUNTER
OUTLOOP:
CMP BX, DIM
JE ENDALLLOOP
MOV SI, 0; SI IS COL COUNTER OR INNERLOOP COUNTER
INLOOP:
CMP SI, DIM
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, 0;
ROWLOOP:
CMP BX, DIM
JE ENDCOPY;
MOV SI, 0
COLLOOP:
CMP SI, DIM
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
END
¡¡