Oblig 2 (INF1000 - V?r 2010)

M?l: Form?let med denne oppgaven er ? gi trening i bruk av forgreninger, l?kker, arrayer, og metoder, samt trening i ? programmere kommunikasjon med bruker via terminal.

Leveringsfrist

Fredag 5. mars kl 16.00, leveres via JolyViktig: 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.

kolonnenummer
radnr.
   0  1  2  3  4  5  6  7  8  9  10  11  12  13  14
     

Feltene (eller mer presist: utvinningsrettighetene til dem) legges ut for salg enkeltvis.  Det er ingen grenser for hvor mange felter 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 som kan holde rede p? hvilke felter som er solgt, til hvilke eiere.  Systemet skal ogs? holde rede p? hvor mye olje (m?lt i antall fat) som er utvunnet i hvert felt.  Bruker av systemet skal v?re 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 andre ting (se under).

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 sett fra brukerens side:

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.  Brukeren skal kunne gi f?lgende 6 kommandoer:

  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 f?rst sp?rre om navnet p? feltet som ?nskes kj?pt og navnet p? det 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 at kj?pet gikk i orden, f.eks. med en utskrift som dette: 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 felt 3-12 fra f?r!

    (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 svarte 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 og navnet p? oljeselskapet som eier det.  Listen skal ogs? vise antall fat olje som er utvunnet i feltet (se deloppgave 4, "Oppdater oljeutvinning").  Du kan anta at antall fat utvunnet olje er et heltall og at det kan representeres med en int-variabel.  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: 100 fat
       Felt 9-0 eies av Shell. Total utvinning i feltet: 500 fat
    
    Du avgj?r selv i hvilken rekkef?lge programmet skal g? gjennom feltene for ? skrive ut informasjon om de som har eier (f.eks. rad for rad fra toppen og ned).

  3. Lag oversiktskart med statistikk:
    Programmet skal da skrive ut p? skjermen et kart hvor hvert felt 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 ditt skrive ut en linje som sier hvor mange felt som var solgt og hvilken andel av feltene det tilsvarer i prosent.  Prosentandelen skal avrundes til én desimal.  Her er et eksempel p? hvordan kartet kan se ut: her er det 7 "x"-er slik at statistikken blir 7 solgte felt (4.7% av feltene).

        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  .  .  .  .  .  .  .  .  .  .  .  .  .  x
    
       Antall solgte felt: 7  (4.7% av feltene)
    
  4. Oppdater oljeutvinning:
    Hver sjette m?ned m? oljeselskapene ringe til funksjon?ren og fortelle 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 alle disse hvor mye olje som er blitt utvunnet der de siste seks m?nedene (m?lt i antall fat), f.eks. slik:
       Antall fat utvunnet i felt 3-12 (Shell) siste 6 mnd.: 0
       Antall fat utvunnet i felt 5-6 (Esso) siste 6 mnd.: 20
       Antall fat utvunnet i felt 9-0 (Shell) siste 6 mnd.: 500
    
    (Tallet p? slutten av hver linje er det som bruker taster inn).  Programmet skal registrere disse opplysningene 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 om utvinning, og viser den oppdaterte utvinningen for hvert felt n?r 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. Avslutt.
    Programmet skal da avslutte. Det er ikke meningen at programmet skal ta vare p? (skrive til fil) de dataene som er registrert av funksjon?ren.
Nedenfor ser du et eksempel p? starten av 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
 6. Avslutt
Velg kommando: 1

** Kj?p et felt **
Oppgi feltet som ?nskes kj?pt: 3-6
Oppgi 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
 6. Avslutt
Velg kommando: 2

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

.... osv ....

Tips og forutsetninger som kan gj?res
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[0][3] inneholde navnet p? oljeselskapet som eier felt 0-3; og utvunnet[0][3] vil v?re antall fat olje som er utvunnet i det feltet (sistnevnte array kunne ogs? v?rt deklarert som en double-array - her st?r du fritt til ? velge).  Det finnes 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.

Programstruktur:
Nedenfor er det en programskisse du kan bruke som utgangspunkt (du beh?ver ikke ? f?lge det, men det er i alle fall et forslag til en ryddig start p? programmet ditt).  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.


import easyIO.*;

class Oblig2 {
    public static void main(String[] args) {
        Olje ol = new Olje();
        ol.kommandol?kke(); // Kj?rer metoden kommandol?kke i klassen Olje
        System.out.println("-- Programmet avslutter --");
    }
}

class Olje {
    // Klargj?ring for innlesing/utskrift, gjelder for hele klassen:
    In tast = new In();
    Out skjerm = new Out();

    // Her kan du deklarere arrayene eier[][] og utvunnet[][]:
    // ...

    // Metoden "kommandol?kke()":
    // Denne er den f?rste metoden i klassen Olje som blir utf?rt.
    void kommandol?kke() {
        int kommando = 0;

        while (kommando != 6) {

            // 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. Liste over solgte felt");

            // Her kan du skrive ut en ledetekst, f.eks. "Velg kommando: "
            // ...
            // Og s? leser du input som bruker taster inn:
            kommando = 6;  // (Erstatt 6 med kode som leser fra tastatur.)

            switch (kommando) {
                case 1: kj?pEtFelt(); break;
                case 2: listeOverSolgteFelt(); break;
                case 3: lagOversiktskartMedStatistikk(); break;
                // ... fyll inn case-er for de to andre kommandoene her.

                default: break;
            }
        }
    }

    // De andre metodene: (en for hver kommando)

    void kj?pEtFelt() {
        // Programmér kj?p av felt her:

        // - Be bruker taste inn rad-kol., og oljeselskap.

        // - Test om arrayen eier[][] allerede har et oljeselskap i den
        //   angitte rad-kol.:  (a) Hvis ikke => registrér kj?pet, osv...

    }

    void listeOverSolgteFelt() {

    }

    void lagOversiktskartMedStatistikk() {

    }

    // ...Osv. (2 metoder til)
}

Her er noen tips og kommentarer til de forskjellige kommandoene:

  1. 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 siden du trenger disse n?r du skal sette inn 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 ? ta med blant skilletegnene, men kan godt v?re med som vist ovenfor.  Mellomroms-tegnet derimot m? tas med inne i anf?rselstegnene hvis man vil at det skal betraktes som skilletegn (f.eks. hvis du vil godta at bruker taster inn "3 - 6" eller "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 kan i noen tilfeller gi et annen resultat enn ventet n?r det som sammenlignes er to tekster (?rsaken til dette kommer vi tilbake til senere i kurset).  For ? teste om to tekster er like skal man i stedet bruke metoden .equals(), slik: "if (tekst1.equals(tekst2))".  Dette tester om innholdet i de 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.

  2. 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 "utvinning: 0 fat" p? hver linje; og s?, n?r du har programmert deloppgave 4 ("Oppdater oljeutvinning") utvider du listen til ? vise riktig utvinning for feltene.

  3. 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" det var.

  4. 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.

  5. 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.

Du kan gj?re egne forutsetninger etter behov s? lenge disse ikke er i strid med oppgaven, men s?rg for ? kommentere disse i programmet.  Et tips: S?rg f?rst for ? f? kommandol?kken til ? fungere, dvs. s?rg for at programmet klarer ? lese inn de lovlige kommandoene fra tastatur p? korrekt m?te.  Deretter g?r du videre og programmere de enkelte kommandoene (i vilk?rlig rekkef?lge).  Det er et krav at du lager minst en metode for hver kommando (unntatt Avslutt).

Husk ? kompilere og teste programmet ditt ofte mens du skriver det! (hvis ikke s? kan det samle seg mange feil som blir vanskeligere ? rette etterp?).

Leveringskrav
Du skal levere en egenprogrammert løsning (det er f.eks. ikke lov å "låne" programbiter av andre studenter eller å hente programbiter fra Internet), og du plikter å ha lest og forstått følgende krav til innleverte oppgaver ved Institutt for informatikk:

Oppgaven (.java-filen) skal leveres elektronisk i Joly-systemet: Tilbakemelding blir gitt via e-post og godkjentsystemet (wwws.ifi.uio.no) innen to uker etter leveringsfristen.  Mer informasjon om tilbakemelding og prosedyrer rundt innlevering kan du lese i Reglement for obligatoriske oppgaver ved Ifi.

Lykke til!