/**************/ /* laskuri3.c */ /****************************************************************************/ /* ** Ohjelma, jolla voidaan laskea autojen lukum„„ri„. ** ** Toimii sellaisenaan vain mik„li kirjastosta l”ytyy ** funktiot: getch, clrscr, gotoxy, textcolor, textbackground, cprintf ** ** N„ytt” muutettu graafisemman n„k”iseksi ja n„yt”n osien ** hallintaa on parannettu. ** N„pp„imet ja laskurit ovat taulukoissa, jotka loppuvat loppu ** n„pp„imeen ja laskuriin (tunnus, yleens„ 0). ** ** Vesa Lappalainen ** 31.7.1992 ** ** Teht„vi„: 1) Lis„„ ohjelmaan polkupy”rien laskeminen. ** Moneenko kohtaan tulee muutos? ** 2) Lis„„ ohjelmaan lis„n„pp„imet + ja - joiden painamisen ** j„lkeen vastaavasti K:lla ja H:lla joko lis„t„„n tai ** v„hennet„„n. ** Tulosta jonnekin kohti n„ytt”„ se, kumpiko tila (+ vai -) on ** menossa! ** 3) Muuta m„„rityksi„ siten, ett„ kullekin n„pp„imelle ja ** laskurille ja niiden sisustoille voidaan antaa sek„ ** taustan, ett„ tekstin v„ri erikseen. ** ** */ /****************************************************************************/ #include #include #include #include #include #define MIN_X 1 /* N„yt”n koko */ #define MIN_Y 1 #define MAX_X 80 #define MAX_Y 25 /****************************************************************************/ /* Yleiset tyypit: */ typedef struct { int x; int y; } koord_tyyppi; typedef struct { koord_tyyppi vasen_yla; /* Laatikon vasemman yl„kulman koordinaatit */ koord_tyyppi koko; /* Laatikon sis„koko. Jos (0,0) niin pienin mah.*/ } laatikko_tyyppi; /* Jos <0, niin ei raameja */ typedef struct { /* Tyyppi n„pp„imelle: */ char valinta_kirjain; /* Kirjain, jota painamalla komento tot. */ char *teksti; /* N„pp„imeen tulostettava teksti. */ laatikko_tyyppi nappain; /* N„pp„imen sijainti ja koko */ int komento; /* Mik„ komento n„pp„imell„ tehd„„n. */ int lisa_viesti; /* Jos halutaan v„litt„„ jokin lis„tieto */ } nappain_tyyppi; /* esim. numeron„pp„imen arvo tms. */ typedef struct { /* Tyypit laskurin„yt”ille: */ int tunnus; /* Laskurin tunniste */ int arvo; /* Laskurin nykyinen arvo */ char *format; /* Tulostuksen formaatti C-muodossa */ laatikko_tyyppi tila; /* Laskurin tulostusalueen paikka ja koko*/ } laskuri_tyyppi; /****************************************************************************/ /* Globaalit n„pp„imet: */ typedef enum { /* Tunnetut komennot: */ TYHJA, /* Lopun tunniste */ POISTU, NOLLAA, LISAA } komento_tyyppi; typedef enum { /* K„ytetyt laskurityypit ja niiden tunnisteet */ TYHJA_LASKURI, /* Lopun tunniste */ HENKILOAUTOJA, KUORMA_AUTOJA } laskuri_tunniste_tyyppi; nappain_tyyppi nappaimet[] = { /* x y lev kork */ { 'X',"eXit" ,{{ 2, 2},{ 0, 0}}, POISTU , 0 }, { 'N',"Nollaa" ,{{30,13},{ 0, 0}}, NOLLAA , 0 }, { 'H',"Henkil”autoja" ,{{13, 5},{ 0, 0}}, LISAA , HENKILOAUTOJA }, { 'K',"Kuorma-autoja" ,{{38, 5},{ 0, 0}}, LISAA , KUORMA_AUTOJA }, { 0 ,NULL ,{{ 0, 0},{ 0, 0}}, TYHJA , 0 } }; /****************************************************************************/ /* Globaalit laskurit: */ laskuri_tyyppi laskurit[] = { /* x y lev kork */ { HENKILOAUTOJA, 0 , "%19d ",{{10, 8},{20, 1}} }, { KUORMA_AUTOJA, 0 , "%19d ",{{35, 8},{20, 1}} }, { TYHJA_LASKURI, 0 , NULL ,{{ 0, 0},{ 0, 0}} } }; /****************************************************************************/ komento_tyyppi lue_komento( /* */ nappain_tyyppi *nappaimet, int *lisa ) /* ** Funktio palauttaa valitun komennon tunnuksen ja mahdollisen lis„viestin. ** Funktiosta palataan vasta kun oikeata n„pp„int„ on painettu. */ { /* Seuraava toimii mm. Turbo C:ss„: */ char c; int i; *lisa = 0; while (1) { c = toupper(getch()); for (i=0; nappaimet[i].valinta_kirjain; i++) if ( nappaimet[i].valinta_kirjain == c ) { *lisa = nappaimet[i].lisa_viesti; return nappaimet[i].komento; } } } /****************************************************************************/ void piirra_laatikko(laatikko_tyyppi *tila, int oletus_lev) /* ** Oletusleveytt„ ja korkeutta 1 k„ytet„„n, mik„li niit„ ei ole ** m„„r„tty tila-tietueessa (koko.x == 0 ja/ta koko.y == 0) ** Luotetaan siihen, ettei yksikaan laatikko ole nayton ulkopuolella ** tai aivan oikeassa reunassa */ { int i,x,y,x_lev,y_kork; x = tila->vasen_yla.x; y = tila->vasen_yla.y; x_lev = tila->koko.x; y_kork = tila->koko.y; if ( x_lev == 0 ) { x_lev = oletus_lev; tila->koko.x = x_lev; } if ( y_kork == 0 ) { y_kork = 1; tila->koko.y = y_kork; } if ( ( x_lev < 0 ) || ( y_kork < 0 ) ) return; /*----------------------------------------------------------------*/ /* Yl„viiva: ------------------------------------------------- */ if ( ( x > MIN_X ) && ( y > MIN_Y ) ) { gotoxy(x-1,y-1); cprintf("Ú"); /* vasen yl„kulma */ } if ( y > MIN_Y ) for (i=x; i<=min(x+x_lev-1,MAX_X); i++) { gotoxy(i,y-1); cprintf("Ä"); /* yl„viiva */ } if ( ( x+x_lev <= MAX_X ) && ( y > MIN_Y ) ) { gotoxy(x+x_lev,y-1); cprintf("¿"); /* oikea yl„kulma */ } /*----------------------------------------------------------------*/ /* Keskiviivat: | | */ for (i=y; i<=min(y+y_kork-1,MAX_Y); i++) { if ( x > MIN_X ) { gotoxy(x-1,i); cprintf("³"); /* vasen tolppa */ } if ( x+x_lev <= MAX_X ) { gotoxy(x+x_lev,i); cprintf("³"); /* oikea tolppa */ } } /*----------------------------------------------------------------*/ /* Alaviiva: ------------------------------------------------- */ y = y+y_kork; if ( ( x > MIN_X ) && ( y <= MAX_Y ) ) { gotoxy(x-1,y); cprintf("À"); /* vasen alakulma */ } if ( y <= MAX_Y ) for (i=x; i<=min(x+x_lev-1,MAX_X); i++) { gotoxy(i,y); cprintf("Ä"); /* alaviiva */ } if ( ( x+x_lev <= MAX_X ) && ( y <= MAX_Y ) ) { gotoxy(x+x_lev,y); cprintf("Ù"); /* oikea alakulma */ } } /****************************************************************************/ void nayta_laskuri(laskuri_tyyppi *laskuri) { textcolor(BLACK); textbackground(CYAN); gotoxy(laskuri->tila.vasen_yla.x,laskuri->tila.vasen_yla.y); cprintf(laskuri->format,laskuri->arvo); } /****************************************************************************/ void nollaa_laskurit(laskuri_tyyppi *laskurit) { int i; for (i=0; laskurit[i].tunnus != TYHJA_LASKURI; i++) { laskurit[i].arvo=0; nayta_laskuri(&laskurit[i]); } } /****************************************************************************/ void lisaa_laskuria(laskuri_tyyppi *laskurit,int tunnus) { int i; for (i=0; laskurit[i].tunnus != TYHJA_LASKURI; i++) { /* Ets. laskuri */ if ( laskurit[i].tunnus == tunnus ) { laskurit[i].arvo++; nayta_laskuri(&laskurit[i]); return; } } } /****************************************************************************/ void piirra_naytto(nappain_tyyppi *nappaimet,laskuri_tyyppi *laskurit) { int i; textcolor(WHITE); textbackground(WHITE); clrscr(); textcolor(BLACK); textbackground(YELLOW); for (i=0; nappaimet[i].valinta_kirjain; i++) { piirra_laatikko(&nappaimet[i].nappain,strlen(nappaimet[i].teksti)); gotoxy(nappaimet[i].nappain.vasen_yla.x,nappaimet[i].nappain.vasen_yla.y); cprintf(nappaimet[i].teksti); } textcolor(BLUE); textbackground(CYAN); for (i=0; laskurit[i].tunnus != TYHJA_LASKURI; i++) { piirra_laatikko(&laskurit[i].tila,1); nayta_laskuri(&laskurit[i]); } } /****************************************************************************/ int laske(nappain_tyyppi *nappaimet,laskuri_tyyppi *laskurit) { komento_tyyppi komento; int lisa_viesti; while (1) { komento = lue_komento(nappaimet,&lisa_viesti); switch (komento) { case LISAA : lisaa_laskuria(laskurit,lisa_viesti); break; case NOLLAA : nollaa_laskurit(laskurit); break; case POISTU : return 0; } } } /****************************************************************************/ int main(void) { piirra_naytto(nappaimet,laskurit); laske(nappaimet,laskurit); return 0; }