Game-Apps für Smartphones und Tablets

Bern University oh Teacher Education  
HomeOnline-Editor startenDruckenAndroid-TurtlegrafikJava-Online

MasterMind


MasterMind ist ein bekanntes Logikspiel. Der Computer legt zu Beginn einen vierstelligen geordneten Farbcode fest, der aus sechs Farben ausgewählt wird; eine Farbe kann auch mehrmals verwendet werden. Der Spieler versucht den Code herauszufinden, in dem er reihenweise farbige Stifte setzt. Nach jedem Zug erhällt er die Information, wie viele Stifte er in Farbe und Position richtig gesetzt hat (schwarzer Stift) und wie viele Stifte zwar die richtige Farbe haben, aber an einer falschen Position stehen (weisser Stift). Ziel ist es, den Farbcode mit möglichst wenigen Zügen zu erraten. Gelingt es dem Spieler nicht, den Farbcode in 7 Zügen zu erraten, wird die Lösung angezeigt.

In unserem MasterMind werden die Farbstifte mit linkem Masklick an der entsprechenden Position gesetzt. Erneutes Klicken bewirkt Farbwechsel. Ein Zug wird mit Klick auf Fragezeichen beendet.
Ist das Spiel bendet, kann mit Klick auf das Spielbrett ein neue Spiel gestartet werden.

Beispiel im Online-Editor bearbeiten

App installieren auf Smartphone oder Tablet

QR-Code

Sources downloaden (Mastermind.zip)

 

Programmcode:

// MasterMind.java

package app.mastermind;

import ch.aplu.android.*;
import java.util.ArrayList;

public class MasterMind extends GameGrid implements GGTouchListener
{
  private int[] secretCode = new int[4];
  private int currentRow;
  private boolean roundFinished;
  private ActiveRowMarker marker;
  GGTextField status;
  private int placedPegs = 0;
  
  public MasterMind()
  {
    super(7, 10, cellZoom(60), TRANSPARENT, "mastermind"false);
    setScreenOrientation(FIXED);
  }

  public void main()
  {
    this.addTouchListener(thisGGTouch.click);
    getBg().setPaintColor(RED);
    reset();
    doRun();
  }


  public boolean touchEvent(GGTouch touch)
  {
    if (roundFinished)
    {
      reset();
      return true;
    } 
    
    Location loc = toLocationInGrid(touch.getX(), touch.getY());

    if (placedPegs == && loc.x == && loc.y == currentRow)
    { // click on evalButton -> evaluate
      int[] guess = new int[4];
      for (int = 0; i < 4; i++)
        guess[i] = getOneActorAt(new Location(+ i, currentRow)).getIdVisible();
      evaluateGuess(guess);
    }

    if (loc.y == currentRow && loc.x > && 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
      {  
        getOneActorAt(loc).showNextSprite(); // -> next color
      }
      
    }
    refresh();
    return true;
  }

  public void reset()
  {
    removeAllActors();
    getBg().clear();
    currentRow = this.getNbVertCells() - 2; 
    roundFinished = false;
    for (int = 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 = 0; i < 4; i++)
      if (guess[i] == secretCode[i])
        blackPegs++;
    ArrayList<Integer> alreadyProcessed = new ArrayList<Integer>();
    for (int color : secretCode)
      for (int = 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)
  {
    showToast(reason);
    showToast("Click to play again");
    removeActor(marker);
    showSolution();
    roundFinished = true;
  }

  private void showTips(int whitePegs, int blackPegs)
  {
    for (int = 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 = 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 += + ", ";
    return result;
  }
}

// -----------class ActiveRowMarker -----------
class ActiveRowMarker extends Actor
{
  public ActiveRowMarker ()
  {
    super("activerowmarker");
  }
}

// ----------class EvalPeg -----------------
class EvalPeg extends Actor
{
  public EvalPeg(int sprite)
  {
    // sprite 0 = black, sprite 1 = white
    super(true"epeg"2);
    show(sprite);
  }
}

// -----------class EvaluateButton------------
class EvaluateButton extends Actor
{
  public EvaluateButton()
  {
    super("ebutton");
  }
}

//-------- class Peg-------------------------
class Peg extends Actor
{
  public static final int NbColors = 6;
  public Peg()
  {
    super("peg"NbColors);
  }
}

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 = toLocationInGrid(touch.getX(), touch.getY())
addActor(new Peg(), loc)

An der Position des Touch-Klicks wird ein farbiger Stift erzeugt
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