TicTacToe MiniMax Algorithmus geht nicht

Fabel

Neues Mitglied
Ich wollte ein Tic-Tac-Toe mit einem Computer gesteuerten Gegenspieler programmieren, dafür habe ich einen zwei dimensionalen JButton Array verwendet. Leider geht der Computer immer das Array durch und macht seinen Zug bei der nächsten freien Stelle. Ich habe mir auch schon den Code auf Wikipedia angsehen, allerdings finde ich meinen Fehler nicht.

Hier macht der Computer seinen Zug:
Java:
public void hardgame() {

    int bestscore = Integer.MIN_VALUE;
    int movei= 0;
    int movej= 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            buttons[i][j].setForeground(new Color(245, 248, 255));
            if (buttons[i][j].getText() == "") {
            buttons[i][j].setText("O");
            int score = minimax(buttons, 0, false);
            buttons[i][j].setText("");
            if (score > bestscore) {
                bestscore = score;
               movei = i;
               movej = j;

            }
            }
        }
    }
    buttons[movei][movej].setText("O");
    check();
    if (!ende) {
        textfield.setText("X am Zug");
        player1_turn = true;
    }
}
Und hier soll der Computer seinen Zug machen:
Java:
[/B]
public int minimax(JButton[][] buttons, int depth, boolean isMax) {
    if(victor != 0){
        return victor;
    }

    if (isMax) {
        int bestscore = Integer.MIN_VALUE;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j<3;j++) {
                buttons[i][j].setForeground(new Color(245, 248, 255));
                if (buttons[i][j].getText() == "") {

                    buttons[i][j].setText("O");
                    int score = minimax(buttons, depth + 1, false);
                    buttons[i][j].setText("");
                    bestscore = Math.max(score, bestscore);
                }
            }
        }


        return bestscore;
    } else {
        int bestscore = Integer.MAX_VALUE;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j<3; j++) {
                buttons[i][j].setForeground(new Color(245, 248, 255));
                if (buttons[i][j].getText() == "") {

                    buttons[i][j].setText("X");
                    int score = minimax(buttons, depth + 1, true);
                    buttons[i][j].setText("");
                    bestscore = Math.min(score, bestscore);
                }
            }
        }
        return bestscore;
    }

}
[B]
 
K

kneitzel

Gast
Zeige mL den ganze Code. Aber was so erst einmal auffällt: Du hast eine Prüfung auf Victor aber diese Variable wird icht gesetzt. Er läuft also immer in ein return hinein, dass in den Felder nichts mehr frei ist so dass er die verschachtelten Schleifen durchläuft um dann denn Initialisierten Wert zurück zu geben.
 

Fabel

Neues Mitglied
Hier ist mein ganzer Code, und schonmal danke für den Tipp:
Java:
[/B]
package tictac;

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class TicTacToe implements ActionListener {
    Random random = new Random();
    JFrame frame = new JFrame("TicTacToe");
    JPanel title_panel = new JPanel();
    JPanel button_panel = new JPanel();
    JPanel options = new JPanel();
    JLabel textfield = new JLabel();
    JButton ai = new JButton();
    JButton twoplayer = new JButton();
    JCheckBox easy = new JCheckBox();
    JCheckBox medium = new JCheckBox();
    JCheckBox hard = new JCheckBox();
    ButtonGroup gruppe = new ButtonGroup();
    JLabel turn = new JLabel();
    JLabel difficulty = new JLabel();
    JButton[][] buttons = new JButton[3][3];
    boolean player1_turn;
    boolean realplayer;
    boolean jmdgewonnen = false;
    int victor = 0;
    boolean ende = false;
    boolean unentschieden = false;

    TicTacToe() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(730, 800);
        frame.getContentPane().setBackground(new Color(245, 248, 255));
        frame.setLayout(new BorderLayout());
        frame.setVisible(true);
        gruppe.add(easy);
        gruppe.add(medium);
        gruppe.add(hard);
        textfield.setBackground(new Color(161, 189, 255));
        textfield.setForeground(new Color(245, 248, 255));
        textfield.setFont(new Font("Arial", Font.BOLD, 70));
        textfield.setHorizontalAlignment(JLabel.CENTER);
        textfield.setText("Tic-Tac-Toe");
        textfield.setOpaque(true);
        title_panel.setLayout(new BorderLayout());
        title_panel.setBounds(0, 0, 800, 100);
        options.setBounds(0, 0, 800, 300);
        button_panel.setLayout(new GridLayout(3, 3));
        button_panel.setBackground(new Color(245, 248, 255));
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j <3; j++){
                buttons[i][j] = new JButton();
                button_panel.add(buttons[i][j]);
                buttons[i][j].setFont(new Font("Arial", Font.BOLD, 120));
                buttons[i][j].setFocusable(false);
                buttons[i][j].addActionListener(this);
                buttons[i][j].setBackground(new Color(161, 189, 255));
            }

        }
        turn.setBackground(new Color(161, 189, 255));
        turn.setForeground(new Color(245, 248, 255));
        turn.setFont(new Font("Arial", Font.BOLD, 56));
        turn.setHorizontalAlignment(JLabel.CENTER);
        turn.setText("2 Spieler oder gegen KI?");
        turn.setOpaque(true);
        ai.setBackground(new Color(181, 203, 255));
        ai.setFont(new Font("Arial", Font.BOLD, 50));
        ai.setHorizontalAlignment(JLabel.CENTER);
        ai.setFocusable(false);
        ai.setSize(50, 50);
        ai.setText("Einzelspieler");
        ai.setForeground(new Color(245, 248, 255));
        twoplayer.setBackground(new Color(181, 203, 255));
        twoplayer.setFont(new Font("Arial", Font.BOLD, 50));
        twoplayer.setHorizontalAlignment(JLabel.CENTER);
        twoplayer.setFocusable(false);
        twoplayer.setSize(50, 50);
        twoplayer.setText("Mehrspieler");
        twoplayer.setForeground(new Color(245, 248, 255));

        // ai difficluty
        difficulty.setBackground(new Color(161, 189, 255));
        difficulty.setForeground(new Color(245, 248, 255));
        difficulty.setFont(new Font("Arial", Font.BOLD, 56));
        difficulty.setHorizontalAlignment(JLabel.CENTER);
        difficulty.setText(" Schwierigkeitsgrad: ");
        difficulty.setOpaque(true);

        easy.setBackground(new Color(161, 189, 255));
        easy.setForeground(new Color(245, 248, 255));
        easy.setFont(new Font("Arial", Font.BOLD, 40));
        easy.setHorizontalAlignment(JLabel.CENTER);
        easy.setText("Easy");
        easy.setOpaque(true);

        medium.setBackground(new Color(161, 189, 255));
        medium.setForeground(new Color(245, 248, 255));
        medium.setFont(new Font("Arial", Font.BOLD, 40));
        medium.setHorizontalAlignment(JLabel.CENTER);
        medium.setText("Medium");
        medium.setOpaque(true);

        hard.setBackground(new Color(161, 189, 255));
        hard.setForeground(new Color(245, 248, 255));
        hard.setFont(new Font("Arial", Font.BOLD, 40));
        hard.setHorizontalAlignment(JLabel.CENTER);
        hard.setText("Hard");
        hard.setOpaque(true);

        title_panel.add(textfield);
        frame.add(title_panel, BorderLayout.NORTH);
        options.add(turn);
        options.add(ai);
        options.add(twoplayer);
        options.add(difficulty);
        options.add(easy);
        options.add(medium);
        options.add(hard);

        frame.add(options, BorderLayout.CENTER);
        medium.setSelected(true);
        check();
        firstTurn();

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        jmdgewonnen = false;
        unentschieden = false;
        check();

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3;j++){
                if (e.getSource() == buttons[i][j]) {
                    if (player1_turn) { // erster Spieler
                        if (buttons[i][j].getText() == "") {

                            buttons[i][j].setForeground(new Color(245, 248, 255));
                            buttons[i][j].setText("X");
                            check();

                            player1_turn = false;

                            if (realplayer) {
                                check();

                                textfield.setText("O am Zug");
                                check();

                            } else {
                                textfield.setText("Der Computer zieht");
                                if (easy.isSelected()) {
                                    easygame();
                                } else if (hard.isSelected()) {
                                    hardgame();
                                } else {
                                    mediumgame();
                                }
                                check();

                            }

                        }

                    } else if (realplayer) { // zweiter Spieler
                        check();

                        if (buttons[i][j].getText() == "") {
                            buttons[i][j].setForeground(new Color(245, 248, 255));
                            buttons[i][j].setText("O");
                            player1_turn = true;
                            textfield.setText("X am Zug");
                            check();

                        }
                        check();


                    }

                }

            }

        }
    }

    public void firstTurn() {
        twoplayer.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                jmdgewonnen = false;
                unentschieden = false;
                realplayer = true;
                for (int i = 0; i < 3; i++) {
                    for(int j = 0; j < 3; j++){
                        buttons[i][j].setText("");
                        buttons[i][j].setBackground(new Color(161, 189, 255));
                        buttons[i][j].setEnabled(true);
                    }

                }
                frame.add(button_panel);
                options.setVisible(false);
                button_panel.setVisible(true);
                realplayer = true;
                check();
                draw();
                if (random.nextInt(2) == 0) {
                    player1_turn = true;
                    textfield.setText("X am Zug");
                } else {
                    player1_turn = false;
                    textfield.setText("O am Zug");
                }

            }
        });

        ai.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                unentschieden = false;
                ende = false;
                victor = 0;
                realplayer = false;
                check();
                for (int i = 0; i < 3; i++) {
                    for(int j = 0; j < 3; j++){
                        buttons[i][j].setText("");
                        buttons[i][j].setBackground(new Color(161, 189, 255));
                        buttons[i][j].setEnabled(true);
                    }

                }
                frame.add(button_panel);
                options.setVisible(false);
                button_panel.setVisible(true);
                realplayer = false;

                if (random.nextInt(2) == 1) {
                    player1_turn = true;
                    textfield.setText("Du bist am Zug");
                } else {
                    player1_turn = false;
                    textfield.setText("Der Computer zieht");
                    if (easy.isSelected()) {
                        easygame();
                    } else if (hard.isSelected()) {

                        hardgame();
                    } else {
                        mediumgame();
                    }

                }

            }
        });
    }

    public void check() {
        // x com
        //horizontal

        if (buttons[0][0].getText() == "X" && buttons[1][0].getText() == "X" && buttons[2][0].getText() == "X") {
            xWins();

        }
        if (buttons[0][1].getText() == "X" && buttons[1][1].getText() == "X" && buttons[2][1].getText() == "X") {
            xWins();

        }
        if (buttons[0][2].getText() == "X" && buttons[1][2].getText() == "X" && buttons[2][2].getText() == "X") {
            xWins();

        }
        // vertikal
        if (buttons[0][0].getText() == "X" && buttons[0][1].getText() == "X" && buttons[0][2].getText() == "X") {
            xWins();

        }
        if (buttons[1][1].getText() == "X" && buttons[1][2].getText() == "X" && buttons[1][0].getText() == "X") {
            xWins();

        }
        if (buttons[2][1].getText() == "X" && buttons[2][2].getText() == "X" && buttons[2][0].getText() == "X") {
            xWins();

        }
        // diagonal
        if (buttons[0][0].getText() == "X" && buttons[1][1].getText() == "X" && buttons[2][2].getText() == "X") {
            xWins();
        }
        if (buttons[2][0].getText() == "X" && buttons[1][1].getText() == "X" && buttons[0][2].getText() == "X") {
            xWins();
        }
        // O Wins
        //horizontal

        if (buttons[0][0].getText() == "O" && buttons[1][0].getText() == "O" && buttons[2][0].getText() == "O") {
                oWins();

        }
        if (buttons[0][1].getText() == "O" && buttons[1][1].getText() == "O" && buttons[2][1].getText() == "O") {
            oWins();

        }
        if (buttons[0][2].getText() == "O" && buttons[1][2].getText() == "O" && buttons[2][2].getText() == "O") {
            oWins();

        }
        // vertikal
        if (buttons[0][0].getText() == "O" && buttons[0][1].getText() == "O" && buttons[0][2].getText() == "O") {
            oWins();

        }
        if (buttons[1][1].getText() == "O" && buttons[1][2].getText() == "O" && buttons[1][0].getText() == "O") {
            oWins();

        }
        if (buttons[2][1].getText() == "O" && buttons[2][2].getText() == "O" && buttons[2][0].getText() == "O") {
            oWins();

        }
        // diagonal
        if (buttons[0][0].getText() == "O" && buttons[1][1].getText() == "O" && buttons[2][2].getText() == "O") {
            oWins();
        }
        if (buttons[2][0].getText() == "O" && buttons[1][1].getText() == "O" && buttons[0][2].getText() == "O") {
            oWins();
        }
        draw();
    }

    public void xWins() {
        victor= 10;
        jmdgewonnen = true;
        ende = true;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                buttons[i][j].setEnabled(false);
            }
        }
        textfield.setText("Tic-Tac-Toe");
        if (realplayer) {
            turn.setText("X hat gewonnen");
        } else {
            turn.setText("Mensch hat gewonnen");
        }
        button_panel.setVisible(false);
        options.setVisible(true);
        firstTurn();
    }

    public void oWins() {
        victor = -10;
        jmdgewonnen = true;
        ende = true;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                buttons[i][j].setEnabled(false);
            }
        }

        button_panel.setVisible(false);
        options.setVisible(true);
        textfield.setText("Tic-Tac-Toe");
        if (realplayer) {
            turn.setText("O hat gewonnen");

        } else {
            turn.setText("Die AI hat gewonnen");
        }
        firstTurn();
    }

    public void draw() {
        victor=0;
        if (buttons[0][0].getText() != "" && buttons[1][1].getText() != "" && buttons[2][2].getText() != ""
                && buttons[0][1].getText() != "" && buttons[0][2].getText() != "" && buttons[1][0].getText() != ""
                && buttons[1][2].getText() != "" && buttons[2][0].getText() != "" && buttons[2][1].getText() != ""){
        for (int i = 0; i <3; i++){
            for (int j = 0; j <3; j++) {

                    if (!jmdgewonnen) {
                        victor = 0;
                        buttons[i][j].setEnabled(false);
                        button_panel.setVisible(false);

                        }
                    options.setVisible(true);
                    textfield.setText("Tic-Tac-Toe");
                    ende = true;
                    unentschieden = true;
                    turn.setText("Keiner hat gewonnen");
                    firstTurn();
                    }
                }
                }
            }
    public void easygame() {
        check();
        if(!ende){


        for (int i = 0; i <3; i++) {
            for (int j = 0; j < 3; j++) {
                buttons[i][j].setForeground(new Color(245, 248, 255));
            }
        }
        Random rand = new Random();
        int random1;
        int random2;
        random1 = rand.nextInt(3);
        random2 = rand.nextInt(3);
        if (buttons[0][0].getText() != "" && buttons[1][1].getText() != "" && buttons[2][2].getText() != ""
                && buttons[0][1].getText() != "" && buttons[0][2].getText() != "" && buttons[1][0].getText() != ""
                && buttons[1][2].getText() != "" && buttons[2][0].getText() != "" && buttons[2][1].getText() != "") {

        } else {

            while (buttons[random1][random2].getText() != "") {
                random1 = rand.nextInt(3);
                random2 = rand.nextInt(3);
            }
            buttons[random1][random2].setText("O");
            check();

            if (!ende) {
                textfield.setText("X am Zug");
                player1_turn = true;
            }
        }
        }
    }

    public void mediumgame() {
        check();


        Random rand = new Random();
        int random;
        random = rand.nextInt(2);

        if (random == 1) {
            easygame();
        }
        if (random == 0) {
            hardgame();
        }
        check();

        if (!ende) {
            textfield.setText("X am Zug");
            player1_turn = true;
        }
    }

    public void hardgame() {

        int bestscore = Integer.MIN_VALUE;
        int movei= 0;
        int movej= 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                buttons[i][j].setForeground(new Color(245, 248, 255));
                if (buttons[i][j].getText() == "") {
                buttons[i][j].setText("O");
                int score = minimax(buttons, 0, false);
                buttons[i][j].setText("");
                if (score > bestscore) {
                    bestscore = score;
                   movei = i;
                   movej = j;

                }
                }
            }
        }
        buttons[movei][movej].setText("O");
        check();
        if (!ende) {
            textfield.setText("X am Zug");
            player1_turn = true;
        }
    }

    /*
     * public void scores() {
     * Map<String, Integer> map = new Hashmap<>();
     * map.put(X, 10);
     * map.put(O, -10);
     * map.put(tie, 0);
     * }
     */
    public int minimax(JButton[][] buttons, int depth, boolean isMax) {
        if(victor != 0){
            return victor;
        }

        if (isMax) {
            int bestscore = Integer.MIN_VALUE;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j<3;j++) {
                    buttons[i][j].setForeground(new Color(245, 248, 255));
                    if (buttons[i][j].getText() == "") {
                        buttons[i][j].setText("O");
                        int score = minimax(buttons, depth + 1, false);
                        buttons[i][j].setText("");
                        bestscore = Math.max(score, bestscore);
                    }
                }
            }


            return bestscore;
        } else {
            int bestscore = Integer.MAX_VALUE;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j<3; j++) {
                    buttons[i][j].setForeground(new Color(245, 248, 255));
                    if (buttons[i][j].getText() == "") {

                        buttons[i][j].setText("X");
                        int score = minimax(buttons, depth + 1, true);
                        buttons[i][j].setText("");
                        bestscore = Math.min(score, bestscore);
                    }
                }
            }
            return bestscore;
        }

    }
}

[B]
 
K

kneitzel

Gast
Der Code ist recht unübersichtlich. Was Dir fehlt ist auf jeden Fall die korrekte Prüfung. Wenn das Spiel beendet ist, dann gibst Du den Victor Wert zurück.
Daher wird vom Prinzip her ein check() notwendig. Du hast aber das Problem, dass check nicht nur etwas prüft sondern auch etwas macht. Es ruft halt draw auf, das prinzipiell prüft, ob noch Züge möglich sind. Aber dabei wird dann auch das Spielfeld verändert, so dem nicht mehr so sein sollte. Oder wenn jemand gewonnen hat, werden Variablen umgesetzt. Und das ist halt weniger geschickt. Hier muss vermutlich der Code generell noch weiter angepasst werden, so dass Du da eine saubere Trennung hast bezüglich eine Stellung prüfen und auf die Prüfung zu reagieren.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Z Minimax-Algorithmus für TicTacToe Spiele- und Multimedia-Programmierung 5
H MiniMax bei TicTacToe(x-O) funzt nicht (ganz :P) Spiele- und Multimedia-Programmierung 11
ItundMathe1994 TicTacToe Spiel programmieren Spiele- und Multimedia-Programmierung 2
M schematische Darstellung TicTacToe Spiele- und Multimedia-Programmierung 7
T TicTacToe Spiele- und Multimedia-Programmierung 5
A Multidimensionler Array - Elemente vergleichen (TicTacToe) Spiele- und Multimedia-Programmierung 4
S TicTacToe Spiele- und Multimedia-Programmierung 2
J Tictactoe Spiele- und Multimedia-Programmierung 3
timbeau TicTacToe - Bitte um Feedback Spiele- und Multimedia-Programmierung 4
A TicTacToe Spiel Spiele- und Multimedia-Programmierung 3
H Uniaufgabe : TicTacToe Spiele- und Multimedia-Programmierung 9
H TicTacToe Code Vereinfachen Spiele- und Multimedia-Programmierung 5
E TicTacToe Spiele- und Multimedia-Programmierung 44
R TicTacToe: Spieler kann nicht gewinnen Spiele- und Multimedia-Programmierung 15
B minimax Algorithmus Spiele- und Multimedia-Programmierung 5
B Umsetzung des Minimax-Algorithmus Spiele- und Multimedia-Programmierung 2
krgewb Anderer Algorithmus für Bounding Box Spiele- und Multimedia-Programmierung 9
F Algorithmus für bessere Kollisionsabfragen Spiele- und Multimedia-Programmierung 10
Z Such-Algorithmus Spiele- und Multimedia-Programmierung 2
E A-Stern Algorithmus Problem und Implementierung einer Map Spiele- und Multimedia-Programmierung 6
E Pathfinding Algorithmus Spiele- und Multimedia-Programmierung 2
S Problem mit 4 gewinnt(MinMax Algorithmus) Spiele- und Multimedia-Programmierung 2
S A*-Algorithmus Spiele- und Multimedia-Programmierung 12
S A* Algorithmus Spiele- und Multimedia-Programmierung 14
S Algorithmus zur Ressourcesuche für die KI Spiele- und Multimedia-Programmierung 5
C Algorithmus um Flächen zu erkennen Spiele- und Multimedia-Programmierung 6
L Fehlersuche beim Weichzeichner-Algorithmus Spiele- und Multimedia-Programmierung 9
A Negamax-Algorithmus Spiele- und Multimedia-Programmierung 7

Ähnliche Java Themen

Neue Themen


Oben