1 /*
2 013 - Game of Life
3 CPCRSLIB demo
4
5 zcc +cpc -lndos -create-app -Cz--audio -lm rs013.c
6 */
7
8
9 #include <cpc.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <graphics.h>
13
14
15 #define ANCHO 20
16 #define ALTO 20
17 #define MUERTA 0
18 #define VIVA 1
19
20
21
22 //Una célula muerta con exactamente 3 células vecinas vivas "nace" (al turno siguiente estará viva).
23 //Una célula viva con 2 ó 3 células vecinas vivas sigue viva, en otro caso muere o permanece muerta (por "soledad" o "superpoblación").
24 unsigned char celulas[400];
25 unsigned char celulas_tmp[400];
26
27 char txt_numb[4];
28
29 unsigned char celula_gph[] = {255,255,255,255}; //Dibujo de la célula
30 unsigned char cursor_gph[] = {0xcc,0xcc,0xcc,0xcc}; //Dibujo del cursor
31
32
dibujar(void)33 void dibujar(void){
34 unsigned char i,j;
35 for (i=0;i<ANCHO;i++)
36 for (j=0;j<ALTO;j++) {
37 if (celulas[j*ANCHO+i]){
38 cpc_PutSp(celula_gph,2,2,cpc_GetScrAddress(2*i,2*j));
39 }
40 }
41 }
42
valida(signed char i,signed char j)43 unsigned char valida(signed char i, signed char j) {
44 /* Controla si la posicion esta fuera del recinto */
45 if ((i<0) || (i>=ANCHO) || (j<0) || (j>=ALTO)){
46 return 0;
47 } else return 1;
48 }
49
50
vecinas(unsigned char i,unsigned char j)51 unsigned char vecinas(unsigned char i, unsigned char j) {
52 unsigned char x,y;
53 unsigned char valor=0;
54 unsigned int v0, v1, v2;
55
56 v0=j*ANCHO+i;
57 v1=v0-ANCHO;
58 v2=v0+ANCHO;
59 if (valida(i-1,j)) valor += celulas[v0-1];
60 if (valida(i+1,j)) valor += celulas[v0+1];
61
62 if (valida(i-1,j-1)) valor += celulas[v1-1];
63 if (valida(i+1,j-1)) valor += celulas[v1+1];
64 if (valida(i,j-1)) valor += celulas[v1];
65
66 if (valida(i-1,j+1)) valor += celulas[v2-1];
67 if (valida(i+1,j+1)) valor += celulas[v2+1];
68 if (valida(i,j+1)) valor += celulas[v2];
69
70
71 return valor;
72 }
73
74
ciclo(void)75 void ciclo(void){ //Simula una iteración.
76 //celulas[] global
77 unsigned char i,j,v,c;
78 unsigned int v0;
79 for (i=0;i<ANCHO;i++){
80 for (j=0;j<ALTO;j++) {
81 v=vecinas(i,j);
82 v0=j*ANCHO+i;
83 c=celulas[v0];
84 if (c==1){//celula viva
85 if (v==2 || v==3) {celulas_tmp[v0]=1; //regla 2
86 } else {
87 celulas_tmp[v0]=0;
88 }
89 } else {// celula muerta
90 if (v==3) {celulas_tmp[v0]=1;
91 } //regla 1
92 else {celulas_tmp[v0]=0;
93 }
94 }
95 }
96 }
97 }
98
iniciarCelulas(void)99 void iniciarCelulas(void){
100 int i;
101
102 for (i==0;i<400;i++){
103 celulas[i]=0;
104 celulas_tmp[i]=0;
105 }
106
107 }
108
109
introducirCelulas(void)110 void introducirCelulas(void){ //Rutina para meter manualmente las células iniciales
111 unsigned char i, j, i0, j0;
112 iniciarCelulas(); //Se limpian todas.
113
114 i=i0=j=j0=0;
115 cpc_PutSpXOR(cursor_gph,2,2,cpc_GetScrAddress(2*i,2*j));
116 cpc_ScanKeyboard();
117 while (!cpc_TestKeyF(5)){ // Repeat until ESC pressed
118 cpc_ScanKeyboard(); // Scans whole keyboard
119 if (cpc_TestKeyF(0) && i<20) i++; // right move key
120 if (cpc_TestKeyF(1) && i>0) i--; // left move
121 if (cpc_TestKeyF(2) && j<20) j++; // down move key
122 if (cpc_TestKeyF(3) && j>0) j--; // up move
123 if (cpc_TestKeyF(4) ) { // select
124 if (celulas[j*20+i]==0){
125 celulas[j*20+i]=1;
126 cpc_PutSpXOR(celula_gph,2,2,cpc_GetScrAddress(2*i,2*j));
127 } else {
128 celulas[j*20+i]=0;
129 cpc_PutSpXOR(celula_gph,2,2,cpc_GetScrAddress(2*i,2*j));
130 }
131 };
132
133 #asm
134 ld b,20
135 .ko
136 halt
137 djnz ko
138 #endasm
139
140 if (i0!=i || j0!=j) {
141 cpc_PutSpXOR(cursor_gph,2,2,cpc_GetScrAddress(2*i0,2*j0));
142 i0=i;
143 j0=j;
144 cpc_PutSpXOR(cursor_gph,2,2,cpc_GetScrAddress(2*i,2*j));
145 }
146
147 }
148 }
149
150
swap(void)151 void swap(void){
152 /* int i;
153 for (i=0;i<400;i++){
154 celulas[i]=celulas_tmp[i];
155 } */
156
157 #asm
158 ld bc,400
159 ld hl,_celulas_tmp
160 ld de,_celulas
161 ldir
162
163
164
165 #endasm
166 }
clrCelulasTmp(void)167 void clrCelulasTmp(void){
168 /* int i;
169 for (i=0;i<400;i++){
170 celulas_tmp[i]=0;
171 } */
172
173 #asm
174
175
176 xor a
177 ld bc,400
178 ld hl,_celulas_tmp
179 ld de,_celulas_tmp+1
180 ld (hl),a
181 ldir
182
183 #endasm
184
185 }
186
main()187 main(){
188 unsigned int ite=0;
189 unsigned char cite[7];
190
191 while(!cpc_TestKey(5)){
192 cpc_ClrScr();
193
194 draw(348,0,348,40);
195 cpc_DisableFirmware();
196 cpc_SetColour(16,20); //background
197 cpc_SetColour(0,20); //border
198 cpc_SetColour(1,10); //
199
200 cpc_SetMode(0);
201 cpc_SetInkGphStr(0,0);
202 cpc_SetInkGphStr(2,2);
203 cpc_SetInkGphStr(1,8);
204
205 cpc_PrintGphStrXY2X("GAME;OF;LIFE",50,6);
206 cpc_PrintGphStrXY("ARTABURU;2009",49,24);
207 cpc_AssignKey(0,0x4002); // key "1" assigned to 0
208 cpc_AssignKey(1,0x4101); // key "2"
209 cpc_AssignKey(2,0x4004); // key "3"
210 cpc_AssignKey(3,0x4001); // key "4"
211 cpc_AssignKey(4,0x4580); // key "space"
212 cpc_AssignKey(5,0x4804); // key "ESC"
213
214 //iniciarCelulas();
215 cpc_SetInkGphStr(0,0);
216 cpc_SetInkGphStr(2,10);
217 cpc_SetInkGphStr(1,32);
218 cpc_PrintGphStrXY("ENTER;CELLS;USING;CURSOR;KEYS",9,62);
219 cpc_PrintGphStrXY("AND;SPACE;;ESC;TO;FINISH",9,70);
220 introducirCelulas();
221 cpc_PrintGphStrXY("ITERATION;;;;;;;;;;;;;;;;;;;;",9,62);
222 itoa(ite,txt_numb,10);
223 cpc_PrintGphStrXY(txt_numb,9+18,62);
224
225 cpc_PrintGphStrXY(";;;;;;;;;;;;;;;;;;;;;;;;",9,70);
226 while(!cpc_TestKey(5)){
227 ite++;
228 dibujar();
229 clrCelulasTmp();
230 ciclo();
231 swap();
232 itoa(ite,txt_numb,10);
233 cpc_PrintGphStrXY(txt_numb,9+18,62);
234 cpc_PutSp((char *) 0x8000,42,42,0xc000);
235 }
236 clrCelulasTmp();
237 swap();
238 }
239 return 0;
240 }
241
242
243