Population---一个用汇编模拟人类迁徙的程序
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:
1. PrintArray:
This procedure outputs the given array D of 15x15 in ASCII characters. It prints a
“.” character instead of a 0, and a “*” character instead of a 1.
2. CountNeighbors:
This procedure takes input of the row index and column index [r,c] in (bx, si), and
returns in AL its total number of neighbor(s) of the array element D[r,c].
For simplicity, we will assume that the cells located on the left, right, top and
bottom boarders are always empty (0).
3. NewGeneration:
For each cell (interior), call CountNeighbors, and then based on the given rules
above, decide the life of its corresponding cell in next generation. Copy all cells
of the new generation back to the cells of current generation.
Extend your program Main to do the following:
call PrintArray;
repeat 5 times
call NewGeneration;
call PrintArray;
return to DOS;
2. 我的程序
Microsoft (R) Macro Assembler Version 6.11 02/25/03 11:47:43 LIFESTYLE Page 1 - 1 TITLE LIFESTYLE = 000F DIM EQU 15; .DOSSEG .MODEL SMALL .STACK 100H 0000 .DATA 0000 0F DIMENSION DB DIM 0001 0A 0D 24 RETURNSTR DB 0AH, 0DH, '$' 0004 00 COUNTER DB 0; 0005 0000 POS DW 0; 0007 00 00 00 00 00 00 OLD DB 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0 ;0 00 00 00 00 00 00 00 00 00 0016 00 00 01 00 01 00 DB 0,0,1,0, 1,0,0,1, 1,0,1,0, 1,0,0 00 01 01 00 01 00 01 00 00 0025 00 01 00 00 00 01 DB 0,1,0,0, 0,1,0,1, 0,0,0,0, 0,0,0 00 01 00 00 00 00 00 00 00 0034 00 00 00 00 00 00 DB 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,0 00 00 00 00 00 00 01 00 00 0043 00 01 01 01 00 01 DB 0,1,1,1, 0,1,1,1, 0,1,1,1, 0,0,0 ;4 01 01 00 01 01 01 00 00 00 0052 00 01 01 01 00 00 DB 0,1,1,1, 0,0,0,0, 0,1,1,0, 0,1,0 00 00 00 01 01 00 00 01 00 0061 00 01 01 01 00 00 DB 0,1,1,1, 0,0,0,0, 1,1,1,0, 0,0,0 00 00 01 01 01 00 00 00 00 0070 00 00 00 00 01 01 DB 0,0,0,0, 1,1,0,0, 1,1,1,1, 0,1,0 00 00 01 01 01 01 00 01 00 007F 00 00 00 00 01 00 DB 0,0,0,0, 1,0,0,0, 1,1,1,1, 0,0,0 ;8 00 00 01 01 01 01 00 00 00 008E 00 00 00 00 00 01 DB 0,0,0,0, 0,1,1,0, 0,0,1,0, 0,0,0 01 00 00 00 01 00 00 00 00 009D 00 01 01 01 00 00 DB 0,1,1,1, 0,0,0,1, 1,0,0,0, 1,1,0 00 01 01 00 00 00 01 01 00 00AC 00 00 00 00 00 00 DB 0,0,0,0, 0,0,0,0, 1,1,1,1, 1,0,0 00 00 01 01 01 01 01 00 00 00BB 00 00 00 00 01 01 DB 0,0,0,0, 1,1,1,1, 1,1,1,1, 1,1,0 ;12 01 01 01 01 01 01 01 01 00 00CA 00 00 00 01 00 01 DB 0,0,0,1, 0,1,1,1, 1,0,0,0, 0,0,0 01 01 01 00 00 00 00 00 00 00D9 00 00 00 00 00 00 DB 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0 ;14 00 00 00 00 00 00 00 00 00 00E8 000F [ NEW DB 15 DUP(?) ;0 00 ] 00F7 000F [ DB 15 DUP(?) 00 ] 0106 000F [ DB 15 DUP(?) 00 ] 0115 000F [ DB 15 DUP(?) 00 ] 0124 000F [ DB 15 DUP(?) ;4 00 ] 0133 000F [ DB 15 DUP(?) 00 ] 0142 000F [ DB 15 DUP(?) 00 ] 0151 000F [ DB 15 DUP(?) 00 ] 0160 000F [ DB 15 DUP(?) ;8 00 ] 016F 000F [ DB 15 DUP(?) 00 ] 017E 000F [ DB 15 DUP(?) 00 ] 018D 000F [ DB 15 DUP(?) 00 ] 019C 000F [ DB 15 DUP(?) ;12 00 ] 01AB 000F [ DB 15 DUP(?) 00 ] 01BA 000F [ DB 15 DUP(?) ;14 00 ] 0000 .CODE 0000 START: 0000 B8 ---- R MOV AX, @DATA 0003 8E D8 MOV DS, AX; 0005 E8 0188 CALL PRINTARRAY; 0008 B9 0005 MOV CX, 5; 000B MAINLOOP: 000B E8 00E7 CALL NEWGENERATION; 000E E8 017F CALL PRINTARRAY; 0011 B4 09 MOV AH, 09; 0013 BA 0001 R MOV DX, OFFSET RETURNSTR; 0016 CD 21 INT 21H 0018 E2 F1 LOOP MAINLOOP; 001A B8 4C00 MOV AX, 4C00H 001D CD 21 INT 21H 001F COUNTNEIGHBORS PROC NEAR 001F 51 PUSH CX; 0020 52 PUSH DX; 0021 BA 0007 R MOV DX, OFFSET OLD; DX HOLD ARRAY OLD 0024 8B C3 MOV AX, BX; COPY ROW TO AX TO DO MUL 0026 F6 26 0000 R MUL DIMENSION 002A 03 C6 ADD AX, SI; NOW AX HOLDS ARRAY INDEX 002C A3 0005 R MOV POS, AX; NOW POS HOLD INDEX DURING LOOPING 002F 8B C3 MOV AX, BX; NOW AX HOLDS BX 0031 C6 06 0004 R 00 MOV COUNTER, 0; RECORD NEIGHBORS 0036 UPLEFT: 0036 83 F8 00 CMP AX, 0; CHECK IF IT IS FIRST ROW 0039 74 14 JE UP; 003B 83 FE 00 CMP SI, 0; CHECK IF IT IS FIRST COL 003E 74 0F JE UP; 0040 8B 1E 0005 R MOV BX, POS 0044 83 EB 10 SUB BX, 16 0047 03 DA ADD BX, DX ;BX IS POINTING TO ELEMENT OF ARRAY 0049 8A 0F MOV CL, [BX]; 004B 00 0E 0004 R ADD COUNTER,CL 004F UP: 004F 83 F8 00 CMP AX, 0; CHECK IF IT IS FIRST ROW 0052 74 0F JE UPRIGHT; 0054 8B 1E 0005 R MOV BX, POS 0058 83 EB 0F SUB BX, 15 005B 03 DA ADD BX, DX ;BX IS POINTING TO ELEMENT OF ARRAY 005D 8A 0F MOV CL, [BX]; 005F 00 0E 0004 R ADD COUNTER,CL 0063 UPRIGHT: 0063 83 F8 00 CMP AX, 0; CHECK IF IT IS FIRST ROW 0066 74 14 JE RIGHT; 0068 83 FE 0E CMP SI, 14; CHECK IF IT IS LAST COL 006B 74 0F JE RIGHT; 006D 8B 1E 0005 R MOV BX, POS 0071 83 EB 0E SUB BX, 14 0074 03 DA ADD BX, DX 0076 8A 0F MOV CL, [BX]; 0078 00 0E 0004 R ADD COUNTER,CL 007C RIGHT: 007C 83 FE 0E CMP SI, 14 007F 74 0F JE DOWNRIGHT 0081 8B 1E 0005 R MOV BX, POS 0085 83 C3 01 ADD BX, 1 0088 03 DA ADD BX, DX 008A 8A 0F MOV CL, [BX]; 008C 00 0E 0004 R ADD COUNTER,CL 0090 DOWNRIGHT: 0090 83 FE 0E CMP SI, 14 0093 74 14 JE DOWN 0095 83 F8 0E CMP AX, 14 0098 74 0F JE DOWN 009A 8B 1E 0005 R MOV BX, POS 009E 83 C3 10 ADD BX, 16 00A1 03 DA ADD BX, DX 00A3 8A 0F MOV CL, [BX]; 00A5 00 0E 0004 R ADD COUNTER,CL 00A9 DOWN: 00A9 83 F8 0E CMP AX, 14 00AC 74 0F JE DOWNLEFT 00AE 8B 1E 0005 R MOV BX, POS 00B2 83 C3 0F ADD BX, 15 00B5 03 DA ADD BX, DX 00B7 8A 0F MOV CL, [BX]; 00B9 00 0E 0004 R ADD COUNTER,CL 00BD DOWNLEFT: 00BD 83 F8 0E CMP AX, 14 00C0 74 14 JE LEFT 00C2 83 FE 00 CMP SI, 0 00C5 74 0F JE LEFT 00C7 8B 1E 0005 R MOV BX, POS 00CB 83 C3 0E ADD BX, 14 00CE 03 DA ADD BX, DX 00D0 8A 0F MOV CL, [BX]; 00D2 00 0E 0004 R ADD COUNTER,CL 00D6 LEFT: 00D6 83 FE 00 CMP SI, 0 00D9 74 0F JE ENDDIR 00DB 8B 1E 0005 R MOV BX, POS 00DF 83 EB 01 SUB BX, 1 00E2 03 DA ADD BX, DX 00E4 8A 0F MOV CL, [BX]; 00E6 00 0E 0004 R ADD COUNTER,CL 00EA ENDDIR: 00EA 8B D8 MOV BX, AX 00EC B8 0000 MOV AX, 0 00EF A0 0004 R MOV AL, COUNTER 00F2 5A POP DX 00F3 59 POP CX 00F4 C3 RET 00F5 COUNTNEIGHBORS ENDP 00F5 NEWGENERATION PROC NEAR 00F5 50 PUSH AX 00F6 53 PUSH BX 00F7 51 PUSH CX 00F8 52 PUSH DX 00F9 56 PUSH SI 00FA 57 PUSH DI 00FB 55 PUSH BP 00FC BD 0007 R MOV BP, OFFSET OLD; BP HOLDS OLD ARRAY 00FF BA 00E8 R MOV DX, OFFSET NEW; DX HOLDS NEW ARRAY 0102 BB 0001 MOV BX, 1; BX IS ROW COUNTER OR OUTLOOP COUNTER 0105 OUTLOOP: 0105 83 FB 0E CMP BX, 14 0108 74 54 JE ENDALLLOOP 010A BE 0001 MOV SI, 1; SI IS COL COUNTER OR INNERLOOP COUNTER 010D INLOOP: 010D 83 FE 0E CMP SI, 14 0110 74 49 JE ENDOUTLOOP 0112 33 C0 XOR AX, AX; 0114 E8 FF08 CALL COUNTNEIGHBORS 0117 A2 0004 R MOV COUNTER, AL; COUNTER HOLDS NUM OF NEIGHBORS 011A 8B C3 MOV AX, BX; COPY ROW TO AX TO DO MUL 011C F6 26 0000 R MUL DIMENSION 0120 03 C6 ADD AX, SI ; AX HOLDS INDEX OF ARRAY 0122 8B F8 MOV DI, AX; COPY INDEX OF ARRAY TO DI 0124 03 FD ADD DI, BP; DI IS POINTING TO ELEMENT OF ARRAY OLD 0126 8A 0D MOV CL, [DI]; USE BP TO DO COM NEXT 0128 80 F9 00 CMP CL, 0 012B 74 10 JE TOBORN; IF THERE IS NO LIFE PREVIOUSLY 012D 80 3E 0004 R 02 TODIE: CMP COUNTER, 2 0132 74 12 JE LIFE 0134 80 3E 0004 R 03 CMP COUNTER, 3 0139 74 0B JE LIFE 013B EB 13 JMP DIE; 013D TOBORN: 013D 80 3E 0004 R 03 CMP COUNTER, 3 0142 74 02 JE LIFE 0144 EB 0A JMP DIE 0146 LIFE: 0146 8B F8 MOV DI, AX; DI HOLDS INDEX OF ARRAY OF NEW 0148 03 FA ADD DI, DX; DI POINTING TO ELEMENT OF ARRAY OF NEW 014A B1 01 MOV CL, 1; 014C 88 0D MOV [DI], CL; 014E EB 08 JMP ENDINLOOP 0150 DIE: 0150 8B F8 MOV DI, AX; 0152 03 FA ADD DI, DX 0154 B1 00 MOV CL, 0 0156 88 0D MOV [DI],CL 0158 ENDINLOOP: 0158 46 INC SI; 0159 EB B2 JMP INLOOP 015B ENDOUTLOOP: 015B 43 INC BX; 015C EB A7 JMP OUTLOOP; 015E ENDALLLOOP: 015E BB 0001 MOV BX, 1; 0161 ROWLOOP: 0161 83 FB 0E CMP BX, 14 0164 74 22 JE ENDCOPY; 0166 BE 0001 MOV SI, 1 0169 COLLOOP: 0169 83 FE 0E CMP SI, 14 016C 74 17 JE ENDROWLOOP 016E 8B C3 MOV AX, BX; PREPARE MUL 0170 F6 26 0000 R MUL DIMENSION 0174 03 C6 ADD AX, SI; AX HOLDS THE INDEX OF ARRAY 0176 8B FA MOV DI, DX; 0178 03 F8 ADD DI, AX; DI POINTINT TO ELEMENT OF ARRAY NEW 017A 8A 0D MOV CL, [DI]; BP HOLDS VALUE OF NEW 017C 8B FD MOV DI, BP; 017E 03 F8 ADD DI, AX; DI PINTING TO ELEMENT OF ARRAY OLD 0180 88 0D MOV [DI], CL; COPY VALUE TO OLD ARRAY 0182 46 INC SI; 0183 EB E4 JMP COLLOOP; 0185 ENDROWLOOP: 0185 43 INC BX; 0186 EB D9 JMP ROWLOOP; 0188 ENDCOPY: 0188 5D POP BP 0189 5F POP DI 018A 5E POP SI 018B 5A POP DX 018C 59 POP CX 018D 5B POP BX 018E 58 POP AX 018F C3 RET 0190 NEWGENERATION ENDP; 0190 PRINTARRAY PROC NEAR 0190 50 PUSH AX; 0191 53 PUSH BX; 0192 51 PUSH CX; 0193 52 PUSH DX; 0194 BB 0007 R MOV BX, OFFSET OLD ;BX IS ARRAY OLD 0197 B9 0000 MOV CX, 0; CX IS INNER COUNTER 019A C6 06 0004 R 00 MOV COUNTER, 0; 019F OUTERLOOP: 019F 80 3E 0004 R 0F CMP COUNTER, DIM 01A4 74 2F JE ENDLOOP ; 01A6 B9 0000 MOV CX, 0; INITIALIZE INNER COUNTER TO 0 01A9 INNERLOOP: 01A9 83 F9 0F CMP CX, DIM; 01AC 74 1A JE ENDOUTER; 01AE 8A 07 MOV AL, [BX] 01B0 3C 00 CMP AL, 0 01B2 74 04 JE PRINTDOT 01B4 PRINTSTAR: 01B4 B2 2A MOV DL, '*' 01B6 EB 02 JMP DOPRINTING; 01B8 PRINTDOT: 01B8 B2 2E MOV DL, '.' 01BA DOPRINTING: 01BA B4 02 MOV AH, 02H 01BC CD 21 INT 21H 01BE PRINTSPACE: 01BE B2 20 MOV DL, 32 01C0 B4 02 MOV AH, 02H 01C2 CD 21 INT 21H 01C4 ENDINNER: 01C4 43 INC BX; 01C5 41 INC CX; 01C6 EB E1 JMP INNERLOOP; 01C8 ENDOUTER: 01C8 B4 09 MOV AH, 09H 01CA BA 0001 R MOV DX, OFFSET RETURNSTR; 01CD CD 21 INT 21H 01CF FE 06 0004 R INC COUNTER; 01D3 EB CA JMP OUTERLOOP; 01D5 ENDLOOP: 01D5 5A POP DX 01D6 59 POP CX 01D7 5B POP BX 01D8 58 POP AX 01D9 C3 RET 01DA PRINTARRAY ENDP END START Microsoft (R) Macro Assembler Version 6.11 02/25/03 11:47:43 LIFESTYLE Symbols 2 - 1 Segments and Groups: N a m e Size Length Align Combine Class DGROUP . . . . . . . . . . . . . GROUP _DATA . . . . . . . . . . . . . 16 Bit 01C9 Word Public 'DATA' STACK . . . . . . . . . . . . . 16 Bit 0100 Para Stack 'STACK' _TEXT . . . . . . . . . . . . . 16 Bit 01DA Word Public 'CODE' Procedures, parameters and locals: N a m e Type Value Attr COUNTNEIGHBORS . . . . . . . . . P Near 001F _TEXT Length= 00D6 Private NEWGENERATION . . . . . . . . . P Near 00F5 _TEXT Length= 00F8 Private PRINTARRAY . . . . . . . . . . . P Near 0190 _TEXT Length= 004A Private Symbols: N a m e Type Value Attr @CodeSize . . . . . . . . . . . Number 0000h @DataSize . . . . . . . . . . . Number 0000h @Interface . . . . . . . . . . . Number 0000h @Model . . . . . . . . . . . . . Number 0002h @code . . . . . . . . . . . . . Text _TEXT @data . . . . . . . . . . . . . Text DGROUP @fardata? . . . . . . . . . . . Text FAR_BSS @fardata . . . . . . . . . . . . Text FAR_DATA @stack . . . . . . . . . . . . . Text DGROUP COLLOOP . . . . . . . . . . . . L Near 0169 _TEXT COUNTER . . . . . . . . . . . . Byte 0004 _DATA DIE . . . . . . . . . . . . . . L Near 0150 _TEXT DIMENSION . . . . . . . . . . . Byte 0000 _DATA DIM . . . . . . . . . . . . . . Number 000Fh DOPRINTING . . . . . . . . . . . L Near 01BA _TEXT DOWNLEFT . . . . . . . . . . . . L Near 00BD _TEXT DOWNRIGHT . . . . . . . . . . . L Near 0090 _TEXT DOWN . . . . . . . . . . . . . . L Near 00A9 _TEXT ENDALLLOOP . . . . . . . . . . . L Near 015E _TEXT ENDCOPY . . . . . . . . . . . . L Near 0188 _TEXT ENDDIR . . . . . . . . . . . . . L Near 00EA _TEXT ENDINLOOP . . . . . . . . . . . L Near 0158 _TEXT ENDINNER . . . . . . . . . . . . L Near 01C4 _TEXT ENDLOOP . . . . . . . . . . . . L Near 01D5 _TEXT ENDOUTER . . . . . . . . . . . . L Near 01C8 _TEXT ENDOUTLOOP . . . . . . . . . . . L Near 015B _TEXT ENDROWLOOP . . . . . . . . . . . L Near 0185 _TEXT INLOOP . . . . . . . . . . . . . L Near 010D _TEXT INNERLOOP . . . . . . . . . . . L Near 01A9 _TEXT LEFT . . . . . . . . . . . . . . L Near 00D6 _TEXT LIFE . . . . . . . . . . . . . . L Near 0146 _TEXT MAINLOOP . . . . . . . . . . . . L Near 000B _TEXT NEW . . . . . . . . . . . . . . Byte 00E8 _DATA OLD . . . . . . . . . . . . . . Byte 0007 _DATA OUTERLOOP . . . . . . . . . . . L Near 019F _TEXT OUTLOOP . . . . . . . . . . . . L Near 0105 _TEXT POS . . . . . . . . . . . . . . Word 0005 _DATA PRINTDOT . . . . . . . . . . . . L Near 01B8 _TEXT PRINTSPACE . . . . . . . . . . . L Near 01BE _TEXT PRINTSTAR . . . . . . . . . . . L Near 01B4 _TEXT RETURNSTR . . . . . . . . . . . Byte 0001 _DATA RIGHT . . . . . . . . . . . . . L Near 007C _TEXT ROWLOOP . . . . . . . . . . . . L Near 0161 _TEXT START . . . . . . . . . . . . . L Near 0000 _TEXT TOBORN . . . . . . . . . . . . . L Near 013D _TEXT TODIE . . . . . . . . . . . . . L Near 012D _TEXT UPLEFT . . . . . . . . . . . . . L Near 0036 _TEXT UPRIGHT . . . . . . . . . . . . L Near 0063 _TEXT UP . . . . . . . . . . . . . . . L Near 004F _TEXT 0 Warnings 0 Errors .. . . . . . . . . . . . . . . .. . * . * . . * * . * . * . . .. * . . . * . * . . . . . . . .. . . . . . . . . . . . * . . .. * * * . * * * . * * * . . . .. * * * . . . . . * * . . * . .. * * * . . . . * * * . . . . .. . . . * * . . * * * * . * . .. . . . * . . . * * * * . . . .. . . . . * * . . . * . . . . .. * * * . . . * * . . . * * . .. . . . . . . . * * * * * . . .. . . . * * * * * * * * * * . .. . . * . * * * * . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . * * * . . . . . . .. . . . . . * * * . . * . . . .. * . . * * . * * . * * . . . .. * . * * . * . * * . * * . . .. . . . . . * * . . . . . . . .. * . . . . . . . . . . * . . .. . * . * * . * . . . . * . . .. . . . * . * * * . . . * . . .. . * * * * * . . . * . * . . .. . * . . . * * * . . . * * . .. . * * * * . . . . . . . . . .. . . . * . . . . . . . . * . .. . . . . . . . . . * * * . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . * . * . . . . . . .. . . . . . . . . . * * . . . .. . * * * . . . . . . . . . . .. . * * * . . . . * . * * . . .. . * . . * * * * . . * * . . .. . . . . * . * . . . . . . . .. . . * * * . * * . . * * * . .. . * . . . . . * . . . * * . .. . * . * . . . . * . . * . . .. * . . . . . * . . . * * * . .. . * . * * * * . . . . * * . .. . . . * * . . . . . * * . . .. . . . . . . . . . . * * . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . * . . . . . . . . . . . .. . * . * . . . . . . . * . . .. * . . . . * * * . * * * . . .. . * . . * . * * . * * * . . .. . . * . . . . . . . . . * . .. . . * * * . * * . . * . * . .. . * . . * . * * * . . . . . .. * * * . . . . * . . . . . . .. * * . * . . * * . . * . . . .. . . * * . . * . . . . . . . .. . . * * . . . . . . . . . . .. . . . . . . . . . . * * . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . * . . . . . . . . . . . .. . * * . . . * . . . . * . . .. * * * . * * . * . * . . * . .. . * . . . . . * . * . . * . .. . * * . * . . . * * . . * . .. . * * . * . * . * . . * . . .. * . . . * . . . * . . . . . .. . . . * . * . . . . . . . . .. * . . * . . * * . . . . . . .. . . . . * . * * . . . . . . .. . . * * . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . .. . * * . . . . . . . . . . . .. * . . . . * * . . . . . . . .. * . . * . * . * . . * * * . .. . . . . * * * * . * * * * . .. * . . . . * . . . * * * * . .. * . * . * . . . * . . . . . .. . * * . * . . * . . . . . . .. . . . * . * * * . . . . . . .. . . . * . . . * . . . . . . .. . . * . * * * * . . . . . . .. . . . * . . . . . . . . . . .. . . . . . . . . . . . . . . .. . . . . . . . . . . . . . .