Search code examples
javajcreator

tic tac toe Jcreator stuck


Here is how the entire thing looks like now.

And then there is the details that you're forced to add and more details and more details and more details and more and more and more and more and more and more and more and more and more and more and more

import java.util.Scanner;

public class Tictactoe {
    static char[][] MakeMove(char[][] spelplan, char spelare, int rad, int kolumn) {
        spelplan[rad][kolumn] = spelare;
        char[][] board = new char[4][4];
        System.out.println(spelplan[rad][kolumn]);
        return spelplan;
    }

    static boolean CheckMove(char[][] spelplan, int x, int y) {
        if (spelplan[x][y] != ' ') {
            return false;
        } else {
            return true;
        }
    }

    static void SkrivUtSpelplan(char[][] spelplan) {
        System.out.println("-------");
        System.out.println("|" + spelplan[1][1] + "|" + spelplan[1][2] + "|" + spelplan[1][3] + "|");
        System.out.println("|-+-+-|");
        System.out.println("|" + spelplan[2][1] + "|" + spelplan[2][2] + "|" + spelplan[2][3] + "|");
        System.out.println("|-+-+-|");
        System.out.println("|" + spelplan[3][1] + "|" + spelplan[3][2] + "|" + spelplan[3][3] + "|");
        System.out.println("-------");
    }

    static boolean KollaVinst(char[][] spelplan) {
        return false;
    }

    public static void main(String[] args) {
        char spelplan[][] = new char[4][4];
        char spelare;
        int rad = 3, kolumn = 3, i = 0;
        for (int x = 1; x < 4; x++) {
            for (int y = 1; y < 4; y++) {
                spelplan[x][y] = ' ';
            }
        }

        System.out.println("-------");
        System.out.println("| | | |");
        System.out.println("|-+-+-|");
        System.out.println("| | | |");
        System.out.println("|-+-+-|");
        System.out.println("| | | |");
        System.out.println("-------");

        while (KollaVinst(spelplan) == false) {

            CheckMove(spelplan, rad, kolumn);

            for (i = 0; i < 9; i++) {
                if (i % 2 == 0) {
                    spelare = 'X';
                } else {
                    spelare = 'O';
                }

                System.out.println("Spelare 1 skriv vilken rad: 1-3");
                int x = new Scanner(System.in).nextInt();

                System.out.println("Spelare 1 skriv vilken kolumn: 1-3");
                int y = new Scanner(System.in).nextInt();

                if (CheckMove(spelplan, x, y) == true) {
                    MakeMove(spelplan, spelare, x, y);
                }
                System.out.println(" ");
                SkrivUtSpelplan(spelplan);
            }
        }
    }
}

Solution

  • Based on what you posted so far (I am really hoping for an edit that clarifies what you are attempting)

    I am assuming you are trying to build a loop that doesn't end until the board is finished. until it is finished, a move is asked from the player. the move is made (if legal). Then the board is printed.

    your code has a number of issues:

    1. CheckMove(spelplan, rad, kolumn) is only ever executed with rad=3,kolumn=3. I would expect this to be run using the user input.
    2. You reuse your loop variables. (int i = new scanner) and later (for i=i). never do that. the i=i is pointless anyway and you end up doing i++ which means you lose the user input.
    3. inside the while loop you never do makeMove(spelplan, i, j). I would expect this to occur before printing out the board.
    4. the for loops (i and j) don't seem to be useful. Your method skrivutSpelPlan already prints the board and it only needs to be called once. you don't use the loop variables i or j.

    I am fighting the urge to write out suggestions / code as you indicated you didn't want it. In pseudocode, you would want your loop structured like:

    while (!isBoardSolved) {
        (x,y) = getUserInput(); // this is not java :D don't use it
        if (isLegalMove(x,y)) {
             makeMove(x,y);
        } else {
             reportError();
        }
        printBoard();
    }
    

    in your printBoard method, you should loop. you currently have hardcoded [0] [1] etc. use a forloop for row and forloop for col.

    your checkmove doesn't check the board. it checks if the board[x][y] != board[x][y] which is never true. (well ok technically in a multithreaded environment, it could be true if a racecondition occurs and it's accessible) You have to think what checkMove does.

    MakeMove is ok, except you don't need to return the new playing field. if you do

    char[][] board = new char[4][4];
    MakeMove(board, 'a', x, y);
    System.out.println(board[x][y]); // should print 'a' unless x or y were out of bounds.
    

    then board gets updated and the a is printed.

    ok I'm trying not to spoil your fun, just giving pointers. Please update the question with the details of your problem. where are you stuck, what do you need.

    When you have this working I recommend posting it to https://codereview.stackexchange.com/ and get some more feedback on good coding style and practices.

    to test diagonals, you could use:

    // y = row number, so y = y + 1 means the row below y
    // x = column number. so x = x + 1 means the column to the right of x
    public boolean isSolved(char[][] board) {
        // check horizontal rows
        return isHorizontalSolved(board) || isVerticalSolved(board) || isDiagonalSolved(board);
    }
    
    public boolean isHorizontalSolved(board) {
        for (int y = 0; y < board.length; ++y) { 
            // for each row, test if all columns are the same
            boolean solved = true;
            char first = board[y][0];
            for (int x = 0; x < boards[y].length; ++x) {
                if (boards[y][x] == ' ' || first != boards[y][x]) { 
                    // if an element is not filled in, this row is not solved
                    // if an element in this row is different than any other element, this row is not solved
                    solved = false;          
                }
            }
            if (solved == true) {
                return true;
            }
        }
        return false;
    }
    
    // check vertical rows
    // leaving this for your own imagination
    
    // check diagonals
    public boolean isDiagonalSolved(char[][] board) {
        // check topLeft to bottomRight:
        char first = board[0][0];
        boolean solved = true;
        for (int y = 0, x = 0; y < board.length && x < board[y].length; ++y, ++x) {
            if (board[y][x] == ' ' || first != board[y][x]) {
                // if field is empty or the fields are not all equal to one another
                solved = false;
            }
        }
        if (solved) {
            return true;
        }
    
        int topRightX = board[0].length - 1;
        solved = true;
        first = board[0][topRightX];
        for (int y = 0, x = topRightX; y < board.length && x >= 0; ++y, --x) {
            if (board[y][x] == ' ' || first != board[y][x]) {
                // if field is empty or the fields are not all equal to one another
                solved = false;
            }
        }
        if (solved) {
            return true;
        }
    
    }
    

    Can't promise it's error less but this is roughly what I would do. for diagonal, traverse topleft to bottom right (0,0) (1,1) (2,2) and topright to bottom left (0, 2), (1,1) (2,0)

    with a gameboard of 3*3 you can hardcode this but I'm used to using loops.