![]() |
Índex |
Miguel A. Almarza
Departament d'Informàtica IES Mare de Deu de la Merce |
Estat inicial: Disposem de sis llistes on posar cartes: Maç,
CartesSortides, Oros, Copes, Espases i Bastons.
El joc consisteix en treure les cartes de la llista Maç
de dues en dues i apilalar-les a la llista CartesSortides. D'aquesta llista
anirem passant cartes a les llistes d'oros, copes espases o bastos de manera
ordenada, és a dir que les llistes dels pals estan ordenades de
menor a major i totes les cartes d'una llista de pal són del mateix
pal.
Per fer el programa de manera que pugui jugar un usuari farem un
menú amb les següents opcions:
0 Acabar
1 Iniciar el joc
|
![]() |
![]() |
Arxiu de capçalera carta.h | |
La classe Carta. | |
#include <iostream.h> #include <string.h> #include "boolean.h" class Carta { int Codigo; public: Carta() {Codigo=0;} Carta(int C){Codigo=C;} friend ostream &operator<< (ostream &stream, Carta &o); friend ostream &operator<< (ostream &stream, Carta *o); Boolean operator==(Carta &o); { if (Codigo==o.Codigo) return CIERTO; else return FALSO; } void CalculaPalo(char * Pal); void CalculaNombreCarta(char * Nombre); }; ostream &operator<< (ostream &stream, Carta &o) { char Carta[10], Palo[10]; o.CalculaNombreCarta(Carta); o.CalculaPalo(Palo); stream << Carta << " de " << Palo; return stream; } ostream &operator<< (ostream &stream, Carta *o) { char Carta[10], Palo[10]; o->CalculaNombreCarta(Carta); o->CalculaPalo(Palo); stream << Carta << " de " << Palo; return stream; } void Carta::CalculaPalo(char * Pal) { int p; char NombrePalo[4][8]={"Oros","Copas","Espadas","Bastos"}; p=(int)(((float) Codigo)/10); strcpy(Pal,NombrePalo[p]); } void Carta::CalculaNombreCarta(char * Nombre) { int n; char NombreCarta[10][8] = { "As","Dos","Tres","Cuatro","Cinco","Seis","Siete", "Sota","Caballo","Rey"}; n = Codigo % 10; strcpy(Nombre, NombreCarta[n]); } |
Les cartes que treballarem seran les espanyoles, així tindrem quatre pals, oros, copes espases i bastons. Tindrem quaranta cartes i 10 per cadascuns dels pals.
Així la dada principal d'una carta serà un codi numèric del 0 al 39 de manera que la desena d'aquest codi indicarà el pal i la unitat d'aquest codi indica el nombre de la carta dins el pal. Relació de funcions membre:
|
Fitxer de capçalera PILA.H | |
Fitxer de capçalera PILA.H: Classe genèrica NodoPila | |
#include <iostream.h> #include "boolean.h" template <class TipoDato> class NodoPila { TipoDato Informacion; NodoPila<TipoDato> * Siguiente; public: NodoPila() {Siguiente = NULL;} NodoPila(TipoDato V){Informacion=V;Siguiente = NULL;} NodoPila<TipoDato> * DameSiguiente() {return Siguiente;} void PonSiguiente(NodoPila * p){Siguiente = p;} void DameInformacion(TipoDato &c) {c=Informacion;} void PonInformacion(TipoDato c){Informacion=c;} friend ostream &operator<<(ostream &stream,NodoPila<TipoDato> o) { stream << o.Informacion; return stream; } friend ostream &operator<<(ostream &stream,NodoPila<TipoDato> *o) { stream << o->Informacion; return stream; } }; | Recordem que les classes per fer piles són les classes NodoPila i Pila, de manera que la classes Pila anava afegint o
eliminant objectes NodoPila. Segons veiem la classe NodoPila disposa dels constructors per defecte i amb pas de dades, dels mètodes per extreure dades i posar les dades en un node i l'operador d'extracció sobrecarregat. |
Fitxer de capçalera PILA.H: Classe genèrica Pila | |
template <class TipoDato> class Pila { NodoPila<TipoDato> *Principio; public: Pila(){Principio=NULL;} NodoPila<TipoDato> * DamePrincipio() {return Principio;} Boolean Push(TipoDato c); Boolean Pop(TipoDato &c); Boolean EstaVacia() { if (Principio==NULL) return CIERTO; else return FALSO; } }; template <class TipoDato> Boolean Pila<TipoDato>::Push(TipoDato c) { NodoPila<TipoDato> *p; p=new NodoPila<TipoDato>; if (p) { p->PonInformacion(c); p->PonSiguiente(Principio); Principio=p; return CIERTO; } else return FALSO; } template <class TipoDato> Boolean Pila<TipoDato>::Pop(TipoDato &c) { if (Principio!=NULL) { NodoPila<TipoDato> * Auxiliar; Auxiliar=Principio; Principio->DameInformacion(c); Principio = Principio->DameSiguiente(); delete Auxiliar; return CIERTO; } else return FALSO; } | La classe genèrica Pila té el constructor i les funcions Push i Pop que insereixen i extreuen respectivament dades de la pila. |
Fitxer de capçalera PILA.H: Classe genèrica PilaV | |
template <class TipoDato> class PilaV : public Pila<TipoDato> { public: void PilaV<TipoDato>::VaciaPila(); }; template <class TipoDato> void PilaV<TipoDato>::VaciaPila() { TipoDato c; while (!EstaVacia()) Pop(c); } | La classe pila no disposa de mètodes per buidar els objectes de tipus pila. Hem fet aquesta classe que hereta de forma
pública de la classe Pila per tal d'afegir aquesta funcionalitat.
Podem dir que hem fet aquesta nova classe per mantenir un purisme, quasi bé exagerat. Altre solució més simple hagués estat afegir directament el mètode VaciaPila directament a la classe Pila. |
El fitxer de capçalera auxiliar boolen.h | |
#ifndef _BOOLEAN_ #define _BOOLEAN_ 1 typedef int Boolean; #define CIERTO 1 #define FALSO 0 #endif | Al llarg de tot el programa farem ús d'aquestes constants booleanes |
La classe JuegoDelTonto i el programa principal. | |
#include "pila.h" #include "cartas.h" #include "boolean.h" #include <STDLIB.H> #include <conio.h> class JuegoDelTonto { PilaV<Carta> Mazo; PilaV<Carta> Palo[4]; PilaV<Carta> Deposito; int NumeroCartasASacar; public: JuegoDelTonto() { IniciaJuego(); NumeroCartasASacar =2;} void IniciaJuego(); void PresentaDatos(); void PasaCartaDePila(PilaV<Carta> &Origen,PilaV<Carta> &Destino) { Carta Trans; if (!Origen.EstaVacia()) { Origen.Pop(Trans); Destino.Push(Trans); } } void PasaDepositoAMazo(); void SacaCartas(); void PideCartasASacar(); void Juega(); }; void JuegoDelTonto::IniciaJuego() { int Numero[40]; int i,j; Boolean Sortear; NumeroCartasASacar =2; Mazo.VaciaPila(); for(i=0;i<4;i++) Palo[i].VaciaPila(); Deposito.VaciaPila(); randomize(); for (i=0;i<40;i++) { Sortear=CIERTO; while (Sortear) { Numero[i]=random (40); Sortear=FALSO; for(j=0;j<i;j++) if (Numero[i]==Numero[j]) Sortear=CIERTO; } Mazo.Push(Numero[i]); } } void JuegoDelTonto::PideCartasASacar() { gotoxy(40,1); cout << "Dame el numero de cartas a sacar: "; cin >> NumeroCartasASacar; } void JuegoDelTonto::PasaDepositoAMazo() { Carta Trans; while (!Deposito.EstaVacia()) { Deposito.Pop(Trans); Mazo.Push(Trans); } } void JuegoDelTonto::SacaCartas() { int i; Carta Trans; for (i=0;i<NumeroCartasASacar;i++) PasaCartaDePila(Mazo,Deposito); } void JuegoDelTonto::PresentaDatos() { gotoxy(3,14); cout << "Mazo: "; gotoxy(3,15); cout << "Oros: "; gotoxy(3,16); cout << "Copas: "; gotoxy(3,17); cout << "Espadas: "; gotoxy(3,18); cout << "Bastos: "; gotoxy(33,14);cout << "Deposito: "; gotoxy(40,1); cout << " Número de cartas a sacar: "; cout << NumeroCartasASacar; gotoxy(12,14); if (!Mazo.EstaVacia()) cout << Mazo.DamePrincipio(); for(int i=0; i <4; i++) { gotoxy(12,15+i); if (! Palo[i].EstaVacia()) cout << Palo[i].DamePrincipio(); } gotoxy(43,14); if (!Deposito.EstaVacia()) cout << Deposito.DamePrincipio(); } void JuegoDelTonto::Juega() { int Opcion=0; Boolean Acabar = FALSO; clrscr(); gotoxy(1,1); cout << "1 Iniciar juego" << endl; cout << "2 Saca cartas" << endl; cout << "3 Mover del mazo a oros" << endl; cout << "4 Mover del mazo a copas" << endl; cout << "5 Mover del mazo a espadas" << endl; cout << "6 Mover del mazo a bastos" << endl; cout << "7 Pasar deposito a mazo" << endl; cout << "8 Numero de cartas a sacar" << endl; cout << "9 Salir" << endl; while (!Acabar) { gotoxy(1,10); cin >> Opcion; switch (Opcion) { case 1 : IniciaJuego(); break; case 2 : SacaCartas();break; case 3: case 4: case 5: case 6: PasaCartaDePila(Deposito,Palo[Opcion-3]); break; case 7 : PasaDepositoAMazo(); break; case 8 : PideCartasASacar(); break; case 9 : Acabar=CIERTO; break; } PresentaDatos(); } } | La classe JuegoDelTonto és la classe que ens permet jugar a aquest joc.
Dades:
|
Programa del juego del tonto | |
main() { JuegoDelTonto Juego1; Juego1.Juega(); return 0; } |
La classe String. | |
#include <iostream.h> #include <string.h> #include <stdlib.h> class ClaseString { char * Punter; int Longitud; public: ClaseString(); ClaseString(char *Cadena); ClaseString(const ClaseString &obClaseString); ~ClaseString() {delete [] Punter;} friend ostream &operator<<(ostream &Flux, ClaseString &obClaseString); friend istream &operator>>(istream &Flux, ClaseString &obClaseString); ClaseString operator=(ClaseString &obClaseString); ClaseString operator=(char *Cadena); ClaseString operator+(ClaseString &obClaseString); ClaseString operator+(char *Cadena); friend ClaseString operator+(char *Cadena, ClaseString &obClaseString); int operator==(ClaseString &obClaseString) {return !strcmp(Punter,obClaseString.Punter);} int operator!=(ClaseString &obClaseString) {return strcmp(Punter,obClaseString.Punter);} int operator<(ClaseString &obClaseString) {return strcmp(Punter,obClaseString.Punter)<0;} int operator>(ClaseString &obClaseString) {return strcmp(Punter,obClaseString.Punter)>0;} int operator<=(ClaseString &obClaseString) {return strcmp(Punter,obClaseString.Punter)<=0;} int operator>=(ClaseString &obClaseString) {return strcmp(Punter,obClaseString.Punter)>=0;} int operator==(char *Cadena) {return !strcmp(Punter,Cadena);} int operator!=(char *Cadena) {return strcmp(Punter,Cadena);} int operator<(char *Cadena) {return strcmp(Punter,Cadena)<0;} int operator>(char *Cadena) {return strcmp(Punter,Cadena)>0;} int operator<=(char *Cadena) {return strcmp(Punter,Cadena)<=0;} int operator>=(char *Cadena) {return strcmp(Punter,Cadena)>=0;} int Long(){return strlen(Punter);} void HazCadena(char * Cadena) { strcpy(Cadena,Punter);} operator char * () {return Punter;} //Cast hacia char * }; ClaseString::ClaseString() { Longitud=1; Punter = new char[Longitud]; if (!Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } Punter[0]='\0'; } ClaseString::ClaseString(char *Cadena) { Longitud=strlen(Cadena)+1; Punter = new char[Longitud]; if (!Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } strcpy(Punter,Cadena); } ClaseString::ClaseString(const ClaseString &obClaseString) { Longitud=strlen(obClaseString.Punter) + 1; Punter = new char[Longitud]; if (!Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } strcpy(Punter,obClaseString.Punter); } ostream &operator<<(ostream &Flux, ClaseString &obClaseString) { Flux << obClaseString.Punter; return Flux; } istream &operator>>(istream &Flux, ClaseString &obClaseString) { char CadenaIn[1024]; int Longitud; for(Longitud=0; Longitud < 1024; Longitud++) { Flux.get(CadenaIn[Longitud]); if (CadenaIn[Longitud]=='\n') break; if ((CadenaIn[Longitud]=='\b') && (Longitud)) Longitud--; } CadenaIn[Longitud] = '\0'; if (Longitud > obClaseString.Longitud) { delete obClaseString.Punter; obClaseString.Punter = new char[Longitud + 1]; if (!obClaseString.Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } obClaseString.Longitud=Longitud; } strcpy(obClaseString.Punter, CadenaIn); return Flux; } ClaseString ClaseString::operator=(ClaseString &obClaseString) { ClaseString obTemporal(obClaseString); if (Longitud < obClaseString.Longitud) { delete Punter; Punter = new char[obClaseString.Longitud+1]; if (!Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } Longitud = obClaseString.Longitud; } strcpy(Punter,obClaseString.Punter); return obTemporal; } ClaseString ClaseString::operator=(char *Cadena) { int L = strlen(Cadena); if (Longitud < L) { delete Punter; Punter = new char[L+1]; if (!Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } Longitud = L; } strcpy(Punter,Cadena); return * this; } ClaseString ClaseString::operator+(ClaseString &obClaseString) { ClaseString obTemporal; int L = Longitud + obClaseString.Longitud +1; delete obTemporal.Punter; obTemporal.Punter = new char[L+1]; if (!obTemporal.Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } obTemporal.Longitud = L; strcpy(obTemporal.Punter,Punter); strcat(obTemporal.Punter,obClaseString.Punter); return obTemporal; } ClaseString ClaseString::operator+(char *Cadena) { ClaseString obTemporal; int L = Longitud + strlen(Cadena) + 1; delete obTemporal.Punter; obTemporal.Punter = new char[L+1]; if (!obTemporal.Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } obTemporal.Longitud = L; strcpy(obTemporal.Punter,Punter); strcat(obTemporal.Punter,Cadena); return obTemporal; } ClaseString operator+(char *Cadena, ClaseString &obClaseString) { ClaseString obTemporal; int L = strlen(Cadena) + obClaseString.Longitud +1; delete obTemporal.Punter; obTemporal.Punter = new char[L+1]; if (!obTemporal.Punter) { cout << "Error. No puedo alojar ClaseString"; exit(1); } obTemporal.Longitud = L; strcpy(obTemporal.Punter,Cadena); strcat(obTemporal.Punter,obClaseString.Punter); return obTemporal; } |