3

To wrap my head around objects and arrays/arraylists, I decided to make a Tic-Tac-Toe app.

Here's the want to do:

The board is composed of a char array[3][3] which looks like/corresponds to:

codeindent         - - -  0,0 1,0 2,0
c                  - - -  0,1 1,1 2,1
c                  - - -  0,2 1,2 2,2

I have the players input their move choice by entering a digit 1-9

1 2 3 
4 5 6
7 8 9

Now I'd like an array where if I called index 4, it would return [0,1] in such a way I could point it directly to the char[][] array so I could do something along the lines of (I know that's not how its implemented but I'm putting var types for my own mental clarity)

char[][] boardArray[??? refArray[int playerMove]] = char currentPlayer

However, I just can't seem to wrap my head around what I need to do. I don't know what type of array it should be or why.

While typing this/looking stuff I just realized arrays are objects and can only store primitives in java. So I couldn't use an array to call an array...is this where I'd use Arraylists?

Thanks for all the answers! The purpose of this little exercise was to use arrays in an overly complicated and ridiculous fashion for the sole purpose of getting me practice with them, but it does seem that java as a language isn't capable of what I want to do in the fashion I want to do it. Definitely gonna go through and try out these other answers too

2
  • 4
    It's not correct that arrays can only store primitives. They can store primitives or objects. Commented Jun 12, 2013 at 19:53
  • I've done this same thing before and I found it easier to do a single array of size 9 to represent the board. No need to convert what the user inputs to the underlying data structure. Displaying the array as three rows is trivial. Commented Jun 12, 2013 at 20:00

5 Answers 5

1

Implementing the multi-array is a perfectly valid way of going about this problem. Accessing the array and storing objects in the array seems to be where your problem lies.

Firstly, arrays can store anything! You can store both primitives and objects (or references to objects) inside them, you just have to change the definition of the array.

For example this will store an array of primitive chars:

char boardArray[][] = new char[3][3];

And this will store an array of Objects:

Object boardArray[][] = new Object[3][3];

With this in mind, let's have a go at your problem:

We start with the multi-array boardArray, we can make it a character array if we want to use characters for our reference ('X' and 'O') and the empty string if it's unused.

//by default this will implement 3x3 matrix with empty strings
char boardArray[3][3] = new char[3][3];

Now we want to go ahead and take some user input:

// get the value
int value = Integer.parseInt(br.readLine().toString());

Then you can calculate the row and column from that field and modify:

// find the row
int row = (value - 1) / 3;

// get the column value (minus one as we want it from 1->9 instead of 0-8)
int column = (value - 1) % 3;

Then you can change values in the array!

if (round % 2 == 0)
    boardArray[row][column] = playerA;
else
    boardArray[row][column] = playerB;

Full code can be seen here. It's not elegant and kind of hacky. There are plenty of ways of going about this problem. I'd recommend creating your own Board class that abstracts the code away from your main class. I'll leave this up to you!

I'd also recommend taking a look at the Java docs and researching tutorials on objects and arrays.

It can seem confusing and daunting, but remember arrays are just blocks of memory that set aside room for you to store a type of object that you want to put into them.

Enjoy my friend!

Sign up to request clarification or add additional context in comments.

Comments

1

Many of the answers here are elegant and more fitting as a final solution. But I write this so that you understand what is going on because I think you need to understand multidimensional arrays in a better way.

when you declare a char array[3][3] , you are declaring a two dimensional array.

char[][] myArray= new char[3][3];

the object myArray is an array of char, with the length 3. myArray[0] is the first cell, myArray[1] is the second, and myArray[2] is the third. what does each cell contain ? it contains a whole array of chars, also with length of three. (as the second dimension states).

so when you in your program write myArray[0], you get the array that is in the first cell. by writing myArray [0][1], you get to the second cell in the array that is found in myArray first cell.

what does this show ?

that you can point to the whole array by pointing to its location. (as I have showed in myArray[0] , myArray[1], ....).

now why are you having problems ? because there is no such array of two elements in your declaration so you can't point to it. the way you constructed your arrays means any such combination will be two cells , either both in the same array or each in a different array.

if you would like to have what you want, you can try: myArray = new char[9][2]

now you have 9 arrays , each of them is of length 2. now, each cell (like myArray[0], myArray[1], ...) points to a two elemnts array. just fill them in what suits your needs and then access with the index given by the user (and you know that arrays start at 0 so if the user clicks 4, you access myArray[3]).

Comments

0

If your goal is to understand how objects and different types of collections work, I might try this:

First, make a Coordinate object, e.g.

Class Coordinate {
  int x;
  int y;
  Coordinate(x, y){
    this.x = x;
    this.y = y;
  }
}

And then a Map of Integer to Coordinate

HashMap<Integer, Coordinate> hm = new HashMap<Integer, Coordinate>();
{
hm.put(1, new Coordinate(0, 0));
hm.put(2, new Coordinate(0, 1));
hm.put(3, new Coordinate(0, 2));
//etc...
}

You could also populate the map in a loop but I felt a little to lazy to code that out

Then when you have a number a need a coordinate you can just say, e.g., hm.get(2) (should evaulate to a Coordinate with x and y values of 0 and 2.

1 Comment

This might work, but it's overly complicated, a simple coordinate transform doesn't justify creating a whole class and a map data structure! a one-liner suffices. No need to take object orientation to this extreme ;)
0

One of the many other possible suggestions,

Have a single dimension array for board

int[] board = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0};

Use this method to convert x,y coordinate to index the board

int xy2idx(int x, int y) {
    return 3 * y + x;
}

For reverse operation ie From index to x and y coordinate you can use

x = idx % 3;
y = idx / 3;

As I said this is just one of the many possible ways to do it :) Have fun :)

Note: the index, x and y are all ZERO based.

Comments

0

Try this snippet of code:

// assuming refArray[playerMove] returns a value between 1-9
int position = refArray[playerMove];
// store the current player in the given position
boardArray[(position-1)/3][(position-1)%3] = currentPlayer;

It's a simple matter of playing with the indexes of the array, nothing more. The above will work for positions between 1 and 9, storing the current player in the given position. There's no need to write complex solutions here, involving classes, methods, etc!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.