Mastermind programmieren, wie den falschen Platz aber richtige Farbe schecken?

Executer

Mitglied
Hey,
ich blicke nicht mehr durch und habe keine aber auch wirklich gar keine Ahnung wie das Problem zu lösen ist, Mastermind ist ein Spiel wo der eine Spieler einen 4 stelligen Farbcode von 4 verschiedenen Farben (in meiner Version) angibt und der andere Spieler diesen anschließend versucht herauszufinden und bei jedem Versuch die Angaben kriegt ob eine Farbe richtig geraten ist und sogar am richtigen Platz ist und anderseits noch ob eine Farbe richtig geraten ist, allerdings nicht am richtigen Platz ist. Dabei ist zu beachten, dass wenn z.B. im gesetzen Code der herauszufinden ist rot-blau-blau-blau ist, dann wenn der ratende Spieler blau-rot-rot-rot angibt eben nicht 3 mal gilt dass er die richtige Farbe aber den falschen Platz hat, sondern nur einmal, bei rot-rot-blau-blau und geratenem Code -> blau-blau-rot-rot sieht das nochmal anders aus, da dort zwei mal sogar die Farbe im richtigen Code ist, gilt auch dass zwei mal die richtige Farbe aber am falschen Platz ist.

Ich habe nun einen Array der für den vorgegebenen Code ist, in welchem die Zahlen 1-4 stehen, je nach Farbe, dabei entspricht 1 = blau und 4 = Gelb.
Zudem habe ich einen Array der für den geratenen Code ist, welcher ebenfalls das gleiche System mit den Farben benutzt.
Nun ist die Abfrage ob richtiger Platz + richtige Farbe relativ einfach:
Code:
for (int j = 0;j<=3 ;j++ )
      {
        if (meinArray[j][i] == meinGeheimcode[j]){
          nf.setInt(nf.getInt()+1);
        }
      } // end of for

jedoch verzweifle ich an der anderen Regel. Wie kann ich schecken ob eine angegebene Farbe im vorgegebenen Code vorhanden ist, jedoch an einer anderen Stelle und anschließend NUR einen Punkt geben, wenn diese Farbe auch noch nicht dran war ??

wem ich das Spiel zu blöd erklärt habe, schaut bitte hier noch einmal nach -> https://de.wikipedia.org/wiki/Mastermind_(Spiel) , ich bedanke mich schonmal für diejenigen die sich mit mir Blödkopf hier beschäftigen.
 
Du könntest z.B. den Wert der gerade geprüft wurde aus den "geratenen Werten" entfernen (oder auf Null setzen), damit er bei der nächsten Position nicht mehr geprüft wird.

Wozu hast du ein zweidimensionales Array?
 
Die Beschreibung auf Wikipedia ist doch eindeutig:

Auf jeden Zug hin bekommt der Rater die Information, wie viele Stifte er in Farbe und Position richtig gesetzt hat und wie viele Stifte zwar die richtige Farbe haben, aber an einer falschen Position stehen.

Du iterierst durch die Positionen. Gibt es einen Treffer in Farbe und Position, ist es ein schwarzer/roter Stift.

Danach musst du noch herausfinden, für welche Positionen der Rater einen weissen Stift bekommt. Versuche, dir diese Fragen zu beantworten:

- Für eine Position X im geratenen Code: welche Informationen brauchst du, um zu entscheiden, ob für diese Position einen weisser Stift gegeben werden soll?
- Wie kommst du an diese Infos dran? Kann dir die erste Iteration für die schwarzen Stifte dabei helfen?
 
Du könntest z.B. den Wert der gerade geprüft wurde aus den "geratenen Werten" entfernen (oder auf Null setzen), damit er bei der nächsten Position nicht mehr geprüft wird.

Wozu hast du ein zweidimensionales Array?
http://prntscr.com/hu5qcj -> so sieht meine Gui aus, jede einzelne Spalte der grauen canvas hat einen Array 0-3, damit ich halt nicht 10 einzelne machen muss habe ich einen zweidimensionalen

Die Beschreibung auf Wikipedia ist doch eindeutig:



