dzag30
dzag30

Reputation: 1

2D Array Help(Tic Tac Toe)

   public boolean isWin()
    {


       boolean winner= false;
       //checks rows first
       if(gameBoard[currentRow][0]==playerOne&&gameBoard[currentRow][1]==playerOne&&gameBoard[currentRow][2]==playerOne)
       {
           winner= true;
       }
       else if(gameBoard[currentRow][0]==playerTwo&&gameBoard[currentRow][1]==playerTwo&&gameBoard[currentRow][2]==playerTwo)
       {
           winner= true;
       }

       //checks columns next
       if(gameBoard[0][currentCol]==playerOne&&gameBoard[1][currentCol]==playerOne&&gameBoard[2][currentCol]==playerOne)
       {
           winner=true;
       }
       else if(gameBoard[0][currentCol]==playerTwo&&gameBoard[1][currentCol]==playerTwo&&gameBoard[2][currentCol]==playerTwo)
       {
           winner=true;
       }

       //checks one diagonal
       if(gameBoard[0][0]==playerOne&&gameBoard[1][1]==playerOne&&gameBoard[2][2]==playerOne)
       {
           winner=true;
       }
       else if(gameBoard[0][0]==playerTwo&&gameBoard[1][1]==playerTwo&&gameBoard[2][2]==playerTwo)
       {
           winner=true;
       }

       //checks other diagonal
       if(gameBoard[2][0]==playerOne&&gameBoard[1][1]==playerOne&&gameBoard[0][2]==playerOne)
       {
           winner=true;
       }
       else if(gameBoard[2][0]==playerTwo&&gameBoard[1][1]==playerTwo&&gameBoard[0][2]==playerTwo)
       {
           winner=true;
       }
       return winner;
   }

This code tests a win in a standard 3 x 3 tic tac toe game. My question is, how would I change the numbers inside to match a game of any size board, such as n x n?

Currently it checks the first row, second row, and third row to check if either player has won in any row, and that follows for columns as well as diagonal. However, when the board size is changed to anything else, this no longer holds true because it doesn't check every possible row/column/diagonal. So how would I make it do this for a board of size n x n. Please no code as I do not wish to plagiarize, but if anybody could provide input, it would be greatly appreciated?

Upvotes: 0

Views: 730

Answers (4)

sprinter
sprinter

Reputation: 27966

If you are allowed to use Java 8 in your assignment then this is a really nice use of streams. The stream solution would look like:

  1. Generate a stream of integers representing numbers up to n (hint: IntStream.range)
  2. Map that to 2 sets of values: the content of the corresponding row and col (hint: Stream.flatMap)
  3. Add to that stream sets for both diagonals (hint: Stream.concat)
  4. Filter for sets that have a single value
  5. If you find any, you have a winner (hint: Stream.findAny)

If you don't know streams then this might be a bit confusing but it does end up with a quite elegant representation of a winning board (i.e. get me all sets of in a line and tell me if any have just one value).

A nice feature of doing this is that it can be trivially converted to parallel streams if required for very large boards.

Upvotes: 0

timleathart
timleathart

Reputation: 560

You could have four loops - one loop checking horizontal, vertical, NE-SW diagonal, and NW-SE diagonal.

Consider the horizontal case: Assuming you still only need three in a row to win, you need to check each row for possible wins (i.e. checking to see if there are three in a row from the same player). A horizontal three-in-a-row needs to start before column n-3, or it will go past the bounds of the board. So, by checking each possible horizontal three-in-a-row starting in columns 0 to n-3, for each row, any horizontal win will be found.

Example for the horizontal case:

for (int j = 0; j < n; j++) {
    for (int i = 0; i < n-3; i++) {
        if (gameBoard[i][j] == gameBoard[i+1][j] && gameBoard[i][j] == gameBoard[i+2][j]) {
            return true;
        }
    }
}

Using this concept you can check for vertical and diagonal wins as well.

Upvotes: 0

Norgul
Norgul

Reputation: 4783

The way I would do it is write a separate function which has field dimensions and player inputs, for example:

String whoWinner(int d, int p1, int p2)

Once you got that covered, place 3 nested for loops (horizontal, vertical, diagonal) and check winning conditions for each player in a way that:

if (arr[i][j]='x') p1+=1;
if (arr[i][j]='o') p2+=1;

if (p1==d) return "P1 wins!";
if (p2==d) return "P2 wins!";

It is a slow method of doing it, but with field dimensions up to, I don't know, 1000, I think you shouldn't have any problems.

Upvotes: 0

Aify
Aify

Reputation: 3537

A really slow but brute force guaranteed to work method would be if you stepped through the arrays, and if the cell is not empty, check all surrounding cells - if you find a line pattern consisting of the same cell type (circle or x), then you've found a winner. If it doesn't find a line pattern, move to the next cell and repeat the process until you've covered the entire board or found a winner.

For example, start at cell 0, 0 and finds an x. 0, 0 checks 0, 1; 1, 0; 1, 1. No winning pattern found, so go to 0, 1 and check all adjacent cells again.

Upvotes: 0

Related Questions