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