Java Programmieren Würfeln mit 2 Würfeln?

3 Antworten

Hey Gamer5434777,

hab dir auch mal was auf die Schnell hingezaubert. Bei 20.000 Würfen sieht der entstehende Graph schon wie erwartet aus:

Bild zum Beitrag

Main:

package dices;

import dices.model.Game;
import dices.model.GameResult;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;

import java.util.Random;
import java.util.Scanner;

public class Main extends Application {

    private static final int WIDTH = 1024;
    private static final int HEIGHT = 768;
    private static final int DICE_COUNT = 2;

    private static final String TITLE = "Dices";
    private static final String X_AXIS_LABEL = "pips";
    private static final String Y_AXIS_LABEL = "count";
    private static final String INPUT_MESSAGE = "Input throw count please: ";

    @Override
    public void start(Stage stage) {

        System.out.println(INPUT_MESSAGE);
        Scanner sc = new Scanner(System.in);
        int throwCount = sc.nextInt();

        stage.setTitle(Main.TITLE);
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        final BarChart<String, Number> barChart = new BarChart<>(xAxis, yAxis);

        barChart.setTitle(TITLE);
        xAxis.setLabel(X_AXIS_LABEL);
        yAxis.setLabel(Y_AXIS_LABEL);

        XYChart.Series series1 = createSeries(throwCount);

        Scene scene = new Scene(barChart, WIDTH, HEIGHT);
        barChart.getData().addAll(series1);
        stage.setScene(scene);
        stage.show();
    }

    private XYChart.Series createSeries(int throwCount) {
        XYChart.Series series = new XYChart.Series();

        Random random = new Random();
        Game game = new Game(DICE_COUNT, random);
        GameResult gameResult = game.play(throwCount);
        int maxPips = gameResult.getMaxPips();

        for (int pipCount = 1; pipCount <= maxPips; pipCount++) {
            int throwsWithResultPip = gameResult.getThrowCountFor(pipCount);
            XYChart.Data chartData = new XYChart.Data(Integer.toString(pipCount), throwsWithResultPip);
            series.getData().add(chartData);
        }

        return series;
    }


    public static void main(String[] args) {
        launch(args);
    }
}

Dice:

package dices.model;

import java.util.Random;

public class Dice {

    private static final int MAX_PIPS = 6;

    private final Random random;

    public Dice(Random random) {
        this.random = random;
    }

    public int role() {
        return random.nextInt(MAX_PIPS) + 1;
    }
}

Game:

package dices.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Game {

    private List<Dice> dices;

    public Game(int diceCount, Random random) {
        this.dices = createDices(random, diceCount);
    }

    public GameResult play(int throwCount) {

        GameResult gameResult = new GameResult();

        for (int i = 0; i < throwCount; i++) {
            int pipCount = dices.stream()
                    .mapToInt(Dice::role)
                    .sum();

            gameResult.add(pipCount);
        }

        return gameResult;
    }

    private List<Dice> createDices(Random random, int diceCount) {
        List<Dice> dices = new ArrayList<>(diceCount);

        for (int i = 0; i < diceCount; i++) {
            dices.add(new Dice(random));
        }

        return dices;
    }

}

GameResult:

package dices.model;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class GameResult {

    private static final String NO_RESULT_MESSAGE = "No results";

    private Map<Integer, Integer> pipCounts;

    public GameResult() {
        pipCounts = new HashMap<>();
    }

    public void add(int pipCount) {
        if (this.pipCounts.containsKey(pipCount)) {
            Integer throwCount = this.pipCounts.get(pipCount);
            throwCount++;
            this.pipCounts.put(pipCount, throwCount);

            return;
        }

        this.pipCounts.put(pipCount, 1);
    }

    public int getMaxPips() {
        Optional<Integer> maxNumber = pipCounts.keySet().stream().max(Integer::compareTo);
        if (!maxNumber.isPresent()) {
            throw new RuntimeException(NO_RESULT_MESSAGE);
        }

        return maxNumber.get();
    }

    public int getThrowCountFor(int pipCount) {
        if (!this.pipCounts.containsKey(pipCount)) {
            return 0;
        }

        return pipCounts.get(pipCount);
    }
}

Wie gesagt, ist eher zweckmäßig.

  • keine saubere Trennung Model und View
  • View ist auch nicht in ein extra Model ausgelagert
  • demnach auch kein Controller
  • keine Prüfung bei Falscheingaben
  • keine Wiederholung des Spiels (einmal und danach darfst Du das Fenster schließen)
  • schön geht anders, aber Refaktorisieren kannst Du sicher selbst
  • besser als alles in die Main zu kloppen (wenn auch nicht sehr viel)
  • dafür kannst Du den Code leicht für mehrere Würfel ändern - ist doch auch was.

Dice: Einfach nur dafür da zu würfeln. Hier wird auch die maximale Augenzahl eines Würfels festgelegt, falls Du das mal ändern möchtest.

Game: Abstrahiert einfach nur eine Spiel, also die angegebenen Würfe mit X Würfeln. Aktuell sind das im Code zwei Würfel. Das Ergebnis vom Spiel wird dann als GameResult zurückgegeben.

GameResult: Speichert in einer HashMap ganz einfach wie viele Augenzahlen vorgekommen sind. Objekte dieser Klasse werden vom Game erzeugt und befüllt. Danach wird das GameResult Objekt in Main benutzt um die View zu bauen. Die HashMap wird nach außen natürlich gekapselt.

Für ne Bewerbung als Entwickler würde ich den Code nicht vorzeigen, aber für die Schule (+andere Ausbildungen) reicht es sicherlich.

Je nach Lust und Laune kannst Du die genannten Punkte angehen. Außerdem könntest Du die Ausgabe aus der Konsole holen und in die UI bringen.

Gruß und viel Spaß

Woher ich das weiß:Berufserfahrung
 - (Schule, programmieren, Java)

Mal spaßeshalber was gebastelt. Bei größeren Projekten sollte man statt dem Array "valueCounts" vielleicht lieber eine HashMap benutzen, aber ich denke mal, für die kleine Aufgabe ist das trotzdem in Ordnung.

import java.util.Random;
import java.util.Scanner;


public class Gambling {
	
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		Random rnd = new Random();
		int maxRounds = 0;
		int valueCounts[] = new int[11];
		
		System.out.print("Bitte Anzahl der Würfe eingeben: ");
		maxRounds = in.nextInt();
		in.close();
		
		if (maxRounds < 1) {
			System.out.println("Es muss mindestens einmal gewürfelt werden.");
			return;
		}
		
		for (int value = 2; value <= 12; value++) {
			valueCounts[value - 2] = 0;
		}
		
		System.out.println("Gewürfelte Werte: ");
		
		for (int round = 0; round < maxRounds; round++) {
			int dice1 = rnd.nextInt(6)+1;
			int dice2 = rnd.nextInt(6)+1;
			
			System.out.println(dice1 + " + " + dice2 + " = " + (dice1 + dice2));
			
			valueCounts[dice1 + dice2 - 2]++;
		}
		
		System.out.println();
		System.out.println("Verteilung der Würfelsummen: ");
		
		for (int value = 2; value <= 12; value++) {
			System.out.println(value + ": " + valueCounts[value - 2] + " mal");
		}
	}
}

User16495  06.03.2019, 12:35

Hier, da kannst Du jemanden vielen Dank für die Mühe sagen.
Danach kopierst Du den Code, gibst Deine Hausaufgabe so ab, bekommst ein Lob und fällst dann bei der nächsten Klausur durch :-)

0

Nö, das sind absolute Anfänger-Aufgaben, damit Du überhaupt vertraut wirst mit dem Programmieren. Wenn Du das nicht selber lösen und googeln willst, kannst Du das Programmieren gleich aufgeben..


Gamer5434777 
Beitragsersteller
 06.03.2019, 11:56

Sehr hilfreiche Antwort!

0