Esta vez repasaremos matrices, funciones, condicionales e iteraciones, todo esto aplicado en el clásico juego del tres en raya, las reglas del juego son muy conocidas, sólo haré unos cuantos razonamientos previos antes de empezar a programar:
Sobre los turnos
Sabemos que son 2 jugadores que juegan
por turnos hasta que alguno gana o el tablero se llena
sin ganador (situación de empate).
Vemos que debe existir una iteración que finalice cuando el juego termina:
var fin_juego = false;
var turno = 0; //los jugadores son 0 y
1
while(!fin_juego)
{
//se hace la jugada
//si se gana en este turno fin_juego
= true;
//si el tablero se llena sin ganador
fin_juego = true;
turno = (turno + 1) % 2; //esto es
para cambiar el turno de 0 a 1 y de 1 a 0
}
Sabemos que es un tablero de 9 casillas
(3 filas y 3 columnas). En principio todas las casillas están vacías
y en cada turno se va llenando alguna de las casillas con la jugada
hecha en el turno.
Si todas las casillas están llenas y
no hay ganador, entonces es un empate.
Para controlar que el juego termine en
empate creamos un condicional en cada iteración que controle
si se llenó el tablero o no.
var fin_juego = false;
var turno = 0; //los jugadores son 0 y
1
var casillas_vacias = 9;
while(!fin_juego)
{
//se hace la jugada
casillas_vacias = casillas_vacias -
1; //al hacer la jugada disminuye en 1 las casillas vacías
//si se gana en este turno fin_juego
= true;
//si el tablero se llena sin ganador
fin_juego = true;
if(!fin_juego &&
casillas_vacias == 0) fin_juego = true;
turno = (turno + 1) % 2; //esto es
para cambiar el turno de 0 a 1 y de 1 a 0
}
Sobre la jugada
El jugador debe seleccionar la casilla
que quiere marcar, para esto utilizaremos las filas y las columnas de
la matriz que representa al tablero.
var boolean fin_juego = false;
var int turno = 0; //los jugadores son
0 y 1
var int casillas_vacias = 9;
var char tablero [3][3];//matriz de 3 x
3 que representa al tablero
var int fila_jugada;
var int columna_jugada;
var char ficha='0'; //será 'X' cuando
el turno sea 1
while(!fin_juego)
{
//se hace la jugada
fila_jugada = leer(); //lee de
consola la fila (de 0 a 2) que selecciona el jugador en ese turno
columna_jugada = leer(); //lee de
consola la columna (de 0 a 2) que selecciona el jugador en ese turno
if(turno == 0) ficha = '0'; //escoge
ficha
else ficha = 'X';
tablero[fila_jugada][columna_jugada]
= ficha;
casillas_vacias = casillas_vacias -
1; //al hacer la jugada disminuye en 1 las casillas vacías
//si se gana en este turno fin_juego
= true;
//si el tablero se llena sin ganador
fin_juego = true;
if(!fin_juego &&
casillas_vacias == 0) fin_juego = true;
turno = (turno + 1) % 2; //esto es
para cambiar el turno de 0 a 1 y de 1 a 0
}
Sobre el control de la jugada ganadora
Cuando se coloca la ficha se hace
control en vertical, horizontal y diagonales a ver si es una jugada
ganadora.
Para el control horizontal, todas las
fichas de la fila_jugada deben ser iguales, por tanto haremos una
validación iterando las columnas.
Para el control vertical, todas las
fichas de la columna_jugada deben ser iguales, por tanto haremos una
validación iterando las filas.
Para el control diagonal, no es
necesario realizarlo siempre, sólo cuando la jugada esté en alguna
diagonal. Y sólo si está en el medio del tablero la comprobación
debe ser de la doble diagonal.
Comprobar diagonal 1
fila_jugada: 0 y columna_jugada:0,
fila_jugada: 2 y columna_jugada:2
Comprobar diagonal 2
fila_jugada: 2 y columna_jugada:0,
fila_jugada: 0 y columna_jugada:2
Comprobar ambas diagonales.
fila_jugada: 1 y columna_jugada:1
Como esta lógica es un poco larga, la
encapsularemos en una función y la utilizaremos en cada
jugada para comprobar si la jugada es ganadora:
Entrada: ¿Qué necesito?
Tablero, fila_jugada, columna_jugada
Salida: ¿Qué quiero?
Booleano que indique si es una jugada
ganadora o no
Función: ¿Cómo lo hago?
Comprobando la Horizontal, Vertical y
cuando toque las diagonales.
Boolean esGanador(tablero, fila_jugada,
columna_jugada)
{
Boolean jugada_ganadora = false;
//validación horizontal
if(Tablero[fila_jugada][0] ==
Tablero[fila_jugada][1] &&
Tablero[fila_jugada][0] ==
Tablero[fila_jugada][2])
{
return true; //jugada ganadora en
la horizontal, termina la ejecución
}
//validación vertical
if(Tablero[0][columna_jugada] ==
Tablero[1][columna_jugada] &&
Tablero[0][columna_jugada] ==
Tablero[2][columna_jugada])
{
return true; //jugada ganadora en
la vertical, termina la ejecución
}
//verifica la diagonal 1 (sólo si es
necesario)
if( (fila_jugada == 0 &&
columna_jugada == 0) || (fila_jugada == 2 && columna_jugada
== 2))
{
if(Tablero[0][0] == Tablero[1][1] &&
Tablero[0][0] == Tablero[2][2])
{
return true; //jugada ganadora en
la diagonal 1, termina la ejecución
}
}
//verifica la diagonal 2 (sólo si es
necesario)
if( (fila_jugada == 0 &&
columna_jugada == 2) || (fila_jugada == 2 && columna_jugada
== 0))
{
if(Tablero[0][2] == Tablero[1][1] &&
Tablero[0][2] == Tablero[2][0])
{
return true; //jugada ganadora en
la diagonal 2, termina la ejecución
}
}
//verifica la doble diagonal(sólo si
es necesario)
if( fila_jugada == 1 &&
columna_jugada == 1)
{
if((Tablero[0][2] == Tablero[1][1] &&
Tablero[0][2] == Tablero[2][0])
||
(Tablero[0][0] == Tablero[1][1] &&
Tablero[0][0] == Tablero[2][2]))
{
return true; //jugada ganadora en
alguna de las diagonales, termina la ejecución
}
}
return jugada_ganadora; //sólo llega
a esta línea de código cuando no es jugada ganadora
}
Incorporamos la llamada a la función
en el programa principal
var boolean fin_juego = false;
var int turno = 0; //los jugadores son
0 y 1
var int casillas_vacias = 9;
var char tablero [3][3];//matriz de 3 x
3 que representa al tablero
var int fila_jugada;
var int columna_jugada;
var char ficha='0'; //será 'X' cuando
el turno sea 1
while(!fin_juego)
{
//se hace la jugada
fila_jugada = leer(); //lee de
consola la fila (de 0 a 2) que selecciona el jugador en ese turno
columna_jugada = leer(); //lee de
consola la columna (de 0 a 2) que selecciona el jugador en ese turno
if(turno == 0) ficha = '0'; //escoge
ficha
else ficha = 'X';
tablero[fila_jugada][columna_jugada]
= ficha;
casillas_vacias = casillas_vacias -
1; //al hacer la jugada disminuye en 1 las casillas vacías
//si se gana en este turno fin_juego
= true;
fin_juego = esGanador(tablero,
fila_jugada, columna_jugada);
//si el tablero se llena sin ganador
fin_juego = true;
if(!fin_juego &&
casillas_vacias == 0) fin_juego = true;
turno = (turno + 1) % 2; //esto es
para cambiar el turno de 0 a 1 y de 1 a 0
}
Con esto tendríamos lo básico para el
tres en raya, pero ¿qué pasaría si el jugador pusiera la ficha en
un lugar ocupado? ¿qué pasaría si inicialmente el tablero está
ocupado?¿No vendría bien agregar una impresión del tablero para
que jugador sepa en cada jugada cuáles son sus opciones de juego?
¿Cómo modificaríais el programa para
agregar estas funcionalidades?
No hay comentarios:
Publicar un comentario