Java :: Aufgabe #203

2 Lösungen Lösungen öffentlich

Programmierung von MasterMind

Anfänger - Java von hollst - 02.07.2018 um 10:54 Uhr
MasterMind ist ein deduktives Spiel, das insbesondere Anfang der 70er Jahre sehr beliebt war.
Ziel des Spiels ist es, einen Geheimcode zu entschlüsseln.

In der klassischen Variante ordnet ein Spieler, genannt "codemaker", eine Sequenz von vier Symbolen
geheim an. Praktisch geschieht dies mittels unterschiedlich oder teilweise bzw. gänzlich
gleich gefärbter Pins oder Murmeln in einer Reihe, wobei maximal sechs Farben zur Verfügung stehen.

Ein zweiter Spieler, genannt "codebreaker", versucht durch Testmuster, gleichfalls bestehend aus vier gereihten
Symbolen (Pins/Murmeln), den Code zu erraten. Hätte der codebreaker 6 * 6 * 6 * 6 = 1.296 Versuche zur Verfügung,
wäre dies kein Problem, allerdings wird die Anzahl der Tests als Spielregel auf zwölf (manchmal weniger) begrenzt.

Als Responds auf ein Testmuster muss der codemaker zwei Informationen geben:

1.) Wieviele Symbole im Testmuster stehen an exakt der gleicher Stelle wie im Geheimmuster (im Falle vier, wäre das
Spiel für den codebreaker gewonnen) und
2.) wieviele Symbole (Pin-/Murmelfarben) sind sowohl im Geheim- als auch im Testmuster
vorhanden, allerdings nicht in übereinstimmender Position in der Reihe.

Die Programmieraufgabe bestehe nun darin, MasterMind interaktiv am PC zu simulieren, wobei der Computer als
codemaker fungiert, der zunächst per Zufallsgenerator das Geheimmuster erzeugt. Anschließend sind sukzessive
maximal zwölf Testmuster vom codebreaker (User) einzugeben und vom codemaker jeweils die zwei Fagen zu beantworten.


Anmerkung: MasterMind wurde auch von Mathematikern unter die Lupe genommen und bereits Mitte/Ende der 70er Jahre konnte
bewiesen werden, dass man es mit maximal fünf Testmustern lösen kann, sehr erstaunlich, oder? Daraufhin wurde
SuperMasterMind vorgeschlagen. Unterschied: Reihen mit fünf Symbolen und acht unterschiedlichen Pin-/Murmelfarben.

Wer MasterMind lediglich als schöne Spielerei ansieht, überlege bitte folgendes: Seit 1971 (release)
wurden bisher pro Jahr im Durchschnitt eine Million Spiele weltweit verkauft. Wärest Du der Erfinder und bekämest
als Lizenzgeber pro Exemplar 10 Cent, Du hättest finanziell ausgesorgt.

Lösungen:

vote_ok
von roadman1991 (360 Punkte) - 01.08.2018 um 10:58 Uhr
Ich habe hier einen kleinen Ansatz, mit 12 Leben

Quellcode ausblenden Java-Code
package florian.mastermind;

public class MasterMind {

	public static void main(String[] args) {
		PlayGround pg = new PlayGround();
		pg.startGame();
	}
}


Quellcode ausblenden Java-Code
package florian.mastermind;

import java.util.Arrays;


// Das Spielfeld
public class PlayGround {
	
	Actor actor;

	SecretCode secretCode;
	
	boolean actorDead = false;
	
	boolean gameWin = false;
	
	
	// Start des Spiels
	void startGame(){
		welcome();
		placeSecretCode();
		placeActor();
		
		// Eine Art 'GameLoop' Die solange läuft bis der Actor keine Leben mehr hat oder das Spiel gewonnen.
		while(actorDead == false) {
			if(gameWin == false) {
			actor.guessCode();
			evaluateGuessedSecretCode();
			} else {
				System.out.println("You Win");
				System.exit(0);
				return;
			}
		}
		System.out.println("Game Over");
		System.exit(0);
		return;
		
	}
	
	SecretCode placeSecretCode(){
		return secretCode = new SecretCode();
	}
	
	Actor placeActor(){
		return actor = new Actor();
	}
	
	// Vergleichen des Secret Codes mit dem des Actors
	void evaluateGuessedSecretCode(){
		if(Arrays.equals(secretCode.getSecretCode(), actor.getGuessedPins())) {
			gameWin = true;
		} else {
			reduceActorLife();
			for(int i = 0; i < secretCode.getSecretCode().length; i++) {
				if(secretCode.getSecretCode()[i].getValue() == actor.getGuessedPins()[i].getValue()) {
					System.out.println("Pin " + (i+1) + " with value of: " + actor.getGuessedPins()[i].getValue() + " was correct");
				}
			}
			
		}
	}
	
	void reduceActorLife(){
		actor.setLife(actor.getLife()-1);
		checkActorsLifeNotZero(actor.getLife());
	}
	
	boolean checkActorsLifeNotZero(int life){
		if (actor.getLife() < 1) {
			actorDead = true;
			return actorDead;
		} else {
			return actorDead;
		}
	}
	
	void welcome(){
		System.out.println("Welcome to Mastermind. You have to guess a secret code of a 4 digit number. \n"
				+ "There are 6 number options for each pin from 0 to 5\n"
				+ "you have 6 lifes. Once 0 lifes are reached, you loose! \n"
				+ "Good luck!");
	}
}


Quellcode ausblenden Java-Code
package florian.mastermind;

import java.util.Random;

public class SecretCode {
	
	private Pin[] secretCode = new Pin[4];
	
	public Pin[] getSecretCode() {
		return secretCode;
	}

	// Secret Code, welcher automatisch generiert wird
	SecretCode(){
		for (int i = 0; i < 4; i++) {
			Pin pin = new Pin();
			Random rnd = new Random();
			int rndNumber = rnd.nextInt(5);
			pin.setValue(rndNumber);
			secretCode[i] = pin;
		}
	}
	
	
}


Quellcode ausblenden Java-Code
package florian.mastermind;

import java.util.Scanner;
//Der Spieler, Aktör
public class Actor {

	private int life;
	
	private Pin[] guessedPins = new Pin[4];

	public Pin[] getGuessedPins() {
		return guessedPins;
	}

	public int getLife() {
		return life;
	}

	public void setLife(int life) {
		this.life = life;
	}
	
	
	// Anzahl der Leben
	Actor(){
		setLife(12);
	}
	
	
	// Actor kann hier eine Kombination von 4 Pins eingeben
	public void guessCode() {
		@SuppressWarnings("resource")
		Scanner reader = new Scanner(System.in);
		for(int i = 0; i < guessedPins.length; i++) {
			System.out.println("Enter Pin " + (i+1) + " : ");
			int n = reader.nextInt();
			Pin pin = new Pin();
			pin.setValue(n);
			guessedPins[i] = pin;
		}
	}
}


Quellcode ausblenden Java-Code
package florian.mastermind;

// Ein Pin im Spiel. Könnte durch ein Enum ersetzt werden
public class Pin {
	private int value;

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}

	// Funktionen zum vergleichen der Pins vom Actor mit dem Secret Code
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + value;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Pin other = (Pin) obj;
		if (value != other.value)
			return false;
		return true;
	}
	
	
}
vote_ok
von guandi (230 Punkte) - 14.08.2018 um 11:36 Uhr
Main Methode:

Quellcode ausblenden Java-Code
import controller.*;


public class MMApp {

	public static void main(String[] args) {
/*			
 			MasterMind ist ein deduktives Spiel, das insbesondere Anfang der 70er Jahre sehr beliebt war.
			Ziel des Spiels ist es, einen Geheimcode zu entschlüsseln.

			In der klassischen Variante ordnet ein Spieler, genannt "codemaker", eine Sequenz von vier Symbolen
			geheim an. Praktisch geschieht dies mittels unterschiedlich oder teilweise bzw. gänzlich 
			gleich gefärbter Pins oder Murmeln in einer Reihe, wobei maximal sechs Farben zur Verfügung stehen. 
			
			Ein zweiter Spieler, genannt "codebreaker", versucht durch Testmuster, gleichfalls bestehend aus vier gereihten 
			Symbolen (Pins/Murmeln), den Code zu erraten. Hätte der codebreaker 6 * 6 * 6 * 6 = 1.296 Versuche zur Verfügung, 
			wäre dies kein Problem, allerdings wird die Anzahl der Tests als Spielregel auf zwölf (manchmal weniger) begrenzt.
			
			Als Responds auf ein Testmuster muss der codemaker zwei Informationen geben:
			
			1.) Wieviele Symbole im Testmuster stehen an exakt der gleicher Stelle wie im Geheimmuster (im Falle vier, wäre das
			Spiel für den codebreaker gewonnen) und 
			2.) wieviele Symbole (Pin-/Murmelfarben) sind sowohl im Geheim- als auch im Testmuster
			vorhanden, allerdings nicht in übereinstimmender Position in der Reihe.
			
			Die Programmieraufgabe bestehe nun darin, MasterMind interaktiv am PC zu simulieren, wobei der Computer als
			codemaker fungiert, der zunächst per Zufallsgenerator das Geheimmuster erzeugt. Anschließend sind sukzessive
			maximal zwölf Testmuster vom codebreaker (User) einzugeben und vom codemaker jeweils die zwei Fagen zu beantworten.
*/
		
//			Erklärung Array zahlenBreaker:
//				Spalte 0 = Spielnummer
//				Spalte 1 = UserZahl 1
//				Spalte 2 = UserZahl 2
//				Spalte 3 = UserZahl 3
//				Spalte 4 = UserZahl 4
//				Spalte 5 = Treffer Exakt
//				Spalte 6 = Treffer Vorhanden
		
// 		zahlenMaker ist das Array in dem die Zufallszahlen des Makers gespeichert werden
		int zahlenMaker[] = new int[4];
		int zahlenBreaker[][] = new int[12][7];
// 		zahlenTreffer - hier werden die exakten und vorhandenen Zahlentreffer gespeichert um keine Doppelzählung zu haben
		int zahlenTreffer[] = new int[5];
		
//		Kleine Begrüßung
		Ausgabe.Begrüßung(); 
//		Erstellung von 4 Zufallszahlen und speichern in dem dazugehörigen Array
		Zufallszahlen.erstellen(zahlenMaker);
//		Für Testzwecke Ausgabe der Maker Zahlen
//		Ausgabe.test(zahlenMaker);
		
//		Spiellänge 12 Runden
		for(int i=0;i<12;i++) {
//			Zuweisen der Spielnummer an dazugehörige Position
			int x = i+1;
			zahlenBreaker[i][0] = x;
//			Ausgeben der Spielnummer
			Ausgabe.spielnummer(zahlenBreaker[i]);
//			Abfragen der Userzahlen und speichern im dazugehörigen Arrayblock
			Ausgabe.UserEingabe(zahlenBreaker[i]);
//			Kontrolle ob der User eine Zahl exakt eingegeben hat
			zahlenBreaker[i][5] = Zahlenkontrolle.kontrolleUserZahlenExakt(zahlenBreaker[i], zahlenMaker, zahlenTreffer);
//			Kontrolle ob der User eine richtige Zahl eingegeben hat die aber nicht am richtigen Platz ist
			zahlenBreaker[i][6] = Zahlenkontrolle.kontrolleUserZahlenVorhanden(zahlenBreaker[i], zahlenMaker, zahlenTreffer);
//			Ausgabe der Spielrunge, der vom User eingegebenen Zahlen und der Treffer für alle bisher gespielten Runden
			for(int j=0; j<=i; j++) {
				Ausgabe.ausgabeTreffer(zahlenBreaker[j]);
			}
//			Ausgabe ob neue Runde oder Spielende
			Ausgabe.rundenende(zahlenBreaker[i]);
//			Zurücksetzen der getroffenen Zahlen für die neue Runde
			for(int k=0;k<5;k++) {
				zahlenTreffer[k] = 0;
			}
		}
		
	}

}


Methode Ausgabe:
Quellcode ausblenden Java-Code
package controller;

import java.util.Scanner;

