Moin Leute, ich bin leider absolut überfordert bei einer KI für das Spiel TicTacToe.
Die Aufgabe ist es eine neue Klasse TTTKI zu programmieren, die die aktuelle Spielfeldsituation übergeben bekommt und ihren nächsten Zug an das Hauptprogramm übergibt. Meine java Kenntnisse sind dazu aber nicht ausreichend, kann das vielleicht einer von euch?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
*
* TicTacToe mit KI
*
* Wenn Ki ausgeschaltet können zwei Spieler abwechselnd klicken
* KIs werden über eine externe Klasse ins Programm eingefügt und diese müssen
* die Schnittstelle erfüllen.
* Wenn KI1 oder KI2 eingeschaltet muss man auch pro Spielzug klicken,
* allerdings wird der Zug von der KI ausgeführt.
* Es können auch zwei KIs gegeneinander spielen.
*/
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
//TTTKI1 ki1 = new TTTKI1();
//TTTKIkei ki2 = new TTTKIkei();
// 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 = false;
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");
}
}
// 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
}