Fehler beim Programmieren von TicTacToe

Diskutiere Fehler beim Programmieren von TicTacToe im Java Basics - Anfänger-Themen Forum; Ich muss mich leider mihe kommentarlos anschließen. Ich habe versucht alleine nur deine Field Klasse zu überlicken, aber das ist ein Ding der...

  1. MoxxiManagarm
    MoxxiManagarm Aktives Mitglied
    Ich muss mich leider mihe kommentarlos anschließen. Ich habe versucht alleine nur deine Field Klasse zu überlicken, aber das ist ein Ding der Unmöglichkeit. Überall hast du duplizierten Code und unendliche if-else / switch-case Konstrukte, von dem ganzen static mal abgesehen.

    Nur um ein Beispiel zu nennen:
    Die getX/Y Funktionen lassen sich einfach mit Ganzzahldivision und Modulo abbilden.

    Code (Java):

        public int getXOfField(int intField) {
            return (intField - 1) / 3; // Ganzzahldivision
        }

        public int getYOfField(int intField) {
            return (intField - 1) % 3; // Modulo - Rest
        }
    Versuche deinen Code zu generalisieren und strikter zu trennen. z.B.
    - Wenn du ein Symbol auf ein Feld setzt ist es doch egal ob es Feld 1 2 3 oder 9 ist. Das Verhalten ist überall gleich, also ist es auch nur ein Code, aber mit verändertem Index.
    - Ob du gegen Computer oder Mensch spielst, ist grundsätzlich auch egal. Mach dir eine Methode getPlayerChoice() und eine getAIChoice(). getPlayerChoice() kannst du sowohl für Spieler 1 und 2 einsetzen und je nach Modus für Spielere 2 eben getAIChoice() anwenden.
    - Field sollte nichts mit Player zu tun haben. Stattdessen sagst du Field einfach nur z.B. field.tryToSetPlayerSymbolAt('x', 9) und du erhälst ein boolean
    - Ich würde auch Field keine printMethode geben - nicht eine. Field sollte nur Spiellogik ("Model") enthalten, überlasse das printen deines Feldes deiner Spielklasse (i/o "Controller"/"View")

    Jeder von uns hat sicherlich mal TicTactoe programmiert und der Code geht selbst mit AI Logik kaum über eine vielleicht zwei A4 Seite(n) hinaus. Das muss dein Ziel sein und alles was diesen Rahmen sprengt musst du versuchen besser zu machen bevor du fortfährst und dich so verrennst. du machst es dir nur umständlich und dein Leben schwer.
     
  2. mihe7
    mihe7 Bekanntes Mitglied
    Was heißt da "leider"? Das ist ja eine bodenlose Unverschämtheit ;)

    @Kleeraphie mal ein Beispiel:

    Code (Java):

    public class Field {
        private final int[] fields = new int[9];
        private int player = 1;
        private int winner;
        public int player() { return player; }
        public int winner() { return winner; }
        public boolean gameOver() { return winner != 0 || tie(); }
        public boolean tie() {
            if (winner != 0) { return false; }
            boolean tie = true;
            for (int field : fields) {
                tie &= field != 0;
            }
            return tie;
        }
        public int get(int field) { return fields[field]; }
        public boolean tryMove(int field) {
            boolean validMove = (fields[field] | winner) == 0;
            if (validMove) {
                fields[field] = player;
                winner = determineWinner();
                player = player % 2 + 1;
            }
            return validMove;
        }
        private int determineWinner() {
            int[] checks = {0,4,8,2,4,6,0,3,6,1,4,7,2,5,8,0,1,2,3,4,5,6,7,8};
            for (int i = 0; i < checks.length;i+=3) {
                if ((fields[checks[i]] & fields[checks[i+1]] & fields[checks[i+2]]) != 0) {
                    return fields[checks[i]];
                }
            }
            return 0;
        }
    }
     
    Mit Lambdas/Streams geht das problemlos noch kürzer.
     
  3. MoxxiManagarm
    MoxxiManagarm Aktives Mitglied
    Hier mal eine grobe Struktur, wie es aussehen könnte. Die wichtigste Logik habe ich offen gelassen. Wie du siehst ist hier kein Anzeichen von vielen if oder switch-cases. Die einzige Klasse mit Ausgabe ist TicTacToe selbst. Du kannst die Spieler beliebig setzen, wenn du willst auch AI gegen AI.

    TicTactoe (open)
    Code (Java):

    package javaforum.org.tictactoe;

    import java.util.Arrays;
    import java.util.Random;


    public class TicTacToe {
        private final Field field;
     
        private final Opponent player1, player2;
        private Opponent activePlayer;
     
        public TicTacToe(Opponent player1, Opponent player2) {
            field = new Field();
         
            this.player1 = player1;
            this.player2 = player2;
        }
     
        public void start() {
            activePlayer = (new Random().nextInt(2) == 0) ? player1 : player2;
            printField();
         
            for(int i = 1; i <= 9; i++) {
                System.out.println(activePlayer.getName() + " it is your turn...");
             
                int move;
                do {
                    move = activePlayer.getRequestedMove();
                } while(! field.setPlayerSymbolAt(activePlayer.getSymbol(), move));
             
                printField();
             
                if(checkWin()) {
                    System.out.println(activePlayer.getName() + " you won!");
                    return;
                } else {
                    togglePlayer();
                }
            }
         
            System.out.println("It's a tie!");
        }
     
        private boolean checkWin() {
            // TODO
            return false;
        }
     
        private void printField() {
            for(char[] line : field.getFieldReadOnly()) {
                System.out.println(Arrays.toString(line));
            }
            System.out.println();
        }
     
        private void togglePlayer() {
            activePlayer = (activePlayer.equals(player2)) ? player1 : player2;
        }
     
        public static void main(String... arg) {
            new TicTacToe(new HumanPlayer('X', "Max"), new HumanPlayer('O', "Moritz"))
                    .start();    
        }
    }
     


    Opponent (open)
    Code (Java):

    package javaforum.org.tictactoe;


    public abstract class Opponent {
        protected char symbol;
        protected String name;
     
        public Opponent(char symbol, String name) {
            this.symbol = symbol;
            this.name = name;
        }
     
        public final String getName() {
            return name;
        }
     
        public final char getSymbol() {
            return symbol;
        }
     
        public abstract int getRequestedMove();
    }

     


    HumanPlayer (open)
    Code (Java):

    package javaforum.org.tictactoe;

    import java.util.Scanner;


    public class HumanPlayer extends Opponent {
        private static Scanner scanner;

        public HumanPlayer(char symbol, String name) {
            super(symbol, name);
         
            if(scanner == null) {
                scanner = new Scanner(System.in);
            }
        }
     
        @Override
        public int getRequestedMove() {
            do {
                System.out.println("Please choose a field (1-9):");
                try {
                    int choice = Integer.valueOf(scanner.nextLine());
                 
                    if(1 <= choice && choice <= 9) return choice;
                } catch(NumberFormatException e) { }
            } while(true);
        }
    }
     


    AIPlayer (open)
    Code (Java):

    package javaforum.org.tictactoe;


    public class AIPlayer extends Opponent {
     
        public AIPlayer(char symbol, String name) {
            super(symbol, name);
        }
     
        @Override
        public int getRequestedMove() {
            // TODO
         
            return 0;
        }
    }

     


    Field (open)
    Code (Java):

    package javaforum.org.tictactoe;

    public class Field {
        private static final char DEFAULT = '-';
     
        private final char[][] field;
     
        public Field() {
            this.field = new char[][]{
                {DEFAULT, DEFAULT, DEFAULT},
                {DEFAULT, DEFAULT, DEFAULT},
                {DEFAULT, DEFAULT, DEFAULT}
            };
        }
     
        public char[][] getFieldReadOnly() {
            return field.clone();
        }
     
        public boolean setPlayerSymbolAt(char playerSymbol, int index) {
            int x = (index - 1) / 3;
            int y = (index - 1) % 3;
         
            if(field[x][y] != DEFAULT) {
                return false;
            } else {
                field[x][y] = playerSymbol;
                return true;
            }
        }
    }

     
     
    Zuletzt bearbeitet: 11. Okt. 2018
  4. Hinweis: Du möchtest Java lernen? Vielleicht hilft dir dieser Kurs hier weiter. Sichere dir hier den Zugriff auf umfangreiches Java-Know How und starte richtig durch!
Die Seite wird geladen...

Fehler beim Programmieren von TicTacToe - Ähnliche Themen

Fehler beim setzen von Farben
Fehler beim setzen von Farben im Forum AWT, Swing, JavaFX & SWT
Fehler beim Start der Serveranwendung
Fehler beim Start der Serveranwendung im Forum Allgemeines EE
Fehler beim laden eines Icons
Fehler beim laden eines Icons im Forum Java Basics - Anfänger-Themen
Fehler beim list.add()
Fehler beim list.add() im Forum Datenbankprogrammierung
Fehler beim convertieren von String to int
Fehler beim convertieren von String to int im Forum Hausaufgaben
Thema: Fehler beim Programmieren von TicTacToe