Código PHP:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE_MAX_PALABRA 30
#define SIZE_MAX_ALFABETO 27
//-----------------------------------------------------------------------------
/* DEFINICION DE TIPOS */
typedef struct ElementoLista
{
char *palabra;
int indice;
struct ElementoLista *sig;
}Elemento;
typedef struct ListaIdentificar {
Elemento *inicio;
Elemento *fin;
int nElementos;
}Lista;
//-----------------------------------------------------------------------------
/* PROTOTIPOS DE FUNCIONES */
void Inicializacion (Lista *lista);
int InsertarEnLista (Lista *lista, Elemento * actual, char *palabra, int indice);
int Sup_en_lista (Lista *lista, int pos);
int Sup_inicio (Lista *lista);
void DestruirLista (Lista *lista);
void Imprimir (Lista *lista);
void PreguntarPalabras(Lista *lista, int nPalabras);
int Menu(void);
void Jugar(void);
int OrdenarLista(Lista *lista);
void LimpiarCadena(char *cadena, int size);
void PasarAMayusculas(char *cadena, int size);
void ActualizarLetrasIntroducidas(char *cadena, int size, char caracter);
int ActualizarLetrasRestantes(char *cadena, int size, char caracter);
int ActualizarMascara(char *mascara, char *palabra, int size, char caracter);
int LlenarLista(FILE *archivo, Lista *lista);
//-----------------------------------------------------------------------------
int main()
{
int retval;
do{
retval = Menu();
switch(retval)
{
case 1:
Jugar();
break;
}
}while(retval != 0);
return(0);
}
//-----------------------------------------------------------------------------
void Inicializacion (Lista *lista)
{
lista->inicio=NULL;
lista->fin=NULL;
lista->nElementos=0;
}
//-----------------------------------------------------------------------------
/*inserción en la lista */
int InsertarEnLista (Lista *lista, Elemento *actual, char *palabra, int indice)
{
Elemento *nuevo_elemento;
if ((nuevo_elemento = (Elemento *) malloc (sizeof (Elemento))) == NULL)
return -1;
if ((nuevo_elemento->palabra = (char *) malloc (SIZE_MAX_PALABRA * sizeof (char))) == NULL)
return -1;
strcpy (nuevo_elemento->palabra, palabra);
nuevo_elemento->indice = indice;
if(actual != NULL)
actual->sig = nuevo_elemento;
nuevo_elemento->sig = NULL;
if(lista->inicio == NULL)
lista->inicio = nuevo_elemento;
lista->fin = nuevo_elemento;
lista->nElementos++;
return 0;
}
//-----------------------------------------------------------------------------
/* eliminar un elemento después de la posición solicitada */
int Sup_en_lista (Lista * lista, int pos)
{
int i;
Elemento *actual;
Elemento *sup_elemento;
if (lista->nElementos <= 1 || pos < 1 || pos >= lista->nElementos)
return -1;
actual = lista->inicio;
for (i = 1; i < pos; ++i)
actual = actual->sig;
sup_elemento = actual->sig;
actual->sig = actual->sig->sig;
if(actual->sig == NULL)
lista->fin = actual;
free (sup_elemento->palabra);
free (sup_elemento);
lista->nElementos--;
return 0;
}
//-----------------------------------------------------------------------------
/* eliminación al inicio de la lista */
int Sup_inicio (Lista *lista)
{
Elemento *sup_elemento;
if (lista->nElementos == 0)
return -1;
sup_elemento = lista->inicio;
lista->inicio = lista->inicio->sig;
if (lista->nElementos == 1)
lista->fin = NULL;
free (sup_elemento->palabra);
free (sup_elemento);
lista->nElementos--;
return 0;
}
//-----------------------------------------------------------------------------
/* destruir la lista */
void DestruirLista (Lista *lista)
{
while (lista->nElementos > 0)
Sup_inicio (lista);
}
//-----------------------------------------------------------------------------
/* visualización de la lista */
void Imprimir (Lista *lista)
{
Elemento *actual;
actual = lista->inicio;
while (actual != NULL){
printf ("%s\n", actual->palabra);
actual = actual->sig;
}
}
//-----------------------------------------------------------------------------
void LimpiarCadena(char *cadena, int size)
{
int indice;
for(indice = 0; indice < size; cadena[indice++] = '\0');
}
//-----------------------------------------------------------------------------
void PasarAMayusculas(char *cadena, int size)
{
int indice;
for(indice=0; indice < size;indice++)
{
if(cadena[indice] >= 'a' && cadena[indice] <= 'z')
cadena[indice] -= 32;
}
}
//-----------------------------------------------------------------------------
int ActualizarLetrasRestantes(char *cadena, int size, char caracter)
{
int indice, j;
char *aux;
if ((aux = (char *) malloc ((size) * sizeof (char))) == NULL)
return -1;
//Buscamos el caracter introducido en el array con los caracteres restantes
//Si lo encuentra lo omite y si es otro lo copia a un array auxiliar
for(indice=0,j=0; indice < size;indice++)
{
if(cadena[indice] != caracter)
{
aux[j]=cadena[indice];
j++;
}
}
//Si se encontró j será menor que indice con lo que finalizo la cadena auxiliar y
//copio el contenido de la variable auxiliar a la cadena a mostrar con los
//caracteres restantes
if(j < indice)
{
aux[j] = '\0';
strcpy(cadena, aux);
}
free(aux);
return 0;
}
//-----------------------------------------------------------------------------
void ActualizarLetrasIntroducidas(char *cadena, int size, char caracter)
{
int indice;
//Recorro los caracteres introducidos en busca del nuevo caracter
for(indice=0; indice < size; indice++)
if(cadena[indice] == caracter){
break;
}
//Si se ha introducido un nuevo caracter y no está en la lista
//le añado el nuevo caracter
if(size == indice)
cadena[size] = caracter;
}
//-----------------------------------------------------------------------------
int ActualizarMascara(char *mascara, char *palabra, int size, char caracter)
{
int indice, aciertos=0, encontrada=0;
for(indice=0; indice < size && size != 0; indice++)
if(mascara[indice] == caracter)
encontrada++;
if(encontrada > 0){
aciertos=0;
}else{
//Busco el caracter introducido en la palabra y si se encuentra lo quito de la palabra
for(indice=0; indice < size && size != 0; indice++)
{
if(palabra[indice] == caracter)
{
mascara[indice] = palabra[indice];
aciertos++;
}
}
}
return aciertos;
}
//-----------------------------------------------------------------------------
void PreguntarPalabras(Lista *lista, int nPalabras){
const char letrasValidas[SIZE_MAX_ALFABETO] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int vidas = 5, indice, largoPalabra, largoIntroducidas, largoRestantes, aciertos;
int contador=0, encontrados, salir = 0;
char palabra[SIZE_MAX_PALABRA], auxPalabra[SIZE_MAX_PALABRA];
char letrasIntroducidas[SIZE_MAX_ALFABETO], letrasRestantes[SIZE_MAX_ALFABETO];
char caracter;
Elemento *actual = lista->inicio;
do{
//Limpio los 3 arrays (Se puede usar en su lugar memset)
LimpiarCadena(letrasRestantes,SIZE_MAX_ALFABETO);
LimpiarCadena(letrasIntroducidas,SIZE_MAX_ALFABETO);
LimpiarCadena(auxPalabra,SIZE_MAX_PALABRA);
//Inicializo las variables que se necesiten
strcpy(letrasRestantes,letrasValidas);
strcpy(palabra,actual->palabra);
largoPalabra = strlen(palabra);
encontrados = 0;
//Si hay algun caracter en minusculas en la palabra lo paso a mayusculas
PasarAMayusculas(palabra,largoPalabra);
//Muestro la mascara para que se vea cuantos caracteres tiene (Se puede hacer con memset)
for(indice=0; indice < largoPalabra;indice++)
{
auxPalabra[indice] = '-';
}
//Mientras no lleguemos al final de la lista y tengamos vidas seguimos
while (actual != NULL && vidas > 0){
do{ //Este bucle es para descartar todos los caracteres no permitidos
//Muestro la informacion
system("CLS");
printf("\n%c: %d", 3, vidas);
printf("\nLetras introducidas: %s",letrasIntroducidas);
printf("\nLetras restantes: %s",letrasRestantes);
printf("\nNumero de palabras solucionadas: %d",contador);
printf("\n%s\n\n",auxPalabra);
printf("Introduce una letra (0 para salir): ");
fflush(stdin); //limpio el flujo de entrada
caracter = getchar(); //Pido el caracter
//Si el caracter introducido esta en minusculas lo paso a mayusculas
PasarAMayusculas(&caracter,1);
}while((caracter < 'A' || caracter > 'Z') && caracter != '0');
//Si se introdujo 0 salimos del juego
if(caracter == '0')
{
salir=1;
printf("\n\nSalida forzada por el usuario.\n\n");
break;
}
largoRestantes = strlen(letrasRestantes);
ActualizarLetrasRestantes(letrasRestantes,largoRestantes, caracter);
//Busco el caracter introducido en la palabra y si se encuentra lo quito de la palabra
encontrados += aciertos = ActualizarMascara(auxPalabra, palabra, largoPalabra, caracter);
//Si se ha encontrado el caracter le resto el numero de caracteres encontrados
//al largo de la palabra e inicializo la variable de encontrados
//Si no se encuentra resto una vida
if(aciertos == 0){
vidas--;
}
largoIntroducidas = strlen(letrasIntroducidas);
ActualizarLetrasIntroducidas(letrasIntroducidas,largoIntroducidas, caracter);
//Si el largo de la palabra es 0 es porque ya se metieron todos
//los caracteres de dicha palabra asi que la muestro y obtengo
//la siguiente palabra
if(largoPalabra == encontrados){
contador++;
system("CLS");
printf("\n%c: %d", 3, vidas);
printf("\nLetras introducidas: %s",letrasIntroducidas);
printf("\nLetras restantes: %s",letrasRestantes);
printf("\nNumero de palabras solucionadas: %d",contador);
printf ("\n\n%s Solucionada!!!\n\n", palabra);
actual = actual->sig;
system("PAUSE");
break;
}
//Si no hay vidas hemos perdido asi que lo indico y salimos
if(vidas == 0)
{
salir = 1;
system("CLS");
printf("\n%c: %d", 3, vidas);
printf("\nLetras introducidas: %s",letrasIntroducidas);
printf("\nLetras restantes: %s",letrasRestantes);
printf("\nNumero de palabras solucionadas: %d",contador);
printf("\n\nPartida finalizada.\n\n");
}
}
//Si son iguales es porque ya solucionamos todas las palabras
//solicitadas asi que hemos ganado
if(nPalabras == contador)
{
printf("\n\nHas ganado.\n\n");
salir = 1;
}
}while(salir != 1);
}
//-----------------------------------------------------------------------------
//Ordena el contenido de la lista
int OrdenarLista(Lista *lista)
{
int j,pos,retval;
Elemento *actual,*menor;
Lista *listaAux;
if(lista->nElementos > 1){
//Reservo memoria para la lista auxiliar que usaré para ordenar la lista
if ((listaAux = (Lista *) malloc (sizeof (Lista))) == NULL){
retval = -1; //Valor de retorno que indica que no se pudo obtener suficiente memoria
}else{
//Inicializo la lista auxiliar
Inicializacion(listaAux);
//Mientras que el número de elementos sea mayor que 1...
while(lista->nElementos > 1){
menor = lista->inicio; //le asigno al puntero de tipo Elemento la direccion de inicio de la lista
pos=0; //inicializo la variable para saber la posicion del elemento anterior al de menor indice
//Recorro todos los elementos en busca del que tenga menor indice
for (j=1, actual=lista->inicio; j < lista->nElementos; j++, actual=actual->sig)
{
//Si el indice del actual es mayor que el del siguiente...
if(menor->indice > actual->sig->indice){
menor = actual->sig; //Asigno a menor la direccion del elemento siguiente
pos = j; //Asigno a pos la posicion del elemento anterior al que tiene el indice menor
}
}
//Inserto el elemento menor en la lista auxiliar
InsertarEnLista(listaAux, listaAux->fin, menor->palabra, menor->indice);
if(pos==0){ //Si pos es 0 es porque es el primer elemento de la lista
Sup_inicio(lista); //Elimino al primer elemento de la lista
}else{ //Si pos es diferente de 0...
Sup_en_lista(lista,pos); //Elimino el elemento que está despues de la posicion pos
}
}
if(lista->nElementos == 1){ //Si hay un solo elemento en la lista...
//Inserto ese elemento en la lista auxiliar ya que es el último que falta por ordenar y el que tiene mayor indice
InsertarEnLista(listaAux, listaAux->fin, lista->inicio->palabra, lista->inicio->indice);
Sup_inicio(lista); //Elimino el elemento que queda para limpiar la lista
}
//Recorro la lista auxiliar para rellenar la lista
for(j=0, actual=listaAux->inicio; j < listaAux->nElementos; j++, actual=actual->sig)
InsertarEnLista(lista, lista->fin, actual->palabra, actual->indice);
DestruirLista(listaAux); //Libero la memoria de los elementos de la lista auxiliar
free(listaAux); //Libero la memoria de la lista auxiliar
retval=0; //Valor de retorno que indica que todo fue bien
}
}else{
retval = -2; //Valor de retorno que indica que el numero de elementos de la lista no es correcto
}
return retval;
}
//-----------------------------------------------------------------------------
int LlenarLista(FILE *archivo, Lista *lista)
{
int finLectura=0,j,indice,contador;
char caracter,palabra[SIZE_MAX_PALABRA];
contador = 0;
j=0;
while( finLectura != 1)
{
LimpiarCadena(palabra, SIZE_MAX_PALABRA);
while (!feof(archivo)){
do{
caracter=fgetc(archivo);
}while(caracter=='\n');
if (caracter!=';'){
palabra[j]=caracter;
j++;
}else{
j=0;
//FGETC NO SIRVE YA QUE SOLO CAPTURA UN CARACTER
//¿Y SI EL NUMERO ES POR EJEMPLO 10, O 150, O CUALQUIER OTRO QUE TENGA UN 1 DELANTE?
fscanf(archivo,"%d",&indice);
if(InsertarEnLista(lista,lista->fin, palabra, indice) == -1){
printf("\nError al insertar un elemento a la lista. Pulsa intro para salir.\n\n");
system("PAUSE");
return -1;
}
contador++;
LimpiarCadena(palabra,SIZE_MAX_PALABRA);
}
}
finLectura++;
}
return contador;
}
//-----------------------------------------------------------------------------
//Version ordenando la lista despues de haberla obtenido entera desordenada
void Jugar(){
int cantidad,error,contador;
char caracter;
Lista *lista;
FILE *archivo;
if ((lista = (Lista *) malloc (sizeof (Lista))) != NULL){
Inicializacion(lista);
do{
system ("color b");
system("cls");
printf("\n\t\t\t ¿Con cuantas palabras desea jugar? ");
scanf("%d",&cantidad);
if(cantidad < 3 || cantidad > 10){
error = 1;
printf("\nTiene que ser un valor comprendido entre 3 y 10\n");
system("PAUSE");
}else{
error = 0;
}
}while(error==1);
archivo= fopen("prueba.txt","r");
if (archivo== NULL){
printf("El archivo no se encuentra");
}else{
//Lleno la lista con todas las palabras del archivo indicado
contador = LlenarLista(archivo, lista);
fclose(archivo);
//Si se obtuvieron el numero de palabras indicadas...
if(contador >= cantidad)
{
OrdenarLista(lista);
PreguntarPalabras(lista, cantidad);
system("PAUSE");
system("CLS");
//Imprimimos la lista de palabras
printf("\nLista de palabras:");
printf("\n-----------------\n\n");
Imprimir(lista);
}else{
printf("\nHay menos palabras en el archivo que las deseadas\n\n");
}
}
DestruirLista(lista);
free(lista);
}
printf("\n");
system("PAUSE");
}
//-----------------------------------------------------------------------------
int Menu()
{
char resp;
system ("color b");
system("cls");
printf("\n\n\t\t\t* * * * * MENU DE OPCIONES * * * * *");
printf("\n\t\t---------------------------------------------------");
printf("\n\t\t\t Juego de el ahorcado ");
printf("\n\t\t---------------------------------------------------\n\n\n\n");
printf("\t\t\t\t (1) Jugar \n");
printf("\t\t\t\t (0) salir\n\n");
printf("\t\t\t\t Opcion: ");
resp=getchar();
return (resp - 48); //Devuelvo su valor entero
}
//-----------------------------------------------------------------------------
Utilizo una lista auxiliar en la cual guardo los elementos ya ordenados y los voy eliminando de la lista principal. Luego copio todo ya ordenado en la lista principal y libero la memoria ocupada por la lista auxiliar.
Si consigues un método mejor compartelo aquí por favor, estoy interesado ya que nunca se me ocurrio ordenar una lista enlazada y he visto que es algo complejo de hacer.