Du iterierst durch die Positionen. Gibt es einen Treffer in Farbe und Position, ist es ein schwarzer/roter Stift.

Danach musst du noch herausfinden, für welche Positionen der Rater einen weissen Stift bekommt. Versuche, dir diese Fragen zu beantworten:

- Für eine Position X im geratenen Code: welche Informationen brauchst du, um zu entscheiden, ob für diese Position einen weisser Stift gegeben werden soll?
- Wie kommst du an diese Infos dran? Kann dir die erste Iteration für die schwarzen Stifte dabei helfen?

Es ist klar, dass ich abfragen muss ob die geratene Farbe im angegebenen Code vorkommt, allerdings darf dies ja, falls die Farbe nur 1x im vorgegebenen Code vorhanden ist, nicht 2 mal angegeben werden, sollte der geratene Code zwei mal diese Farbe enthalten. Bisher habe ich es so gemacht :
Code:
if (i == 1 && (meinArray[0][1] == meinGeheimcode[0])) {
        nf2.setInt(nf2.getInt()+1);
      }
      else if (i == 1 && ((meinArray[1][1] == meinGeheimcode[0])||(meinArray[2][1] == meinGeheimcode[0])||(meinArray[3][1] == meinGeheimcode[0]))) {
        nf1.setInt(nf1.getInt()+1);
      }
      if (i == 1 && (meinArray[1][1] == meinGeheimcode[1])) {
        nf2.setInt(nf2.getInt()+1);
      }
      else if (i == 1 && ((meinArray[0][1] == meinGeheimcode[1])||(meinArray[2][1] == meinGeheimcode[1])||(meinArray[3][1] == meinGeheimcode[1]))) {
        nf1.setInt(nf1.getInt()+1);
      }
      if (i == 1 && (meinArray[2][1] == meinGeheimcode[2])) {
        nf2.setInt(nf2.getInt()+1);
      }
      else if (i == 1 && ((meinArray[0][1] == meinGeheimcode[2])||(meinArray[1][1] == meinGeheimcode[2])||(meinArray[3][1] == meinGeheimcode[2]))) {
        nf1.setInt(nf1.getInt()+1);
      } 
      if (i == 1 && (meinArray[3][1] == meinGeheimcode[3])) {
        nf2.setInt(nf2.getInt()+1);
      }
      else if (i == 1 && ((meinArray[0][1] == meinGeheimcode[3])||(meinArray[1][1] == meinGeheimcode[3])||(meinArray[2][1] == meinGeheimcode[3]))) {
        nf1.setInt(nf1.getInt()+1);
      }

Dadurch dass i für den jeweiligen Versuch steht, der gerade dran ist und mir somit dabei hilft welches Numberfield ich updaten muss, ist es relativ schwer (für mich jeweils) eine for schleife oder sowas zu machen, da ich insgesamt 20 Numberfields habe, wie du oben im screen auch sehen kannst, und diese dann ja nicht alle ansprechen kann. Zumindest habe ich dafür keine Lösung in Form einer For-Schleife oder sowas gefunden.
 
@Executer
Warum keine ArrayList? Ist doch viel besser 😉
Ich werfe eine Idee ein (wenn bereits implementiert, einfach ignorieren):
Java:
MasterMind mm = new MasterMind();
mm.spielInfo();
mm.setSpielData(SStufe.EASY);
mm.zeigeGeheimFarben();

/** Konsolenausgabe */
HARD, Rundenzahl: 8, Farbenzahl: 6
MEDIUM, Rundenzahl: 12, Farbenzahl: 5
EASY, Rundenzahl: 16, Farbenzahl: 4
BABY, Rundenzahl: 20, Farbenzahl: 3
Blau Orange Grün Rot
 
Von der ArrayList habe ich lediglich gehört, da steht mein Wissensstand auf 0
Ich lege dir ans Herz, Themen wie ArrayList, bzw. List zu verinnerlichen, bevor du weitermachst.
Datenstrukturen und Algorithmen: http://openbook.rheinwerk-verlag.de...13_001.htm#mj245f5f8d5a858b46462d64e9b9c0786b
Generics: http://openbook.rheinwerk-verlag.de...07_001.htm#mjc4a1f6f3499a02fb64fe89046739edca

Als Anreiz:
Java:
public class Test
{

    public static void main(String[] args)
    {
        String gelb = "Gelb";
        String blau = "Blau";
        String gruen = "Grün";
        String rot = "Rot";

        List<String> listeA = new ArrayList<>();
        List<String> listeB = new ArrayList<>();
        List<String> listeC = new ArrayList<>();
        List<String> listeD = new ArrayList<>();

        listeA.add(gelb);
        listeA.add(blau);

        listeB.add(rot);
        listeB.add(gruen);

        listeC.add(gelb);
        listeC.add(blau);

        listeD.add(blau);
        listeD.add(gelb);

        System.out.println(listeA.containsAll(listeB));
        System.out.println(listeA.containsAll(listeC));
        System.out.println(listeA.containsAll(listeD));

        check(listeA, listeC);
        check(listeA, listeD);
        check(listeA, listeB);

    }

    static void check(List<String> a, List<String> b)
    {
        for (int i = 0; i < a.size(); i++) {
            if (a.contains(b.get(i)) && a.get(i).equalsIgnoreCase(b.get(i))) {
                System.out.println("Farbe: richtig, Platz: richtig");
            } else if (a.contains(b.get(i)) && !a.get(i).equalsIgnoreCase(b.get(i))) {
                System.out.println("Farbe: richtig, Platz: falsch");
            } else {
                System.out.println("Farbe: falsch");
            }
        }
    }

}

/** Konsolenausgabe */
false
true
true
Farbe: richtig, Platz: richtig
Farbe: richtig, Platz: richtig
Farbe: richtig, Platz: falsch
Farbe: richtig, Platz: falsch
Farbe: falsch
Farbe: falsch
Viel Erfolg 😉
 
Ich verstehe nicht ganz wieso du 4 Listen machst und diese mit 2 der 4 Farben befüllst.
Um dir die Möglichkeiten aufzuzeigen. Aber wie man bei uns zu sagen pflegt: "Meine Aufgabe ist es, dir Hilfe anzubieten, deine, diese freundlich abzulehnen" 😉 Du kannst natürlich weiterhin ein Array nutzen und alle Methoden selbst implementieren. Nichts spricht dagegen und sollte mal gemacht werden, um zu verstehen, wie dies und das funktioniert. Mein Post diente letztendlich als Vorschlag.
 
Mir stellt sich trotzdem noch eine Frage.
Beispiel: http://prntscr.com/hu6qza (rechts geraten, links gesuchter Code)
Wenn nun im gesuchten Code zwei mal rot ist, müsste auch die Zahl 2 für richtige Farbe falscher Platz ausgegeben werden, da im geratenen Code zwei mal Rot ist, allerdings an der falschen Stelle. Wie kann ich denn nun sagen dass je nach Anzahl einer Farbe im gesuchten Code auch Punkte für falscher Platz und richtige Farbe gegeben werden darf. Mit der Liste kann ich ja die Farbe nur einmal eintragen, ich hoffe man versteht mein Problem..
 
Du kannst den Code natürlich anpassen, sprich, man kann in dem jeweiligen Label die Zahl der Übereinstimmungen und der richtig belegten Plätze ausgeben lassen. Dies ist überhaupt kein Akt. Ich habe mich hier für String entschieden, um dir in gewöhnlicher Sprache das Ergebnis zu präsentieren 😉 Zudem: eine Methode für alle Ergebnisse. Vergleich dein Weg mit meiner Idee und überlege, was besser und vor allem übersichtlicher ist.
Java:
//Geheime Liste der Farben
List<String> listeA = new ArrayList<>();
//Die Eingabe des Spielers: ein Rate-Versuch
List<String> listeB = new ArrayList<>();

listeA.add(gelb);
listeA.add(gelb);
listeA.add(rot);
listeA.add(blau);
      
listeB.add(gelb);
listeB.add(rot);
listeB.add(gelb);
listeB.add(gruen);
      
check(listeB, listeA);
print(listeB, listeA);

/** Konsolenausgabe */
Farbe vorhanden und stimmt mit Platz überein
Farbe vorhanden, jedoch ein anderer Platz
Farbe vorhanden, jedoch ein anderer Platz
Farbe ist nicht vorhanden
Geheim: Gelb, Spieler: Gelb
Geheim: Rot, Spieler: Gelb
Geheim: Gelb, Spieler: Rot
Geheim: Grün, Spieler: Blau
Mit der Liste kann ich ja die Farbe nur einmal eintragen
Hier verwechselst du ArrayList mit HashSet oder TreeSet 😉
 
Und wie macht man das dann bei deiner Art mit dem überprüfen ob die Farbe bereits gescheckt wurde ?

P.S.: Habe eben was falsch gelesen bei deinem Link... habe es mit der Collection verwechselt
 
Zuletzt bearbeitet:
@Executer
Muss jetzt weg, melde mich jedoch nochmal.
Ich habe dein Problem jetzt verstanden, dies erfordert mehr, als die von mir veröffentlichte Methode check(List a, List b), diese muss ausführlicher programmiert werden!
 
habe es nun so:
Java:
if (i == 0) {
       for (int j=0;j<=3 ;j++ )
          {
             if (meinArray[j][i] == meinGeheimcode[j]){
             nf0.setInt(nf0.getInt()+1);
          }
             else if (meinGeheimcode[j] == meinArray[0][i] || meinGeheimcode[j] == meinArray[1][i] || meinGeheimcode[j] == meinArray[2][i] || meinGeheimcode[j] == meinArray[3][i]) {
             nf.setInt(nf.getInt()+1);
          } // end of if-else
          } // end of for
      }

Nun habe ich den Fehler, dass wenn ich einmal den gesuchten Code grün-gelb-grün-gelb habe und den geratenene blau-blau-blau-gelb (-> eine Richtige Farbe mit richtigem Platz -> Richtige plätze und richtige Farbe = 1, Richtige Farbe falsche Plätze = 0), dass das Programm dann Richtige plätze und richtige Farbe = 1, Richtige Farbe falsche Plätze = 1 ausgibt, die richtige Lösung steht ja in der Klammer. Außerdem kann ich auch nicht nachvollziehen wie er auf die Zahl 2 addieren kann, else if wird doch nur ausgeführt wenn das if davor nicht zutrifft oder ?
 
Zuletzt bearbeitet:
Vergiss den letzten Satz, meine natürlich wie er in meinem oberen Numberfield (nf) überhaupt eine 1 setzen kann, da diese nur in der else if Bedingung steht, die bei zutreffendem if soweit ich weiß nicht ausgeführt werden sollte.
 
Also, habe bis jetzt nicht viel mehr herausgefunden, weiß nur dass es einen Fehler gibt der so aussieht -> http://prntscr.com/huaigl
Hoffe das veranschaulicht das Problem jetzt gut, hier nochmal den Code den ich momentan benutze, der dieses Problem allerdings nicht durchblickt:
Java:
if (i == 0) {
       for (int j=0;j<=3 ;j++ )
          {
             if (meinArray[j][i] == meinGeheimcode[j]){
             nf0.setInt(nf0.getInt()+1);
          }
             else if (meinGeheimcode[j] == meinArray[0][i] || meinGeheimcode[j] == meinArray[1][i] || meinGeheimcode[j] == meinArray[2][i] || meinGeheimcode[j] == meinArray[3][i]) {
             nf.setInt(nf.getInt()+1);
          } // end of if-else
          } // end of for
      }

Hoffe jemand anders hat eine Ahnung wie man das Lösen könnte, ich hätte nur die Idee dass man dem Programm sagt dass die Array Stelle die die Vorgänger benutzt haben um einen Punkt zu geben nicht mehr erlaubt ist, weiß aber nicht wie ich die rauskriegen könnte, ich habe ja einen zweidimensionalen Array [][], bei dem die zweite Klammer den Versuch angibt(i=...) und der erste die stelle, dabei ist die oberste geratene Farbe 0 und die unterste 3.
 
@Executer
Java:
String gelb = "Gelb";
String blau = "Blau";
String gruen = "Grün";
String rot = "Rot";

//Geheime Liste der Farben
List<String> listeA = new ArrayList<>();
listeA.add(rot);
listeA.add(rot);
listeA.add(gelb);
listeA.add(gelb);

List<String> listeB = new ArrayList<>();
List<String> listeC = new ArrayList<>();
List<String> listeD = new ArrayList<>();

listeB.add(rot);
listeB.add(rot);
listeB.add(gelb);
listeB.add(gelb);

listeC.add(rot);
listeC.add(gelb);
listeC.add(rot);
listeC.add(gelb);

listeD.add(gruen);
listeD.add(gruen);
listeD.add(blau);
listeD.add(blau);

System.out.println("Ausgangssituation");
print(listeA, listeB);

System.out.println("Liste A und Liste B: Zahlen und Positionen gleich");
check2(listeA, listeB);
System.out.println("Liste A und Liste C: Zahlen und Positionen gleich und gemischt");
check2(listeA, listeC);
System.out.println("Liste A und Liste D: Zahlen und Positionen stimmen nicht überein");
check2(listeA, listeD);

/** Konsolenausgabe */
Ausgangssituation
Geheim: Rot, Spieler: Rot
Geheim: Rot, Spieler: Rot
Geheim: Gelb, Spieler: Gelb
Geheim: Gelb, Spieler: Gelb
Liste A und Liste B: Zahlen und Positionen gleich
Farbe an richtiger Stelle: 4 Mal
Liste A und Liste C: Zahlen und Positionen gleich und gemischt
Farbe an richtiger Stelle: 2 Mal, Farbe vorhanden, aber nicht an richtiger Stelle:  2 Mal
Liste A und Liste D: Zahlen und Positionen stimmen nicht überein
Weder die Farben noch Positionen stimmen überein
Wie so oft, brachte ein Schreibtischtest binnen Minuten die Lösung. Die Idee teile ich mit dir, des Aha-Momentes will ich dich nicht berauben 😉

- Vergleiche den GeheimArray und den SpielerArray
- Wenn Platz und Farbe übereinstimmen, schwarz++, die Position im SpielerArray wird überschrieben, so, dass es durchs Raster fällt.
- Vergleiche anschließend die Arrays nocheinmal und bei Übereinstimmung white++
- passe die Textausgabe den aktuellen Bedingungen an.

Viel Erfolg!
 
Das Programm will mich veräppeln.
Java:
if (i == 0) {
       for (int j=0;j<=3 ;j++)
          {
            if (meinArray[j][i] == meinGeheimcode[j]){
            nf0.setInt(nf0.getInt()+1);
            meinArray[j][i]=0;
          }
            else if (meinGeheimcode[j] == meinArray[0][i] || meinGeheimcode[j] == meinArray[1][i] || meinGeheimcode[j] == meinArray[2][i] || meinGeheimcode[j] == meinArray[3][i]) {
            nf.setInt(nf.getInt()+1);
          } // end of if-else
          } // end of for
      }

gesuchter code: grün-gelb-grün-gelb
geratener code: blau-blau-gelb-blau

wie kommt das Programm auf 2 mal richtige Farbe falscher Platz, ich kann es einfach nicht nachvollziehen, für mich ergibt das einfach keinen Sinn, da das else if dafür zwei mal durch den gesuchten Code gehen muss um zwei mal +1 zu geben
 
