1

I've done some looking around on here for a solution, but I can't find one. I tried these ones and many others, and I run into the same issue.

I am trying to make a simple text game, and I run into the issue where I have a main class, and a class called "gameboard" that I have as an array defined like this:

static GameBoard[] gameboard = new GameBoard[9];

Now, this works fine until I try to change the characteristics of a single one of these array objects. I will do:

gameboard[input].setState(2);

and the specific instance of gameboard that should change will not be the only one: all of them change when I do this. It's weird. Only gameboard[**input**] should change, not all 9 of the gameboard instances. EVERY variable and method I have is "static", but because of the main method (public static void main...), everything seems to have to be static. How do I get rid of all this static?

GameBoard Class

package com.name.tictactoe;

public class GameBoard {
 char[] States = {'N','X','O'};
 char state;

public  void setState(int s){
    state = States[s];
}
public  char getState(){
    return state;
}
}

Main class (called Game)

package com.name.tictactoe;

import java.util.Scanner;

public class Game {

static boolean turn, win;
static GameBoard[] gameboard;
static Scanner kb = new Scanner(System.in);
static int input;

public static void main(String[] args){
    gameboard = new GameBoard[9];
    reset();
    displayStates();
    askTurn();
    displayStates();
    askTurn();

}

public static void askTurn() {
    System.out.println();
    System.out.println();
    System.out.println("Where do you want to go?  Use the numbers shown, where the first segment is the top and the last is the bottom - left to right.");
    input = kb.nextInt();
    if(input > 8){
        System.out.println("Input out of bounds.  Game over by default.");
        try {
            Thread.sleep(1000000000);} catch (InterruptedException e) {e.printStackTrace();}
    }
    gameboard[input].setState(2);
}

public static void reset(){
    for(int i = 0; i < 9; i++){
        gameboard[i].setState(0);
    }
}

public static void displayStates(){
    for(int i = 0; i < 9; i++){
        System.out.print(gameboard[i].getState() + " ");
        if(i ==2 || i ==5){
            System.out.print("  II  ");
        }
    }
    System.out.println();
    for(int i = 0; i < 9; i++){
        System.out.print(i + " ");
        if(i ==2 || i ==5){
            System.out.print("  II  ");
        }
    }
    System.out.println();
}

}

UPDATE: The current answers don't work. Although Eclipse doesn't realize this, making GameBoard non-static causes null pointer exceptions when any method in it is referenced.

Community
  • 1
  • 1
Bobdabiulder
  • 160
  • 3
  • 12
  • "EVERY variable and method I have is "static"" - well that's not a good idea, if you want different instances to have different state. Do you understand what `static` means? – Jon Skeet Jun 20 '16 at 19:48
  • Your issue is you are trying to have `static` instances which is a contradiction. `setState` is not changing all of them, you only have one set of static variables to update. – Grayson Jun 20 '16 at 19:51
  • Not fully, even though I learned Java over 2 years ago. I haven't used Java much recently, but I don't recall ever learning "static". English tells me "static" is unchanging, but I think that's _slightly_ off, as the value can change. – Bobdabiulder Jun 20 '16 at 19:53
  • What you're describing shouldn't be happening. If you show the code demonstrating the problem, we can try to point out the mistake. – shmosel Jun 20 '16 at 20:03

3 Answers3

3

A static variable belongs to the class, not the object, so of course all of your GameBoards are being affected!

Just because you're in a static method doesn't mean you can't manipulate instance variables. First, make everything in your GameBoard class non-static (unless you really do need some of the values shared across all instances). This includes your instance variables and your getter/setter methods.

If your program works exclusively from the main method, then keep your GameBoard[] object static. Then, when you make that method call:

gameboard[input].setState(2);

This will change only the state of the GameBoard at index input.

Edit:

To instantiate your GameBoard[] with basic GameBoard objects inside of it, you can do this at the beginning of your main method:

for(int x=0; x<gameboard.length; x++) {
    gameboard[x] = new GameBoard(); //Assuming you want to use the default constructor
}
Zircon
  • 4,677
  • 15
  • 32
  • Doesn't work. I get a null pointer exception when I call any non-static method of the other class. Sorry. – Bobdabiulder Jun 20 '16 at 19:57
  • Have you instantiated each `GameBoard`? Remember, declaring `GameBoard[] gameboard = new GameBoard[9];` only creates an array to hold `GameBoard`s, but the array is empty. – Zircon Jun 20 '16 at 20:09
  • Thank you! This works flawlessly! Now I can make the game more effective, detect a win, and eventually get a working AI. :):) – Bobdabiulder Jun 20 '16 at 20:32
1

The other objects in your array should not change. Can you add some more code for more context?

As far as I can understand you, you are doing something like:

public class Main {
    public static String[] strings = new String[2];

    public static void main(String[] args) {
        strings[0] = "test";
        System.out.println(strings[1]);
    }
}

In my example output is "null" as expected.

How do I get rid of all this static?

Just create instances of your objects in the main function.

GameBoard[] gameboard = new GameBoard[9];

Jezor
  • 3,253
  • 2
  • 19
  • 43
1

For what you describe to happen all the elements of the gameboard array must be set to the same object (nothing to do with the array being static), check your code where you populate the gameBoard array with new instances of the GameBoard class for a bug that could cause the same instance to be written to all elements (or post that code here so people can see the problem).

rnbrough
  • 11
  • 1