dice game

This commit is contained in:
Daniel Langbein 2024-12-14 18:05:35 +00:00
parent 46348bb898
commit d4d7d8ceb6
Signed by: langfingaz
GPG Key ID: 6C47C753F0823002
8 changed files with 289 additions and 28 deletions

1
ueb08/.gitignore vendored
View File

@ -1,4 +1,5 @@
/.idea/
/app/build/
# Ignore Gradle project-specific cache directory
/.gradle/

View File

@ -1,14 +0,0 @@
/*
* This source file was generated by the Gradle 'init' task
*/
package org.example;
public class App {
public String getGreeting() {
return "Hello World!";
}
public static void main(String[] args) {
System.out.println(new App().getGreeting());
}
}

View File

@ -0,0 +1,67 @@
package org.example;
public class Dice {
private DiceEyes diceEyes;
private boolean marked = false;
private boolean fixed = false;
public Dice() {
roll();
}
/**
* Rolls this dice. It will have a new random `DiceEyes` afterward.
*/
public void roll() {
diceEyes = DiceEyes.random();
}
public DiceEyes getDiceEyes() {
return diceEyes;
}
public boolean isFixed() {
return fixed;
}
public void fix() {
fixed = true;
marked = false;
}
public void unFix() {
fixed = false;
}
public boolean isMarked() {
return marked;
}
public void toggleMarked(){
if(isMarked()){
unMark();
}else{
mark();
}
}
private void mark() {
marked = true;
fixed = false;
}
public void unMark() {
marked = false;
}
@Override
public String toString() {
if (isFixed()) {
return "[" + diceEyes + "]";
} else if (isMarked()) {
return "(" + diceEyes + ")";
} else {
return " " + diceEyes + " ";
}
}
}

View File

@ -0,0 +1,47 @@
package org.example;
public enum DiceEyes {
ONE(1),
TWO(2),
THREE(3),
FOUR(4),
FIVE(5),
SIX(6);
private final int i;
DiceEyes(int i) {
this.i = i;
}
public static DiceEyes random(){
// In range [0,1)
double randDouble = Math.random();
// In range [0,6)
randDouble *= 6d;
// Round floor -> One of the integers {0, 1, 2, 3, 4, 5}
int randInt = (int) randDouble;
return DiceEyes.values()[randInt];
}
public int points(){
return switch (this) {
case ONE -> 100;
case FIVE -> 50;
default -> 0;
};
}
public int triplePoints(){
return switch (this) {
case ONE -> 1000;
case FIVE -> 500;
default -> 0;
};
}
@Override
public String toString() {
return String.valueOf(i);
}
}

View File

@ -0,0 +1,53 @@
package org.example;
import java.util.Scanner;
public class Game {
private static final Scanner scanner = new Scanner(System.in);
public static void main(String... args) {
loop(
new Player("Sam"),
new Player("Daniel")
);
}
private static void loop(Player... players) {
while (true) {
for (Player player : players) {
System.out.println("\n" +
"===================================\n" +
"Next player: " + player.getName());
player.rollTheDices();
System.out.println(player);
interactWith(player);
}
}
}
private static void interactWith(Player player) {
while (true) {
System.out.println("" +
"[r] roll the dices\n" +
"[i] mark dice i\n" +
"[f] finish round");
String line = scanner.nextLine();
switch (line) {
case "r":
player.rollTheDices();
System.out.println(player);
break;
case "f":
player.finishRound();
System.out.println(player);
return;
default:
int i = Integer.parseInt(line);
player.toggleMark(i);
System.out.println(player);
break;
}
}
}
}

View File

@ -0,0 +1,117 @@
package org.example;
import java.util.Arrays;
import java.util.stream.Collectors;
import static org.example.DiceEyes.FIVE;
import static org.example.DiceEyes.ONE;
public class Player {
private final String name;
private int totalScore = 0;
private int roundScore = 0;
private Dice[] dices = new Dice[]{
new Dice(), new Dice(), new Dice(),
new Dice(), new Dice(), new Dice()
};
public Player(String name){
this.name = name;
}
public void rollTheDices() {
// If all dices are fixed and score points,
// (1) add selectionScore to roundScore,
// (2) unFix all dices
// (3) and roll the dices again
boolean cond = Arrays.stream(dices)
.filter(Dice::isFixed)
.filter(d -> d.getDiceEyes() == ONE || d.getDiceEyes() == FIVE)
.count() == 6;
if (cond) {
roundScore += selectionScore();
Arrays.stream(dices).forEach(Dice::unFix);
rollUnfixedDices();
return;
}
// Fix all currently marked dices.
Arrays.stream(dices)
.filter(Dice::isMarked)
.forEach(Dice::fix);
rollUnfixedDices();
}
private void rollUnfixedDices() {
Arrays.stream(dices)
.filter(d -> !d.isFixed())
.forEach(Dice::roll);
}
public void toggleMark(int diceIdx) {
if (diceIdx < 0 || diceIdx >= dices.length) {
throw new IllegalArgumentException("Invalid dice index: " + diceIdx);
}
if (dices[diceIdx].isFixed()) {
throw new IllegalArgumentException("Dice " + diceIdx + " is already fixed");
}
dices[diceIdx].toggleMarked();
}
public void finishRound() {
totalScore += roundScore + selectionScore();
roundScore = 0;
// Unfix and unmark all dices
for (Dice dice : dices) {
dice.unMark();
dice.unFix();
}
}
private int selectionScore() {
int ones = 0;
int fives = 0;
for (Dice dice : dices) {
if (dice.isFixed() || dice.isMarked()) {
switch (dice.getDiceEyes()) {
case ONE:
ones++;
break;
case FIVE:
fives++;
break;
}
}
}
int toggledScore = 0;
while (ones >= 3) {
toggledScore += ONE.triplePoints();
ones -= 3;
}
while (fives >= 3) {
toggledScore += FIVE.triplePoints();
fives -= 3;
}
toggledScore += ONE.points() * ones;
toggledScore += FIVE.points() * fives;
return toggledScore;
}
public String getName() {
return name;
}
@Override
public String toString() {
return totalScore + " + " + (roundScore + selectionScore()) + ": " + dicesToString();
}
private String dicesToString() {
return Arrays.stream(dices).map(Dice::toString).collect(Collectors.joining(" "));
}
}

View File

@ -1,14 +0,0 @@
/*
* This source file was generated by the Gradle 'init' task
*/
package org.example;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AppTest {
@Test void appHasAGreeting() {
App classUnderTest = new App();
assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
}
}

View File

@ -0,0 +1,4 @@
package org.example;
class GameTest {
}