Search code examples
code-golfrosetta-stonetic-tac-toe

Code Golf: Tic Tac Toe


Post your shortest code, by character count, to check if a player has won, and if so, which.

Assume you have an integer array in a variable b (board), which holds the Tic Tac Toe board, and the moves of the players where:

  • 0 = nothing set
  • 1 = player 1 (X)
  • 2 = player 2 (O)

So, given the array b = [ 1, 2, 1, 0, 1, 2, 1, 0, 2 ] would represent the board

X|O|X
-+-+-
 |X|O
-+-+-
X| |O

For that situation, your code should output 1 to indicate player 1 has won. If no-one has won you can output 0 or false.

My own (Ruby) solution will be up soon.

Edit: Sorry, forgot to mark it as community wiki. You can assume the input is well formed and does not have to be error checked.


Update: Please post your solution in the form of a function. Most people have done this already, but some haven't, which isn't entirely fair. The board is supplied to your function as the parameter. The result should be returned by the function. The function can have a name of your choosing.


Solution

  • C, 77 (83) characters

    This is a variant of dmckee's solution, except that each pair of digits in the Compact Coding is now the base-9 digits of the ASCII characters.

    The 77-char version, does not work on MSVC:

    // "J)9\t8\r=,\0" == 82,45,63,10,62,14,67,48,00 in base 9.
    char*k="J)9 8\r=,",c;f(int*b){return(c=*k++)?b[c/9]&b[c%9]&b[*k--%9]|f(b):0;}
    

    This 83-char version, should work on every C compiler:

    f(int*b){char*k="J)9    8\r=,",s=0,c;while(c=*k++)s|=b[c%9]&b[c/9]&b[*k%9];return s;}
    

    (Note that the spaces between the 9 and 8 should be a tab. StackOverflow converts all tabs into spaces.)


    Test case:

    #include <stdio.h>  
    void check(int* b) {
        int h0 = b[0]&b[1]&b[2];
        int h1 = b[3]&b[4]&b[5];
        int h2 = b[6]&b[7]&b[8];
        int h3 = b[0]&b[3]&b[6];
        int h4 = b[1]&b[4]&b[7];
        int h5 = b[2]&b[5]&b[8];
        int h6 = b[0]&b[4]&b[8];
        int h7 = b[2]&b[4]&b[6];
        int res = h0|h1|h2|h3|h4|h5|h6|h7;
        int value = f(b);
        if (value != res)
            printf("Assuming f({%d,%d,%d, %d,%d,%d, %d,%d,%d}) == %d; got %d instead.\n", 
                b[0],b[1],b[2], b[3],b[4],b[5], b[6],b[7],b[8], res, value);
    }
    #define MAKEFOR(i) for(b[(i)]=0;b[(i)]<=2;++b[(i)])
    
    int main() {
        int b[9];
    
        MAKEFOR(0)
        MAKEFOR(1)
        MAKEFOR(2)
        MAKEFOR(3)
        MAKEFOR(4)
        MAKEFOR(5)
        MAKEFOR(6)
        MAKEFOR(7)
        MAKEFOR(8)
            check(b);
    
        return 0;
    }