Anuncios

Biennvenidos sean a este post, hoy veremos un nuevo concepto.

Anuncios

Ya vimos mediante el proyecto de cartas algunos conceptos como son el array de struct y el struct de struct, pero hoy de forma teorica agregaremos un nuevo concepto como es un struct con un array, sabemos que tenemos un mazo de cartas pero por el momento solamente podemos asignar un numero determinado de cartas pero que sucede si cambian la cantidad porque cambiamos de juego de cartas, para ello vamos a hacer una serie de modificaciones aplicando el concepto de arrays en un struct, para ello retomaremos el proyecto sino lo poseen descarguen el siguiente archivo:

Anuncios

Simplemente extraigan los archivos en un mismo directorio, ahora iremos a nuestro archivo cartas.h para modificar la estructura encargada del jugador de la sigueinte manera:

typedef struct {
        int totalCartas;
        Carta* jugador[cCartasEnMano];
} Jugador;
Anuncios

Lo que hicimos fue eliminar a las cartas que teniamos antes para crear un array que creara todas las cartas necesarias en base a la constante que establecimos para las cartas en mano, el otro servira para saber cuantas cartas tenemos, nuestra siguiente modificacion sera en la funcion de IniciarJugador donde lo modificaremos de la siguiente manera:

void IniciarJugador(Jugador* aJugador)
{
        aJugador->totalCartas = 0;
        for(int i=0; i < cCartasEnMano; i++)
                aJugador->jugador[i] = NULL;
}
Anuncios

En este caso volvemos a aplicar lo mismo, quitamos los objetos que representaban a las cartas por el array de la struct y los iniciamos con el valor de NULL mediante un bucle for, nuestra siguiente modificacion sera la funcion AgregarCartaAJugador con el siguiente codigo:

void AgregarCartaAJugador(Jugador* aJugador, Carta* aCarta)
{
        if(aJugador->totalCartas==cCartasEnMano) return;
        aJugador->jugador[ aJugador->totalCartas ] = aCarta;
        aJugador->totalCartas++;
}
Anuncios
Anuncios

Como pueden observar no solamente el codigo se facilito un poco mas sino que desaparecieron dos elementos, la llamada a la funcion para obtener la carta del mazo asi como tambien el doble apuntador de la carta, dado que lo trabajaremos directamente sobre el array, observen tambien que no debemos almacenar el valor del total de cartas del jugador sino que lo obtenemos directamente, sacando estos pequeños detalles el resto sigue trabajando de la misma forma, es decir si la cantidad de cartas en mano es igual al total de cartas sale de la funcion, despues asignaremos la carta que pasamos a cada posiccion del array del jugador y por ultimo incrementaremos al total de cartas, nuestra ultima modificacion sera con la funcion MostrarJugador:

void MostrarJugador(Jugador* aJugador, char* aCadenaJug, char* aCadenaLider)
{
        printf("%s%s\n", aCadenaLider, aCadenaJug);
        for(int i=0; i < cCartasEnMano; i++)
        {
                printf("%s", aCadenaLider);
                MostrarCarta(aJugador->jugador[i]);
                printf("\n");
        }
}
Anuncios

Al igual que sucedio en la funcion anterior quitamos el llamado a la funcion de obtener carta del jugador, pero continuaremos recibiendo los tres argumentos, el jugador y dos cadenas, seguiremos mostrandolas pero la diferencia sera a la funcion de mostrar la carta pasaremos una posicon del array del jugador, como pueden ver resulto mas practico y ahora si definitivamente dejamos de usar una funcion que podia generar mas conflicto que solucion, especialmente a la hora de la depuracion, por ultimo al final debemos agregar la siguiente funcion:

void MostrarTodosJugadores(Jugador* jugadores[ cNumJugadores ])
{
	MostrarJugador(jugadores[0], "Jug 1: ", "");
	MostrarJugador(jugadores[1], "Jug 2: ", "");
	MostrarJugador(jugadores[2], "Jug 3: ", "");
	MostrarJugador(jugadores[3], "Jug 4: ", "");
}
Anuncios

Esta funcion sera la encargada de mostrar todos los jugadores, para ello llamaremos a MostrarJugador con cada una de las posiciones del array de jugadores pasados, lo hacemos de esta forma para mostrar a cada jugador, antes de continuar como mencionamos un poco antes la funcion ObtenCartaJugador ya no teenemos necesidad de utilizarlo y como a su vez algunos elementos de esta funcion desaparecieron les recomiendo eliminarla sino comentarla porque de lo contrario devolvera un error al compilarlo, con todo esto comentado veamos como quedo nuestro archivo cartas.h:

cartas.h


enum {
	cCartasEnMazo = 48,
	cCartasEnMano = 3,
	cCartasEnPalo = 12,
	cNumJugadores = 4
};

typedef enum {
	oro = 1,
	copa,
	basto,
	espada
} Palo;

typedef enum {
	uno = 1, dos, tres, cuatro, cinco, seis,
	siete, ocho, nueve, sota, caballo, rey
} Numero;

typedef struct
{
	Palo palo;
	int valorPalo;
	Numero numero;
	int valorNumero;
} Carta;

typedef struct {
	int totalCartas;
	Carta* jugador[cCartasEnMano];
} Jugador;

void CartaAString(Carta* aCarta,char aCadenaCarta[20])
{
	switch(aCarta->numero)
	{
		case uno: strcpy(aCadenaCarta, "as "); break;
		case dos: strcpy(aCadenaCarta, "dos "); break;
		case tres: strcpy(aCadenaCarta, "tres "); break;
		case cuatro: strcpy(aCadenaCarta, "cuatro "); break;
		case cinco: strcpy(aCadenaCarta, "cinco "); break;
		case seis: strcpy(aCadenaCarta, "seis "); break;
		case siete: strcpy(aCadenaCarta, "siete "); break;
		case ocho: strcpy(aCadenaCarta, "ocho "); break;
		case nueve: strcpy(aCadenaCarta, "nueve "); break;
		case sota: strcpy(aCadenaCarta, "sota "); break;
		case caballo: strcpy(aCadenaCarta, "caballo "); break;
		case rey: strcpy(aCadenaCarta, "rey "); break;
		default: strcpy(aCadenaCarta, "??? "); break;
	}

	switch(aCarta->palo)
	{
		case oro: strcat(aCadenaCarta,"de Oro"); break;
		case copa: strcat(aCadenaCarta,"de Copas"); break;
		case basto: strcat(aCadenaCarta,"de Bastos"); break;
		case espada: strcat(aCadenaCarta,"de Espadas"); break;
		default: strcat(aCadenaCarta,"de ????"); break;
	}
}

void IniciarCarta(Carta* aCarta, Palo p, Numero n)
{
	aCarta->palo		= p;
	aCarta->valorPalo	= (int)p;
	aCarta->numero		= n;
	aCarta->valorNumero	= (int)n;
}

void MostrarCarta(Carta* aCarta)
{
	char cadenaCarta[20] = {0};
	CartaAString(aCarta, cadenaCarta);
	printf("%18s", cadenaCarta);
}

void IniciarMazo( Carta* aMazo )
{
	Numero n[]={ uno, dos, tres, cuatro, cinco, seis,
			siete, ocho, nueve, sota, caballo, rey };

	Carta* aC;

	for(int i=0; i < cCartasEnPalo; i++)
	{
		aC=&(aMazo[i + (0*cCartasEnPalo)]);
		IniciarCarta(aC, oro, n[i]);

		aC=&(aMazo[i + (1*cCartasEnPalo)]);
		IniciarCarta(aC, copa, n[i]);

		aC=&(aMazo[i + (2*cCartasEnPalo)]);
		IniciarCarta(aC, basto, n[i]);

		aC=&(aMazo[i + (3*cCartasEnPalo)]);
		IniciarCarta(aC, espada, n[i]);
	}
}

void MostrarMazo( Carta* aMazo )
{
	printf("%d cartas en el mazo\n\n", cCartasEnMazo);
	int indice = 0;

	printf("El mazo ordenado: \n");

	for(int i=0; i < cCartasEnPalo; i++)
	{
		indice=i + (0*cCartasEnPalo);
		printf(" (%2d)", indice + 1);
		MostrarCarta(&(aMazo[indice]));

		indice=i + (1*cCartasEnPalo);
		printf(" (%2d)", indice + 1);
		MostrarCarta(&(aMazo[indice]));

		indice=i + (2*cCartasEnPalo);
		printf(" (%2d)", indice + 1);
		MostrarCarta(&(aMazo[indice]));

		indice=i + (3*cCartasEnPalo);
		printf(" (%2d)", indice + 1);
		MostrarCarta(&(aMazo[indice]));

		printf("\n");
	}
	printf("\n");
}

