98919 VISITAS ACERCA ARCHIVOS BLOG FOTOS PROYECTOS

¿Cómo Resolver Un Juego De Mesa Con C++?

Alguna vez un amigo me regaló un juego de mesa que se hace llamar Solitario.

Solitario de Fotorama de México.

La forma de jugar es mover una pieza por encima de otra, o sea, brincarla. Entonces la pieza que nos hemos saltado, debe desaparecer del tablero, nos la comemos. Más o menos como se juega en las damas inglesas. Al final debe quedar solo una pieza en el tablero.

Entonces tenemos un programita que puede encontrar un montón de soluciones para este problema.

#include <iostream>
#include <conio.h>

using namespace std;

int tablero[5][5];
int pila[15][4];
int piezas;

void llenarTablero () {
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j <= i; j++) {
			tablero[i][j] = 1;
		}
	}
}

void imprimirTablero () {
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 4 - i; j++) {
			cout << " ";
		}
		for (int j = 0; j <= i; j++) {
			cout << tablero[i][j] << " ";
		}
		cout << endl;
	}
}

void imprimirPila () {
	cout << endl;
	for (int i = 0; i < 13; i++) {
		cout << pila[i][0] << "," << pila[i][1] << " > " << pila[i][2] << "," << pila[i][3] << endl;
	}
	cout << endl;
	getch();
}

void deshacerBrinco(int y0, int x0, int y1, int x1, int y2, int x2) {
	// ocupar posición inicial
	tablero[y0][x0] = 1;
	// ocupar posision intermedia
	tablero[y1][x1] = 1;
	// desocupar posición final 
	tablero[y2][x2] = 0;
}

// 0s son posición inicial
// 1s son posición intermedia
// 2s son posición final
int hacerBrinco (int y0, int x0, int y1, int x1, int y2, int x2) {
	// posición final dentro del tablero
	if (y2 >= 0 && y2 < 5 && x2 >= 0 && x2 <= y2) {
		// posición intermedia ocupada
		// posición final vacía
		if (tablero[y1][x1] == 1 && tablero[y2][x2] == 0) {
			// desocupar posición inicial
			tablero[y0][x0] = 0;
			// desocupar posision intermedia
			tablero[y1][x1] = 0;
			// ocupar posición final 
			tablero[y2][x2] = 1;

			// guardar movimiento en pila
			pila[14 - piezas][0] = y0;
			pila[14 - piezas][1] = x0;
			pila[14 - piezas][2] = y2;
			pila[14 - piezas][3] = x2;

			void siguienteSalto();
			siguienteSalto();
			deshacerBrinco(y0, x0, y1, x1, y2, x2);
			
			return 1;
		}
	}
	return 0;
}

void siguienteSalto () {
	if (--piezas == 1) {
		imprimirTablero();
		imprimirPila();
	}

	if (piezas > 1) {
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j <= i; j++) {
				// posición actual ocupada
				if (tablero[i][j] == 1) {
					// izquierda
					hacerBrinco(i, j, i, j - 1, i, j - 2);
					// derecha
					hacerBrinco(i, j, i, j + 1, i, j + 2);
					// arriba izquierda
					hacerBrinco(i, j, i - 1, j - 1, i - 2, j - 2);
					// arriba derecha
					hacerBrinco(i, j, i - 1, j, i - 2, j);
					// abajo izquierda
					hacerBrinco(i, j, i + 1, j - 1, i + 2, j - 2);
					// abajo derecha
					hacerBrinco(i, j, i + 1, j, i + 2, j);
				}
			}
		}
	}

	++piezas;
}

void quitarPrimera () {
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j <= i; j++) {
			tablero[i][j] = 0; // quitar
			siguienteSalto();
			tablero[i][j] = 1; // poner
		}
	}
}

int main () {
	llenarTablero();
	piezas = 15;
	quitarPrimera();
}

La representación del tablero en memoria es algo así.

Representación del solitario en memoria.

La salida hasta el primer getch() es ..

    1
   0 0
  0 0 0
 0 0 0 0
0 0 0 0 0

2,2 > 0,0
2,0 > 2,2
0,0 > 2,0
3,0 > 1,0
3,3 > 1,1
4,2 > 2,0
1,0 > 3,0
4,0 > 2,0
4,4 > 4,2
4,1 > 4,3
4,3 > 2,1
2,0 > 2,2
2,2 > 0,0

.. lo que significa ..

Solitario después de 0 movimeintos. Solitario después de 1 movimeintos. Solitario después de 2 movimeintos. Solitario después de 3 movimeintos. Solitario después de 4 movimeintos. Solitario después de 5 movimeintos. Solitario después de 6 movimeintos. Solitario después de 7 movimeintos. Solitario después de 8 movimeintos. Solitario después de 9 movimeintos. Solitario después de 10 movimeintos. Solitario después de 11 movimeintos. Solitario después de 12 movimeintos. Solitario después de 13 movimeintos.

Y eso es todo.

publicado el 22 de marzo de 2008 a las 20:40

Advertencia

La información de esta página no es confiable. El conocimiento se adquirió de forma empírica (o por fuerza bruta) y algunos términos pudieron ser inventados. Los trucos mencionados en este blog difícilmente son la manera más eficiente de resolver algún problema. La información no se actualiza y tampoco proviene de fuentes oficiales. Mejor acérquese a la documentación oficial, compre libros o visite la Wikipedia.

Comentarios Y Quejas Aquí






usa gravatar.com

Arti

Interesante, no sabia que existeria un juego asi, parece entretenido, pero mas aun que chido haber hecho un programa que de resolucion a este...

publicado el 8 de mayo de 2008 a las 16:23

El juego me lo regaló el abuelo .. Octavio! Tienes que regresar!

publicado el 8 de mayo de 2008 a las 18:55

usa gravatar.com

Arti

Ah que el buen abuelo,siempre le encantaron los juegos de mesa, sobre todo el ajedrez(de las mas de 100 partidas que juge con él solo le gané 1 y empate 1 también ja ja),era muy bueno, aún recuerdo cuando de vez en cuando nos quedabamos en su casa a jugar cartas y demas. changos ya no es lo mismo sin él...

publicado el 10 de mayo de 2008 a las 22:19

usa gravatar.com

Fernando

que genial...

publicado el 11 de mayo de 2008 a las 16:44

usa gravatar.com

mxmike

muy bien!!!
esto lo escribo por si algun lector no le corre el codigo...
en mi compilador (visual c++) en la linea 20 donde haces el for con j, le cambie la variable a k porque me decia que se repetia j ( con el for de la linea 23) y en la ultima funcion int main() le puse al final return 0; porque al compilar me decia que no devolvia valor y ps corrió y efectivamente puede resolver el problema de esa forma. te felicito.

publicado el 26 de octubre de 2008 a las 23:08

Hola mxmike:

Que bueno que compilaste el código, el primer error que raro suena. Y el "return 0" no es obligatorio, según el estándar de C99 el "return 0" es implícito en C y C++. Supongo que tu compilador no es muy moderno. :D

publicado el 29 de octubre de 2008 a las 19:45