Ver Mensaje Individual
  #34 (permalink)  
Antiguo 11/07/2008, 21:31
aceutico
 
Fecha de Ingreso: julio-2008
Mensajes: 38
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: ¿Por qué no hacemos una competencia entre programadores?

Aquí está el código del programa de arriba.

Está escrito en C, supongo que es válido... no sé si tratan ese lenguaje por aquí (está muy antiguo ya), he visto que había un subforo así que supongo que sí.

Código:
/*
 * TicTacToe - Copyright (C) aceutico <[email protected]> - GPLv3
 */

#include <stdio.h>
#include <string.h>

#define l(n) d[p[n]]
#define fa for (i = 0; i < 9; ++i)
#define fai(n) fa if (s[i] == n)
#define j(k) fai(k) { main(5 * -2, i); goto oo; }
#define s(n, x, y, z) s[n] = p[x] + p[y] + p[z];
#define jj(x, y, z, t) { j(x); j(y); j(z); j(t); }
#define ll(n) l(n), l(n+1), l(n+2)
#define x ((char)argv)
#define u(x) if (!p[x]) p[x] = 5 * 2;
#define uu(n, x, y, z) case n: u(x) else u(y) else u(z); break;

char p[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};

int main(int argc, char *argv[])
{
	char i, g = 0, e = 0, f = 0, s[8],
		d[11] = {'-', ('-' - 1) * 2, 0, 0, 0,
			0, 0, 0, 0, 0, '\'' + '('};
	unsigned short int m;

	switch (argc) {
	case -10:
		switch ((int)argv) {
			/* Cálculo de posición */
			uu(3, 4, 3, 5); uu(0, 0, 2, 1);
			uu(6, 6, 8, 7); uu(1, 0, 6, 3);
			uu(2, 2, 8, 5); uu(4, 4, 1, 7);
			uu(5, 4, 0, 8); uu(7, 4, 2, 6);
		}
		return 1;

	case -11:
		main(-12, argv);
		scanf("%hu", &m);
		return m;

	case 2:
		/* Argumentos para el programa */
		if (!strcmp(argv[1], "--facil"))
			f = 1;
		else {
			main(-12, "TicTacToe. Jugable en dos modos:\n"
				"Difícil (por defecto)\n"
				"Fácil (pasar como argumento: --facil)\n");
			return 0;
		}
	
	default:
		printf("TicTacToe, modo: %s. Vea --help.\n",
			f ? "Fácil" : "Difícil");

		/* Bucle principal */
		for (;;) {
oo:			printf("%c%c%c 012\n%c%c%c 345\n%c%c%c 678\n",
				ll(0), ll(3), ll(6));
			
			/* Mueve */
			for (;;) {
				m = main(-11, "Movimiento (0-8): ");
				if (m <= 8)
					if (!p[m])
						break;
			}

			p[m] = 1;

			/* Recalcular */
			s(0, 0, 1, 2); s(3, 3, 4, 5);
			s(6, 6, 7, 8); s(1, 0, 3, 6);
			s(4, 1, 4, 7); s(2, 2, 5, 8);
			s(5, 0, 4, 8); s(7, 2, 4, 6);
		
			/* Comprobar si has ganado */
			fai(3) {
				g = 1;
				goto o;
			}

			/* Comprobar si hemos empatado */
			e = 1;
			fa if (!p[i]) {
				e = 0;
				break;
			}

			if (e)
				goto o;

			/* Comprobar si he ganado */
			fai (20)
				goto o;

			/* Defenderme si es necesario */
			j(2);

			/* Atacar, añadir, bloquear o rellenar */
			if (!f)
				jj(10, 0, 1, 11)
			else
				jj(11, 1, 0, 10)
		}

o:		printf("Ganador: %s\n", e ? "Empate" : (g ? "Tu" : "Yo"));
		return 0;
	
	case -2 -10:
		printf(argv);
		return -10;
	}
}
Espero que les guste. La indentación creo que está perfecta. La eficiencia... Podría mejorarse, supongo. La longitud del código creo que es pequeña: Son 85 líneas eliminando líneas en blanco y demás.

Sobre los comentarios, quizá hagan falta un par más, para aclarar el funcionamiento. ¿Cómo lo ven?

Pruébenlo y me cuentan si lograron encontrar una forma de ganarle, ¿sí?

Última edición por aceutico; 12/07/2008 a las 13:42