void IniciarJugador(Jugador* aJugador)
{
	aJugador->totalCartas = 0;
	for(int i=0; i < cCartasEnMano; i++)
		aJugador->jugador[i] = NULL;
}

void AgregarCartaAJugador(Jugador* aJugador, Carta* aCarta)
{
	if(aJugador->totalCartas==cCartasEnMano) return;
	aJugador->jugador[ aJugador->totalCartas ] = aCarta;
	aJugador->totalCartas++;
}

void MostrarJugador(Jugador* aJugador, char* aCadenaJug, char* aCadenaLider)
{
	printf("%s%s\n", aCadenaLider, aCadenaJug);
	for(int i=0; i < cCartasEnMano; i++)
	{
		printf("%s", aCadenaLider);
		MostrarCarta(aJugador->jugador[i]);
		printf("\n");
	}
}

Carta* TomarCartaDelMazo(Carta aMazo[], int indice)
{
	Carta* aCarta = &aMazo[indice];
	return aCarta;
}

void MostrarTodosJugadores(Jugador* jugadores[ cNumJugadores ])
{
	MostrarJugador(jugadores[0], "Jug 1: ", "");
	MostrarJugador(jugadores[1], "Jug 2: ", "");
	MostrarJugador(jugadores[2], "Jug 3: ", "");
	MostrarJugador(jugadores[3], "Jug 4: ", "");
}
Anuncios

Pero como podemos probarlo? Para ello debemos pasar al archivo cartas.c y debemos modificar el codigo actual por el siguiente:

cartas.c

#include <stdio.h>
#include <string.h>
#include "cartas.h"

int main()
{
	Carta mazo[ cCartasEnMazo ];
	Carta* aMazo = mazo;
	IniciarMazo(&mazo[0]);

	Jugador j1, j2, j3, j4;

	Jugador* jugadores[] = { &j1, &j2, &j3, &j4 };

	for(int i=0; i < cNumJugadores; i++)
		IniciarJugador(jugadores[i]);

	for(int i=0; i < cNumJugadores; i++)
	{
		AgregarCartaAJugador(jugadores[0],
				TomarCartaDelMazo(aMazo, i));
		AgregarCartaAJugador(jugadores[1],
				TomarCartaDelMazo(aMazo, i+12));
		AgregarCartaAJugador(jugadores[2],
				TomarCartaDelMazo(aMazo, i+24));
		AgregarCartaAJugador(jugadores[3],
				TomarCartaDelMazo(aMazo, i+36));
	}

	MostrarTodosJugadores(jugadores);
}
Anuncios
Anuncios

No es muy distinto pero tiene sus diferencias, especialmente en como debemos manejar ahora a los jugadores, las primeras cuatro lineas del main son iguales, desues empezamos con lo nuevo, aqui definimos un apuntador de array donde almacenaremos los cuatro jugadores generados anteriormente, despues por medio de un bucle iniciaremos a todos los jugadores, para despues por medio del mismo bucle que existia antes agregaremos las cartas a cada jugador, en este caso la unica diferencia es que en lugar de pasar la direccion de memoria de cada jugador le pasamos cada uno de los jugadores del array del mismo nombre, por ultimo mostramos a todos los jugadores mediante la funcion nueva, con todo esto comentado podemos pasar a compilarlo y ver como es su salida:

tinchicus@dbn001vrt:~/lenguajes/C$ ./prog/cartas
Jug 1: 
         as de Oro
        dos de Oro
       tres de Oro
Jug 2: 
       as de Copas
      dos de Copas
     tres de Copas
Jug 3: 
      as de Bastos
     dos de Bastos
    tres de Bastos
Jug 4: 
     as de Espadas
    dos de Espadas
   tres de Espadas
tinchicus@dbn001vrt:~/lenguajes/C$
Anuncios

Como pueden ver volvimos a obtener la misma salida que antes pero con un codigo un poco mas mejorado y depurado donde cada vez se nos dificulta menos entenderlo y no tener que agregar nuevos elementos sino trabajar con los que tenemos pero todavia estamos lejos de ser funcional.

Anuncios

En resuemn, hoy hemos visto como implementar un array en un struct, como declararlos, como se le establece informacion, como recuperarlos, a si como gracias a esta forma de trabajar pudimos eliminar un par de procesos innecesarios y redundantes, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50