• Advertisement
Sign in to follow this  

TicTacToe array problem

This topic is 2966 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there, im reading through java for students and in the 2d array chapter one of the exercises is to create a tic tac toe game. My problem is that i am writing a method to initialise the array and then another method to find out the winner as below

private void init() {
		String str = "";
		
		for (int i = 0; i <=2; i++) {
			for (int j=0; j<=2; j++) {
				grid[j] = str;
			}
		}
	}

private boolean winningCombinations() {
		
		if (grid[0][0] == grid[0][1] && grid[0][1] == grid[0][2]) {
			win = true;
		}
		if (grid[0][0] == grid[1][0] && grid[1][0] == grid[2][0]) {
			win = true;
		}
		if (grid[0][1] == grid[1][1] && grid[1][1] == grid[2][1]) {
			win = true;
		}
		if (grid[0][2] == grid[1][2] && grid[1][2] == grid[2][2]) {
			win = true;
		}
		if (grid[1][0] == grid[1][1] && grid[1][1] == grid[1][2]) {
			win = true;
		}
		if (grid[2][0] == grid[2][1] && grid[2][1] == grid[2][2]) {
			win = true;
		}
		if (grid[0][0] == grid[1][1] && grid[1][1] == grid[2][2]) {
			win = true;
		}
		if (grid[2][0] == grid[1][1] && grid[1][1] == grid[0][2]) {
			win = true;
		}
		
		else {
			win = false;
		}
		
		return win;
	}


Now my problem is when i initialise the array before the game starts all the data in the array is equal so the method winningCombinations is returning true and declaring a win. Should i not be initialising the array in this way or is it just my logic that is incorrect for the method. Thanks a lot for your help in this.

Share this post


Link to post
Share on other sites
Advertisement
Each grid element needs to hold three distinct states, "Empty", "X and "O". An enumeration would be perfect, but you might want to use null strings to represent empty elements for the moment.

Your winningCombinations method is incorrect through. You should use String#equals, not == for comparing strings. Otherwise you can get situations where the comparison returns false for strings with identical contents. That, and you would need to check that the elements are not "empty", depending on how you want to represent them.

It is idiomatic to write loops like this:

for(int i = 0 ; i < N ; ++i) {
// ...
}

Rather than testing if "loopCounter <= N - 1".

Share this post


Link to post
Share on other sites
Quote:
Original post by Dr1fter
Now my problem is when i initialise the array before the game starts all the data in the array is equal so the method winningCombinations is returning true and declaring a win. Should i not be initialising the array in this way or is it just my logic that is incorrect for the method.
After you check for equality check the contents of the array to see if one of those array elements contains a valid move. An empty string is not valid. Presumably "X" or "O" is though.

edit: I don't know Java didn't let you compare strings like that mentioned by rip-off so that would need to be fixed as well.

Share this post


Link to post
Share on other sites

if (grid[2][0] == grid[1][1] && grid[1][1] == grid[0][2]) {
win = true;
}

else {
win = false;
}

Under which circumstances do you think the else body will be executed?

Share this post


Link to post
Share on other sites
thank you for the quick replies.

@rip-off, thanks i will change it to .equals since i am comparing strings (rookie error) :).

@DevFred, i assume the else will be executed if the if statement before it is not true, what i was trying to achieve is the else statement to be executed if all the other if's are not true. Would i need to put an else in each of the if statements to achieve that? i was hoping for it to check each if statement and if none are true then the else would be called.

Share this post


Link to post
Share on other sites
DevFred is trying to say that if everything is equal at startup, regardless if it is " ", "X", "O".

Change your win checks to if grid[][] == "X" && grid[][] == "X".

To save you some time, allow your function to have a string passed to it. So pass in "X" and then "0" and just do grid[][] == str && grid[][] == str

Share this post


Link to post
Share on other sites
Quote:
Original post by Dr1fter
i assume the else will be executed if the if statement before it is not true

Correct.

Quote:
Original post by Dr1fter
Would i need to put an else in each of the if statements to achieve that?

You can simply replace each "if" (except the first) with "else if". But may I recommend a different solution?

private boolean winningCombinations()
{
boolean win = false;
if (...)
{
win = true;
}
if (...)
{
win = true;
}
if (...)
{
win = true;
}
...
return win;
}

Note the complete absence of else.

Share this post


Link to post
Share on other sites
You could use "return true" whenever you find out that the game is won:

private boolean winningCombinations()
{
if (...)
{
return true;
}

if (...)
{
return true;
}

if (...)
{
return true;
}

...

return false;
}

Share this post


Link to post
Share on other sites
And here is a more data-driven approach:

// Can you guess what these numbers mean?
private static final int[][][] winning_lines = {
{{0, 0}, {0, 1}, {0, 2}},
{{1, 0}, {1, 1}, {1, 2}},
{{2, 0}, {2, 1}, {2, 2}},

{{0, 0}, {1, 0}, {2, 0}},
{{0, 1}, {1, 1}, {2, 1}},
{{0, 2}, {1, 2}, {2, 2}},

{{0, 0}, {1, 1}, {2, 2}},
{{2, 0}, {1, 1}, {0, 2}}
};

private boolean winningCombinations()
{
// These two constants just increase readability in the coming loop
final int x = 0;
final int y = 1;

// The following loop will run eight times,
// Once for every possible winning line
for (int[][] pos: winning_lines)
{
String a = grid[pos[0][y]][pos[0][x]];
String b = grid[pos[1][y]][pos[1][x]];
String c = grid[pos[2][y]][pos[2][x]];

// If all three are equal and not empty, we have a winner!
if (!a.isEmpty() && a.equals(b) && b.equals(c)) return true;
}
// We tried every combination and could not determine a winner, thus:
return false;
}


It still looks overly complex to my eyes which have been spoiled by Haskell :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement