Tic-Tac-Toe Evaluation

This month’s Exercise may seem like a repeat of the Exercise “We Have a Winnah!” from July of 2013. It’s not.

The July 2013 Exercise involved solving a tic-tac-toe like grid. Alas, the grid was filled with ones and zeros and only one grid pattern was presented. In a true game of tic-tac-toe, three characters occupy the grid: X, O, and blank. Further, multiple possibilities must be tested to assure a victory, which is why I’m presenting this, updated challenge.

For this month’s Exercise, your task is to determine whether a completed and valid tic-tac-toe game grid holds a winning combination, which is three Xs or three Os across, down, or diagonal. To help meet this goal, I’ve provided a program skeleton available below as well as on GitHub.

Something I learned while researching this project is that you can’t randomly pack an array and expect it to represent realistic game play. Therefore, each string in the game[] array represents a valid 3-by-3 game grid as a string of x, o, and space characters:

char *game[6] = {
    "xxoooxxox",
    "o x xox ",
    "xx oxxooo",
    "o xooox x",
    " xo ox o",
    "x oxo xox"
};

Each string lays out as rows and columns: "xxoooxxox" stands for the completed game shown in Figure 1.

sample game

Figure 1. A sample game grid, no winner.

The six strings in the array represent various possible solutions to a game of tic-tac-toe, along with some cat’s games (no winner). The code skeleton provided below contains the game[] array, the output_grid() function to display the array as a tic-tac-toe game, but the code is missing the is_winner() function that evaluates each string for a winner and returns the winning token character.

#include <stdio.h>

/* generate the tic-tac-toe grid */
void output_grid( char *g )
{
    int row;

    for( row=0; row<3; row++)
    {
        printf(" %c %c %c\n",
                *(g+(3*row)),
                *(g+(3*row)+1),
                *(g+(3*row)+2)
              );
    }
}

/* determine whether the game was won */
char is_winner( char *g )
{
    return(' ');
}

int main()
{
    char *game[6] = {
        "xxoooxxox",
        "o x xox  ",
        "xx oxxooo",
        "o xooox x",
        " xo ox  o",
        "x oxo xox"
    };
    int x,r;

    /* examine all five game results */
    for( x=0; x<6; x++ )
    {
        output_grid( game[x] );
        printf("Game %d: ",x+1);
        r = is_winner( game[x] );
        switch(r)
        {
            case ' ':
                puts("No winner\n");
                break;
            case 'x':
                puts("X wins!\n");
                break;
            case 'o':
                puts("O wins!\n");
                break;
            default:
                puts("Unknown value\n");
        }
    }

    return(0);
}

Your task for the Exercise is to code the is_winner() function. Ensure that it evaluates all possible solutions and returns the winning token character, ‘x’ or ‘o’, or ‘ ‘ (space) for no winner. Click here to view my solution.

2 thoughts on “Tic-Tac-Toe Evaluation

  1. /* determine whether the game was won
    Assumes only 1 win possible and picks first one found
    Check for only char ‘x’ or ‘o’ for possible wins
    Assumes the input string will only contain ‘x’,’o’,’ ‘
    */
    char is_winner( char *g )
    {
    //Assume no winner response
    char results = ‘ ‘;
    // Create table 8 possible win vectors
    const int wv[8][3] = {{0,1,2},{0,4,8},{0,3,6},{1,4,7},{2,4,6},{2,5,8},{3,4,5},{6,7,8}};

    //Loop through all possible
    for(int loop=0; loop < 8; loop++)
    {
    // calcluate the sum of the scalars of one of the win vectors
    int win = g[wv[loop][0]]+g[wv[loop][1]]+g[wv[loop][2]];

    // Some debug to help see what is happening
    printf("%d:win=%d – %d %d %d\n", loop, win, wv[loop][0],wv[loop][1], wv[loop][2]);

    //Check for either all 'x' or all 'o'
    if('x'*3 == win)
    {
    results = 'x';
    break;
    }
    if('o'*3 == win)
    {
    results = 'o';
    break;
    }
    }

    return(results);
    }

Leave a Reply