简体   繁体   中英

Check for winner in an NxN tic tac toe game (C program)

I have a homework where I have to create an N x N tic tac toe game in C program. I've been working on it for two days now and my only problem is to check for winners.

Can anyone give me suggestions on how can I check for horizontal win/ diagonal etc.?

The size of the board is N x N where the user determines the size.
I have made an array board[i][j] where I save the movements of the players. I am open for any suggestions on how may I do this horizontal check or diagonal etc.

I tried doing something like this for horizontal check

void horizontalwin()
{
    for (r=0; r<size; r++){
        for(c=0; c<size; c++){
            for(int n=1; n<=size; n++)
        if(board[r][c]==board[r][c+n]&& board[r][c]!='_')
          win=1;
          break;
        }
    }
}

but this way it stops checking if it finds two columns and it doesn't go to the end of the row to check if all columns in the row have a match.

Depending on how the 2D array board is defined, one potential problem is here:

if(board[r][c]==board[r][c+n]&& board[r][c]!='_')  
                          ^^    

For example, if board is defined somewhere as:

int board[size][size] = {0};  

Then:

If c can grow to size-1
And if r can grow to size-1
Then if n is greater than 0
board[r][c+n] will exceed the 2nd index array bounds. This will cause undefined behavior .

Also, the phrase:

if(board[r][c]==board[r][c+n]&& board[r][c]!='_')
  win=1;
  break;

will break even if win does not equal 1 .

It should probably be written:

if(board[r][c]==board[r][c+n]&& board[r][c]!='_')
{
    win=1;
    break;
}

Three nested loops seems excessive. You should only need two nested loops to check for a horizontal or vertical win. You only need a non-nested loop to check for diagonal wins.

For horizontal checking, you can check each row in turn. If all columns on the row contain the same, non-empty value (ie not the '_' character), then return a win. After checking all rows, return no win.

Since this is homework, I will just show how to check a single row for a win. Basically, it involves checking all elements in the row but one (for example, skip the first element) to see if it is either empty or different to its neighbour (the previous element if the first element was skipped). If any of the tests fail, then there is no win on that row.

        for (c = 1; c < size; c++) {
            if (board[r][c] == '_' || board[r][c] != board[r][c-1]) {
                break; // no winner on this row
            }
        }
        if (c == size) {
            // board[r][0] is the winner!
            // do something here to return the winner.
        }
        // else: no winner on row r
        // continue iterating over the remaining rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM