Expand | |||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||||||||||||||||||||||||||
Oppgave a) - Felt og konstruktører (6 poeng)En Dice-instans skal ha informasjon om (verdien til) et visst antall terninger og en poengverdi (score). Terning-verdiene settes ved initialisering (på ulike måter), mens poengverdien kan settes ved initialisering eller senere. Skriv kode for felt og konstruktører, samt metoden randomDieValuesiht. API-beskrivelsen. Bruk random-metoden i Math-klassen, som er beskrevet som følger: public static double random() Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
Oppgave b) - Dice som tekst (8 poeng)Skriv standardmetodensom brukes for å lage en tekstlig representasjon av et Dice-objekt på formatet som er angitt i API-beskrivelsen. Skriv også valueOf-metoden, som brukes for å lage et nytt Dice-objekt med spesifikke terningverdier og evt. en poengverdi fra en Stringpå samme format.
Formatet er "[t1, t2,... tn]=poeng", hvor t1- tn er terningverdier og poeng er poengverdien. Poeng-delen, altså " =poeng" skal ikke være med hvis poeng er -1 (ennå ikke satt). Eksempel: Hvis et Dice-objekt har terningverdiene 1, 1 og 3 og poengene ikke er satt (= -1), så vil den tekstlige representasjonen være "[1, 1, 3]". Dersom terningene er tre 6-ere som har gitt 600 poeng, så vil teksten være "[6, 6, 6] = 600".
Oppgave c) - Terningverdier (5 poeng)Skriv metodene getDieCount, getDieValue og getValueCount iht. API-beskrivelsen.
Oppgave d) - Poeng (score) (3 poeng)Skriv metodene getScore og setScore iht. API-beskrivelsen.
Oppgave e) - Iterable (3 poeng)Dice-klassen implementerer Iterable<Integer>-grensesnittet. Implementer metoden(e) som da er nødvendig. Skriv også kode som eksemplifiserer hvordan man ved bruk av Dicekan dra nytte av at den implementerer nettopp dette grensesnittet.
Oppgave f) - add og remove (8 poeng)Skriv metodene add og remove, som alle tar et Dice-objekt som eneste argument. Merk at ingen av disse endrer på verken this-objektet eller argumentet, og poengverdien(e) benyttes ikke.
Her er noen eksempler på bruken av disse metodene, hvor tekst-formatet i API-beskrivelsen brukes for å representere Dice-objekter: [1, 2].add([1, 4]) returnerer [1, 2, 1, 4] // merk at rekkefølgen ikke spiller noen rolle [1, 1, 2].remove([1, 4]) gir [1, 2] // merk at rekkefølgen ikke spiller noen rolle Merk at remove ikke har samme logikk som Collectionsin removeAll-metode.
|
Expand | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||
Oppgave a) - Tre eller flere like (6 poeng)Skriv kode for klassen ThreeOrMoreOfAKind (tre eller flere like), som implementerer DiceScorer med følgende logikk: For et Dice-argument uten tre eller flere like returneres null. Ellers returneres et (nytt) Dice-objekt med alle de like terningverdiene, altså tre eller flere like verdier. For tre like får en 100 ganger verdien det er tre eller flere like av, f.eks. 300 poeng for tre 3-ere. For hver ekstra terning med samme verdi så doblespoengene, f.eks. får en 1200 (= 300 * 2 * 2) poeng for fem 3-ere. Merk at hvis en har mange nok terninger, så kan en få tre eller flere like for flere terningverdier. En skal da velge den terningverdien som gir flest poeng. Hvis en f.eks. har terningene [2, 2, 2, 2, 5, 5, 5] så skal en velge de tre 5-erne, siden de gir 500 poeng, mens de fire 2-erne gir bare 400. Hvis flere terningverdier gir samme, høyeste poengverdi, så skal den med flest like terninger velges.
Oppgave b) - Beregning av total poengsum (6 poeng)Hvis en har mange terninger og er heldig, så kan én eller flere DiceScore-regler kombineres flere ganger. En får da summen av poengene som hver bruk av en regel gir. Én terning kan selvsagt ikke være med i mer enn én kombinasjon. Hvis en f.eks. har "tre eller flere like"-regelen implementert av ThreeOrMoreOfAKind-klassen og får fire 3-ere og tre 4-ere så vil en få 600 poeng for 3-erne og 400 poeng for 4-erne og dermed 1000 til sammen. Det blir mer komplisert hvis flere regler "konkurrerer" om de samme terningene. F.eks. vil jo de samme fire 3-ere og tre 4-ere utgjøre hus (to 3-ere og tre 4-ere) og ett par (to 3-ere), hvis tilsvarende poengregler var med. Poengberegningen for et spesifikt spill gjøres generelt som følger:
For eksemplet over, med bare ThreeOrMoreOfAKind-regelen og terningene [1, 3, 3, 3, 3, 4, 4, 4, 5] så vil en få som resultat (en Collection med) Dice-objektene [3, 3, 3, 3] = 600og [4, 4, 4] = 400. To av terningene, 1 og 5, ble i dette tilfellet ikke poenggivende og dermed ikke med i resultatet.
Oppgave c) - Summering med Stream-teknikken (3 poeng)Vis hvordan du kan beregne totalpoengsummen som en Collection av Dice-objekter tilsvarer, vha. Stream-teknikken. Du har altså en Collection av Dice-objekter med poengverdier og skal summere disse poengverdiene: Collection<Dice> diceObjectsWithScore = computeDiceScores(...); int totalPoints = ... compute total points using the Stream technique ...
|
Expand | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||
Det finnes flere måter å implementere Dice-klassen og alle dens metoder, med ulike fordeler og ulemper. En måte å tillate bruk av flere implementasjoner er å gjøre om Dice til et grensesnitt og så ha en eller flere implementasjonsklasser, hvor den eksisterende Dice-klassen blir en av disse: public interface Dice { ... } public class DiceImpl1 implements Dice { ... tilsvarer løsningen i deloppgavene 1-6 ... } public class DiceImpl2 implements Dice { ... alternativ løsning ... }
Navnene på implementasjonsklassene kan selvsagt være mer forklarende. Oppgave a) - Dice-grensesnittet (4 poeng)Dette var en flervalgsoppgave med to spørsmål og valg av ett av flere alternativer.
Spørsmål 1: Tre alternative grensesnitt er foreslått, basert på den nåværende Dice-klassen:
Spørsmål 2: Den opprinnelige Dice-klassen implementerer Iterable<Integer>. Spørsmålet er hvordan dette skal håndteres ved overgangen til et Dice-grensesnitt.
Oppgave b) - Arv (6 poeng)Hvis en har flere implementasjoner av det nye Dice-grensesnittet, så kan en regne med at visse deler av disse vil bli nokså eller helt like. Ett aspekt som typisk vil bli (nokså) likt er håndtering av poengene (score). Forklar med tekst og/eller kode hvordan du vil håndtere det vha. arvingsmekanismen, slik at løsningen tillater stor grad av gjenbruk av kode i subklasser og blir ren og ryddig.
Oppgave c) - Delegering (10 poeng)Dice sin add-metode skal lage en ny Dice-instans (altså instans av en klasse som implementerer Dice) som kombinerer terningverdier fra to andre Dice-instanser (this og argumentet). En kan tenke seg at metoden returnerer en instans av en ny Dice-implementasjon kalt DiceAdder, som bruker delegering. Den vil ha to Dice-felt og en konstruktør som tar inn to Dice-instanser: DiceAdder(Dice dice1, Dice dice2) { ... feltene settes her ... } Hver Dice-metode kan da bruke/delegere til disse to Dice-instansene i sin løsning, f.eks. vil getDieCount() returnere summen av getDieCount() for hver av de to Dice-instansene: public int getDieCount() { return dice1.getDieCount() + dice2.getDieCount(); } Forklar med tekst og/eller kode hvordan delegeringsteknikken vil bli brukt i følgende metoder i en slik DiceAdder-klasse: getDieValue, getValueCount, contains, add og remove. Kommenter spesielt hvis delegeringsteknikken ikke passer for en spesifikk metode!
|
Expand | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||||||||
Oppgave a) - final (2 poeng) Dette var en flervalgsoppgave med ett spørsmål og to korrekte alternativer og ett galt et. Spørsmål: Hvilke, om noen, av feltene øverst i FarkleRound-klassen kan ha modifikatoren final?
Oppgave b) - Kode i bank (2 poeng)Dette er en tekstinnfyllingsoppgave som vurderes automatisk. Spørsmål: Nederst i bank-metoden er en kodelinje erstattet med "... put this object in a state that indicates this round is finished ...". Skriv inn den korrekte kodelinjen. Koden må være korrekt, komplett og konsis, uten kommentarer, siden den sjekkes automatisk.
Oppgave c) - Unntakstyper (3 poeng)Dette er en flervalgsoppgave med tre spørsmål. I keepAndRoll-metoden utløses unntak i tre tilfeller. Spørsmål 1: Hvilken av disse unntakstypene passer i det første tilfellet?
Spørsmål 2: Hvilken av disse unntakstypene passer i det andre tilfellet?
Spørsmål 3: I det tredje tilfellet bruker vi unntakstypen SomeKindOfException, som er tenkt som en egendefinert unntakstype. Hvilken unntakstype bør brukes som superklassen til SomeKindOfException?
Oppgave d) - Kode i keepAndRoll (2 poeng)Nederst i keepAndRoll-metoden er én eller flere kodelinjer erstattet med "... what code needs to be here ? ...". Skrive linjen(e) som mangler. Koden vil bli lest av sensor.
Oppgave e) - FarkleRound-objektdiagram (6 poeng) Underveis i og etter en Farkle-runde vil tilstanden til runden være representert ved hjelp av flere objekter, inkludert et FarkleRound-objekt. Tegn objektdiagram for tilstanden etter runden som er beskrevet i det tredje eksemplet (fremhevet med fet skrift) for Farkle-reglene. Bruk blyantikonet til høyre på verktøylinja for tekstfeltet, for å aktivere tegneverktøyet. Det kan være lurt å kladde på forhånd, siden tegneverktøyet er litt begrenset...
|
Expand | |||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||
Dice-klassen har en konstruktør som initialiserer den med tilfeldige terningverdier, og det gjør den vanskelig å teste, fordi en jo ikke vet hvilke verdier random-metoden genererer. Et alternativ er en konstruktør som henter verdier fra en Supplier<Integer>(se nedenfor). Til vanlig kan en bruke en Supplier-implementasjon som leverer tilfeldige tall vha. Math.random(), mens til testing kan en lage en som gir ut bestemte verdier:
Supplierer deklarert som følger:
Oppgave a) - Funksjonelt grensesnitt (3 poeng) Er DiceScorer et funksjonelt grensesnitt? Forklar hvorfor/hvorfor ikke!
Oppgave b) - Alternativ Dice-konstruktør (3 poeng)Implementer den alternative Dice-konstruktøren.
Oppgave c) - Testing av Dice-klassen (5 poeng)Skriv en eller flere test-metoder for Dice sin valueOf-metode. Du kan anta det finnes en metode kalt assertDieValuessom sjekker terningverdiene til en Dice: assertDieValues(dice, 1, 2, 3) // utløser assert-unntak hvis dice ikke har terningverdiene 1, 2, 3 og bare disse.
|
Expand | |||||||||
---|---|---|---|---|---|---|---|---|---|
| |||||||||
Du skal lage en liten JavaFX-app for terningspill basert på Dice-klassen. I første omgang skal du støtte terningkast og poengberegning:
Følgende FXML er skrevet for appen:
Skriv en JavaFX-kontroller som implementerer ønsket oppførsel. Den skal passe til den oppgitte FXML-en og bruke klasser og metoder beskrevet tidligere i oppgavesettet. Hvis det er detaljer du er usikker på, så forklar med tekstkommentarer i koden.
|