Removi os ficheiros helper. Está tudo no funnysort.c agora.
[funnysort.git] / funnysort.c
blobdaed978b8273c6456537136b9c62fb6bad2694e1
1 /* funnysort.c */
2 #include <stdio.h>
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <pthread.h>
6 #include <unistd.h>
7 #include <stdbool.h>
9 #include "congl.h"
11 #define LARGURA 40
12 #define ALTURA 20
13 #define NITERA 100
15 typedef enum {A=0, VAZIO, ORDENADOR} item_t;
17 //void tab_criar(unsigned int altura, unsigned int largura);
18 //void tab_libertar(void);
19 //void tab_ler(unsigned int x, unsigned int y, item_t *i);
20 //void tab_escrever(unsigned int x, unsigned int y, item_t i);
21 //void tab_imprimir(void);
23 struct carac_s {
24 conglColor_t fundo;
25 conglColor_t frente;
26 char simbolo;
29 /* características de cada item. O índice é o item. */
30 struct carac_s carac[] = {
31 {congl_magenta, congl_white, ' '},
32 {congl_green, congl_white, ' '},
33 {congl_black, congl_white, ' '}
36 static item_t *tab;
37 static bool tab_valido = false;
38 static unsigned int altura;
39 static unsigned int largura;
41 /* Cria o tabuleiro, trata da sua inicialização e desenha uma representação no
42 * ecrã.
44 void tab_criar(unsigned int a, unsigned int l)
46 assert(!tab_valido);
48 unsigned int r, s;
49 unsigned int pos;
51 tab = calloc(a*l, sizeof(item_t));
53 if (tab == NULL) {
54 perror("tab_criar");
55 return;
57 altura = a;
58 largura = l;
60 /*inicializar o conteúdo do tabuleiro */
61 /* r: altura
62 * l: largura
64 for (r = 0; r < a; ++r) {
65 for (s = 0; s < l; ++s) {
66 pos = r*largura+s;
67 tab[pos] = VAZIO;
71 tab_valido = true;
73 /* assert todas as posições são VAZIO */
74 assert(tab_valido);
77 void tab_libertar()
79 assert(tab_valido);
81 free(tab);
82 tab_valido = false;
84 assert(!tab_valido);
87 void tab_ler(unsigned int x, unsigned int y, item_t *i)
89 unsigned int pos = y*largura+x;
91 assert(tab_valido);
93 *i = tab[pos];
95 assert(*i == tab[pos]);
98 void tab_escrever(unsigned int x, unsigned int y, item_t i)
100 unsigned int pos = y*largura+x;
102 assert(tab_valido);
105 tab[pos] = i;
107 assert(tab[pos] == i);
110 void tab_imprimir(void)
112 assert(tab_valido);
114 int r, s;
115 item_t item;
117 conglClearScreen();
118 conglMoveCursor(1, 1);
120 /* r: y
121 * s: x
123 for (r = 0; r < altura; ++r) {
124 for (s = 0; s < largura; ++s) {
125 tab_ler(s, r, &item);
126 conglSetBg(carac[item].fundo);
127 conglSetFg(carac[item].frente);
128 conglDrawChar(carac[item].simbolo);
129 //conglDrawChar(item+0x30);
131 conglSetBg(congl_black);
132 conglSetFg(congl_white);
133 printf("\n");
137 int ordenador (void)
139 int itera;
140 item_t item, item_outro;
141 int x, x_outro;
142 int y, y_outro;
143 int r;
145 /* inicializa a posição inicial a um valor aleatório */
146 x = random()%LARGURA;
147 y = random()%ALTURA;
148 tab_escrever(x, y, ORDENADOR);
150 for (itera = 0; itera <= NITERA; ++itera) {
151 /* anda aleatoriamente até encontrar um item */
152 item = VAZIO;
153 while (item == VAZIO) {
154 /* tenta pegar num item */
155 pegar_item(x, y, &item);
156 if (item == VAZIO) {
157 /* não conseguiu pegar no item */
158 /* tenta-se mexer para uma nova posição sem item */
159 do {
160 /* cena feia por causa de dar a volta */
161 x_outro = (x+(random()%3)-1)%LARGURA;
162 if (x_outro == -1) x_outro = LARGURA-1;
163 y_outro = (y+(random()%3)-1)%ALTURA;
164 if (y_outro == -1) y_outro = ALTURA-1;
165 tab_ler(x_outro, y_outro, &item_outro);
166 } while (item_outro != VAZIO);
167 tab_escrever(x, y, VAZIO);
168 x = x_outro;
169 y = y_outro;
170 tab_escrever(x, y, ORDENADOR);
171 tab_imprimir();
173 usleep(50000);
176 /* anda aleatoriamente até encontrar um item da mesma cor */
177 while (item != VAZIO) {
178 /* tenta pousar o item */
179 pousar_item(x, y, &item);
180 if (item != VAZIO) {
181 /* não conseguiu pousar o item */
182 /* tenta-se mexer para uma nova posição sem item */
183 do {
184 /* cena feia por causa de dar a volta */
185 x_outro = (x+(random()%3)-1)%LARGURA;
186 if (x_outro == -1) x_outro = LARGURA-1;
187 y_outro = (y+(random()%3)-1)%ALTURA;
188 if (y_outro == -1) y_outro = ALTURA-1;
189 tab_ler(x_outro, y_outro, &item_outro);
190 } while (item_outro != VAZIO);
191 tab_escrever(x, y, VAZIO);
192 x = x_outro;
193 y = y_outro;
194 tab_escrever(x, y, ORDENADOR);
195 tab_imprimir();
197 usleep(50000);
200 /* sai de cima do item */
201 /* cena feia por causa de dar a volta */
202 x_outro = (x+(random()%3)-1)%LARGURA;
203 if (x_outro == -1) x_outro = LARGURA-1;
204 y_outro = (y+(random()%3)-1)%ALTURA;
205 if (y_outro == -1) y_outro = ALTURA-1;
206 tab_ler(x_outro, y_outro, &item_outro);
207 x = x_outro;
208 y = y_outro;
209 tab_escrever(x, y, ORDENADOR);
210 tab_imprimir();
212 /* sai de perto do item que pousou (espero eu) */
213 for (r = 0; (r < 10); ++r) {
214 do {
215 /* cena feia por causa de dar a volta */
216 x_outro = (x+(random()%3)-1)%LARGURA;
217 if (x_outro == -1) x_outro = LARGURA-1;
218 y_outro = (y+(random()%3)-1)%ALTURA;
219 if (y_outro == -1) y_outro = ALTURA-1;
220 tab_ler(x_outro, y_outro, &item_outro);
221 } while (item_outro != VAZIO);
222 tab_escrever(x, y, VAZIO);
223 x = x_outro;
224 y = y_outro;
225 tab_escrever(x, y, ORDENADOR);
226 tab_imprimir();
227 usleep(50000);
231 return 0;
234 int pegar_item (int x, int y, item_t *i)
236 assert (x >= 0 && x < LARGURA);
237 assert (y >= 0 && y < ALTURA);
239 int xnovo, ynovo;
240 item_t item;
241 int r, s;
243 /* tenta adquirir o item */
244 for (r = -1; (r <= 1) && (*i == VAZIO); ++r) {
245 for (s = -1; (s <= 1) && (*i == VAZIO); ++s) {
246 xnovo = (x+r)%LARGURA;
247 if (xnovo == -1) xnovo = LARGURA-1;
248 ynovo = (y+s)%ALTURA;
249 if (ynovo == -1) ynovo = ALTURA-1;
250 //pthread_mutex_lock(&(tabuleiro.mutex[xnovo][ynovo]));
251 tab_ler(xnovo, ynovo, &item);
252 if((item != VAZIO) && (item != ORDENADOR)) {
253 *i = item;
254 tab_escrever(xnovo, ynovo, VAZIO);
255 //pthread_mutex_unlock(&(tabuleiro.mutex[xnovo][ynovo]));
256 /* adquiriu o item */
257 return 0;
259 //pthread_mutex_unlock(&(tabuleiro.mutex[xnovo][ynovo]));
263 /* se não conseguir segue viagem */
265 return 0;
268 int pousar_item (int x, int y, item_t *i)
270 assert (x < LARGURA);
271 assert (y < ALTURA);
273 int xnovo, ynovo;
274 int r, s;
275 item_t item;
277 /* tenta pousar o item */
278 //pthread_mutex_lock(&(tabuleiro.mutex[x][y]));
279 for (r = -1; (r <= 1) && (*i != VAZIO); ++r) {
280 for (s = -1; (s <= 1) && (*i != VAZIO); ++s) {
281 /* cena estúpida por causa da aritmética modular */
282 xnovo = (x+r)%LARGURA;
283 if (xnovo == -1) xnovo = LARGURA-1;
284 ynovo = (y+s)%ALTURA;
285 if (ynovo == -1) ynovo = ALTURA-1;
286 //pthread_mutex_lock(&(tabuleiro.mutex[xnovo][ynovo]));
287 tab_ler(xnovo, ynovo, &item);
288 if(item == *i) {
289 tab_escrever(x, y, item);
290 *i = VAZIO;
291 printf("Pousou!\n");
292 /* pousou o item */
294 //pthread_mutex_unlock(&(tabuleiro.mutex[xnovo][ynovo]));
297 //pthread_mutex_unlock(&(tabuleiro.mutex[x][y]));
299 /* se não conseguir segue viagem */
301 return 0;
304 int main (int argc, char *argv[])
306 /* inicializar o gerador de números aleatórios */
307 srandom((unsigned int)time(NULL));
309 int coiso;
310 int r, s;
312 tab_criar(ALTURA, LARGURA);
313 tab_imprimir();
314 sleep(1);
316 /* preparar o tabuleiro */
317 for (r = 0; r < LARGURA; ++r) {
318 for (s = 0; s < ALTURA; ++s) {
319 coiso = random()%50;
320 if (coiso == 0) tab_escrever(r, s, A);
321 else tab_escrever(r, s, VAZIO);
325 tab_imprimir();
326 /* lançar ordenadores */
327 ordenador();
329 /* o programa termina quando o utilizador premir uma tecla */
330 getchar();
331 conglReset();
332 tab_libertar();
334 exit(0);