// Capítulo 8: Diseño descendente // Fichero formula1.cpp // El siguiente programa realiza // la gestión del campeonato // de Fórmula 1 #include <iostream> #include <stdlib.h> using namespace std; // Definición de constantes const int MAXGPs = 20; const int MAXCONSTRUCTORES = 12; const int MAXPILOTOS = 60; const int MAXNOMGP = 40; const int MAXNOMCONSTRUCTOR = 40; const int MAXNOMPILOTO = 40; const int MAXOPCION = 15; const int PUNTUABLES = 8; const int puntos[PUNTUABLES] = {10,8,6,5,4,3,2,1}; // Estructuras de memoria typedef char tOpcion[MAXOPCION]; typedef char tNombrePiloto[MAXNOMPILOTO]; typedef char tNombreGP[MAXNOMGP]; typedef char tNombreConstructor[MAXNOMCONSTRUCTOR]; struct tGranPremio { tNombreGP nomGP; tNombrePiloto ganador; }; // Estructura para la información de los grandes premios struct tListaGrandesPremios{ tGranPremio GPs[MAXGPs]; int nGPs; }; // Tipo básico para la información de constructores struct tConstructor { tNombreConstructor nom; int puntuacion; int posicionEnlaClas; int piloto1, piloto2; }; // Estructura para la información de los constructores y su clasificación struct tListaConstructores { tConstructor constructores[MAXCONSTRUCTORES]; int clasificacion[MAXCONSTRUCTORES]; int nConstructores; }; // Tipo básico para la información de pilotos struct tPiloto { tNombrePiloto nom; int puntuacion; int posicionEnlaClas; int indiceConstructor; }; // Estructura para los pilotos y sus clasificaciones struct tListaPilotos { tPiloto pilotos[MAXPILOTOS]; int clasificacion[MAXPILOTOS]; int nPilotos; }; //Estructura para los campeonatos struct tFormula1 { int anno; tListaGrandesPremios GPs; int nGPsCelebrados; tListaConstructores constructores; tListaPilotos pilotos; }; // Añadir Gran Premio void insertarGP(tListaGrandesPremios & GPs, tNombreGP nomGP) { if(GPs.nGPs < MAXGPs){ strcpy(GPs.GPs[GPs.nGPs].nomGP,nomGP); strcpy(GPs.GPs[GPs.nGPs].ganador,""); GPs.nGPs++; } } //Leer Grandes Premios void leerGPs(tListaGrandesPremios & GPs) { tNombreGP nomGP; cin >> nomGP; while(strcmpi(nomGP,"FIN_GP")!=0) { insertarGP(GPs,nomGP); cin >> nomGP; } } //Añadir piloto void insertarPiloto(tListaPilotos & pilotos, tNombrePiloto nomPiloto, int indiceConstructor) { strcpy(pilotos.pilotos[pilotos.nPilotos].nom,nomPiloto); pilotos.pilotos[pilotos.nPilotos].indiceConstructor=indiceConstructor; pilotos.pilotos[pilotos.nPilotos].puntuacion = 0; pilotos.pilotos[pilotos.nPilotos].posicionEnlaClas = pilotos.nPilotos; pilotos.clasificacion[pilotos.nPilotos] = pilotos.nPilotos; pilotos.nPilotos++; } //Añadir constructor void insertarConstructor(tListaConstructores & constructores, tNombreConstructor nomConstr, int piloto1, int piloto2) { strcpy(constructores.constructores[constructores.nConstructores].nom, nomConstr); constructores.constructores[constructores.nConstructores].piloto1 = piloto1; constructores.constructores[constructores.nConstructores].piloto2 = piloto2; constructores.constructores[constructores.nConstructores].puntuacion=0; constructores.constructores[constructores.nConstructores]. posicionEnlaClas = constructores.nConstructores; constructores.clasificacion[constructores.nConstructores] = constructores.nConstructores; constructores.nConstructores++; } //Añadir pilotos de un constructor void insertarConstrPilotos(tListaConstructores & constructores, tListaPilotos & pilotos, tNombreConstructor nomConstr, tNombrePiloto nomPiloto1, tNombrePiloto nomPiloto2) { int ic; ic = constructores.nConstructores; insertarConstructor(constructores,nomConstr,pilotos.nPilotos, pilotos.nPilotos+1); insertarPiloto(pilotos,nomPiloto1,ic); insertarPiloto(pilotos,nomPiloto2,ic); } void leerConstrsPilotos(tListaConstructores & constructores, tListaPilotos & pilotos) { tNombreConstructor nomConstr; tNombrePiloto nomPilot1, nomPilot2; cin >> nomConstr; while(strcmpi(nomConstr,"FIN_CONS")!=0) { cin >> nomPilot1 >> nomPilot2; insertarConstrPilotos(constructores,pilotos,nomConstr, nomPilot1,nomPilot2); cin >> nomConstr; } } void inicializarClasificacionConstrs(tListaConstructores & constructores) { int i; i = 0; while(i < constructores.nConstructores) { constructores.clasificacion[i] = i; i++; } } void inicializarClasificacionPilotos(tListaPilotos &pilotos) { int i; i = 0; while(i < pilotos.nPilotos){ pilotos.clasificacion[i] = i; i++; } } void inicializar(tFormula1 & F1) { tNombreGP nomGP; cin >> F1.anno; F1.nGPsCelebrados = 0; F1.GPs.nGPs = 0; F1.constructores.nConstructores = 0; F1.pilotos.nPilotos = 0; leerGPs(F1.GPs); leerConstrsPilotos(F1.constructores,F1.pilotos); } void escribirGP(const tGranPremio & GP) { cout << GP.nomGP << ' ' << GP.ganador << endl; } void escribirGPs(const tListaGrandesPremios & GPs) { int i; i=0; while(i < GPs.nGPs) { escribirGP(GPs.GPs[i]); i++; } } void escribirConstrsPilotos(const tListaConstructores & constructores, const tListaPilotos & pilotos) { int i; i = 0; while(i < constructores.nConstructores) { cout << constructores.constructores[i].nom << ' ' << pilotos.pilotos[constructores.constructores[i].piloto1].nom << ' ' << pilotos.pilotos[constructores.constructores[i].piloto2].nom << endl; i++; } } int buscarPiloto(const tListaPilotos & pilotos, tNombrePiloto nomPiloto) { bool encontrado; int i; encontrado = false; i = 0; while(i < pilotos.nPilotos && !encontrado) { if(strcmpi(nomPiloto,pilotos.pilotos[i].nom)== 0) { encontrado = true; } else { i++; } } if (!encontrado) { i = -1; } return i; } void actualizarClasificacionPilotos(tListaPilotos & pilotos, int p) { bool encontrado; int i; encontrado = false; i= pilotos.pilotos[p].posicionEnlaClas; while (i > 0 && !encontrado){ if(pilotos.pilotos[pilotos.clasificacion[i-1]].puntuacion >= pilotos.pilotos[p].puntuacion) { encontrado = true; } else { pilotos.pilotos[pilotos.clasificacion[i-1]].posicionEnlaClas = i; pilotos.clasificacion[i] = pilotos.clasificacion[i-1]; pilotos.clasificacion[i-1] = p; pilotos.pilotos[p].posicionEnlaClas = i-1; i--; } } } void actualizarClasificacionConstrs(tListaConstructores &constructores, int c) { bool encontrado; int i; encontrado = false; i= constructores.constructores[c].posicionEnlaClas; while (i > 0 && !encontrado) { if(constructores.constructores [constructores.clasificacion[i-1]].puntuacion >= constructores.constructores[c].puntuacion) { encontrado = true; } else { constructores.constructores[constructores.clasificacion[i-1]] .posicionEnlaClas = i; constructores.clasificacion[i] = constructores.clasificacion[i-1]; constructores.clasificacion[i-1] = c; constructores.constructores[c].posicionEnlaClas = i-1; i--; } } } void leerClasificacionGPYActualizarF1(tFormula1 &F1) { tNombrePiloto nomPiloto; int p,ic,cont; cont = 0; cin >> nomPiloto; strcpy(F1.GPs.GPs[F1.nGPsCelebrados].ganador,nomPiloto); F1.nGPsCelebrados++; while(strcmpi(nomPiloto,"FIN_CL")!=0 && cont < PUNTUABLES) { p = buscarPiloto(F1.pilotos,nomPiloto); F1.pilotos.pilotos[p].puntuacion = F1.pilotos.pilotos[p].puntuacion + puntos[cont]; actualizarClasificacionPilotos(F1.pilotos,p); ic = F1.pilotos.pilotos[p].indiceConstructor; F1.constructores.constructores[ic].puntuacion = F1.constructores.constructores[ic].puntuacion + puntos[cont]; actualizarClasificacionConstrs(F1.constructores,ic); cont++; cin >> nomPiloto; } while(strcmpi(nomPiloto,"FIN_CL")!=0){ cin >> nomPiloto; } } bool esPilotoOficial(const tConstructor & constructor, int p) { return p == constructor.piloto1 || p == constructor.piloto2; } bool mismoConstructor(const tListaPilotos & pilotos, int p1, int p2) { return pilotos.pilotos[p1].indiceConstructor == pilotos.pilotos[p2].indiceConstructor; } void sustituirPiloto(tConstructor & constructor, int p1, int p2) { if(constructor.piloto1 == p1) { constructor.piloto1 = p2; } else if(constructor.piloto2 == p1) { constructor.piloto2 = p2; } } void sustitucion(tFormula1 &F1) { tNombrePiloto nomPiloto1,nomPiloto2; int p1, p2, ic; cin >> nomPiloto1 >> nomPiloto2; p1 = buscarPiloto(F1.pilotos, nomPiloto1); if(p1 < 0){ cout << "ERROR PILOTO INEXISTENTE" << endl; } else{ ic = F1.pilotos.pilotos[p1].indiceConstructor; if (!esPilotoOficial(F1.constructores.constructores[ic],p1)) { // ya no es piloto oficial cout << "ERROR NO ES PILOTO OFICIAL" << endl; } else { p2 = buscarPiloto(F1.pilotos, nomPiloto2); if(p2 >= 0) { if(!mismoConstructor(F1.pilotos,p1,p2)) { cout << "ERROR PILOTO DE OTRO CONSTRUCTOR" << endl; } else { sustituirPiloto(F1.constructores.constructores[ic],p1,p2); } } else { p2 = F1.pilotos.nPilotos; insertarPiloto(F1.pilotos,nomPiloto2,ic); sustituirPiloto(F1.constructores.constructores[ic],p1,p2); } } } } void escribirClasificacionPilotos(const tFormula1 & F1) { int i; i = 0; while(i < F1.pilotos.nPilotos) { cout << F1.pilotos.pilotos[F1.pilotos.clasificacion[i]].nom << ' ' << F1.constructores.constructores[F1.pilotos.pilotos [F1.pilotos.clasificacion[i]].indiceConstructor].nom << ' ' << F1.pilotos.pilotos[F1.pilotos.clasificacion[i]].puntuacion << endl; i++; } } void escribirClasificacionConstructores(const tListaConstructores &constructores) { int i; i = 0; while(i < constructores.nConstructores) { cout << constructores.constructores[constructores.clasificacion[i]].nom << ' ' << constructores.constructores[constructores.clasificacion[i]].puntuacion << endl; i++; } } int buscarConstructor(const tListaConstructores & constructores, tNombreConstructor nomConstructor) { bool encontrado; int i; encontrado = false; i = 0; while(i < constructores.nConstructores && !encontrado) { if(strcmpi(nomConstructor,constructores.constructores[i].nom)== 0) { encontrado = true; } else { i++; } } if (!encontrado) { i = -1; } return i; } void escribirOficiales(const tFormula1 & F1) { int p; tNombreConstructor nomConstructor; cin >> nomConstructor; p = buscarConstructor(F1.constructores, nomConstructor); if(p >= 0) { cout << F1.constructores.constructores[p].nom << ' ' << F1.pilotos.pilotos[F1.constructores.constructores[p].piloto1].nom << ' ' << F1.pilotos.pilotos[F1.constructores.constructores[p].piloto2].nom << ' ' << endl; } } // Descomposición del subprograma tratarOpcion en seis subprogramas más simples // // escribirClasificacionPilotos // ecribirClasificacionConstructores // sustitucion // escribirGPs // escribirOficiales // leerClasificacionGPYActualizarF1 void tratarOpcion(tOpcion opcion, tFormula1 &F1) { if(strcmpi(opcion,"PILOTOS")==0) { escribirClasificacionPilotos(F1); } else if (strcmpi(opcion,"CONSTRUCTORES")==0) { escribirClasificacionConstructores(F1.constructores); } else if (strcmpi(opcion,"SUSTITUCION")==0) { sustitucion(F1); } else if (strcmpi(opcion,"GRANDES_PREMIOS")==0) { escribirGPs(F1.GPs); } else if(strcmpi(opcion,"CLAS_GP")==0) { leerClasificacionGPYActualizarF1(F1); } else if(strcmpi(opcion,"OFICIALES")==0) { escribirOficiales(F1); } } // Función principal del programa en la que se ha // aplicado un esquema de recorrido int main() { tFormula1 F1; tOpcion opcion; inicializar(F1); cin >> opcion; while(strcmpi(opcion,"FIN")!=0) { tratarOpcion(opcion,F1); cin >> opcion; } return 0; }