Hallöle,
ich arbeite gerade an einem kleinen Mastermind Spiel. Die Grafik funktioniert gescheit (Keiner meckert jetzt hier über NullLayout, das ist irrelevant für das Problem…) und auch die direkten Treffer, wenn zwei Farben übereinstimmen werden in den Kontrollfeldern richtig dargestellt. (Schwarze Farbe)
Aber die Rote Farbe, die mir anzeigt, ob eine Farbe zwar verhanden, aber nicht an der richtigen Stelle ist, die macht er nicht richtig.
Mein Programm hat zwei Klassen. In “Farbfeld” definiere ich die kleinen Panel mit den Farben, wo man durch einfaches durchklicken auf die nächste Farbe schaltet:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
public class Farbfeld extends JPanel {
private int farbe = -1;
private boolean aktiviert = false;
public Farbfeld() {
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
aufMausReagieren();
}
});
}
public void paint(Graphics stift) {
switch (farbe) {
case 0:
stift.setColor(Color.yellow);
break;
case 1:
stift.setColor(Color.blue);
break;
case 2:
stift.setColor(Color.red);
break;
case 3:
stift.setColor(Color.green);
break;
case 4:
stift.setColor(Color.pink);
break;
case 5:
stift.setColor(Color.cyan);
break;
default:
stift.setColor(Color.gray);
break;
}
stift.fillRect(0,0,this.getWidth(),this.getHeight());
}
public void nextColor() {
if(farbe<5) {
farbe++;
} else {
farbe=0;
}
this.repaint();
}
public int getFarbe() {
return farbe;
}
public void aufMausReagieren() {
if(aktiviert == true) {
nextColor();
repaint();
}
}
public void setAktiviert(boolean neuerwert) {
aktiviert = neuerwert;
}
}```
Der Kern ist die Klasse "Mastermind":
```package mastermind;
import java.awt.Color;
import java.awt.Container;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Mastermind {
private JFrame frame1 = new JFrame("Mastermind");
private JButton buttonpruefen = new JButton("Überprüfen");
private JPanel jPanel1 = new JPanel();
private int anzahlreihen = 8;
private int reihe = 0;
private Farbfeld[][] spielfeld = new Farbfeld[4][anzahlreihen];
private JPanel[][] kontrollfeld = new JPanel[4][anzahlreihen];
private int[] geheimnis = new int[4];
private int schwarz, rot;
private int[] farberichtig = new int[4];
public Mastermind() {
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setSize(200,380);
frame1.setResizable(false);
Container cp = frame1.getContentPane();
cp.setLayout(null);
buttonpruefen.setBounds(20, 315, 120, 33);
buttonpruefen.setMargin(new Insets(2, 2, 2, 2));
buttonpruefen.setVisible(true);
buttonpruefen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
buttonpruefe_ActionPerformed(evt);
}
});
cp.add(buttonpruefen);
jPanel1.setBounds(10, 275, 33, 33);
jPanel1.setBackground(Color.ORANGE);
jPanel1.setVisible(true);
int jx = jPanel1.getX();
int jy = jPanel1.getY();
int jw = jPanel1.getWidth();
for(int py=0; py<anzahlreihen; py++) {
for(int px=0; px<4; px++) {
spielfeld[px][py] = new Farbfeld();
spielfeld[px][py].setBounds(jx+px*(jw+5),jy-py*(jw+5),jw,jw);
if(py==0) {
spielfeld[px][py].setAktiviert(true);
}
cp.add(spielfeld[px][py]);
}
}
for(int py=0; py<anzahlreihen; py++) {
for(int px=0; px<2; px++) {
for(int pz=0; pz<2; pz++) {
kontrollfeld[px+2*pz][py] = new JPanel();
kontrollfeld[px+2*pz][py].setBounds(jx+4*(jw+5)+px*jw/2,jy-py*(jw+5)+pz*jw/2,jw/2-4, jw/2-4);
kontrollfeld[px+2*pz][py].setBackground(Color.LIGHT_GRAY);
cp.add(kontrollfeld[px+2*pz][py]);
}
}
}
frame1.setLocationRelativeTo(null);
frame1.setVisible(true);
start();
}
public void start() {
Random farbwuerfel = new Random();
System.out.print("Geheimcode: ");
for(int n=0;n<4;n++) {
geheimnis[n] = farbwuerfel.nextInt(6);
System.out.print(geheimnis[n]);
}
System.out.println("");
}
public void buttonpruefe_ActionPerformed(ActionEvent evt) {
for(int n=0;n<4;n++) {
farberichtig[n] = 0;
}
schwarz = 0; rot = 0;
for(int px=0;px<4;px++) {
spielfeld[px][reihe].setAktiviert(false);
spielfeld[px][reihe+1].setAktiviert(true);
for(int z=0;z<4;z++) {
if(spielfeld[px][reihe].getFarbe() == geheimnis[z]) {
if(px == z) {
schwarz++;
farberichtig[z] = 1;
} else if(farberichtig[z] != 1) {
System.out.println("px:"+px+" z:"+z);
rot++;
}
}
}
}
//rot -= schwarz;
System.out.println("Übereinstimmungen: "+schwarz);
System.out.println("Indirekt: "+rot);
for(int a=0;a<schwarz;a++) {
kontrollfeld[a][reihe].setBackground(Color.black);
}
for(int b=schwarz;b<schwarz+rot;b++) {
//if(b<4) {
kontrollfeld**[reihe].setBackground(Color.red);
//}
}
reihe++;
}
public static void main(String[] args) {
new Mastermind();
}
}```
Ich habe einen Spielfeldarray[][], wobei x stets die vier Kästchen nebeneinander sind (0 bis 3) und y die Reihe. Die Reihen zählen von unten nach oben, je nach Spielrunde eben. Es gelten also die Klassischen Mastermindregeln.
Rechts sind die vier Komtrollkästchen dazu.
So sieht das dann aus:
Ich klicke in der aktuellen Reihe jeweils die vier Kästchen meine Farbtipps durch und beim Klick auf Überprüfen rechnet er die Tipps in den Kontrollkästchen aus. Außerdem sperrt er die geratene Reihe vor neuen Klicken ab und schaltet die nächste Reihe frei.
Aber beim Überprüfungsalgorithmus gibt es einen Hacken.
Es gibt die 6 Farben (0 bis 5), die alle in einen geheimnis[]-array gespeichert werden.
Und ansonsten krieg ich die Farbwerte eines Kästchens hiermit heraus:
`spielfeld[px][reihe].getFarbe()`
Ich schalte dann in zwei Forschleifen mit dem Wert px für die Nummer des Kontrollkästchens und z für die Nummern der Farblösungen durch.
Wenn etwas übereinstimmt, dann guckt er ob die Ziffern gleich sind. Wenn ja, dann muss es sich um dieselben Felder handeln und er kann Schwarz ausgeben.
Wenn nicht, dann muss er Rot auswerfen.
Und mit Rot hab ich so meine Probleme.
Folgendes Beispiel:
Die Lösung ist: Rot-Grün-Blau-Rot
Wenn ich jetzt als Spieler rate: Rot-Grün-Rot-Blau, dann müsste er mir zwei Schwarze und zwei Rote anzeigen. Die ersten beiden sind komplett richtig (schwarz) und de letzten beiden sind als farben korrekt, aber an der falschen Stelle (rot).
Jedoch denkt das Programm dann schon einen Schritt weiter und sieht, aha, Rot ist ja zweimal da, und zählt dann zu viel hoch. Obwohl Rot ja ganz vorne schon als richtig galt.
Ich hoffe ich habe das jetzt nicht zu verwirrend beschrieben und man versteht es.
====
Meine erste Lösungsidee war:
Ich habe mir das hier geschrieben: `private int[] farberichtig = new int[4];`
Das heißt, wenn eines der vier Kästchen an der richtigen Stelle bestimmt war, ändere ich den Wert da auf 1, damit das Programm dann in einer If-bedingung merkt, das Feld hab ich aber schon verbraten. Das ändert aber irgendwie nichts.
Ich habe keine Ahnung, was da schief läuft.
Kann mir einer sagen, was ich in dem Algorithmus anders machen müsste?
Bei unbekannten Mastermindregeln, kann man diese hier angucken: https://de.wikipedia.org/wiki/Mastermind_(Spiel)
Viele Grüße
Lukas