Search code examples
javapolymorphism

Two child classes modifying same parent variable java


I have an assinment for my university class to build a tic tac toe game. I am very new to Java (one week) but I have coded for about two years. The problem I am running into is in my parent class GAME, I have a 3d array for the board. To manipulate the board, I have two child classes, one for the player and one for the computer player. However, it seems that whenever the computer class or player class changes the board, they are accusing their own version of it, not the shared one in the parent class. I am sure this is just due to my lack of understanding of polymorphism in Java, so any advice would be greatly appreciated!

Parent Game class:

package ticTacToe;
import java.util.Scanner;

public class TicTacToe {

    private String[][] NumberBoard;
    protected String[][] GameBoard;

    public TicTacToe() {

        NumberBoard = new String[3][3];
        GameBoard = new String[3][3];
        int counter = 0;
        for(int i=0; i<3; i++)
        {
            for(int k =0; k<3; k++)
            {
                counter++;
                NumberBoard[i][k] = Integer.toString(counter);
                GameBoard[i][k] = " ";
            }
        }

    }


    public void draw ( String[][] f) {

        for(int i =0; i<3; i++)
        {
            for(int k =0; k<3; k++)
            {
                System.out.print(f[i][k]);
                if(k<2)
                System.out.print(" | ");
            }
            if(i<2) {
            System.out.println();
            System.out.print("---------");
            System.out.println();
            }
        }

    }



    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        TicTacToe Game = new TicTacToe();
        Player RealPerson = new Player();
        Computer ComputerPlayer = new Computer();

        int N = 0;
        while(true) {
            System.out.println();
            System.out.println("PLease choose a spot to place in (0 to quit): ");
            if(input.hasNextInt())
            {
                 N = input.nextInt();
            }
            else
            {
                input.next();
                System.out.println("That wasn't a number, please enter a number( 0 to quit)");
                continue;
            }
            if(N < 0 || N > 9)
            {
                System.out.println("That's not a valid choice, please pick another!");
                continue;
            }

            if (N != 0)
            {
                Game.GameBoard = ComputerPlayer.NormalEval(N+1);
                Game.draw(Game.GameBoard);

                System.out.println();
                System.out.println();
                System.out.println();

                Game.draw(Game.GameBoard);
                Game.GameBoard = RealPerson.BoardUpdater(N);
                //Game.draw(Game.GameBoard);
                System.out.println();
                System.out.println();
                System.out.println();

            }
            else
                break;


        }
        input.close();
        Game.draw(Game.NumberBoard);
        System.out.println();
        System.out.println();



    }

}

Child Player class:

package ticTacToe;

public class Player extends TicTacToe {


public String[][] BoardUpdater(int N) {

        if(N < 4 && N >=0)
            GameBoard[0][N-1] = "X" ;
        if(N > 3 && N < 7)
            GameBoard[1][N-4] = "X";
        if(N > 6 && N <10)
            GameBoard[2][N-7] = "X";
        //draw(GameBoard);

        return GameBoard;
    }

}

Child Computer Class:

package ticTacToe;

public class Computer extends TicTacToe {


    public String[][] NormalEval(int N) {
        //int a = 0;


        if(N < 4 && N >=0)
            GameBoard[0][N-1] = "O" ;
        if(N > 3 && N < 7)
            GameBoard[1][N-4] = "O";
        if(N > 6 && N <10)
            GameBoard[2][N-7] = "O";

        //this.draw(GameBoard);

        return GameBoard;


        //return a;
    }






}


Solution

  • Your inheritance structure is broken in that neither player class should extend from Game. Ask yourself -- is a person playing a game, a more specific version of a game? Answer: no, meaning that this structure does not pass the inheritance "is-a" test.

    Instead of using inheritance, in this situation you should be using composition where the Game class should be a separate class and the two Player classes children of a distinct abstract parent player class with the Game class then holding two instances of the players (if a 2-player game) and likewise the Players each holding a reference to the single Game instance. This is referred to a "has-a" structure.

    public class TicTacToe {
        private AbstractPlayer human = new HumanPlayer(this);
        private AbstractPlayer computer = new ComputerPlayer(this);
    
        //....
    }
    
    public class AbstractPlayer {
        private TicTacToe ticTacToe;
    
        public AbstractPlayer(TicTacToe ticTacToe) {
            this.ticTacToe = ticTacToe;
        }
    }
    
    public class HumanPlayer extends AbstractPlayer {
        public HumanPlayer(TicTacToe ticTacToe) {
            super(ticTacToe);
        }
    }