#include <stdio.h>
#include <stdlib.h>
#define PINPONPAPAS 6
struct persona
{
char *nombre;
struct persona *next;
struct persona *prev;
};
typedef struct persona JUGADOR;
typedef JUGADOR *J_PTR;
J_PTR first = NULL;
J_PTR last = NULL;
char *input_nombre(size_t long_max);
J_PTR add_to_list(char *ch, J_PTR prev_rec);
char input_error_conteo();
int input_error_num_jugadores();
int input_mayor_lista(int jugadores);
char input_error_sino();
void pausa();
void pin_pon_papas();
int main()
{
int i,num_jugadores;
int inicio_conteo, pin; //Numero de jugador para empezar el juego y numero de veces que se va a contar respectivamente
char direccion_conteo; // Las opciones son D = derecha, I = izquierda
char bucle ='X'; //para repetir el programa
char *nombre;
J_PTR j_addr = NULL; //Apunta a los elementos creados en la funcion add_to_list()
J_PTR j_aux = NULL; //Este apuntador se usa cuando se van eliminando los jugadores cada 6 conteos
do
{
pin_pon_papas();
printf("\n\nEnlista a los jugadores y elimina uno a uno para terminar con un ganador\n"); printf("\n\nEscribe el numero de jugadores: "); num_jugadores = input_error_num_jugadores();
while(getchar()!='\n'); //limpiar buffer printf("\nAhora cada uno de sus nombres\n\n"); for(i=0;i<num_jugadores;i++)
{
nombre = input_nombre(30);//Se crean nombres, el parametro es la longitud maxima de texto
j_addr = add_to_list(nombre, j_addr); /*la funcion devuelve new_rec*/
if(i==0)
{
first = j_addr;
}
last = j_addr; //se recorre al ultimo jugador tecleado.
}
first->prev = last;//cierre de
last->next = first;//lista circular
j_addr = first; //Recorrer apuntador al primer elemento creado para imprimir la lista de jugadores.
printf("\nEstos son los participantes:\n\n"); for(i=0;i<num_jugadores;i++)
{
printf("%2d: %s\n",i
+1,j_addr
->nombre
); // printf("Nombre:%s\nDireccion jugador:%p\nprev: %p \nnext: %p\n",nombre,(void *)j_addr,(void *)j_addr->prev,(void *)j_addr->next);
j_addr = j_addr->next;
}
printf("\nEscribe el numero de jugador con el que quieres iniciar el conteo: "); inicio_conteo = input_mayor_lista(num_jugadores);
while(getchar()!='\n'); //key buffer j_addr = first;
for(i=0;i<inicio_conteo-1;i++)
{
j_addr = j_addr->next;
}
printf("\n\nHas elegido a %s !\n\n",j_addr
->nombre
); printf("Quieres iniciar el conteo hacia la derecha o izquierda? (D/I)"); direccion_conteo = input_error_conteo(); //validar dato tecleado
puts("\nIniciando conteo...\n"); if(direccion_conteo=='D')
{
for(pin=0;pin<num_jugadores-1;pin++)
{
for(i=0;i<PINPONPAPAS;i++)
{ //Ubicar al jugador a eliminar
j_addr = j_addr->next;
}
pin_pon_papas();
printf(", sale %s\n\n",j_addr
->nombre
); j_aux = j_addr->next;
j_aux->prev = j_addr->prev;
j_aux = j_addr->prev;
j_aux->next = j_addr->next;
j_aux = j_addr->prev;
j_addr = j_aux;
pausa();
}
}
else
{
for(pin=0;pin<num_jugadores-1;pin++)
{
for(i=0;i<PINPONPAPAS;i++)
{ //Ubicar al jugador a eliminar
j_addr = j_addr->prev;
}
pin_pon_papas();
printf(", sale %s\n\n",j_addr
->nombre
); j_aux = j_addr->next;
j_aux->prev = j_addr->prev;
j_aux = j_addr->prev;
j_aux->next = j_addr->next;
j_aux = j_addr->next;
j_addr = j_aux;
pausa();
}
}
printf("\nEl ultimo jugador en pie es %s!\n",j_addr
->nombre
); printf("\n\nQuieres jugar de nuevo? ( S/N ): "); bucle = input_error_sino();
first = NULL;
last = NULL;
j_aux = NULL;
j_addr = NULL;
i=0;
}while(bucle=='S');
return 0;
}
/*Funcion: J_PTR add_to_list()
Proposito: Crear un bloque en memoria para el jugador y asigna los apuntadores a siguiente y previo*/
J_PTR add_to_list(char *name, J_PTR prev_rec)
{
J_PTR new_rec = NULL;
new_rec
= (J_PTR
) malloc(sizeof(JUGADOR
)); // Crear jugador if(!new_rec)
{ //Validacion de malloc
printf("Error al reservar memoria"); }
new_rec->nombre = name;
new_rec->next = NULL;
new_rec->prev = NULL;
if(prev_rec) //Si hay un elemento antes
{
prev_rec->next = new_rec;
new_rec->prev = prev_rec;
} //aqui solamente se crea la lista doble, en main()es donde se cierra la lista
return(new_rec);
}
/*Funcion: input_nombre(size_t long_max)
Proposito: Funcion para entrada de datos, primero reservo el espacio en memoria de longitud definida en el
parametro long max, despues sigue la entrada de datos.*/
char *input_nombre(size_t long_max)
{
char *nombre =NULL;
if ((nombre
= malloc(long_max
+ 1)) != NULL
) {
//en caso de que no haya bloques de memoria
if (fgets(nombre
, long_max
, stdin
) == NULL
) {
nombre = NULL;
}
else
{
size_t i;
for (i = 0; nombre[i] != '\0' && nombre[i] != '\n'; i++);
if (nombre[i] == '\n')
{
nombre[i] = '\0';
}
else
{
int ch;
while ((ch
= getchar()) != EOF
&& ch
!= '\n'); }
}
}
return nombre;
}
/*Funcion: input_error_conteo
Proposito: Solo permte dos opciones D = derecha, I = izquierda.*/
char input_error_conteo()
{
char direccion='\0';
while(direccion!='D'&&direccion!='I') //Error
{
printf("\nDato no valido, intenta de nuevo: "); direccion = getche();
}
return direccion;
}
/*Funcion: input_error
Proposito: Valida que los datos de entrada del usuario sean numeros, evita que se procesen letras o signos.*/
int input_error_num_jugadores()
{
int respuesta;
char si_no;
while((scanf("%d",&respuesta
) != 1)||respuesta
<2||respuesta
>50) //en caso de ñ o datos raros. {
if(respuesta==1)
{
printf("\n\nAl menos debe haber 2 jugadores: "); }
else if(respuesta<1)
{
printf ("\n\nDato no valido intenta de nuevo: "); }
else
{
printf("\n\nEl juego no permite mas de 50 jugadores: "); }
}
return respuesta;
}
/*Funcion: input_mayor_lista
Proposito: Valida que los datos de entrada del usuario sean numeros, evita que se procesen letras, signos o
numeros negativos, se usa cuando se pregunta por el jugador a partir del cual se iniciara el conteo.*/
int input_mayor_lista(int jugadores)
{
int respuesta;
while((scanf("%d",&respuesta
) != 1)||respuesta
<=0||respuesta
>jugadores
) //en caso de ñ y datos raros. {
printf ("\nDato no valido intenta de nuevo: "); }
return respuesta;
}
/*Funcion:input_error_sino
Proposito: Valida que la respuesta sea el caracter S o N,
se usa en la ultima pregunta para volver a correr el programa */
char input_error_sino()
{
char respuesta;
respuesta = getche();
while(respuesta!='S'&&respuesta!='N') //Error si teclea otra cosa
{
printf("Opcion invalida, intenta de nuevo: "); respuesta = getche();
}//Fin mensaje error
return (respuesta);
}
void pausa()
{
int delay;
for(delay=0;delay<181111100;delay++); //espacio entre impresiones
}
void pin_pon_papas()
{
pausa();
pausa();
pausa();
}