Subido por Jhonnathan Bolaños

Lab4 B51093

Anuncio
Universidad de Costa Rica
Facultad de Ingenierı́a
Escuela de Ingenierı́a Eléctrica
IE-0117 Programación bajo plataformas abiertas
Laboratorio 4: Trivia
Luis Alberto Soto Camacho, B57082
Esteban Varela Serrano, B57475
Jhonnathan Bolaños Paniagua, B51093
I-2019
Tabla de contenidos
1. Enunciado
2. Procedimiento
2.1. Sección 1 .
2.2. Sección 2 .
2.3. Sección 3 .
2.4. Sección 4 .
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
3
4
6
3. Resultados
7
4. Conclusiones
9
1.
Enunciado
Implemente un juego de trivia utilizando el lenguaje de programación c. El programa funcionará
de la siguiente manera:
1. Imprimir una bienvenida.
2. Solicitar a los jugadores (máximo 4) sus nombres.
3. Presentar una pregunta a cada jugador rotando tanto las preguntas como los jugadores hasta
que no haya más preguntas que hacer. Las preguntas deben ser leı́das de un archivo de texto
cuyo formato esta especificado en la figura 1.
1
4. Sumar un punto por cada pregunta contestada correctamente al jugador apropiado.
5. Imprimir el nombre del ganador al finalizar el juego
2.
Procedimiento
La elaboración del juego de trivia se dividió en 4 secciones principales, las cuales se explican a
continuación:
2.1.
Sección 1
Primeramente se declaran las variables a utilizar en el código. Se declaran las variables para
almacenar la cantidad de jugadores y las preguntas, por esto se utilizan datos de tipo entero.
int pn;
int cantprgnts;
//Cantidad de jugadores
//Cantidad de preguntas
Luego, para almacenar los nombres de los jugadores se utilizan variables de tipo char (caracter),
estos se almacenan en un puntero (arreglo) de tamaño 4 para poder acceder más fácilmente a ellos.
char n1[128];
//Nombres de los jugadores
char n2[128];
char n3[128];
char n4[128];
char* n[4]= {n1,n2,n3,n4};
Ahora se inicializan las variables que van a almacenar los puntales de los jugadores, estas
poseen un valor inicial de cero que es el puntaje con el que todos los jugadores inician la trivia.
Estas variables se almacenan en un arreglo de tipo entero.
int
int
int
int
int
p1 =
p2 =
p3 =
p4 =
p[4]
0;
//Puntos de los jugadores
0;
0;
0;
= {p1,p2,p3,p4};
Se definen las variables para almacenar tanto las preguntas como las respuestas del archivo .txt.
De igual manera que en el caso de los nombres de los jugadores, se almacenan las opciones en un
puntero de tamaño 4.
char pregunta[128]; //Array de la pregunta escaneada del .txt
char op1[128];
//Array de las respuestas escaneadas del .txt
char op2[128];
char op3[128];
char op4[128];
char* op[4] = {op1,op2,op3,op4};
2
Finalmente se definen las variables los tipos de respuesta y se inicializa la variable del jugador
actual en 0, ya que esta variable funcionará como un contador. También se utiliza una variable de
tipo char que guarde el nombre del jugador ganador que se mostrará al final del juego.
int respcorrecta;
int respdada;
int actualplyr = 0;
char ganador[128];
2.2.
//Número de la respuesta correcta
//Respuesta dada por el jugador
//Jugador actual
//Nombre del ganador
Sección 2
Esta sección muestra las instrucciones presentadas al inicio del juego, donde se solicita la cantidad de jugadores y de acuerdo con el número seleccionado se le pide a cada jugador ingresar su
nombre.
Primeramente se imprimen en pantalla las instrucciones del juego:
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("**********************************************************\n");
printf("
Juego de Trivia
\n");
printf("************************************************************");
printf("\n\n Instrucciones:\n -Lea cada pregunta e ingrese el valor de la
respuesta que considere correcta.\n -Cada respuesta correcta suma un punto.
\n -El jugador con más puntos gana.\n");
printf("-En caso de querer salir del juego antes presione cualquier letra
cuando soliciten el número de la respuesta. \n \n");
Luego, se solicita al usuario que ingrese la cantidad de jugadores, para esto se utiliza la función
scanf que va a almacenar el valor entero ingresado por el usuario en la variable pn. También
se implementa un ciclo mediante un while para que cuando el valor ingresado sea menor a dos
o mayor que cuatro se imprima en pantalla que ocurrió un error y que el usuario debe volver a
ingresar el número de jugadores. Al ser variables de tipo entero se utilizan los especificadores de
formato %d, %i que corresponden a los datos de tipo entero.
printf("Ingrese cantidad de jugadores (2-4): ");
scanf("%d", &pn);
printf("\n");
while(pn < 2 || pn > 4){
printf("Error, intente de nuevo.\n ");
scanf("%i",&pn);
printf("\n");
}
Para almacenar los nombres de los jugadores se utiliza un for, que recorre el arreglo declarado
para almacenar los nombres de los jugadores y mediante la función scanf en cada iteración se
guarda cada uno de estos nombres en la posición correspondiente, iniciando en n[0]. El ciclo se
3
detiene cuando el valor de la variable auxiliar i es menor que el número de jugadores ingresado
previamente.
for (int i = 0; i < pn; i++)
{
printf("Ingrese el nombre del jugador número %d: ", i+1);
scanf("%s", n[i]);
}
printf("\n");
2.3.
Sección 3
Esta sección se compone de las preguntas junto con sus respectivas opciones, las cuales son
escaneadas de un archivo de texto y se imprimen una por una de acuerdo con el turno de cada
jugador, además se devuelve el resultado de cada respuesta dada por el jugador y se van sumando
los puntos por cada respuesta acertada.
Primeramente se define la variable f in, donde se va a almacenar el contenido que se lee del
archivo de preguntas. Luego con fopen se abre el archivo y se asocia con f in, se utiliza r ya que
solamente se desea leer del archivo. Para leer y guardar las preguntas del archivo de texto se utiliza
la función fscanf, que va a guardar el contenido leı́do de la primer lı́nea del archivo y lo almacena
en cantprgnts.
FILE* f_in;
f_in = fopen(argv[1], "r");
fscanf(f_in, "%i\n", &cantprgnts);
Luego mediante un for se escanea la pregunta y el número de la respuesta correcta que se
encuentra al final de cada pregunta del archivo. Esto se va a repetir hasta finalizar con la cantidad
de preguntas presentes en el archivo.
for (int i = 0; i < cantprgnts; i++)
{
fscanf(f_in, "%[^\n] %[^\n] %[^\n] %[^\n] %[^\n]", pregunta, op[0],
op[1], op[2], op[3]);
fscanf(f_in, "%i\n\n", &respcorrecta);
\\Se escanea y almacena la respuesta correcta.
4
Se muestra en consola la pregunta a realizar y entre paréntesis el nombre del jugador actual
( %s indica que el tipo de dato es un caracter). Después se imprimen cada una de las opciones de
la pregunta y se solicita la respuesta del jugador, este valor se almacena en la variable respdada
mediante la función scanf.
printf("%s(Jugador actual: %s)\n", pregunta, n[actualplyr]);
printf("%s\n %s\n %s\n %s\n \n", op[0], op[1], op[2], op[3]);
printf("Ingrese el número de la respuesta correcta: ");
scanf("%i", &respdada);
printf("\n");
Mediante la condición if se establece que en caso de que la respuesta ingresada sea la correcta
se le asigna un punto al jugador, esto se realiza en la última lı́nea, cuando se accede al vector de
puntajes (p) en la posición correspondiente al jugador actual (actualplyr). Además se imprime
en pantalla que el jugador respondió correctamente.
if (respdada == respcorrecta)
{
printf("------------------------------------ \n");
printf("¡Correcto!, la respuesta correcta es la %i.\n",
respcorrecta);
printf("%s obtiene 1 punto. \n", n[actualplyr]);
printf("------------------------------------ \n \n");
p[actualplyr] = p[actualplyr] + 1;
}
En el caso contrario se imprime en pantalla que el jugador falló y se indica el número de la
respuesta correcta. El puntaje del jugador se mantiene sin ningún cambio.
else
{
printf("---------------------------------------- \n");
printf("INCORRECTO, la respuesta correcta era la número %i.\n",
respcorrecta);
printf("---------------------------------------- \n \n" );
}
Luego, mediante otro if se controla el contador actualplyr que indica cuando es el turno del
siguiente jugador. Cuando se tiene que el jugador actual +1 es igual que el número de jugadores
ingresado por el usuario (pn), entonces se vuelve a iniciar con el primer jugador para realizar la
siguiente pregunta. Para que el mensaje de ”siguiente jugador”no se repita en todas las ocasiones
se utiliza un if, y ası́ solo se muestra el mensaje en consola hasta la última pregunta.
5
if (actualplyr+1 == pn)
{
actualplyr = 0; \\Se regresa al primer jugador.
}
else
{
actualplyr = actualplyr + 1; \\Siguiente jugador.
}
if(i<cantprgnts-1){
printf("El siguiente jugador es %s. \n\n", n[actualplyr]);
}
} //Fin del ciclo for.
2.4.
Sección 4
En esta parte el procedimiento es sencillo, se cuentan los puntos de todos los jugadores presentes
y a partir de esto se imprime al ganador o el empate.
//Seccion 4: se muestra el puntaje y se elije un ganador
//Se muestra el p
printf("\n \n \n");
printf("------------------------------------------- \n");
printf("El puntaje final de cada jugador es: \n \n");
ganador[0] = n[0]; //Ganador default (para que no genere problemas).
Se utiliza un for para imprimir en pantalla el nombre de cada jugador y sus puntos obtenidos.
for (int i = 0; i < pn; i++)
{
printf("%s: %i.\n", n[i], p[i]);
}
Luego mediante cuatro condiciones if se detecta cual jugador ganó o si el juego terminó con un
empate. Los else if sólo se ejecutan si la condición que poseen es verdadera, mientras que el else
final se utiliza cuando ocurre el empate, ya que ninguna de las condiciones anteriores se cumplió.
if (p[0]>p[1] && p[0]>p[2] && p[0]>p[3]){
//Caso en que el jugador 1 gana.
printf("El ganador es ¡%s!\nGracias por jugar. :)\n", n[0]);
printf("------------------------------------------- \n");
6
}else if (p[1]>p[0] && p[1]>p[2] && p[1]>p[3]){
//Caso en que el jugador 2 gana.
printf("El ganador es ¡%s!\nGracias por jugar. :)\n", n[1]);
printf("------------------------------------------- \n");
}else if (p[2]>p[0] && p[2]>p[1] && p[2]>p[3]){
//Caso en que el jugador 3 gana.
printf("El ganador es ¡%s!\nGracias por jugar. :)\n", n[2]);
printf("------------------------------------------- \n");
}else if (p[3]>p[0] && p[3]>p[1] && p[3]>p[2]){
//Caso en que el jugador 4 gana.
printf("El ganador es ¡%s!\nGracias por jugar. :)\n", n[3]);
printf("------------------------------------------- \n");
}else{
//Caso en el que ocurre un empate.
printf("Hay un empate\n\n");
printf("------------------------------------------- \n");
}
fclose(f_in); //Se cierra el archivo de preguntas.
return 0;
} //Fin del código.
3.
Resultados
Se muestran los resultados obtenidos del juego con algunos ejemplos de prueba.
Estos ejemplos se realizaron con un archivo de texto que contenı́a preguntas sobre capitales de
paı́ses, el inicio del juego mostrado en la terminal se observa en la figura 1.
Figura 1: Inicio del juego donde se muestran las instrucciones.
7
Luego en la siguiente figura, al ingresar la cantidad de los jugadores se observa el caso cuando la
cantidad digitada es incorrecta, y después cuando el número ingresado es el correcto. Si el número
se encuentra dentro de los permitidos se solicitan los nombres de los jugadores.
Figura 2: Cantidad y nombres de los jugadores.
Cuando se realiza la pregunta y el jugador logró responder correctamente se muestra:
Figura 3: Cuando la respuesta es correcta.
En el caso que la respuesta sea incorrecta:
Figura 4: Cuando la respuesta es incorrecta.
8
Al finalizar las preguntas si se obtuvo un ganador se muestra:
Figura 5: Cuando uno de los jugadores ganó.
Si el puntaje final es igual para al menos dos jugadores se genera un empate y ningún jugador
resulta ganador:
Figura 6: Empate.
4.
Conclusiones
Es importante tomar en cuenta que el sı́mbolo ∗ en C se puede utilizar para definir variables
de tipo puntero pero también para acceder al contenido que almacena una variable de este
tipo al desreferenciarla.
Cuando se están utilizando arreglos no se debe utilizar el operador & en ellos, ya que los
arreglos son punteros (direcciones de memoria). También, aunque los arreglos son punteros,
al definir un arreglo se debe hacer adecuadamente y no utilizando la notación de puntero.
Hay que tomar en cuenta las distintas condiciones que se escriben en los ciclos, como en un
while, ya que en ocasiones por no corroborar las condiciones establecidas el programa puede
entrar en un ciclo infinito.
9
Descargar