Zuletzt bearbeitet:
finally, ich habe es, hatte bei der Bedingung mal wieder einen Fehler, ich habe die verglichene Farbe aus dem geratenen Code immer vertauscht, das war allerdings gar nicht nötig, also anstatt
Code:
else if ( meinArray[0][i] == meinGeheimcode[j] || meinArray[1][i] == meinGeheimcode[j] .........
musste das dort hin
Code:
else if (meinArray[j][i] == meinGeheimcode[0] || meinArray[j][i] == meinGeheimcode[1] ........
 
So, jetzt noch schnell das mit dem aus dem Raster setzen für die else if Fälle gemacht (zunächst wird die Stelle gesucht durch die der Punkt gegeben wurde(die for-schleife))mit:
Java:
else if (meinArray[j][i] == meinGeheimcode[0] || meinArray[j][i] == meinGeheimcode[1] || meinArray[j][i] == meinGeheimcode[2] || meinArray[j][i] == meinGeheimcode[3]) {
            nf17.setInt(nf17.getInt()+1);
            for (int k=0;k<=3 ;k++ ) {
              if (meinGeheimcode[k]== meinArray[j][i]) {
              meinGeheimcode[k] = 5;
              }
            } // end of for
          } // end of if-else

Nun funktioniert alles so wie es soll !
Danke für deine Hilfe, hast mir echt weitergeholfen, damit ist meine Facharbeit schon fast fertig 🙂
Jetzt nurnoch ein bisschen Dokumentieren und eventuell weitere Fehler suchen, melde mich falls ich welche finde🙄
 
Spielst du schon oder tippst du noch? 🙂
Die Statistik über die gespielte Spiele gibt es natürlich auch noch, aber ich bin echt platt und habe auf MasterMind irgendwie keine richtige Lust mehr.

Lass sehen! 😉
Java:
Wahl: Schwierigkeitsstufe
HARD, Rundenzahl: 2, Farbenzahl: 6
MEDIUM, Rundenzahl: 12, Farbenzahl: 5
EASY, Rundenzahl: 16, Farbenzahl: 4
BABY, Rundenzahl: 20, Farbenzahl: 3
Hard: 1, Medium: 2, Easy: 3, Baby: 4, Abbruch: 5
5
Sehr schade, dass Sie jetzt gehen wollen
Java:
Wahl: Schwierigkeitsstufe
HARD, Rundenzahl: 8, Farbenzahl: 6
MEDIUM, Rundenzahl: 12, Farbenzahl: 5
EASY, Rundenzahl: 16, Farbenzahl: 4
BABY, Rundenzahl: 20, Farbenzahl: 3
Hard: 1, Medium: 2, Easy: 3, Baby: 4, Abbruch: 5
2
Spielrunde Nr: 12
Blue Green Lila Grey Yellow
Farbe Nr: 1 :
Blue
Farbe Nr: 2 :
Green
Farbe Nr: 3 :
Lila
Farbe Nr: 4 :
Grey
Farbe Nr: 5 :
Yellow
Farbe vorhanden und an richtiger Stelle: 5 Mal
Gewonnen! Herzlichen Glückwunsch
Java:
Wahl: Schwierigkeitsstufe
HARD, Rundenzahl: 2, Farbenzahl: 6
MEDIUM, Rundenzahl: 12, Farbenzahl: 5
EASY, Rundenzahl: 16, Farbenzahl: 4
BABY, Rundenzahl: 20, Farbenzahl: 3
Hard: 1, Medium: 2, Easy: 3, Baby: 4, Abbruch: 5
1
Spielrunde Nr: 2
Yellow Green Blue Red Lila Orange
Farbe Nr: 1 :
Green
Farbe Nr: 2 :
Blue
Farbe Nr: 3 :
Blue
Farbe Nr: 4 :
Red
Farbe Nr: 5 :
Lila
Farbe Nr: 6 :
Orange
Farbe vorhanden und an richtiger Stelle: 4 Mal, Farbe vorhanden, aber an falscher Stelle: 1 Mal
Spielrunde Nr: 1
Yellow Green Blue Red Lila Orange
Farbe Nr: 1 :
Yellow
Farbe Nr: 2 :
Green
Farbe Nr: 3 :
Blue
Farbe Nr: 4 :
Red
Farbe Nr: 5 :
Red
Farbe Nr: 6 :
Orange
Farbe vorhanden und an richtiger Stelle: 5 Mal
Leider hatten Sie Pech, viel Glück beim nächsten Mal!
Die zu ereatenen Farben waren:
[[Yellow, Green, Blue, Red, Lila, Orange]]
 

Zurück
Oben