Proyecto 1 piedra papel y tijera
Vamos a crear una primera
aplicación de consola con los siguientes requisitos:
·
El usuario podrá elegir una única opción
(piedra, papel o tijera).
·
La opción del oponente debe ser aleatoria.
·
El usuario debe recibir un mensaje indicando el
resultado.
·
El usuario debe ser preguntado si quiere jugar de
nuevo o no.
Vamos a empezar por crear un
nuevo proyecto en la carpeta Projects que tenemos en el escritorio
Lo abrimos en VS code
Y voy a cambiar el mensaje a
consola por piedra papel y tijera
Console.WriteLine("Piedra,
Papel, Tijera");
Lo que queremos es que el juego
dure mientras el usuario no indique lo contrario. Por ello vamos a usar un
bucle while, con su condición a true de forma que el juego sea un bucle
infinito mientras no se indique lo contrario.
Como se trata de una sencilla app
de consola sin interfaz gráfica vamos a ir mandando mensajes por consola para
que el usuario entienda por dónde va el juego:
Console.WriteLine("Piedra,
Papel, Tijera");
Console.WriteLine("Are
you ready?");
Lo primero que tenemos que hacer
es dar a elegir al usuario qué opción va a querer seleccionar, piedra, papel o
tijera. Para ello como estamos en consola usaremos teclas para elegir las
opciones:
Console.WriteLine("Rock
Paper Scissors");
Console.WriteLine("Are
you ready?");
Console.WriteLine("Choose
R, P or S: [R]ock, [P]aper or [S]cissors: ");
Console.WriteLine("Are you ready?");
//Opciones
Console.WriteLine("Choose R, P or S: [R]ock, [P]aper or [S]cissors: ");
}
Vamos a ver si es cierto que el bucle se detiene a la espera de que el usuario escriba, abrimos nuestra terminal y lanzamos el comando dotnet run
Podemos ver como se muestran
nuestros mensajes y el bucle se detiene al llegar al readLine
Para saber lo que el usuario ha
escrito, lo siguiente será guardar el ReadLine en una variable que podemos
llamar selecedChoice y validar que el usuario hay escogido alguna delas 3
opciones permitidas es decir R, P o S.
NOTA: El método ReadLine devuelve
un string. Así que para la comparación debo comparar contra un string “comillas
dobles”, si pongo un char ‘comillas simples me devolverá error’-
Console.WriteLine("Are you ready?");
Console.WriteLine("Choose R, P or S: [R]ock, [P]aper or [S]cissors: ");
//Leemos la respuesta del usuario y lo guardamos en una variable
var selectedChoice = Console.ReadLine();
con un operador ternario, además hacemos todas las respuestas
Minúsculas
*/
if(selectedChoice?.ToLower() != "r" &&
Console.WriteLine("Please, select only one letter; R, P or S");
}
MÉTODO
Estamos en C# así que a nuestro
método debemos darle un tipado, en nuestro caso va a devolver un string por
tanto crearemos nuestro método y dentro
de él pondremos nuestra estructura de control:
Console.WriteLine("Are you ready?");
}
string SelectChoice()
//Opciones
Console.WriteLine("Choose R, P or S: [R]ock, [P]aper or [S]cissors: ");
//Leemos la respuesta del usuario y lo guardamos en una variable
var selectedChoice = Console.ReadLine();
if(selectedChoice?.ToLower() != "r" &&
Console.WriteLine("Please, select only one letter; R, P or S");
return selectedChoice;
Por tanto, si llamamos a este
método se hará la validación y ahora en caso de que el usuario introduzca una
respuesta errónea usaremos una característica muy útil de los métodos y
funciones que es la recursividad, es decir que el método se llame a sí mismo:
Console.WriteLine("Are you ready?");
string SelectChoice()
//Opciones
Console.WriteLine("Choose R, P or S: [R]ock, [P]aper or [S]cissors: ");
//Leemos la respuesta del usuario y lo guardamos en una variable
var selectedChoice = Console.ReadLine();
/*Validamos que la respuesta sea una de las 3 letras permitidas
con un operador ternario, además hacemos todas las respuestas
Minúsculas
*/
if(selectedChoice?.ToLower() != "r" &&
//Si la respuesta es erróna mandamos mensaje y volvemos a
//LLamar a este mismo método desde sí mismo RECURSIVIDAD
Console.WriteLine("Please, select only one letter; R, P or S");
}
return selectedChoice;
Ahora todas las veces que el
usuario responda mal el método se llamará a sí mismo, y solo saldrá de ese
bucle si el usuario responde con alguna de las opciones correctas, saliendo por
el return, es deci devolviendo la opción escogida.
Pero falta un detalle importante,
debemos llamara a nuestro método para que se ejecute, y debemos llamarlo dentro
de nuestro bucle while ()
Método Parse y Concatenación
Sabemos que nuestro método
SelectedChoice nos devuelve un String, pero como es una sola letra, una cosa
que podemos hacer es convertir esa respuesta de string a char y así presentamos
el método parse. Así que una vez que tenemos la respuesta la convertimos a char
y por último mostramos la respuesta en la salida del programa, concatenando
texto con la variable, para concatenar anteponemos el símbolo $ y de este modo
entre llaves nos deja añadir la variable (template strings) (rojo):
Console.WriteLine("Are you ready?");
var selectedChoice = SelectChoice();
var yourChoice = char.Parse(selectedChoice);
Console.WriteLine($"You selected {yourChoice}");
}
//Opciones
Console.WriteLine("Choose R, P or S: [R]ock, [P]aper or [S]cissors: ");
//Leemos la respuesta del usuario y lo guardamos en una variable
var selectedChoice = Console.ReadLine();
con un operador ternario, además hacemos todas las respuestas
Minúsculas
*/
if(selectedChoice?.ToLower() != "r" &&
//Si la respuesta es erróna mandamos mensaje y volvemos a
//LLamar a este mismo método desde sí mismo RECURSIVIDAD
Console.WriteLine("Please, select only one letter; R, P or S");
return selectedChoice;
Podemos ejecutar desde la
terminal de VS o desde el símbolo de sistema
AGREGANDO LA OPCIÓN DEL OPONENTE
Vamos ahora a añadir la opción
del oponente, para ello vamos a crear un nuevo método. Esta vez en vez de
trabajar con el tipo string vamos a trabajar directamente con el tipo char.
}
Lo que queremos hacer es elegir
un número aleatorio, para ello crearemos un Array de tipo char con las opciones
posibles, mira como declaramos un array con su tipo y como lo inicializamos con
sus valores:
char[] options = new char[] { 'R', 'P', 'S' };
Lo que queremos es elegir de
forma aleatoria una de estas 3 opciones, para ello usaremos el método random.
char[] options = new char[] { 'R', 'P', 'S' };
Ahora vamos a trabajar con el
índice del Array usando el método random que nos elegirá aleatoriamente una
posición del Array para guardarlo como respuesta aleatoria y lo guardamos en
una variable que podemos llamar como queramos en este caso la he llamado randomIndex:
//Creamos e inicailizamos una arry char con las opciones
char[] options = new char[] { 'R', 'P', 'S' };
Random random = new Random();
int randomIndex = random.Next(0, options.Length);
}
Observa que a la variaboe
randomIndex le hemos dado el tipo integer ya que lo que lo que va a guardar es
un numero entero que se corresponderá con alguna posición del array (0, 1, 2).
Sólo nos queda devolver la
respuesta aleatoria que como puedes ver es lo que contiene el Array en la
posición indicada de forma aleatoria:
//Creamos e inicailizamos una arry char con las opciones
char[] options = new char[] { 'R', 'P', 'S' };
Random random = new Random();
int randomIndex = random.Next(0, options.Length);
//en la posición que le indicamos en la variable randomIndex
return options[randomIndex];
}
Ahora hay que llamar a nuestro
nuevo método en el bucle While que es donde tenemos la secuencia principal de
nuestro juego:
Console.WriteLine("Are you ready?");
var selectedChoice = SelectChoice();
//Mostramos por salida la respuesta elegida
Console.WriteLine($"You selected {yourChoice}");
nos devuelve la respuesta aleatoria de nuestro oponente y
guardamos esa respuesta en una variable
*/
}
Vamos a ejecutarlo para ver que tenemos hasta ahora esta vez
desde la consola de VSCode.
Como puedes ver yo elijo r y el PC elije P, no tenemos nada
mas codificado por lo que el bucle vuelve a empezar, por tanto de momento vamos
bien.
RESOVIENDO EL GANADOR DE LA PARTIDA
Primero resolveremos el caso de que sea un empate, que es
cuando los dos escogemos la misma opción, por supuesto todo esto lo programamos
dentro de nuestro while que es el flujo principal de nuestro juego:
Console.Write("Tie¡");
Ahora debemos pensar cómo vamos a solucionar quien gana en
caso de que no sea un empate, podríamos hacerlo con estructuras de contro if
else en el while, pero para hacerlo más limpio lo vamos a hacer en un nuevo
método en este caso un método de tipo void (que no devuelve nada).
Obsrva que al método le tenemos que pasar como parámetros
las variables de las elecciones de cada contrincante, opponentChoice y
yourChoice, separadas con una coma e indicando su tipo en cada una (rojo)
//CASO EMPATE
if(opponentChoice == yourChoice) Console.Write("Tie¡");
}
Y por supuesto hay que llamar al método desde el while
Console.WriteLine("Are you ready?");
var selectedChoice = SelectChoice();
//Mostramos por salida la respuesta elegida
Console.WriteLine($"You selected {yourChoice}");
nos devuelve la respuesta aleatoria de nuestro oponente y
guardamos esa respuesta en una variable para mostrar la
respuesta de nuestro oponente virtul
*/
DecideWinner(opponentChoice, yourChoice);
Ya tenemos el método que analiza si hay empate, ahora
debemos pensar como resolver quien es el ganador y lo vamos a hacer con un
Switch, analizando la opción del usuario contra la opción del sistema
//El usuario elige roca
case 'R':
if(opponentChoice == 'P') //Si el pc elige Papel gana el pc
Console.WriteLine("Paper beats rock, I win¡");
Console.WriteLine("Rock beats Scissors, you win¡");
case 'S':
Console.WriteLine("Scissord beats paper, You win¡");
Console.WriteLine("Rock beats Scissors, I win¡");
case 'P':
Console.WriteLine("Scissord beats paper, I win¡");
Console.WriteLine("Paper beats Rock, You win¡");
Vamos a ejecutar nuestro juego esta vez usando la consola
PowerShell,
1.
Elijo R y el sistema elije R hay empate
2.
Elijo P y el sistema también, hay empate
3.
Elijo s y el sistema elije P, gano yo ya que las
tijeras ganan al papel.
Al final el juego se reanuda ya que estamos dentro de un
while hecho true, así que si no hacemos nada el juego se reanudará eternamente
vamos a dar la opción al usuario de seguir o salir del juego.
En nuestro While añadimos (en rojo)
Console.WriteLine("Are you ready?");
var selectedChoice = SelectChoice();
//Mostramos por salida la respuesta elegida
Console.WriteLine($"You selected {yourChoice}");
nos devuelve la respuesta aleatoria de nuestro oponente y
guardamos esa respuesta en una variable para mostrar la
respuesta de nuestro oponente virtul
*/
DecideWinner(opponentChoice, yourChoice);
//Guardamos su respuesta e una variable
Console.WriteLine("Do you want to play again?");
var playAgain = Console.ReadLine();
if(playAgain?.ToLower() == "y")
break;
Si ahora ejecuto: