In unserem MasterMind (entwickelt durch Stefan Moser) werden die Farbstifte mit linkem Masklick an der entsprechenden Position gesetzt. Erneutes Klicken bewirkt Farbwechsel. Rechtsklick holt die vorhergehende Farbe zurück. Ein Zug wird mit Klick auf Fragezeichen beendet. Ist das Spiel bendet, kann mit Klick auf das Spielbrett ein neue Spiel gestartet werden. Programmcode für lokale Bearbeitung downloaden ( MasterMind.zip) |
Erklärungen zum Programmcode:
reset() for (int i = 0; i < secretCode.length; i++) secretCode[i] = (int)(Math.random() * Peg.NbColors) |
Der Farbcode wird in der Methode reset() zufällig festgelegt. Diese wird beim Spielbeginn und bei der Spielwiederholung aufgerufen. Da in unserem Spiel 6 Farben verwendet, besitzt das Objekt Peg sechs Sprites (peg_0.png ..., peg_5.png) |
loc = toLocation(mouse.getX(), mouse.getY()) |
An der Position des Mausklicks wird ein Stift erzeugt
|
if (mouse.getEvent() == GGMouse.lPress) getOneActorAt(loc).showNextSprite() |
Die Stiftfarbe kann mit Mausklick geändert werden. Durch wiederholtes Klicken wird jeweils die nächste Farbe (das nächste Sprite) angezeigt
|
if (placedPegs == 4) addActor(new EvaluateButton(), new Location(1, currentRow)) |
Wenn 4 Stifte gesetzt sind, erscheint in der aktuellen Reihe ein Evaluationsstift |
for (int i = 0; i < 4; i++) if (guess[i] == secretCode[i]) blackPegs++ |
Falls Position und Farbe übereinstimmt, wird die Anzahl der schwarzen Stifte erhöht |
for (int j = 0; j < 4; j++) if (color == guess[j] && !alreadyProcessed.contains(j)) alreadyProcessed.add(j); whitePegs++ |
Falls nur die Farbe übereinstimmt, wird die Anzahl weissen Stifte erhöht |
Programmcode:
// MasterMind.java import java.awt.*; import java.util.*; import ch.aplu.jgamegrid.*; public class MasterMind extends GameGrid implements GGMouseListener { int[] secretCode = new int[4]; int currentRow; boolean roundFinished; final String version = "0.2"; ActiveRowMarker marker; private int placedPegs = 0; public MasterMind() { super(7, 10, 60, null, "sprites/mastermindbg.png", false); this.addMouseListener(this, GGMouse.lPress | GGMouse.rPress); this.setTitle("MasterMind - V " + version); getBg().setPaintColor(Color.red); reset(); show(); } public boolean mouseEvent(GGMouse mouse) { if (roundFinished) { reset(); return true; } Location loc = toLocation(mouse.getX(), mouse.getY()); if (placedPegs == 4 && loc.x == 1 && loc.y == currentRow) { // click on evalButton -> evaluate int[] guess = new int[4]; for (int i = 0; i < 4; i++) guess[i] = getOneActorAt(new Location(2 + i, currentRow)).getIdVisible(); evaluateGuess(guess); } if (loc.y == currentRow && loc.x > 1 && loc.x < 6) { if (getOneActorAt(loc) == null) { this.addActor(new Peg(), loc); placedPegs++; if (placedPegs == 4) { // show evaluate button addActor(new EvaluateButton(), new Location(1, currentRow)); } } else if (mouse.getEvent() == GGMouse.lPress) getOneActorAt(loc).showNextSprite(); //if leftclick -> next color else getOneActorAt(loc).showPreviousSprite(); //if rightClick -> previous color } refresh(); return true; } public void reset() { removeAllActors(); getBg().clear(); currentRow = this.nbVertCells - 2; roundFinished = false; for (int i = 0; i < secretCode.length; i++) secretCode[i] = (int)(Math.random() * Peg.NbColors); marker = new ActiveRowMarker(); addActor(marker, new Location(1, currentRow)); refresh(); } private void evaluateGuess(int[] guess) { int blackPegs = 0, whitePegs = 0; for (int i = 0; i < 4; i++) if (guess[i] == secretCode[i]) blackPegs++; ArrayList<Integer> alreadyProcessed = new ArrayList<Integer>(); for (int color : secretCode) for (int j = 0; j < 4; j++) if (color == guess[j] && !alreadyProcessed.contains(j)) { alreadyProcessed.add(j); whitePegs++; break; } whitePegs -= blackPegs; showTips(whitePegs, blackPegs); if (blackPegs == 4) // got right combination finishRound("Correct!"); else currentRow--; //go to next column for next try if (currentRow == 1) //no more guesses left finishRound("Pattern not found!"); marker.setLocation(new Location(1, currentRow)); placedPegs = 0; removeActors(EvaluateButton.class); } private void finishRound(String reason) { getBg().setFont(new Font("verdana", Font.PLAIN, 18)); getBg().drawText(reason, new Point(10, 32)); getBg().setFont(new Font("verdana", Font.PLAIN, 18)); getBg().drawText("Click to play again", new Point(10, 590)); removeActor(marker); showSolution(); roundFinished = true; } private void showTips(int whitePegs, int blackPegs) { for (int i = 0; i < 4; i++) { if (blackPegs > 0) { EvalPeg ep = new EvalPeg(0); addActor(ep, new Location(1, currentRow)); ep.turn(90 * i); blackPegs--; } else if (whitePegs > 0) { EvalPeg ep = new EvalPeg(1); addActor(ep, new Location(1, currentRow)); ep.turn(90 * i); whitePegs--; } } } private void showSolution() { int x = 2; for (int spriteNr : secretCode) { Peg peg = new Peg(); peg.show(spriteNr); addActor(peg, new Location(x, 1)); x++; } } private String printArray(int[] a) { String result = ""; for (int b : a) result += b + ", "; return result; } public static void main(String[] args) { new MasterMind(); } } // -----------class ActiveRowMarker ----------- class ActiveRowMarker extends Actor { public ActiveRowMarker () { super("sprites/activeRowMarker.png"); } } // ----------class EvalPeg ----------------- class EvalPeg extends Actor { public EvalPeg(int sprite) { // sprite 0 = black, sprite 1 = white super(true, "sprites/EvalPeg.png", 2); show(sprite); } } // -----------class EvaluateButton------------ class EvaluateButton extends Actor { public EvaluateButton() { super("sprites/EvaluateButton.png"); } } //-------- class Peg------------------------- class Peg extends Actor { public static final int NbColors = 6; public Peg() { super("sprites/peg.png", NbColors); } } |