Oblig 2 (INF1000 - H?st 2010)

M?l: Form?let med denne oppgaven er ? gi trening i bruk av forgreninger, l?kker, arrayer, metoder, programmering av kommunikasjon med bruker via terminal, og som ekstraoppgaver filbehanding og utregning med tekster.

Leveringsfrist

Fredag 1. oktober kl 16.00, leveres via dette InnleveringssystemetViktig: Les slutten av oppgaven for detaljerte leveringskrav.

Oppgave

Utenfor kysten av Utopia er det et omr?de med store oljeforekomster under havbunnen, og myndighetene har bestemt seg for ? selge rettighetene til ? utvinne olje til oljeselskaper. Det aktuelle havomr?det er rektangul?rt og er delt opp i et rutenett med 10 x 15 ruter (se figuren under), hvor radene er nummerert fra 0 til 9 og kolonnene er nummerert fra 0 til 14.  Hver rute kalles et utvinningsfelt (eller bare felt).  Hvert felt har et entydig navn p? formen radnr-kolnr hvor radnr er et heltall mellom 0 og 9, og kolnr er et heltall mellom 0 og 14.  For eksempel angir 0-0, 0-1, 0-2, ... 0-14 feltene i ?verste rad (fra venstre mot h?yre) i figuren under.

                                      [Fig. 1: Kart over oljefeltene]

Feltene (eller mer presist utvinningsrettighetene til dem) legges ut for salg enkeltvis.  Det er ingen grenser for hvor mange felt et oljeselskap kan eie, men et felt kan ikke ha mer enn ett oljeselskap som eier (dvs. hvert felt er enten ikke solgt eller det eies av ett oljeselskap).

Myndighetene i Utopia trenger et datasystem for ? administrere oljefeltene.  Oppgaven din er ? programmere dette systemet, som skal kunne holde rede p? hvilke felt som er solgt, til hvilke eiere, og hvor mye olje (m?lt i antall fat) som er utvunnet i hvert felt.  Bruker av systemet tenker vi er en funksjon?r som jobber for myndighetene i Utopia.  N?r et oljeselskap ?nsker ? kj?pe et gitt felt, ringer de funksjon?ren som s? bruker ditt program for ? registrere kj?pet av feltet.  Funksjon?ren skal ogs? kunne f? ut fra programmet en oversikt over feltene med eiere og en del annen nyttig informasjon, som forklart nedenfor.

Programmet skal v?re kommandostyrt: det skal kunne ta imot en kommando fra brukeren, utf?re kommandoen, ta imot en ny kommando, osv., helt til brukeren ?nsker ? avslutte. Mer konkret skal programmet oppf?re seg slik:

Programmet skal gjenta de tre trinnene ovenfor helt til brukeren gir kommando om ? avslutte.  Programmet blir mye ryddigere hvis du lager en egen metode for hver kommando, og derfor er det et krav at din l?sning har minst en metode for hver kommando (unntatt Avslutt-kommandoen).

Kommandoene

Brukeren skal kunne gi seks av disse kommandoene:

1. Kj?p et felt
2. Liste over solgte felt
3. Lag oversiktskart med statistikk
4. Oppdater oljeutvinning
5. Finn raden med h?yest oljeutvinning
6. (Ekstraoppgave): Skriv til fil
7. (Ekstraoppgave): Les fra fil
8. (Ekstraoppgave): Selskap med flest felt  (vanskelig)
0. Avslutt

Kommando 1-5 og 0 er krav, mens 6-8 er valgfrie ekstraoppgaver.  Det anbefales likevel for alle ? l?se nr. 6 og 7 fordi det vil lette arbeidet med oblig 3, som er den st?rste obligatoriske oppgaven i kurset.  Ekstraoppgave 8 er ment for spesielt interesserte.


  1. Kj?p et felt:
    Denne kommandoen vil funksjon?ren gi hvis et oljeselskap ringer og sier at de ?nsker ? kj?pe et felt.  Programmet skal da sp?rre om navnet p? feltet som ?nskes kj?pt og navnet p? oljeselskapet som ?nsker ? kj?pe feltet.  Deretter skal programmet sjekke om feltet er ledig (dvs. ikke har noen eier):

    (a) Hvis feltet er ledig skal programmet registrere at det inntastede oljeselskapet n? eier det aktuelle feltet.  Programmet skal ogs? skrive ut p? skjermen en beskjed om at kj?pet gikk i orden, f.eks.: Felt 3-12 er n? kj?pt av Shell

    (b) Hvis feltet ikke var ledig skal programmet f?rst sjekke om selskapet som eier feltet fra f?r er det samme selskapet som bruker tastet inn.  I s? fall skal programmet skrive en melding om det, f.eks. Oljeselskapet Shell eier allerede felt 3-12!

    (c) Hvis verken (a) eller (b) var tilfelle, s? betyr det at feltet som bruker tastet inn har en annen eier.  Da skal programmet skrive ut n?v?rende eier av feltet og sp?rre bruker om kj?pet virkelig skal gjennomf?res, dvs. om feltet skal overtas av det nye selskapet.  Hvis bruker svarer ja skal kj?pet registreres som i del (a).  Hvis bruker svarer noe annet enn ja skal det gis en melding til bruker om at ingen endring ble registrert.


  2. Liste over solgte felt:
    Programmet skal da g? gjennom alle feltene, og for de feltene som har eier skal programmet skrive ut p? skjermen feltnavnet, navnet p? oljeselskapet som eier det, og antall fat olje som er utvunnet i feltet.  Eksempel p? utskrift:

    Felt 3-12 eies av Shell. Total utvinning i feltet: 0 fat
    Felt 5-6 eies av Esso. Total utvinning i feltet: 80 fat
    Felt 9-0 eies av Shell. Total utvinning i feltet: 50 fat
    


  3. Lag oversiktskart med statistikk:
    Programmet skal da skrive ut p? skjermen et kart hvor feltene er markert med en "." hvis det er ledig og "x" hvis det er solgt (dvs. er kj?pt av et oljeselskap).  Etter at kartet er skrevet ut skal programmet ogs? skrive ut 3 verdier: (a) Antall felt som er solgt; (b) Summen av alle utvinningene i alle felt; og (c) Gjennomsnittlig utvinning, regnet ut som antall fat per solgte felt.  Gjennomsnittet skal avrundes til én desimal.  Her er et eksempel p? hvordan kartet kan se ut:

       0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
    0  x  .  .  .  .  .  .  .  .  .  .  .  .  .  .
    1  .  .  .  x  .  .  .  .  .  .  .  .  .  .  .
    2  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
    3  .  .  .  .  .  .  .  .  .  .  .  .  x  .  .
    4  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
    5  .  .  .  .  .  .  x  .  .  .  .  .  .  .  .
    6  .  .  .  .  x  .  .  .  .  .  .  .  .  .  .
    7  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
    8  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
    9  .  .  .  .  .  .  .  .  .  .  .  .  .  .  x
    
    Antall solgte felt: 6   Total utvinning: 560 fat
    Gjennomsnittlig utvinning: 93.3 fat pr solgte felt
    


  4. Oppdater oljeutvinning:
    Hver sjette m?ned m? oljeselskapene gi beskjed til funksjon?ren om hvor mye olje de har utvunnet p? feltene sine i l?pet av de seks siste m?nedene.  Da bruker funksjon?ren denne kommandoen for ? registrere informasjonen.  Programmet skal g? gjennom feltene som har eier, og sp?rre for hver av disse hvor mye olje som er blitt utvunnet der de siste seks m?nedene, f.eks. slik:

    Antall fat utvunnet i felt 3-12 siste 6 mnd. (tidligere total 0 fat): 0
    Antall fat utvunnet i felt 5-6 siste 6 mnd. (tidligere total 80 fat): 20
    Antall fat utvunnet i felt 9-0 siste 6 mnd. (tidligere total 50 fat): 500
    

    (Tallene som st?r understreket p? slutten av linjene er det som bruker taster inn, alt annet skal programmet ditt skrive ut).  Programmet skal registrere opplysningene som bruker taster inn ved ? summere de nye antall oljefat inn i arrayen som holder dataene om utvinning, f.eks. hvis utvinningen i felt 5-6 var 80 oljefat fra f?r, skal verdien n? bli 100.  S?rg for at l?sningen din i deloppgave 2 ("Liste over solgte felt") benytter seg av disse opplysningene og viser den oppdaterte utvinningen neste gang bruker utf?rer kommando 2.


  5. Finn raden med h?yest oljeutvinning:
    Programmet skal da finne ut og gi en melding til bruker om hvilken rad som har produsert mest olje, dvs. i hvilken rad er summen av utvinningene (for alle felt i raden) h?yest.  Hvis det er flere rader som har det samme maksimale antall utvunnede oljefat er det nok at programmet skriver nummeret p? én av disse radene.  Meldingen til bruker skal vise b?de radnummeret der h?yest sum utvinning ble funnet, og sum utvinning for raden, f.eks. slik:

    Rad med h?yest oljeutvinning: rad 9 (500 fat)
    


  6. (Ekstraoppgave): Skriv til fil:
    Et lite problem med programmet beskrevet ovenfor er at dataene man har registrert mens programmet kj?rer g?r tapt hvis det avsluttes.  Hvis du ?nsker ? fikse dette kan du utvide programmet slik at det tar vare p? dataene ved ? lagre de i en datafil kalt olje.txt n?r brukeren utf?rer kommando "6".  Datafilen kan for eksempel se slik ut:

    3
    0;0;100;Statoil
    1;3;200;BP
    3;12;50;Shell
    

    I dette eksemplet betyr tallet 3 p? f?rste linje at det er 3 felt som er solgt, og at det dermed ogs? er 3 linjer til i datafilen, med informasjon om disse solgte felt.  Neste linje betyr at Statoil eier felt 0-0 og har utvunnet 100 fat olje der; neste linje angir at BP eier felt 1-3 og har utvunnet 200 fat olje p? det feltet, osv. Husk ? lukke fila med fil.close();


  7. (Ekstraoppgave): Les fra fil:
    Denne oppgaven er ogs? valgfri, og g?r ut p? ? lese datafilen som blir opprettet i foreg?ende oppgave ("Skriv til fil").  Vi tenker oss at man utf?rer denne kommandoen n?r man starter programmet, for ? hente inn dataene som ble lagret i filen olje.txt forrige gang man kj?rte programmet.  Derfor er det greit om du bare overskriver dataene i arrayene med dataene som leses fra fil.  (Men hvis du vil gj?re det annerledes er det ogs? greit, ekstraoppgavene st?r man fritt til ? l?se som man vil.)


  8. (Ekstraoppgave): Selskap med flest felt:  (Vanskelig!)
    Den som vil ha en st?rre utfordring kan bryne seg p? denne ekstraoppgaven: Finn selskapet som har kj?pt flest felt.


  9. Avslutt.
    Programmet skal da avslutte.

Kj?reeksempel

Nedenfor ser du et eksempel p? en kj?ring av programmet.  Bruker-input er markert med understreking.  Dette kj?reeksemplet er bare ment ? illustrere hvordan kommunikasjonen med bruker kan foreg?; dersom du ?nsker ? presentere menyen eller andre ting annerledes, s? kan du gj?re det.


> java Oblig2
*** Utopias Oljefeltadministrasjon ***
Meny:
 1. Kj?p et felt
 2. Liste over solgte felt
 3. Lag oversiktskart med statistikk
 4. Oppdater oljeutvinning
 5. Finn raden med h?yest oljeutvinning
 0. Avslutt
Velg kommando: 1

** Kj?p et felt **
Felt som ?nskes kj?pt: 3-6
Oljeselskapets navn: Statoil
Felt 3-6 er n? kj?pt av Statoil

Meny:
 1. Kj?p et felt
 2. Liste over solgte felt
 3. Lag oversiktskart med statistikk
 4. Oppdater oljeutvinning
 5. Finn raden med h?yest oljeutvinning
 0. Avslutt
Velg kommando: 2

** Liste over solgte felt **
Felt 3-6 eies av Statoil. Total utvinning i feltet: 0 fat

...osv...

Hint

Disse hint er bare for de som ?nsker litt ekstra-hjelp. Du trenger ikke lese dette avsnittet for ? l?se obligen, men alle m? lese siste avsnitt om Leveringskrav.  Det kan ogs? bli lagt ut flere ekstra-hint senere.

  1. Generelle tips: Et godt sted ? starte kan v?re ? f? kommandol?kken til ? fungere.  S?rg for at programmet klarer ? lese inn kommandoer fra tastatur og vise menyen.  Deretter g?r du videre og programmerer de enkelte kommandoene, i vilk?rlig rekkef?lge.  N?r du skriver programmet anbefales det at du kompilerer og pr?vekj?rer det ofte underveis, da unng?r du at det samler seg mange feil som blir vanskeligere ? rette samlet etterp?.  Husk at det er et krav at du lager minst én metode for hver kommando (unntatt Avslutt).

    Hvis noe er uklart i oppgaveteksten kan du gj?re egne forutsetninger, men s?rg for ? beskrive disse ved hjelp av Java-kommentarer i programmet.  Det er lov ? utvide funksjonaliteten eller gj?re programmet mer brukervennlig, men retter m? fortsatt kunne taste inn kommando 1-5 som tall, og basis-funksjonaliteten til disse skal v?re som forklart ovenfor.


  2. Arrayene: For hvert felt er det to opplysninger som skal tas vare p?: (1) navnet p? oljeselskapet som eier det; og (2) hvor mye olje som er utvunnet i feltet.  Du kan bruke to to-dimensjonale arrayer til ? lagre disse opplysningene:

    String[][] eier = new String[10][15];
    int[][] utvunnet = new int[10][15];
    

    Da vil f.eks. eier[1][3] inneholde navnet p? oljeselskapet som eier felt 1-3; og utvunnet[1][3] vil v?re antall fat olje som er utvunnet i det feltet.  Det finnes ogs? andre m?ter ? l?se oppgaven p?, bl.a. kunne vi klart oss med bare én to-dimensjonal array med pekere til objekter av en klasse som vi selv lager, men denne teknikken gjennomg?s senere i kurset og b?r ikke anvendes i denne oppgaven.


  3. Kj?p et felt:  N?r programmet skal lese inn navnet p? feltet som skal kj?pes, m? du trekke ut radnummeret og kolonnenummeret fra feltnavnet.  Hvis f.eks. brukeren skriver 3-6 s? m? du alts? "f? tak i" tallene 3 og 6 for ? kunne lagre navnet p? oljeselskapet i eier-arrayen. Dette kan gj?res p? flere m?ter; en av dem er ? bruke setningene:

    int radnr = tast.inInt("-\n\r ");
    int kolnr = tast.inInt("-\n\r ");
    

    Her er det en variant av inInt() som brukes.  Det som st?r i anf?rselstegn er de tegnene som skal betraktes som skilletegn - alts? de tegnene som inInt() skal se p? som "blanke tegn" f?r og etter tallene.  De spesielle skilletegnene linjeskift ("\n") og vognretur ("\r") er ikke n?dvendige ? angi som skilletegn, siden de alltid betraktes som skilletegn i easyIO, men kan godt v?re med som vist ovenfor.  Mellomroms-tegnet kan tas med inne i anf?rselstegnene for ? gj?re programmet mer brukervennlig (da vil programmet ogs? godta at bruker taster inn "3 - 6" eller t.o.m. "3 6" som feltnavn).

    I del (a) m? programmet ha en m?te ? finne ut om et felt er solgt eller ikke.  En enkel m?te ? finne ut om f.eks. felt 3-6 er solgt er ? se om eier[3][6] er satt til et navn eller ikke.  Rett etter at 2D-arrayen eier er deklarert er alle verdiene i arrayen lik den spesielle verdien null, og du kan derfor sjekke om 3-6 er ledig ved ? teste om eier[3][6] == null.

    I del (b) skal du sammenligne tekst-verdier med hverandre og finne ut om de er like.  Vanligvis bruker man "==" i Java for ? teste om to verdier er like, men dette fungerer p? en litt annen m?te med tekst-verdier.  For ? sjekke om to tekster er like bruker man i stedet metoden .equals(), slik: "if (tekst1.equals(tekst2)) {...".  Dette tester om innholdet i to tekst-pekerne er likt.  Mer om dette kan du lese i avsnitt 6.4.1 p? side 105 i l?reboka.  Ved sammenligning av en tekst mot den spesielle verdien null derimot, s? skal man bruke "==" (eller "!="), se (a) ovenfor.

    I del (c) trenger du et ja/nei-sp?rsm?l.  Det kan programmeres p? mange m?ter, f.eks. vha. en inWord()-setning som leser inn "ja" eller "nei" fra bruker, eller vha. inChar("\n ") og betrakte 'j' som ja-svaret, og alt annet som nei.


  4. Liste over solgte felt:  Denne listen er nyttig for ? sjekke at de andre deloppgavene fungerer, og kan programmeres f.eks. rett etter at del (a) av "Kj?p et felt" er gjort.  For ? forenkle arbeidet kan du f?rst programmere utskriften til ? bare vise 0 som utvinning i alle feil, og s?, n?r du har programmert deloppgave 4 ("Oppdater oljeutvinning") legger du til visning av riktig utvinning for feltene.


  5. Lag oversiktskart med statistikk:  Denne oppgaven kan l?ses p? mange m?ter.  Det enkleste er kanskje ? programmere kartet alene f?rst, og s? n?r du har gjort det, kan du legge inn i samme kode som tegner kartet en teller-variabel som holder rede p? hvor mange "x"-er det var, og til slutt legger du til summering av oljeutvinningene.


  6. Oppdater oljeutvinning:  Husk at du i denne oppgaven skal addere den innleste verdien til den verdien som allerede er registrert i systemet, ikke bare erstatte verdien med den nye som bruker tastet inn.  Verdien som lagres i arrayen skal alts? v?re det totale antall fat olje som er utvunnet i feltet.


  7. Finn raden med h?yest oljeutvinning:  Finn helst din egen m?te ? l?se denne deloppgaven p?!  Hvis du st?r helt fast s? er to mulige m?ter ? l?se deloppgaven p?: (1) ? f?rst lage en éndimensjonal tilleggs-array der du lagrer summene for radene.  (2) En annen l?sning er ? l?pe gjennom feltene vha. to nestede l?kker og hele tiden under gjennoml?pene holde rede p? sum utvinning i n?v?rende rad, maksimal radsum funnet s? langt, og radnummer der sistnevnte ble funnet.


  8. (Ekstraoppgave): Les fra fil:  N?r du begynner ? programmere lesing av datafilen b?r du legge inn testutskrifter som skriver ut p? skjermen det som faktisk blir lest fra filen, slik at du kan kontrollere at datafilen blir lest riktig.  Dette kan du gj?re f.eks. ved ? bruke f?lgende to programsetninger i stedet for bare ? lese dataene fra fil med int x = fil.inInt(" ;"); 

    int x = fil.inInt(" ;");  skjerm.outln("x=" + x);
    


  9. Programstruktur:  Nedenfor er det en programskisse du kan bruke som utgangspunkt.  Du beh?ver ikke ? f?lge det, men dette er i alle fall et forslag til en ryddig start p? programmet.  Hvis du f?lger denne skissen s? trenger du ikke endre noe i den f?rste klassen (class Oblig2), det er nok at du gj?r alle endringene dine i klassen Olje.  Det vil ogs? bli lagt ut et forslag til prekode i bloggen som ikke benytter easyIO.

    import easyIO.*;
    // Her kan du skrive evt. kommentarer om besvarelsen din.
    
    class Oblig2 {
        public static void main(String[] args) {
            System.out.println("*** Utopias Oljefeltadministrasjon ***");
            Olje ol = new Olje();
            ol.kommandolokke(); // Kj?rer metoden kommandolokke() i klassen Olje.
            System.out.println("-- Programmet avslutter --");
        }
    }
    
    class Olje {
        // Klargj?r for innlesing/utskrift med easyIO, gjelder for hele klassen:
        In tast = new In();
        Out skjerm = new Out();
    
        // Her kan du deklarere arrayene eier[][] og utvunnet[][]:
        // ...
    
        // Metoden "kommandolokke()": Tar imot kommandoer fra bruker og utf?rer disse.
        void kommandolokke() {
            int kommando = -1; // Tilfeldig startverdi.
    
            while (kommando != 0) {
    
                // Legg her setninger som skriver ut menyen, f.eks. linjer med
                // println eller skjerm.outln(), eller kall p? en egen metode.
                System.out.println(" 1. Kj?p et felt");
    
                // Her kan du skrive ut en ledetekst, f.eks. "Velg kommando: "
                // ...
                // Og s? leser du input som bruker taster inn:
                kommando = 0;  // (Erstatt 0 med kode som leser fra tastatur.)
    
                switch (kommando) {
                    case 1: kjopEtFelt(); break;
                    case 2: listeOverSolgteFelt(); break;
                    case 3: lagOversiktskartMedStatistikk(); break;
                    // ... fyll inn case-er for de to andre kommandoene her.
    
                    default: break;
                }
            }
        }
    
        // Metoder for hver kommando:
    
        void kjopEtFelt() {
            // Programmér kj?p av felt her:
    
            // - Be bruker taste inn rad-kol., og oljeselskap.
    
            // - Sjekk om arrayen eier[][] allerede har et oljeselskap i den
            //   angitte rad-kol.:  (a) Hvis ikke => registrér kj?pet, osv...
    
        }
    
        void listeOverSolgteFelt() {
            // Programmér kj?p av felt her:
    
        }
    
        void lagOversiktskartMedStatistikk() {
    
        }
    
        // ...osv... (minst 2 metoder til)
    }
    

