Spelet avslutas efter en hel omgång där någon nått minst 100 poäng. Högst poäng vinner; delad högsta poäng ger oavgjort. Det krävs minst en spelare och minst en tärning per bägare.
Nyckelord: Klasser, Objekt
I denna uppgift ska vi skapa flera klasser som samverkar med varandra för att skapa ett spel. Spelet går ut på att ett godtyckligt antal spelare kastar en bägare med tärningar. Efter en hel omgång där någon nått minst 100 poäng avslutas spelet. Högst poäng vinner; delad högsta poäng ger oavgjort.
Utgå från följande program:
public class KlasserObjektUppgift2 {
public static void main(String[] args) {
// Skriv din kod här
}
}
Uppgift a - Skapa klassen Dice
Skapa först en ny klass Dice. Klassen Dice är en tärning som har två instansvariabler. Ena variabeln är en int som anger antal sidor som tärningen har. Den andra variabeln är också en int och håller värdet på det senaste kastet som tärningen hade.
Skapa klassen Dice enligt ovanstående specifikation. Klassen ska ha en getter till varje instansvariabel som returnerar motsvarande värde. Klassen ska även ha en metod rollDice() som "kastar" tärningen slumpmässigt efter hur många sidor tärningen har. När kastet har gjorts ska instansvariabeln uppdateras därefter.
Ledtråd a
Använd klassen Random för att generera ett slumptal. Kommer du inte ihåg hur man skapar en ny klass? Spana in avsnittet konstruktorn i Java för mer detaljer om hur man skapar en ny klass.
Uppgift b - Skapa klassen DiceCup
Skapa en ny klass DiceCup som håller i fem stycken tärningar. När konstruktorn anropas ska den skapa fem stycken tärningar som sparas i en array i DiceCup. Klassen ska även ha en metod rollDices() som kastar alla tärningar och sparar summan av det senaste tärningskastet i en instansvariabel.
Ledtråd b
Anropa metoden rollDice från klassen Dice för att kasta varje tärning. Gör detta genom att loopa igenom alla tärningar i DiceCup.
Uppgift c - Skapa klassen Player
Nästa klass vi ska skapa är Player. Klassen player innehåller tre instansvariabler.
- En
diceCupsom är spelarens egen tärningsbägare. - En
Stringsom är namnet på spelaren. - En
intsom håller spelarens totala poäng.
Klassen ska ha två getters, en för namnet och en för spelarens totala poäng.
Klassen ska även ha en metod RollDice som vid anrop kastar sin diceCup och summerar poängen till sin totala summa.
Ledtråd c
Anropa metoden rollDices från klassen DiceCup för att kasta hela tärningsbägaren. Uppdatera sedan spelarens totala poäng genom att anropa gettern i DiceCup.
Uppgift d - skapa klassen Logic
I klassen Logic anger vi all logik för att styra spelet. Klassens konstruktor ska ta in en array som håller alla spelare (Player) som deltar i spelet.
Klassen ska ha två metoder. Första metoden doRound ska gå igenom alla spelarna i listan och kasta deras tärningar. Den andra metoden checkIsWinner ska undersöka om någon spelare har minst 100 poäng. Den spelare som har minst 100 poäng vinner. Om fler än en spelare får minst 100 poäng under samma omgång vinner spelaren med högst poäng. Om två spelare har samma poäng blir det oavgjort. Skapa hjälpmetoder vid behov för att kontrollera så att flera spelare inte har samma poäng. Klassen ska även ha en metod highestScore som returnerar den spelare med högst poäng.
Ledtråd d
Loopa igenom alla spelarna i Logic. För varje spelare kan du anropa metoden rollDices som i sin tur anropar DiceCup som i sin tur anropar Dice.
För att avgöra om två spelare har samma poäng kan du spara alla spelarnas poäng i en lista. Sortera sedan listan från lägsta till högsta värdet. Om de två sista värdena är samma, vet du att de två bästa spelarna har spelat oavgjort. Du kan sortera en arraylist genom att först importera klassen Collections:
import java.util.Collections;
Och sedan sortera listan enligt:
Collections.sort(scores);
Uppgift e - Huvudklassen
Vi ska nu knyta ihop allting i huvudklassen. Börja med att skapa ett godtyckligt antal spelare och spara varje spelare i en array. Skapa sedan klassen logic och skicka in arrayen med spelarna till logics konstruktor.
Skapa sedan en loop som kallar på metoden doRound tills dess att en spelare har nått 100 poäng. Avsluta då loopen och skriv ut vinnaren i terminalfönstret.
Ledtråd e
Du kan enkelt skapa flera spelare på samma gång genom:
String[] names = {"Emil", "Gustav", "Ellen"};
// En array med alla spelare
Player[] players = new Player[3];
// Skapar spelarna med givet namn och ger varje spelare en ny DiceCup.
for(int i = 0; i < names.length; i++){
players[i] = new Player(names[i], new DiceCup(nmbrOfDices, nmbrOfSides));
}
Svar
Vi börjar med att gå igenom koden i Dice.
import java.util.Random;
public class Dice {
private final int sides;
private int value;
// Antal sidor som tärningen har
public Dice(int sides) {
if (sides < 1) throw new IllegalArgumentException("Antal sidor måste vara positivt");
this.sides = sides;
}
// Kasta en tärning med antal sidor som tärningen har
public int rollDice() {
Random random = new Random();
this.value = random.nextInt(this.sides) + 1;
return value;
}
// Getter
public int getSides() {
return this.sides;
}
public int getValue() { return this.value; }
}
Vi importerar först klassen Random som vi ska använda för att göra ett slumptal. Vi definierar sedan två instansvariabler sides och value. I konstruktorn tar vi emot hur många sidor tärningen ska ha. Metoden rollDice kastar tärningen och returnerar ett slumpvärde. Avslutningsvis har vi gettern som returnerar antal sidor på tärningen.
Vi fortsätter med klassen DiceCup.
public class DiceCup {
private Dice[] dicecup;
private int sum;
// Konstruktor
public DiceCup(int nmbrOfDices, int sides){
if (nmbrOfDices < 1) throw new IllegalArgumentException("Minst en tärning behövs");
this.dicecup = new Dice[nmbrOfDices];
for(int i = 0; i < nmbrOfDices; i++){
this.dicecup[i] = new Dice(sides);
}
}
// Kastar alla tärningar och sparar summan
public void rollDices(){
int tempSum = 0;
for(int i = 0; i < dicecup.length; i++){
tempSum = tempSum + this.dicecup[i].rollDice();
}
this.sum = tempSum;
}
// Returnerar summan
public int getSum(){
return this.sum;
}
}
Klassen har två instansvariabler, en array som håller tärningarna och ett heltal som är summan på senaste tärningskastet. Konstruktorn skapar sedan nya tärningar och sparar dessa i arrayen. Metoden rollDices går igenom alla tärningar i arrayen och sparar undan summan. Avslutningsvis har vi en getter som returnerar summan.
Klassen Player
public class Player {
// Instansvariabler
private DiceCup diceCup;
private String name;
public int sum;
// Konstruktor
Player(String name, DiceCup diceCup){
this.name = name;
this.diceCup = diceCup;
}
// Kastar alla tärningar och sparar summan
public void rollDice(){
this.diceCup.rollDices();
this.sum = this.sum + this.diceCup.getSum();
}
// Getters
public String getName(){
return this.name;
}
public int getSum(){
return sum;
}
}
Klassen Player håller tre instansvariabler, en tärningsbägare, namnet på spelaren samt den totala poängen som spelaren har. När konstruktorn anropas anger ger vi den en ny DiceCup, samt ett namn. Metoden RollDice kaster alla tärningar i tärningsbägaren och sparar summan i instansvariabeln. Vi har även två getters som returnerar namnet och summan på spelaren.
Klassen Logic
import java.util.ArrayList;
import java.util.Collections;
public class Logic {
// Instansvariabler
private Player[] players;
// Konstruktor
Logic(Player[] players){
if (players.length == 0) throw new IllegalArgumentException("Minst en spelare behövs");
this.players = players;
}
// Gå igenom alla spelarna och kasta deras tärningsbägare
public void doRound(){
for(Player player : players){
player.rollDice();
System.out.println(player.getName() + ": " + player.getSum());
}
}
/* Kolla om det finns en vinnare genom att gå igenom alla spelare
och kolla om någon av spelarna har minst 100 poäng. Metoden isSameScore
kollar om de två spelarna med högst poäng har samma poäng
*/
public boolean checkIsWinner(){
for(Player player : players){
if(player.getSum() >= 100){
return true;
}
}
return false;
}
// Undersöker om spelarna med högst poäng har samma poäng
public boolean isSameScore(){
if (players.length < 2) return false;
// Spara alla poängen i en lista
ArrayList<Integer> scores = new ArrayList<>();
for(Player player : players){
scores.add(player.getSum());
}
// Sortera listan från minsta till högsta tal
Collections.sort(scores);
// Om de två spelarna med högst poäng har samma värde så finns det ingen vinnare.
if(scores.get(scores.size() - 1).equals(scores.get(scores.size() - 2))){
return true;
} else{
return false;
}
}
// returnerar spelaren med högst poäng
public Player highestScore() {
int bestScore = 0;
int bestIndex = 0;
for (int i = 0; i < players.length; i++) {
if(players[i].getSum() > bestScore ){
bestScore = players[i].getSum();
bestIndex = i;
}
}
return players[bestIndex];
}
}
Klassen Logic är kanske den svåraste klassen att hänga med i. Först har vi en instansvariabel som är en array som håller alla spelarna som ska vara med i spelet. Dessa spelare läggs till när konstruktorn anropas. Metoden doRound går igenom alla spelarna i listan och gör var sitt kast. Metoden checkWinner går igenom alla spelarna och kollar om någon av spelarna har fått minst 100 poäng. Den kontrollerar även så att ingen av spelarna har exakt samma poäng. Vi gör detta med en hjälpmetod isSameScore som sparar alla poäng i en arraylist. Genom att spara alla spelarnas poäng i en lista och sedan sortera listan med paketet collections (som vi importerar vid början av klassen) kan vi veta om två spelare har samma poäng. Eftersom listan är sorterad från minsta till högsta tal, vet vi att om de två sista värdena i listan är samma, att de två spelarna med högst poäng har spelat oavgjort.
if (scores.get(scores.size() - 1).equals(scores.get(scores.size() - 2))) {
// Två eller fler har samma högsta poäng.
}
Vi avslutar sedan klassen med en metod highestScore som går igenom alla spelarna i listan och returnerar den spelaren som har högst poäng. Vi sparar hela tiden indexet på högsta poängen för att enkelt kunna returnera spelaren med högst poäng.
Huvudskriptet KlasserObjektUppgift2
public class KlasserObjektUppgift2 {
public static void main(String[] args) {
// Fem tärningar per DiceCup
int nmbrOfDices = 5;
// Varje tärning av 6 sidor i detta exempel
int nmbrOfSides = 6;
// Hittar på tre namn på
String[] names = {"Emil", "Gustav", "Ellen"};
// En array med alla spelare
Player[] players = new Player[3];
// Skapar spelarna med givet namn och ger varje spelare en ny DiceCup.
for(int i = 0; i < names.length; i++){
players[i] = new Player(names[i], new DiceCup(nmbrOfDices, nmbrOfSides));
}
// Skapar ett objekt av klassen logic och skicar in spelarna till konstruktorn
Logic logic = new Logic(players);
// Kollar först om det finns en vinnare. Om det ej finns en vinnare kasta tärningarna på nytt
while(!logic.checkIsWinner()){
logic.doRound();
}
// Kolla vem som är vinnaren och skriv ut
Player winner = logic.highestScore();
if (logic.isSameScore()) {
System.out.println("Oavgjort mellan spelarna med högst poäng");
} else {
System.out.println("The winner is: " + winner.getName() + " with score: " + winner.getSum());
}
}
}
I huvudskriptet definierar vi först antal tärningar och antal sidor på varje tärning. Vi skapar även tre stycken spelare och ger varje spelare var sin DiceCup. Spelarna sparar vi i en array. Vi skapar sedan ett logic-objekt och skickar in arrayen i logic. Nu kan vi skapa en loop som hela tiden kollar om vi har en vinnare. Om vi inte har en vinnare kan logic utföra en ny omgång av spelet.
När vi har en vinnare anropar vi metoden highestScore som returnerar vinnaren. Vi avslutar med att skriva ut vinnaren.
Vi har i detta exemplet sett hur vi kan skapa flera små klassen som samverkar med varandra för att skapa ett större spel. Det är detta som kallas objekt-orienterad programmering!