#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CAR 255
#define CIERTO 1
#define FALSO 0
#define MAX_PALOS 4
#define MAX_NAIPES_PALO 13
#define MAX_LON_LISTA MAX_PALOS*MAX_NAIPES_PALO
#define MAX_COL_TABLERO 7
typedef char Tcadena[MAX_CAR+1];
typedef struct
{
int oculto;
int numero; /* 1 a 13 */
char palo;
} Tnaipe;
typedef struct
{
int nn;
Tnaipe naipe[MAX_LON_LISTA];
} TListaNaipes;
typedef struct
{
int activa;
TListaNaipes lista;
} Tbaraja;
typedef enum{INICIO_JUEGO, MOSTRAR_NAIPE, MOVER_NAIPE, SALIR}Topcion;
void mayuscula( char *letra )
{
if (*letra>='A'&&*letra<='z')
{
if (*letra<='Z')
{
*letra= *letra;
}
else if(*letra>='a')
{
*letra=*letra-('a'-'A');
}
else printf("Error a: caràcter no vàlid\n");
}
else printf("Error b:caràcter no vàlid\n");
}
char pedirCaracter( char msg[MAX_CAR] )
{
char car;
printf("%s\n",msg);
scanf("%c%*c",&car);
mayuscula(&car);
return car;
}
int pedirEntero (char msg[MAX_CAR])
{
int num;
printf("%s\n",msg);
scanf("%d%*c",&num);
return num;
}
void pedirCadena (char msg[MAX_CAR], Tcadena cadena)
{
printf("%s\n", msg);
printf("Escriure un text\n");
scanf("%[^\n]%*c",&cadena);
}
void imprimirNaipe(Tnaipe naipe)
{
if (naipe.oculto== CIERTO)
printf("**** ");
else
if (naipe.numero==13)
printf("K%c ",naipe.palo);
else if (naipe.numero==12)
printf("Q%c ",naipe.palo);
else if (naipe.numero==11)
printf("J%c ",naipe.palo);
else if (naipe.numero==1)
printf("A%c ",naipe.palo);
else
printf("%d%c ",naipe.numero,naipe.palo);
}
void imprimirLista( TListaNaipes lista )
{
int i;
for (i=0; i< lista.nn ; i++)
imprimirNaipe(lista.naipe [i]);
}
void sacarNaipeDeLista(TListaNaipes *lista,int pos, Tnaipe *naipe)
{
int i;
*naipe = (*lista).naipe[pos];
for (i=pos;i<(*lista).nn-1 ;i++)
(*lista).naipe[i]= (*lista).naipe[i+1];
(*lista).nn = (*lista).nn -1;
}
void insertarNaipeEnLista (Tnaipe naipe, int pos, TListaNaipes *lista)
{
int i;
(*lista).nn = (*lista).nn +1;
for (i=(*lista).nn -1;i>pos ;i--)
(*lista).naipe[i]= (*lista).naipe[i-1];
(*lista).naipe[pos]= naipe;
}
void ordenAleatorio( Tbaraja *baraja )
{
int ii, jj, kk;
double max, lon;
Tnaipe naipe;
max = (double)RAND_MAX;
lon = (double)MAX_LON_LISTA;
for (kk= 0; kk< MAX_LON_LISTA; kk++)
{
ii = (int)(((double)rand() / max) * lon);
jj = (int)(((double)rand() / max) * lon);
if (ii != jj)
{
naipe = baraja->lista.naipe[ii];
baraja->lista.naipe[ii] = baraja->lista.naipe[jj];
baraja->lista.naipe[jj] = naipe;
}
}
}
void inicializaBaraja(Tbaraja *baraja)
{
int i,j;
char letra;
Tnaipe naipe;
baraja->lista.nn = 0;
for (i=1;i<MAX_PALOS+1;i++)
{
switch (i)
{
case 1:
letra = 'T';
break;
case 2:
letra = 'P';
break;
case 3:
letra = 'D';
break;
case 4:
letra = 'C';
break;
}
for (j=1;j<MAX_NAIPES_PALO+1;j++)
{
naipe.oculto = CIERTO;
naipe.numero = j;
naipe.palo = letra;
insertarNaipeEnLista(naipe,baraja->lista.nn ,&baraja->lista);
}
}
ordenAleatorio(baraja);
baraja->activa=MAX_LON_LISTA-1;
baraja->lista.naipe[baraja->activa].oculto=FALSO;
}
Tnaipe sacarDeBaraja (Tbaraja *baraja)
{
Tnaipe naipe;
sacarNaipeDeLista(&baraja->lista ,baraja->activa,&naipe);
if (baraja->activa == 0)
baraja->activa = baraja->lista.nn -1;
else
baraja->activa -= 1;
baraja->lista.naipe[baraja->activa].oculto=FALSO;
return naipe;
}
void inicializarDescarte ( TListaNaipes descarte[])
{
int i;
for (i=0; i<MAX_PALOS;i++)
descarte[i].nn = 0;
}
void inicializarTablero(TListaNaipes tablero[], Tbaraja *baraja)
{
int i, j;
for (i=0;i<MAX_COL_TABLERO;i++)
{
tablero[i].nn =0;
tablero[i].nn = i+1;
for (j=0;j<=i;j++)
{
tablero[i].naipe[j] = sacarDeBaraja(baraja);
tablero[i].naipe[j].oculto = CIERTO;
}
tablero[i].naipe[i].oculto = FALSO;
}
}
void MostrarPantalla( TListaNaipes tablero[], TListaNaipes descarte[],Tbaraja baraja )
{
int i, j,k,l,m,MAX_FILAS;
printf("----------------------------------------------------------------------\n");
if (baraja.lista.nn !=0)
{
baraja.lista.naipe[baraja.activa].oculto = FALSO;
for (l=0; l< baraja.lista.nn ; l++)
if (baraja.lista.naipe[l].oculto== CIERTO)
printf("*");
else
if (baraja.lista.naipe[l].numero==13)
printf("K%c ",baraja.lista.naipe[l].palo);
else if (baraja.lista.naipe[l].numero==12)
printf("Q%c ",baraja.lista.naipe[l].palo);
else if (baraja.lista.naipe[l].numero==11)
printf("J%c ",baraja.lista.naipe[l].palo);
else if (baraja.lista.naipe[l].numero==1)
printf("A%c ",baraja.lista.naipe[l].palo);
else
printf("%d%c ",baraja.lista.naipe[l].numero,baraja.lista.naipe[l].palo);
}
else
printf("...");
printf("\n");
printf("----------------------------------------------------------------------\n");
for (i=0; i <MAX_PALOS;i++)
{
if (descarte[i].nn == 0)
printf("....\t");
else
imprimirNaipe(descarte[i].naipe[descarte[i].nn-1]);
printf("\t");
}
printf("\n");
printf("----------------------------------------------------------------------\n");
printf("0\t 1\t 2\t 3\t 4\t 5\t 6\t\n");
printf("----------------------------------------------------------------------\n");
MAX_FILAS=0;
for (m=0;m<MAX_COL_TABLERO;m++)
{
if (MAX_FILAS<tablero[m].nn)
MAX_FILAS = tablero[m].nn;
}
for (j=0;j<MAX_FILAS;j++)
{
k=0;
for (k=0;k<MAX_COL_TABLERO;k++)
{
if (tablero[k].nn <= j)
printf("\t");
else
{
imprimirNaipe(tablero[k].naipe[j]);
printf("\t");
}
if (k==6)
printf("\n");
}
}
printf("----------------------------------------------------------------------\n");
}
Topcion menu()
{
Topcion a;
pedir:
a= pedirEntero("Opcions\n0 -> INICIAR JOC\n1 -> MOSTRAR CARTA\n2 -> MOURE CARTA\n3 -> SORTIR\nLa seva opció és:");
if (a>3||a<0)
{
a=3;
scanf("%*c");
goto pedir;
}
else
return a;
}
void mostrar_naipe( TListaNaipes tablero[], Tbaraja *baraja )
{
char c;
int a, e;
c = pedirCaracter("B-> Mostrar naipe de Baraja , T->Mostrar naipe de Tablero\n");
if (c!='B'&&c!='T')
printf("Error, caràcter no vàlid\n");
else
{
if (c=='T')
{
e = pedirEntero("Introdueixi la columna\n");
if (e<0||e>6)
printf("Error: columna no vàlida\n");
else
a= tablero[e].nn;
if (tablero[e].naipe[a-1].oculto == CIERTO)
{
tablero[e].naipe[a-1].oculto = FALSO;
}
else
printf("Això no es pot fer\n");
}
else
{
if (baraja->activa == 0)
{
baraja->lista.naipe[baraja->activa].oculto=CIERTO;
baraja->activa = baraja->lista.nn -1;
baraja->lista.naipe[baraja->activa].oculto=FALSO;
}
else
{
baraja->lista.naipe[baraja->activa].oculto=CIERTO;
baraja->activa -= 1;
baraja->lista.naipe[baraja->activa].oculto=FALSO;
}
}
}
}
void baraja2descarte( Tbaraja *baraja, TListaNaipes *descarte )
{
int a;
Tnaipe n;
pedir1:
a=pedirEntero("A quina columna desitja moure la carta?(0-1-2-3)");
if ((a<0)||(a>3))
goto pedir1;
else
if (descarte[a].nn ==0)
{
if (baraja->lista.naipe[baraja->activa].numero ==1)
{
n = sacarDeBaraja(baraja);
insertarNaipeEnLista(n,descarte[a].nn,&descarte[a]);
}
else
{
printf("La carta no es pot moure perquè no és un As\n");
goto pedir1;
}
}
else
if (baraja->lista.naipe[baraja->activa].palo != descarte[a].naipe[descarte[a].nn-1].palo)
{
printf("Pal diferent\n");
goto pedir1;
}
else if (baraja->lista.naipe[baraja->activa].numero== descarte[a].naipe[descarte[a].nn-1].numero+1)
{
descarte[a].naipe[descarte[a].nn-1].oculto=CIERTO;
n = sacarDeBaraja(baraja);
insertarNaipeEnLista(n,descarte[a].nn,&descarte[a]);
}
else
{
printf("Nombre diferent\n");
goto pedir1;
}
}
void baraja2tablero( Tbaraja *baraja, TListaNaipes *tablero )
{
Tnaipe n;
int a;
pedir2:
a= pedirEntero("A quina columna desitja moure la carta?\n");
if ((a<0)||(a>6))
goto pedir2;
else
if (baraja->lista.naipe[baraja->activa].palo == tablero[a].naipe[tablero[a].nn -1].palo)
{
printf("Error: mateix pal\n");
goto pedir2;
}
else
if (tablero[a].nn !=0)
{
if (tablero[a].naipe[tablero[a].nn -1].oculto !=FALSO)
{
printf("Error: darrera carta no visible\n");
goto pedir2;
}
else
if (tablero[a].naipe[tablero[a].nn -1].numero != baraja->lista.naipe[baraja->activa].numero +1)
{
printf("Error: el numero de la carta no és vàlid\n");
goto pedir2;
}
else
{
n = sacarDeBaraja(baraja);
insertarNaipeEnLista(n,tablero[a].nn,&tablero[a]);
}
}
else
if (baraja->lista.naipe[baraja->activa].numero ==13)
{
n = sacarDeBaraja(baraja);
insertarNaipeEnLista(n,tablero[a].nn,&tablero[a]);
}
else
{
printf("Error: No es pot moure la carta\n");
goto pedir2;
}
}
void tablero2descarte(TListaNaipes *tablero,TListaNaipes *descarte)
{
int a,b;
pedir3:
a= pedirEntero("Des de quina columna vol moure la carta?(0-1-2-3-4-5-6)\n");
if ((a<0)||(a>6))
goto pedir3;
else
b= pedirEntero("A quina columna vol moure la carta?(0-1-2-3)\n");
if ((b<0)||(b>3))
goto pedir3;
else
if (descarte[b].nn == 0)
{
if (tablero[a].naipe[tablero[a].nn-1].numero != 1)
{
printf("Error a: numero de la carta no vàlid\n");
goto pedir3;
}
else
{
insertarNaipeEnLista(tablero[a].naipe[tablero[a].nn -1],descarte[b].nn, &descarte[b]);
sacarNaipeDeLista(&tablero[a],tablero[a].nn-1,&tablero[a].naipe[tablero[a].nn -1]);
}
}
else
if(tablero[a].naipe[tablero[a].nn -1].numero !=descarte[b].naipe[descarte[b].nn-1].numero+1)
{
printf("Error b: numero de la carta no vàlid\n");
goto pedir3;
}
else
if(tablero[a].naipe[tablero[a].nn -1].palo !=descarte[b].naipe[descarte[b].nn-1].palo)
{
printf("Error: pal diferent\n");
goto pedir3;
}
else
{
insertarNaipeEnLista(tablero[a].naipe[tablero[a].nn -1],descarte[b].nn, &descarte[b]);
sacarNaipeDeLista(&tablero[a],tablero[a].nn-1,&tablero[a].naipe[tablero[a].nn -1]);
}
}
void tablero2tablero(TListaNaipes *tableroF, TListaNaipes *tableroD)
{
int a, b, c, m, n, p, q;
pedir4:
a= pedirEntero("Des de quina columna desitja moure la/es carta/es?(0-1-2-3-4-5-6)\n");
if ((a<0)||(a>6))
{
printf("Error a: Columna no vàlida\n");
goto pedir4;
}
else
{
b= pedirEntero("¿A quina columna desitja moure la carta?(0-1-2-3-4-5-6)\n");
if ((b<0)||(b>6))
{
printf("Error b: Columna no vàlida\n");
goto pedir4;
}
else
{
c= pedirEntero("Quantes cartes vol moure?\n");
q=0;
for (p=0;p<tableroF[a].nn; p++)//q=numcartasvisibles
{
if (tableroF[a].naipe[p].oculto == FALSO)
q+=1;
}
if (c<1||c>tableroF[a].nn)
{
printf("Error: No es poden moure tantes cartes\n");
goto pedir4;
}
else
{
if (c<=q)
{
if (tableroD[b].nn ==0&&tableroF[a].naipe[tableroF[a].nn - c].numero ==13 ) //si el tablero de destino está vacio sólo se puede mover la K
{
for (n = c;n>=1;n--)
{
insertarNaipeEnLista(tableroF[a].naipe[tableroF[a].nn - n],tableroD[b].nn,&tableroD[b]);
sacarNaipeDeLista(&tableroF[a],tableroF[a].nn - n,&tableroF[a].naipe[tableroF[a].nn - n]);
}
}
else
{
if(tableroD[b].naipe[tableroD[b].nn -1 ].oculto ==CIERTO)//mover "normal"
{
printf("Error: la carta de destinació no es visible\n");
goto pedir4;
}
else
{
for (m=1; m <= c; m++)
{
if (tableroF[a].naipe[tableroF[a].nn -m ].oculto ==CIERTO)
{
break;
goto pedir4;
}
}
if (tableroF[a].naipe[tableroF[a].nn - c].numero != tableroD[b].naipe[tableroD[b].nn -1].numero -1)
{
printf("Error: El nombre de la carta no és vàlid\n");
goto pedir4;
}
else
{
if (tableroF[a].naipe[tableroF[a].nn - c].palo == tableroD[b].naipe[tableroD[b].nn -1].palo)
{
printf("Error: Mateix pal\n");
goto pedir4;
}
else
{
for (n = c;n>=1;n--)
{
insertarNaipeEnLista(tableroF[a].naipe[tableroF[a].nn - n],tableroD[b].nn,&tableroD[b]);
sacarNaipeDeLista(&tableroF[a],tableroF[a].nn - n,&tableroF[a].naipe[tableroF[a].nn - n]);
}
}
}
}
}
}
else
{
printf("Error: no es pot mopure més cartes de les visibles\n");
goto pedir4;
}
}
}
}
}
void moverNaipe( TListaNaipes tablero[], TListaNaipes descarte[], Tbaraja *baraja )
{
char a, b;
pedir5:
a=pedirCaracter("¿Origen del movimient? T->Tablero B->Baraja\n");
b=pedirCaracter("¿Destinció del moviment? T->Tablero D->Descarte\n");
if (a == 'T')//Tablero
{
if (b=='T')
tablero2tablero(tablero,tablero);
else if (b=='D')
tablero2descarte(tablero,descarte);
else
{
printf("Error a:Moviment no permès\n");
goto pedir5;
}
}
else if (a == 'B')
{
if (b =='T')
baraja2tablero(baraja,tablero);
else if (b == 'D')
baraja2descarte(baraja,descarte);
else
{
printf("Error b:Moviment no permès\n");
goto pedir5;
}
}
else
{
printf("Error c:Moviment no permès\n");
goto pedir5;
}
}
int ganador( TListaNaipes descarte[] )
{
int a,b,c;
c=0;
for (a=0;a<MAX_PALOS;a++)
{
b=descarte[a].nn ;
c +=b;
}
if (c ==MAX_LON_LISTA)
return CIERTO;
else
return FALSO;
}
void escribirLista( FILE *fp, TListaNaipes lista )
{
/* (oculto, numero y palo). Ejemplo:
3
1 11 P
1 1 C
0 10 D*/
int a;
fprintf(fp,"%d\n",lista.nn );
for (a=0;a < lista.nn; a++)
fprintf(fp,"%d %d %d\n",lista.naipe[a].oculto , lista.naipe[a].numero ,lista.naipe[a].palo );
}
void leerLista( FILE *fp, TListaNaipes *lista )
{
int a,b;
fscanf(fp,"%d%*c",&a);
lista->nn = a;
for (b=0;b< a; b++)
fscanf(fp,"%d%*c%d%*c%d%*c",&lista->naipe[b].oculto ,&lista->naipe[b].numero ,&lista->naipe[b].palo);
}
void inicializar( TListaNaipes tablero[], TListaNaipes descarte[],Tbaraja *baraja )
{
char a;
Tcadena b;
FILE *fic;
int d,e;
a=pedirCaracter("¿Desitja carregar una partida d'un fitxer?- (S)í (N)o -\n");
if (a == 'S')
{
printf("¿Nom del fitxer?\n");
scanf("%[^\n]%*c",&b);
fic=fopen(b,"r");if (fic==NULL) {printf("Error obrint fitxer...\nNova partida...\n");goto inicio;}
fscanf(fic,"%d%*c",&baraja->activa);
leerLista(fic,&baraja->lista);
for (d=0;d<MAX_PALOS;d++)
leerLista(fic,&descarte[d]);
for (e=0;e<MAX_COL_TABLERO;e++)
leerLista(fic,&tablero[e]);
fclose(fic);
}
else
{
inicio:
inicializarDescarte(descarte);
inicializaBaraja(baraja);
inicializarTablero(tablero,baraja);
}
}
void finalizar( TListaNaipes tablero[], TListaNaipes descarte[], Tbaraja baraja )
{
char c;
FILE *fic;
Tcadena nom;
int d, e;
c= pedirCaracter("¿Desitja desar la partida?-(S)í (N)o-\n");
if (c == 'S')
{
printf("¿Nom del fitxer?");
scanf("%[^\n]%*c",&nom);
fic = fopen(nom,"w");if (fic==NULL) {printf("Error amb fitxer...\n");goto fin;}
fprintf(fic,"%d\n",baraja.activa);
escribirLista(fic,baraja.lista);
for (d=0;d<MAX_PALOS;d++)
escribirLista(fic,descarte[d]);
for (e=0;e<MAX_COL_TABLERO;e++)
escribirLista(fic,tablero[e]);
fclose(fic);
}
else
{
fin:
printf("Gràcies per jugar :-)\n");
}
}
void main()
{
Topcion f;
int a;
Tbaraja baraja;
TListaNaipes descarte[MAX_PALOS];
TListaNaipes tablero[MAX_COL_TABLERO];
inicializar(tablero,descarte,&baraja);
printf("Benvingut/uda a Solitari by MaRtInI -http:"//oscarmartinez.cjb.net\n");
men:
a=ganador(descarte);
if (a == CIERTO)
{
printf(" #####^^^^^#####| (''-''-/').___..--'''`-._ \a\n");
printf(" ## H A ##| `6_ 6 ) `-. ( ).`-.__.`) \a\n");
printf(" $ GUANYAT $| (_Y_.)' ._ ) `._ `. ``-..-' \a\n");
printf(" ## ##| _..`--'_..-_/ /--'_.' ,' \a\n");
printf(" #####-----#####| (il),-'' (li),' ((!.-' \a\n");
}
MostrarPantalla( tablero, descarte, baraja);
f =menu();
if (f==MOSTRAR_NAIPE)
{
mostrar_naipe(tablero,&baraja);
goto men;
}
else if (f==INICIO_JUEGO)
{
inicializar(tablero,descarte,&baraja);
goto men;
}
else if (f==SALIR)
{
finalizar(tablero,descarte,baraja);
exit(0);
}
else if (f ==MOVER_NAIPE)
{
moverNaipe(tablero,descarte,&baraja);
goto men;
}
else//Cas no possible
{
printf("No entenc");
goto men;
}
}