Skip to content
This repository has been archived by the owner on Jul 10, 2019. It is now read-only.
cbestevez edited this page May 21, 2019 · 55 revisions

¡Bienvenidos a la wiki del 'PROCRASTINADOR 3000' by cafranpa!

Esta es nuestra wiki, en ella explicaremos la consistencia y desarrollo general de nuestro trabajo y de cada una de sus partes, así como la evolución de nuestros objetivos en el. Para ello, nos ayudaremos tanto de imagenes y comentarios de codigo, como de videos de trazas de ejecución, con el fin de que todos podamos jugar y pasarlo bien.


  1. ¿Qué es "cafranpa"?

'cafranpa' es el nombre que decidimos poner a nuestro grupo para realizar el trabajo de informática. Denominado de esta manera por ser un anagrama de nuestros nombres. El grupo 'cafranpa' esta compuesto por

  • Francisco Delgado López(fdelgadol)
  • Candela Estévez Romero(cbestevez)
  • Pablo Blázquez Gervas(pabloblazquezgervas)

Somos 3 alumnos de la ETSIDI que han decidido crear este programa que descubrireis a continuacion...


  1. ¿Qué es el PROCRASTINADOR 3000?

'Procrastinador 3000' es el nombre que le hemos puesto a nuestro trabajo. Como este indica, se trata de un programa(bot) de multifunciones cuyo objetivo es el de "distraer" o ayudar a que el jugador emplee su tiempo libre en un juego divertido y didáctico.

La idea principal de este programa era hacer un procrastinador similar al que hemos realizado, pero con menos(y diferentes) juegos, pero como ya explicamos en el README.md, esta idea que tuvimos en su día iba a ir variando conforme dieramos mas temario en clase..., y así ha ocurrido! Procrastinador 3000 se compone actualmente de 7 juegos distintos que tienen como objetivo, entretener, enseñar y divertir.

Aunque lo descubriréis mas adelante, cuando empecéis a jugar, os adelantamos ya que los juegos que lo conforman son los siguientes:

  • Bola del ocho
  • Combate
  • Cuñado
  • Flota
  • Questionary
  • Recetario
  • Búsqueda del tesoro

Podéis comparar el Diagrama de flujo inicial, con el Diagrama de flujo final.

Diagrama de flujo inicial.

Diagrama de flujo actual y definitivo.

Como sabéis, el diagrama de flujo explica gráficamente como funciona el programa, aún así, vamos a haceros una breve guía para que podáis usarlo a la perfección, la encontraréis en el apartado nº.6 de esta wiki.


  1. Programas que conforman el PROCRASTINADOR 3000

En este apartado pretendemos comentar los códigos que consideramos más complejos de entender y los que podrían desencadenar más problemas a la hora de ser evaluados por alguien externo que los vea por primera vez

Como todo programa multifunciones o de juegos variados, el Procrastinador 3000 está formado(como hemos mencionado anteriormente) por 7 atractivos juegos cuyo código de composición describiremos ahora.(Además el programa cuenta con comentarios en el propio código que sirven de aclaración).

Primero de todo, el programa precisa los datos de un usuario(que sera el jugador del juego), para que estos sean almacenados, consta de una estructura(lin. 9-89 ProcastLyb.c)

