Moin Freunde, ich verzweifle gerade sehr zu folgender TicTacToe Vorlage eine KI mit MiniMax Algorithmus zu programmieren.
Eine (mehr oder wenig dumme) KI habe ich schon, allerdings bin ich mit ihr nicht zufrieden da sie aus sehr vielen if-Anweisungen besteht…
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class tictactoe extends JFrame {
// Anfang Variablen
// Anfang Attribute
private int SpielerAmZug;
private int[][] Feld = new int[3][3];
private boolean spielende;
private boolean KI1;
private boolean KI2;
//KIs deklarieren und initialisieren
KI ki1 = new KI();
//JustKIn2 ki2 = new JustKIn2();
// Ende Attribute
// Ende Variablen
public tictactoe(String title) {
// Frame-Initialisierung
super(title);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) { System.exit(0); }
});
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(MouseEvent e) {
Spielzug(e);
//JOptionPane.showMessageDialog(null,"X-Position: "+e.getX()+"\nY-Position: "+e.getY());
}
});
int frameWidth = 300;
int frameHeight = 300;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2 ;
setLocation(x, y);
Container cp = getContentPane();
cp.setLayout(null);
// Anfang Komponenten
// Ende Komponenten
setResizable(false);
setVisible(true);
// Feldarray auf Null setzen
for (int i = 0; i<=2; i++)
for (int j = 0; j<=2; j++) Feld[i][j] = 0;
//Spieler 1 am Zug
SpielerAmZug = 1;
//Spiel läuft
spielende = false;
//KIs eingeschaltet?
KI1 = true;
KI2 = false;
}
// Anfang Methoden
public void Spielerwechsel() {
if (SpielerAmZug == 1) SpielerAmZug = 2;
else SpielerAmZug = 1;
}
//Methode zum Spielende
private void Spielende(boolean sieger) {
if (sieger) JOptionPane.showMessageDialog(null,"Spieler " + SpielerAmZug + " hat gewonnen");
else JOptionPane.showMessageDialog(null,"unentschieden");
//Spiel ist zu Ende
spielende = true;
}
//Methode untersucht die aktuelle Spielsituation!!!
public void Spielsituation(){
boolean sieger = false;
boolean unentschieden = false;
//Zeile oder Reihe komplett?
for (int i=0; i<3; i++)
{
if ((Feld[i][0]!=0) && (Feld[i][0]==Feld[i][1]) && (Feld[i][1]==Feld[i][2])) sieger = true;
if ((Feld[0][i]!=0)&&(Feld[0][i]==Feld[1][i])&&(Feld[1][i]==Feld[2][i])) sieger = true;
}
//Diagonale komplett?
if (((Feld[0][0]!=0)&&(Feld[0][0]==Feld[1][1])&&(Feld[1][1]==Feld[2][2])) ||
((Feld[0][2]!=0)&&(Feld[0][2]==Feld[1][1])&&(Feld[1][1]==Feld[2][0]))) sieger = true;
//unentschieden - alle Felder belegt und kein Sieger?
if ((Feld[0][0]!=0)&&(Feld[0][1]!=0)&&(Feld[0][2]!=0)&&
(Feld[1][0]!=0)&&(Feld[1][1]!=0)&&(Feld[1][2]!=0)&&
(Feld[2][0]!=0)&&(Feld[2][1]!=0)&&(Feld[2][2]!=0)) unentschieden = true;
//Wenn es einen Sieger oder unentschieden gibt, gib die entsprechende Meldung aus, ansonsten wieterspielen.
if (sieger) Spielende(true);
else if (unentschieden) Spielende(false);
else Spielerwechsel();
}
private void Spielzug(MouseEvent e) {
//Mausklick wird nur akzeptiert, wenn Spiel noch läuft
if (!spielende){
// ungültige Initialisierung von Zeile und Spalte
int Zeile = -1;
int Spalte = -1;
//Spielt eine KI oder spielt der Mensch?
if (SpielerAmZug == 1 && KI1){
ki1.setSituation(Feld);
Zeile = ki1.getZeile();
Spalte = ki1.getSpalte();
} else if (SpielerAmZug == 2 && KI2) {
//ki2.setSituation(Feld);
//Zeile = ki2.getZeile();
//Spalte = ki2.getSpalte();
} else {
//Spalte, in die geklickt wurde (0..2) lässt sich leicht berechnen
Spalte = 3*e.getX() / this.getWidth();
//Zeile leider nicht, da wieder der obere Rand dazugehört...
if (e.getY() < (this.getHeight()-23)/3+23) Zeile = 0;
else if (e.getY() < 2* (this.getHeight()-23)/3+23) Zeile = 1;
else Zeile = 2;
}
//Array Feld mit dem neuen Eintrag belegen, falls schon belegt, Meldung machen
if (Feld[Zeile][Spalte] == 0) {
Feld[Zeile][Spalte] = SpielerAmZug;
repaint();
Spielsituation();
}
else JOptionPane.showMessageDialog(null,"Feld ist schon belegt! Wähle ein anderes Feld aus.");
}
}
// Anfang Ereignisprozeduren
public void paint(Graphics g) {
//Hier wird das Spielfeld gezeichnet
g.setColor(Color.white);
g.fillRect(0,0,this.getWidth(),this.getHeight());
g.setColor(Color.black);
g.drawLine(0,(this.getHeight()-23)/3+23,this.getWidth(),(this.getHeight()-23)/3+23); //Ausgleich um 23 Pixel, da Rahmen oben zur Höhe mitzählt (23 Pixel)
g.drawLine(0, 2* (this.getHeight()-23)/3+23,this.getWidth(),2* (this.getHeight()-23)/3+23);
g.drawLine(this.getWidth()/3,0,this.getWidth()/3,this.getHeight());
g.drawLine(2*this.getWidth()/3,0,2*this.getWidth()/3,this.getHeight());
//und jetzt noch die gesetzten Kreise und Kreuze je nach Feldbelegung
for (int i = 0; i<=2; i++)
for (int j = 0; j<=2; j++) {
switch (Feld[i][j]) {
case 1 : {
g.setColor(Color.blue);
g.fillOval(j*this.getWidth()/3 +12 , i*((this.getHeight()-23)/3)+23 + 12, this.getHeight()/3 - 25 ,this.getHeight()/3 - 25 );
break;
}
case 2 : {
g.setColor(Color.red);
g.fillOval(j*this.getWidth()/3 +12 , i*((this.getHeight()-23)/3)+23 + 12, this.getHeight()/3 - 25 ,this.getHeight()/3 - 25 );
}
}
}
}
// Ende Ereignisprozeduren
public static void main(String[] args) {
new tictactoe("tictactoe");
}
// Ende Methoden
}