public class Ausgabe {

// 	Begrüßungstext
	public static void Begrüßung() {
		System.out.println("Willkommen bei MasterMind.");
		System.out.println("Der CodeMaker wünscht dir viel Glück!");
	}
	
//	Eingabe der Userzahlen
	public static void UserEingabe(int []usrZahl) {
		boolean eingabe = false;
		int x = 0;
		
		Scanner myScanner = new Scanner(System.in);
		
//		Schleife für die Eingabe von 4 Zahlen ab 1 da 0 in dem Array die Rundennummer enthält
		for(int i=1; i<5; i++) {
			
//			Auffordern für die eingabe einer Zahl und Kontrolle
			 do{
				System.out.println("Bitte gib deine " + i + ". Zahl zwischen 1 und 6 ein:");
				x = myScanner.nextInt();
				
//				Aufrufen der Methode für die Kontrolle der Eingabe
				eingabe = Zahlenkontrolle.kontrolleUserEingabe(x);
				
//			Die Zahl muss so lange eingegeben werden bis sie den Vorgaben entspricht
			}while(eingabe == false);
			 
//			Abspeichern der eingegebenen und geprüften Userzahl im Array
			usrZahl[i] = x;
		}
	}
	
//	Ausgabe der Spielnummer, Usereingabe und der Treffer
	public static void ausgabeTreffer(int []x) {
		System.out.print("Spiel Nr: " + x[0] + " - Deine Eingabe: ");
		for(int i=1; i<5;i++) {
			System.out.print(x[i]);
			if(i<4) {
				System.out.print(", ");
			}
		}
		System.out.println(" - Treffer Exakt: " + x[5] + " - Vorhanden: " + x[6]);
	}
	
//	Ausgabe der Rundennummer
	public static void spielnummer(int []x) {
		System.out.println("Dies ist Spiel Nummer: " + x[0]);
	}
	
//	Ausgabe des weiteren Spielverlaufs
	public static void rundenende(int []x) {
		
//		Prüfen ob das Spiel gewonnen wurde und Ausgabe
		if(x[5] == 4) {
			System.out.println("Sie haben gewonnen!");
			System.out.println("Spielende...");
			
//			Beenden des Spieles
			System.exit(1);
			
//		Prüfen ob die Rundenzahl erreicht wurde und das Spiel verloren
		}else if(x[0]==11){
			System.out.println("Leider Verloren!");
		}else {
			System.out.println("Neuer Verusch!");
		}
	}
	
//	Ausgabe der Makerzahlen für Testzwecke
//	public static void test(int [] zahlenMaker) {
//		for(int i=0; i<4;i++) {
//			System.out.print(zahlenMaker[i] + " ");
//		}
//		System.out.println("");
//	}
}


Methode Zahlenkontrolle:
Quellcode ausblenden Java-Code
package controller;

public class Zahlenkontrolle {

//	Kontrolle der Userzahlen
	public static boolean kontrolleUserEingabe(int usrZahl) {
		boolean eingabe = false;
		
//		Wenn die eingegebene Userzahl nicht 0 ist und kleiner als 7 dann ist die Eingabe richtig
		if(usrZahl>0 & usrZahl<7) {
			eingabe = true;
		}
		
		return eingabe;
	}
	
//	Kontrolle ob eine Userzahl exakt mit einer Zahl des Makers übereinstimmt und speichern des Ergebnisses in einem Array
	public static int kontrolleUserZahlenExakt(int []breakerZahlen, int []makerZahlen, int [] zahlenTreffer) {
		int treffer = 0;
		
//		j ist eine Zahl höher als i um die Daten an dem richtigen Arrayplatz zu speichern
		int j = 1;
		
//		Prüfen aller 4 Zahlen
		for(int i=0; i<4; i++) {
			
//			Wenn die Userzahl exakt mit der Makerzahl übereinstimmt wird der Treffer hochgezählt und in einem Array gespeichert
			if(makerZahlen[i] == breakerZahlen[j]) {
				treffer ++;
				zahlenTreffer[j] = 1;
			}
			j++;
		}
		return treffer;
	}
	
//	Kontrolle ob die eingegebenen Userzahlen bei den Makerzahlen vorhanden sind aber nicht exakt getroffen wurden
	public static int kontrolleUserZahlenVorhanden(int []breakerZahlen, int []makerZahlen, int [] zahlenTreffer) {
		int treffer = 0;
		
//		Überprüfen jeder vom User eingegebenen Zahl mit jeder vom Maker erstellten Zahl
		for(int i=0; i<4; i++) {
			for(int j=1; j<5; j++) {
				
//				Wenn die Zahlen vom Maker und User übereinstimmen UND die Zahl nicht von der exakten Prüfung schon gezählt wurde
//				Zähle den Treffer eins hoch und speicher den Treffer in dem Array
				if(makerZahlen[i] == breakerZahlen[j] & zahlenTreffer[j] != 1) {
					treffer ++;
					zahlenTreffer[j] = 1;
				}
			}
		}
		return treffer;
	}
}


Methode Zufallszahlen:
Quellcode ausblenden Java-Code
package controller;

public class Zufallszahlen {

//	Erstellen von 4 Zufallszahlen und spiechern dieser in dem Maker Array
	public static void erstellen(int [] maker) {
		
//		int maker[] = new int[4];
		int zufallsZahl = 0;
		
		for(int i=0; i<4; i++) {
			
			zufallsZahl  = 0;
			
			while( zufallsZahl == 0 | zufallsZahl > 6 ) {
				zufallsZahl  = (int) (Math.random() * 10);
			}
			
			maker[i] = zufallsZahl;

		}
		
//		return maker;
	}
}
2094002

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.