int ingreso(usuario *iz)
{
	FILE *p; usuario usuario[4];
	int i,j;char aux[20], res;
	p=fopen("usuarios.txt","r");

Con ella, el jugador puede sobrescribir un nuevo 'usuario' y poner ahí su nombre(observaréis que hay 3 usuarios ya creados con nuestros nombres y uno completamente nuevo, podéis sobrescribir cualquiera sin ningún problema).

Al lado del nombre de cada juego se encuentra un marcador que acumula el número de veces que ese usuario ha jugado al juego en cuestión.

Una vez realizado este paso, el jugador se encuentra listo para empezar a jugar(encontraréis los pasos a seguir en el juego en el apartado nº.6 de la wiki), dado que el jugador escogerá entre uno de los 7 programas disponibles, hablaremos del código empleado en cada uno de estos a continuación.

  • Bola del ocho

Bola del 8cho es el nombre que recibe 1 de los 7 juegos del programa, su objetivo es pedir al usuario que este realice una pregunta, a la cual el programa responderá con una frase escogida totalmente al azar de entre todas las que se encuentran en un fichero(encontraréis los ficheros empleados en el programa en el apartado nº.4.

Para más detalle, dejamos la siguiente captura de pantalla de la salida por consola de Bola del 8cho.

Para conseguir que las preguntas sean seleccionadas de forma aleatoria, nos hemos servido del código siguiente:

int i;
i=rand()%20+0;
printf("%s\n",res[i].string);

Este código forma parte de una función, por tanto para comprenderlo a la perfección, os recomendamos echar un vistazo al apartado nº.5 de la wiki, donde vienen explicadas con más detenimiento.

  • Combate

El 2º juego interactivo del procrastinador tiene como objetivo entretener al jugador y hacerlo partícipe de una 'lucha' dos a dos, con la participación del propio ordenador como oponente del jugador, convirtiéndola de esta manera, en una lucha algo más compleja y dinámica.

int yo, el, defensayo, defensael;
int danho1, danho2, espada, garras, pocion=3, n, curas, w;
char s;

Estas son las variables empleadas en el combate, como veréis, los nombres de algunas hacen referencia al jugador(ej: defensayo), y otras al enemigo, el ordenador(ej: defensael). En cambio, otras se refieren a los tipos de 'ataque' que pueden llevar a cabo ambos 'combatientes'.

espada=golpe(espada, 8);
garras=golpe(garras, 5);
danho1=danhoyo(danho1, 5);
danho2=danhoel(danho2, 3);
curas=pcn(curas);
defensayo=15;
defensael=18;

En estas líneas de código se refleja el valor inicial que se le da a cada variable, es decir el valor de 'daño' que produce cada tipo de 'ataque' al oponente(las funciones de las que se ayudan están explicadas en el apartado nº.5.

scanf("%i", &n);
while(n<1||n>4);
switch (n)
{
//Ataque
 case 1:
  if((espada<defensael)&&(espada-8!=20))
  printf("Intentas atacar, pero no le das porque has sacado un %i\n ", espada);
  else if(espada-8==20)
  {
   danho1=danho1*2;
   printf("Golpe critico! Le has quitado %i puntos de vida\n", danho1);
   el-=danho1;
  }
  else
  {
printf("Le has dado con un %i, le has hecho %i puntos de danho\n",espada, danho1);	
el-=danho1;
}
break;

Este bloque de código explica brevemente como funciona una parte del programa: nos deja ver como con un 'switch-case', el programa se encargará de evaluar 'n' y se ejecutará una acción u otra(en este caso se observa la variación en los 'puntos de vida' y los 'puntos de daño').

A continuación, visualizaréis el comienzo del programa 'combate', programa que aprenderéis fácilmente a usar siguiendo la guía de usuario(apartado nº.6).

  • Cuñado

El programa pide al usuario que elija ente adivinanzas o chistes malos.

De elegir chistes, cuñado enseñará al jugador la lista de los chistes posibles para escoger. De elegir adivinanzas, dará una serie de oportunidades para responder correctamente, o perder.

printf ("\nBienvenido al programa cunhado. Por favor, escribe lo que prefieras:\n1)Chiste\n2)Adivinanza\n");
scanf ("%i", &f);
while (f!=1&&f!=2)
pf=fopen("chistes.txt","r");
if(pf==NULL)
if (f!=2)
 {
   printf("Has escogido los Chistes! Aqui estan todos\n");
   sleep(3);
   pf=fopen("chistes.txt","r");
   if(pf==NULL)
   ...}

Con estas líneas de código esperamos que se entienda mejor la ejecución que sigue el programa.

  • Hunde la Flota

Hunde la flota es una variación del programa tradicional de papel y boli de hundir los barquitos del oponente, ahora versión ordenador!!

La función del siguiente bloque de código es colocar los 'barcos', representados por letras según el tipo('destructor' o 'submarino').

printf("\n\nPor favor, escoge una coordenada desde la que poner tu barco, y una direccion con las teclas 'wasd'.\n");
printf("\nDime un numero x (1-9):\n");
do
scanf("%i", &x);
while((x<1)||(x>9));
printf("\nAhora dime un numero y (1-9):\n");
do
scanf("%i", &y);
while((y<1)||(y>9));
x=x-1;
y=y-1;

Los barcos se colocan en la posición que escoja el usuario(la fila y columna correspondiente al numero introducido por teclado).

Al igual que pasaba con el programa combate, hunde la flota es un 'combate' dos a dos en el que el usuario juega en contra del ordenador, esto quiere decir, que el ordenador también dispondrá de barcos, pero dado que es una máquina, estos serán generados aleatoriamente. Así lo muestran las líneas de código descritas a continuación:

{
x= rand() % 8 + 0;
y= rand() % 8 + 0;
}
  • Questionary

El Questionary consiste en una modificación de los juegos de mesa de toda la vida(ej. trivial) pero en versión para ordenador, consta de reglas sencillas. El usuario debe escoger entre 4 categorías, de las cuales, cada una posee 10 preguntas que pondrán a prueba el conocimiento del jugador.

Captura de la imagen que aparece al comenzar el juego.

Cada pregunta acertada acumula un punto en la variable 'contador'.

int puntos=0;
int contador;

Al finalizar el juego, aparecerá en pantalla la puntuación del usuario junto a una frase descriptiva que el juego le dedica a este, en base a sus nota.

Este programa emplea ficheros para imprimir las preguntas en pantalla, y funciones encargadas de comprobar si las respuestas del usuario son correctas(suma 1 punto), o no(no suma ni resta). Estas respuestas se almacenan en la variable siguiente:

char ansUsuario;

Código encargado de comprobar si son (o no) correctas las respuestas dadas.

if(actualAns == correctAns) //Esto se ejecutara cuando la respuesta otorgada por el usuario sea igual a la respuesta que el programa reconoce como correcta//
	{
		printf("\nRespuesta correcta, ganas 1 punto.\n");
		return 1;
	}
	else
	{
		printf("\nRespuesta incorrecta, la correcta era la %c.\n", correctAns);
		return 0;
	}		
  • Recetario

Este programa se basa en un 'libro' de recetas(de ahí su nombre), con el detalle de ser exclusivo para celíacos(sus ingredientes son libres de glúten), el programa da la opción de escoger entre una receta dulce o salada:

printf("Escoge si prefieres una receta dulce(d) o salada(s)\n"); //A continuacion, el usuario teclea 'd' si desea una receta dulce o 's' si la prefiere salada//
scanf(" %c", &select1); //El usuario elige un menu escribiendo una letra en el teclado//
switch(select1)

Después deja escoger si se desea un menu para cada momento del dia:

Con el siguiente código:

printf("Por favor, escoge una de las siguientes recetas, escribiendo la letra que aparezca al lado de la que desees\n");
printf("1.Revoltillo o tortilla(a)\n2.Tostada con crema de cacahuete o almendras y platano(b)\n3.Tortitas saladas caseras de trigo sarraceno o maiz(c)\n");
scanf(" %c", &select3);

Y por ultimo el programa deja escoger una receta(la cual está guardada en un fichero) de las ofrecidas y la imprime en pantalla:

switch(select3)
	{
		case 'a':
		  printf("Has escogido: 1.'Revoltillo o tortilla'\n");
 	  	  fc_s_D_a (); 
 	  	break;
		case 'b':
		  printf("Has escogido: 2.'Tostada con crema de cacahuete o almendras y platano'\n");
		  fc_s_D_b (); 
		break;
	 	case 'c':
	  	  printf("Has escogido: 3.'Tortitas saladas caseras de trigo sarraceno o maiz'\n");
   	  	  fc_s_D_c (); 
		break;
		default:
		  printf("Esta opcion no es valida\n"); 
		break;
  • Búsqueda del tesoro

Este juego se basa en ir escribiendo coordenadas para buscar el tesoro escondido en un tablero 11x11.

El tesoro se esconde aleatoriamente gracias a este código:

posicion *res=tesoro;
srand(time(NULL));
res->x=rand() % 10+0;

Estas coordenadas, introducidas por el usuario, serán almacenadas en el programa y se encargarán de 'desplazar' la posición del jugador por el tablero:

posicion *t=tesoro,*u=usuario;
u->x=u->y=0;


  1. Ficheros implementados en el programa

En esta sección vamos a comentar los ficheros que hemos usado para realizar y completar el programa.

  • Ficheros en La bola del 8cho

Dado que el programa se basa en mensajes aleatorias otorgadas por el ordenador a modo de respuesta a las preguntas realizadas por el jugador, es preciso disponer de esas respuestas. Con el fin de que estas no supusieran un estorbo en las líneas de código, decidimos meterlas en este fichero. Como podréis observar, en él hay 21 frases posibles que sirven a modo de respuesta.

  • Ficheros en Cuñado

Con el mismo objetivo del apartado anterior de no estorbar en las líneas de código con más texto del necesario, la lista de chistes que se podrán escoger, será impresa en pantalla mediante una función que imprime el fichero en el que se localiza dicha lista.

El número que se encuentra entre paréntesis al lado de cada fichero es el que debe introducir el usuario para solicitar el chiste determinado.

  • Ficheros en Questionary

Como hemos explicado anteriormente, este programa se basa en hacer preguntas al usuario, a las cuales este deberá responder, y en base a las respuestas, el programa le dará una nota.

En la carpeta general de este programa se encuentran a su vez, las carpetas donde se guardan cada uno de los ficheros de preguntas de los 4 bloques(en formatos .txt : historia, geografía, ciencia y arte.

  • Ficheros en Recetario

Al ser este un programa cuya función es la de enseñar al usuario recetas celíacas, y con objeto de obtener una estética adecuada, resultaba evidente la necesidad de estructurar el texto en ficheros. Así pues, en la carpeta principal podemos encontrar las subcarpetas de dulce y salado. Dentro de ambas carpetas, se encuentran los ficheros de cada receta en archivos .txt. Como se explica en el apartado nº.5 de la wiki(sección Recetario), los nombres de cada receta están codificados según sus características principales.


  1. Funciones implementadas en el programa

Hemos dedicado este apartado a comentar las funciones principales del programa, que recordemos, se compone de 7 'juegos' o pasatiempos, por lo tanto, explicaremos de forma detallada las funciones implementadas en cada uno de ellos. Hemos intentado que el nombre de las funciones expresara lo mejor posible la acción que estas realizan, aún así, la finalidad de este apartado es el de aclarar al máximo posible la razón o motivo por el cual hemos decidido programar las funciones que tenemos, y como nos han ayudado a intentar realizar un programa lo más profesional posible.

Usaremos la siguiente metodología con cada función:

Insertaremos el cabecero de la función a describir y, posteriormente, explicaremos las funciones con un breve texto situado justo debajo.

  • Funciones del programa principal
int ingreso(usuario *iz)
void registro(usuario iz, int io)

Ambas funciones van en conjunto.

Están compuestas por estructuras en su mayor parte. Su trabajo es el de almacenar(en las estructuras) los nombres de los usuarios que vayan a jugar. Por defecto en el programa se encuentran nuestros nombres(los de los creadores del Procrastinador 3000) en usuarios ya creados, pero permite reescribirlos, o escribir en el que viene vacío. Esta función almacena los datos del nuevo usuario y contabiliza al lado del nombre de cada juego, las veces que cada usuario ha jugado a este.

boladelocho()

Función que implementa el 'juego'(programa completo) de La bola del 8cho en el programa principal.

combate()

Función que implementa el 'juego'(programa completo) de Combate en el programa principal.

cunhado()

Función que implementa el 'juego'(programa completo) de Cuñado en el programa principal.

flota()

Función que implementa el 'juego'(programa completo) de Hundir la flota en el programa principal.

questionary()

Función que implementa el 'juego'(programa completo) de Questionary en el programa principal.

recetario()

Función que implementa el 'juego'(programa completo) de Recetario en el programa principal.

busquedatesoro()

Función que implementa el 'juego'(programa completo) de Búsqueda del tesoro en el programa principal.

  • Funciones del programa Bola del 8cho
char mins(char ans)

Únicamente convierte en minúsculas todas las letras encontradas.

void futuro()

Permite que el usuario escriba cualquier cosa en modo de pregunta(se debe omitir el primer signo de interrogación), hasta que encuentre un salto de página. Este dato al ser irrelevante para el resto del programa, se dirige a una variable, la cual, es inútil de cara al programa(podríamos considerarlo como datos irelevantes). Después ejecuta el programa(explicado en Bola del ocho apartado nº.3). Pregunta al usuario si quiere realizar otra pregunta.

Realiza una recursividad si la respuesta es s(si) y después finaliza el programa.

void prediccion()

Se encarga de generar un numero aleatorio del 0 al 20 usado para 'responder' a la pregunta del usuario. Almacena en un vector las respuestas, imprime en pantalla la respuesta que pertenece a la posición(determinada en ese momento) elegida aleatoriamente.

int lecturafichero(FILE *pf, string *res, int n)

Abre el fichero correspondiente si se puede, y en caso contrario devuelve 'NULL'. Además almacena en cada posición del vector (res.string) una respuesta.

  • Funciones del programa Combate
int golpe(int b, int h)

Función que genera un numero aleatorio + bonuses, representa la puntería del combatiente.

int danhoyo(int b, int h)
int danhoel(int b, int h)

Funciones que generan el daño del jugador y del monstruo respectivamente, donde 'yo' se usa para referirse al jugador usuario y 'el' se refiere al oponente(el ordenador).

int pcn(int b)

Genera números aleatorios simulando una poción que emplean los 'combatientes' para aumentar sus puntos de defensa y así, tener más posibilidades de vencer al oponente.

  • Funciones del programa Cuñado
int golpe(int b, int h)

Esta función recicla a su vez una función empleada en el programa Combate, por tanto, ha sido definida anteriormente.

  • Funciones del programa Hundir la flota
void imprime_tablero(char M[9][9])
void imprime_num(int M[9][9])

La función imprime el tablero(matriz) base donde el usuario y el ordenador colocarán sus 'barcos'.

void vaciar_tablero(char M[9][9], char p);
void vaciar_num(int M[9][9], int p);

Estas funciones vacían las matrices, y las rellenan con "-" y "0" respectivamente

void enemigo_barcos(int M[9][9])

Genera las posiciones de los barcos del ordenador, que se crean de forma aleatoria cada vez que se comienza el juego.

void turno_jugador(int m[9][9], char ti[9][9], char t1[9][9], int *u)
void turno_bot(int t0[9][9], int t2[9][9], char t1[9][9], int *u)
void turno(int t[9][9], char ti[9][9], char t1[9][9], int t0[9][9], int t2[9][9])

Estas tres funciones se encargan de los turnos de cada oponente(tanto el jugador usuario, como el ordenador).

  • Funciones del programa Questionary
int puntuacion(char actualAns, char correctAns)

La función se encarga de comprobar si la respuesta del usuario a la pregunta realizada es correcta o no, dependiendo de esto, devuelve un valor u otro. Este valor del 'return' sirve para contabilizar los puntos que gana(o no) el jugador.

void leefichero_p1_h()

El trabajo de la función es la de leer el fichero que se indique. Dado que el programa Questionary está basado en preguntas almacenadas en ficheros(descritos en el apartado nº.4), el programa está conformado por esta misma función, la cual aparece tantas veces como preguntas hay. La única variación entre ellas es el fichero que abren, cada uno tiene un nombre diferente y característico.

int questHistoria(char *name)

La función recoge la parte del programa encargado de las preguntas de historia, por tanto, se ayuda de las funciones que acaban de ser descritas justo encima en este mismo apartado. Es decir, imprime en pantalla las preguntas, almacena la respuesta que introduce el usuario, y junto a las funciones antes descritas, contabiliza los puntos en base a que la respuesta dada sea(o no) correcta.

int questGeografia(char *name)

la función trabaja exactamente igual que la función anterior(int questHistoria(char *name)), con la única diferencia de que esta se encarga de lo relativo a las preguntas de geografía.

int questCiencia(char *name)

la función trabaja exactamente igual que la función anterior(int questGeografia(char *name)), con la única diferencia de que esta se encarga de lo relativo a las preguntas de ciencia.

int questArte(char *name)

la función trabaja exactamente igual que la función anterior(int questCiencia(char *name)), con la única diferencia de que esta se encarga de lo relativo a las preguntas de arte.

  • Funciones del programa Recetario para celíacos
void fc_s_D_a () 

Antes de explicar la función, se debe aclarar que, en vista del gran número de recetas que aparecen en el programa, tuvimos que referenciar a cada una de ellas con un código que surge del anagrama formado con las opciones escogidas por el usuario(ej. 'c_s_D_a' significa: receta para (c)elíacos, (s)alada, para el (D)esayuno y de todas las de este grupo, es la opción(a)). El código de cada receta viene explicado de forma precisa en los comentarios de código del programa en sí.

Esta función es el 'esqueleto' base de todas las funciones usadas en el programa Recetario. Es decir, es una función genérica encargada de imprimir en pantalla el fichero que contiene la receta cuyo código indica.

  • Funciones del programa Búsqueda del tesoro
void enterrar(posicion *tesoro)

La función se encarga de 'enterrar' el tesoro, para ello, obtiene un valor aleatorio para la posición 'x' del tesoro y otra para la posición 'y'.

int busqueda(posicion *tesoro, posicion *usuario)

Esta es la función principal del programa, pues permite al usuario empezar a jugar en la posición (0,0), conforme el jugador escribe cuantas posiciones desea desplazarse, va dando información de la posición del jugador con respecto al tesoro y devuelve un numero. Si es cero, es porque ha ganado el juego y en ese caso el jugador recibe la opción de volver a jugar. En caso contrario, la función permite al usuario seguir moviéndose hacia arriba, abajo, y de izquierda a derecha, esto lo consigue gracias a las funciones descritas a continuación.

int avancevertical(int n, posicion *usuario)

Permite avanzar en vertical hacia arriba o hacia abajo 'n' unidades. Además advierte al usuario si este se sale del tablero de juego, haciendo que retroceda tantas funciones como este había modificado, de manera que lo deja en la misma posición de antes.

int avancehorizontal(int n, posicion *usuario)

Funciona igual que la función anterior(de avance vertical), pero esta permite avanzar en horizontal modificando la 'x'.


  1. Guía para el uso de PROCRASTINADOR 3000

A pesar de la sencillez del programa, creemos necesaria una guía para que todo usuario jugador pueda disfrutar del juego desde el minuto cero.

Es de vital importancia que se sigan las instrucciones que da el propio programa(una vez se está jugando) en la consola de juego.

Referencia de la sintaxis usada.

  • (s/r) 'seleccionar, o reescribir

  • (r/s) 'repetir categoría de juego, o salir'

  • (s/n) 'si, o no'

  • (s/cualquier otra tecla) 'si, quiero repetir; no, quiero salir'

  • (o/s) 'escoger otro programa, o salir'

El programa comienza preguntando el nombre de usuario con el cual el jugador desee identificarse, este debe seleccionar uno de los 4 perfiles disponibles(s), o puedes reescribir uno nuevo con tu nombre(r) . Una vez realizado este paso, empezamos a jugar.

A continuación, el programa pregunta a cual de los 7 juegos desea acceder el usuario, basta con teclear el número de juego deseado y entonces el programa accede a este.

Como nuestra intención es que el usuario disfrute al máximo, decidimos poner las instrucciones de cada juego en la propia consola de este, por tanto, una vez dentro de cada juego, estos son bastante explícitos con sus instrucciones propias.

Esperamos que estas breves instrucciones y el vídeo de la traza de ejecución (apartado nº.7) sirvan de toda la ayuda que necesitéis para pasarlo bien con nuestro Procrastinador 3000


  1. Vídeo de una traza de ejecución del PROCRASTINADOR 3000

Por si es de vuestro interés, aquí os dejamos un vídeo de un ejemplo de juego en el que probamos la Bola del 8cho y el Questionary


Esperamos que se hayan entendido correctamente todos los temas tratados en la wiki acerca de nuestro trabajo y que disfrutéis del juego.

Gracias por visitar nuestro Procrastinador 3000 .