Leveringskrav

Du skal bare levere én fil, som m? ha filendelsen ".java" (alts? ikke .tgz eller noe annet), og filnavnet b?r v?re Oblig2.java.  Java-n?kkelordet "package" skal ikke brukes i programmet.  Hvis du bruker norske bokstaver (???) i filen b?r tegnsettet ("encoding") til filen v?re utf-8 eller iso-8859-1.  Tips om dette kan du finne i bloggen

Hvis du har kommentarer til gruppel?rer ang?ende besvarelsen din, f.eks. de som nevnes i f?lgende avsnitt, s? skriver du disse i en Java-kommentar ?verst i programmet f?r du leverer.  Det er lov ? levere flere utgaver av besvarelsen din, det er bare den siste du leverer innen fristen som blir rettet.  Husk ? velge oblignummer 2 i innleveringssystemet i alle innleveringer du gj?r av oblig 2.

Du kan diskutere med andre studenter hvordan dere skal l?se oppgavene, men det er ikke lov ? kopiere noe Java-kode fra dem, selv om du endrer p? koden etterp?, og det er heller ikke lov ? hente programbiter fra andre besvarelser, for eksempel fra Internet. Hver student skal skrive sitt eget program. Dette er n?rmere forklart i følgende krav til innleverte oppgaver ved Ifi, som du plikter ? ha lest og forstått f?r du leverer din besvarelse:

Alle innleveringer vil bli kontrollert med Joly-algoritmen, s? hvis du 澳门葡京手机版app下载et mye med andre eller hentet mye hjelp fra andre kilder enn l?reb?ker, websidene til kurset, eller gruppel?rere, b?r du nevne disse kildene i besvarelsen din og hvilke deler av programmet det gjelder, som forklart i lenken ovenfor.

Tilbakemelding p? obligen din vil du f? via e-post og Godkjentsystemet wwws.ifi.uio.no innen to uker etter leveringsfristen.  Mer informasjon om tilbakemelding og prosedyrer rundt innlevering kan du finne i Reglement for obligatoriske oppgaver ved Ifi.  Hvis du skal levere forbedret utgave av obligen etter fristen, s? skal du fortsatt bruke samme innleveringssystem og velge oblignummer 2 der.

Hvis du har sp?rsm?l, kommmentarer, eller finner feil i oppgaveteksten kan du skrive disse i kurs-bloggen.

Lykke til!