/* uima2.cpp Uimahypyn pistelasku. Huom! Ohjelmassa voi olla "vikoja", joita korjataan tehtavissa. Vesa Lappalainen 25.2.1999 Kaantamista varten projektiin mukaan: uima2.cpp ALI\ioali.c ALI\mjonotpp.cpp (huom. uusi versio 25.2.1999) ALI\mjonot.c ALI\vstring.cpp ( BC 3.1, TC 3.0, huom. uusi versio 25.2.1999 ) Lisaksi tulee omistaa (EI SAA LAITTAA PROJEKTIIN) ALI\ioali.h ALI\mjonotpp.h ALI\mjonot.h (huom. uusi versio 25.2.1999) ALI\vstring (BC 3.1, TC 3.0, nimettyna string) Muutoksia 27.2.1999/vl: - muutettu toimivaksi cNayton kirjoitusvirheiden jalkeen - lisatty cNayttoon toimivia metodeja - lisatty kommentit - cKierros ja cTulos luokista summa attribuutiksi ja se lasketaan automaattisesti aina kun summa voi muuttua - vahan lisaa saanti- ja asetusmetodeja (lahinna luokkiin cUimahyppaja ja cTulos) - etsi -metodi luokkaan cKilpailu ================================================================================ Tehtavia: ================================================================================ Seuraavia tehdessa mikaan olemassa oleva EI saa lakata toimimasta. Vain cNaytto-luokan metodeja saa muuttaa. Muita muutettaessa (julkisia metodeja) pitaa joko kuormittaa (overload) metodeja tekemalla sellaisia, joissa on enemman tai erinimisia parametreja tai kirjoittaa kokonaan uusia metodeja (tietysti oletusarvojen kaytto parametreissa tayttaa taman vaatimuksen) 01) Missa kaikkissa luokissa pitaisi olla destruktori? Toteuta destruktorit! 02) Suunnittele talletusformaatti, jossa yhdessa tiedostossa on kilpailijatiedot ja toisessa tulostiedot (relaatio kilpailijan numeron mukaan ja tietysti kierroksen mukaan) 03) Toteuta talletus ja lukeminen tiedostosta. 04) Muuta tulosten syotto sellaiseksi, etta numeron antamisen jalkeen ennen vaikeusatseen kysymista tulostuu kilpailjan nimi. 05) Muuta tulosten syotto sellaiseksi, etta numeron sijasta voi antaa joko nimen tai numeron. 06) Mieti miten edellisessa kohdassa pitaisi toimia, jos nimi ei olekaan yksikasitteinen. 07) Korjaa Ilmoittautuminen sellaiseksi, etta jos annetulla numerolla jo on kilpailija, niin varoituksessa tulostetana myos kilpailijan nimi. 08) Muuta cTulos-rakennetta siten, etta kierrosmaara on cKilpailun attribuuttina. Samoin tietysti cTuloksessa. Tee cTulokseen dynaaminen kierrosmaara. Tee vastaavasti cKierrokseen dynaaminen tuomarimaara. (Vihje: voit joutua tekemaan uuden konstruktorin cUimahyppaajaan, cTulokseen, ja cKierrokseen). Ratkaisussa Ei ola pakko tehda kayttoliittymaan naiden kysymysta, vaan hyvaksytaan sellainen, missa kierros- ja tuomarimaara annetaan paaohjelmassa cKilpailu-luokan konstruktorin parametreina. Dynaamisuus tarkoitaa tassa sita, etta koko paatetaan luontiaikana, koon ei ole pakko muuttua jalkeenpain. 09) Nyt summa lasketaan aina kun tiedot muuttuvat. Muuta summan lasku sellaiseksi (cKierros ja cTulos) etta on attribuutti laskettu ja kun kaytetaan saantimetodia getSumma(), niin ensin summa lasketaan, jollei sita ole viela laskettu edellisten muutosten jaljilta. Tasta olisi hyotya, jos laskeminen olisi KAUHEAN hidasta ja itse tulosta tarvittaisiin paljon harvemmin kuin siihen vaikuttavia tekijoita muutetaan. 11) Muuta tulostus sellaiseksi, etta tulostetaan vaan siihen kierrokseen saakka, joka on menossa. 12) Lisaa tulostukseen kilpailijoiden lajittelu paremmuusjarjestykseen tuloksen mukaan. 13) Muuta tulosten syotto sellaiseksi, etta jos kilpailijalle on jo annettu kierroksen pisteet, tulee kysymys siita, halutaanko todella antaa uudelleen. 14) Muuta luokassa cKilpailu kilpailjan lisaaminen sellaiseksi, etta jos tila loppuu (max_kilp), niin tilaa tehdaan ensin lisaa ja sitten lisataan (kunnon dynaamisuus) 15) Tee muistinloppumis- yms. virhekasittely try-catch -poikkeuksilla 16) Tee ohjelmaan Windows-kayttoliittyma Borland C++ Builderilla (= cNaytto-luokka kokonaan uusiksi). ================================================================================ Suunnitelma: ================================================================================ Terve.... 0 = lopeta 1 = ilmoittautuminen 2 = valitse kierros 3 = anna pisteita 4 = tulosta 1 Anna kilpailijan nimi >Kalle[ret] Anna numero >5[ret] Anna kilpailijan nimi >Pelle[ret] Anna numero >5[ret] Uikutusta... Anna numero >6[ret] 2 Kierroksen numero >12[ret] uikuruu Kierroksen numero >2[ret] 3 Anna kilpailijan numero>5[ret] Hypyn vaikeusaste >3.5[ret] Anna tuomaripisteet >7 9 4 5.5 6[ret] Anna kilpailijan numero>[ret] 4 ... ================================================================================ Tietorakenne: ================================================================================ cNaytto ------ kilpailu | o-+---> ------ kierros | 2 | | 4 | max_kilp ------ | 2 | lkm | o | hyppaajat |--+-- | v |----| cUimahyppaaja hyppaajat[0] | o-+-------------------->|--------------------------| |----| nro | 5 | hyppaajat[1] | o-+-+ nimi | Kalle | |----| | | |----------------------| | hyppaajat[2] | | | tulos summa | | 110.2 | | |----| | | | |------------------- | | hyppaajat[3] | | | kierros[0]| | | 3.5 | 7 9 4 5.5 6| | | |----| | | | |------------------- | | | kierros[1]| | | 0.0 | 0 0 0 0 0| | | | | | |------------------- | | | kierros[2]| | | 0.0 | 0 0 0 0 0| | | | | | |------------------- | | | | |----------------------| | | |--------------------------| | | | +--------> |--------------------------| | 6 | | Pelle | | |----------------------| | | | 0.0 | | | | |------------------- | | | | | 0.0 | 0 0 0 0 0| | | | | |------------------- | | | | | 0.0 | 0 0 0 0 0| | | | | |------------------- | | | | | 0.0 | 0 0 0 0 0| | | | | |------------------- | | | |----------------------| | |--------------------------| ================================================================================ */ #include #include #include #include #include "ioali.h" #include "mjonotpp.h" using namespace std; //------------------------------------------------------------------------------ // Saadaan %lf kasittely linkitettya mukaan :-( void hopo() { double d; scanf("%lf",&d); } const int TUOMAREITA=5; const int KIERROKSIA=3; class cKierros { double tuomarit[TUOMAREITA]; double vaikeusaste; double summa; double laskeSumma(); public: cKierros(); string getTuomarit() const; string getAsString() const; void setAsString(string &st); void setTuomarit(string &st); double getSumma() const { return summa; } void setVaikeusaste(string &s) { sscanf(s.c_str(),"%lf",&vaikeusaste); laskeSumma(); } }; cKierros::cKierros() { for (int i=0; i= max_kilp ) return "Ei mahdu!"; cUimahyppaaja *uusi = new cUimahyppaaja(u); if ( uusi == NULL ) return "Muisti ei riit„!"; hyppaajat[lkm] = uusi; lkm++; return NULL; } cUimahyppaaja &anna(int n) { if ( n < 0 || lkm <= n ) return vika; return *hyppaajat[n]; } int Kilpailijoita() const { return lkm; } int Kierroksia() const { return KIERROKSIA; } int etsi(int n) const; }; int cKilpailu::etsi(int n) const { for (int i=0; igetNro() == n ) return i; return -1; } //------------------------------------------------------------------------- // cNaytto //------------------------------------------------------------------------- class cNaytto { cKilpailu *kilpailu; int kierros; void ilmoittautuminen(); void anna_pisteita(); void valitse_kierros(); void tulosta() const; public: cNaytto(cKilpailu *k) : kilpailu(k) , kierros(1) {} void lisaa(); void paamenu(); }; void cNaytto::ilmoittautuminen() { string nimi, snro; int nro; while ( 1 ) { lue_jono_oletus("Anna kilpailijan nimi",25,30,"",nimi); if ( nimi == "" ) return; while ( 1 ) { lue_jono_oletus("Anna numero",25,30,"",snro); if ( snro == "" ) return; if ( sscanf(snro.c_str(),"%d",&nro) == 0 ) return; if ( kilpailu->etsi(nro) < 0 ) break; cout << "Kilpailija on jo!\n"; } cUimahyppaaja hyppaaja(nimi,nro); const char *virhe = kilpailu->lisaa(hyppaaja); if ( virhe ) cout << virhe; } } void cNaytto::anna_pisteita() { string st1,st2; int nro; // Hypyn vaikeusaste >3.5[ret] // Anna tuomaripisteet >7 9 4 5.5 6[ret] while ( 1 ) { cout << "Anna kilpailijan numero>"; lue_rivi(cin,nro,0); if ( nro == 0 ) return; int i = kilpailu->etsi(nro); if ( i < 0 ) continue; cout << "Hypyn vaikeusaste >"; lue_rivi(cin,st1); if ( st1 == "" ) return; cout << "Anna tuomaripisteet >"; lue_rivi(cin,st2); if ( st2 == "" ) return; cUimahyppaaja &u = kilpailu->anna(i); u.setVaikeusaste(kierros,st1); u.setTuomarit(kierros,st2); } } void cNaytto::valitse_kierros() { char s[80]; string sk;int k; while ( 1 ) { sprintf(s,"%d",kierros); lue_jono_oletus("Kierroksen numero",0,0,s,sk); if ( sk == "" ) return; sscanf(sk.c_str(),"%d",&k); if ( 1 <= k && k <= kilpailu->Kierroksia() ) { kierros = k; return; } } } void cNaytto::tulosta() const { cout << "----------------------------------\n"; for (int i=0; iKilpailijoita(); i++) { cUimahyppaaja &u = kilpailu->anna(i); cout << setw(3) << u.getNro() << " " << u.getNimi() << ": " << u.getSumma() << "\n"; for (int k=1; k<=kilpailu->Kierroksia(); k++) { cout << " " << setw(2) << k << " " << u.getTulos(k) << "\n"; } } cout << "----------------------------------\n"; } void cNaytto::paamenu() { char painettu; while ( 1 ) { cout << "\n\n"; cout << "Uimahyppykilpailu\n"; cout << "\n"; cout << "Kierros : " << kierros << "\n"; cout << "\n"; cout << "Valitse:\n"; cout << " 0 = lopeta\n"; cout << " 1 = ilmoittautuminen\n"; cout << " 2 = valitse kierros\n"; cout << " 3 = anna pisteita\n"; cout << " 4 = tulosta\n"; cout << ":"; painettu = odota_nappain("01234",'3',MERKKI_ISOKSI); cout << "\n\n"; switch ( painettu ) { case '0' : return; case '1' : ilmoittautuminen(); break; case '2' : valitse_kierros(); break; case '3' : anna_pisteita(); break; case '4' : tulosta(); break; } } } //---------------------------------------------------------------------- // Testipaaohjelmia //---------------------------------------------------------------------- #if 0 int main(void) { cKierros k; cout << k.getTuomarit() << "\n"; cout << k.getAsString() << "\n"; string st1("7 9 4 5.5 6"); k.setTuomarit(st1); cout << k.getTuomarit() << "\n"; string st2("7 9 4 5.5 6 :3.5"); k.setAsString(st2); cout << k.getAsString() << "\n"; return 0; } #endif #if 0 int main(void) { cTulos t; cout << t.getSumma() << "\n"; string st2("7 9 4 5.5 6 :3.5"); t.setAsString(1,st2); cout << t.getSumma() << "\n"; cout << t.getTulos(1) << "\n"; return 0; } #endif #if 0 int main(void) { cUimahyppaaja kalle("Kalle",5); string st1("7 9 4 5.5 6"); string st2("3.5"); kalle.setTuomarit(1,st1); kalle.setVaikeusaste(1,st2); cout << kalle.getTulos(1) << "\n"; return 0; } #endif #if 0 int main(void) { cKilpailu k; cUimahyppaaja kalle("Kalle",5); string st1("7 9 4 5.5 6"); string st2("3.5"); kalle.setTuomarit(1,st1); kalle.setVaikeusaste(1,st2); k.lisaa(kalle); k.lisaa(kalle); cout << k.anna(0).getTulos(1) << "\n"; cout << k.anna(1).getTulos(1) << "\n"; return 0; } #endif #if 1 //---------------------------------------------------------------------- // Varsinainen paaohjelma //---------------------------------------------------------------------- int main(void) { cKilpailu k; cNaytto naytto(&k); naytto.paamenu(); return 0; } #endif