TopCoder problem "TicSolver" used in TCCC '03 Semifinals 2 (Division I Level Two)



Problem Statement

    Tic-Tac-Toe is a game played on a 3x3 board. The players alternate claiming spots on the board until one player has 3 spots in a row (horizontally, vertically, or diagonally), or there are no spots left to claim. The first player to move will always use 'O's to claim his spots whereas the second player will use 'X's. Claiming 3 spots in a row means you win and play stops. If no spots are left and nobody has won, the game is a draw.



By examing a Tic-Tac-Toe board it is often possible to determine whether a particular player should win. More precisely, a player should win if there exists a sequence of moves such that, regardless of his opponent's moves, he will always win. Another way of saying this is, a player should win a given position if playing the right moves will always produce a win regardless of the opposition's efforts to thwart his victory.



You will be a given a String[] board describing the current state of the game. board will contain 3 elements representing the rows of the board. Each element will contain 3 characters representing the spots in that row. For example:
board = {"XO."
         "..."
         ".OX"}
As seen above, the 'X's and 'O's represent each player's respective moves and the '.'s represent unclaimed spots. Your method will return a String according to the following rules:

1) If the board position is invalid (could not be achieved through a succession of valid moves) return "INVALID"

2) If the first player (player using 'O's) should win or has already won return "FIRST"

3) If the second player (player using 'X's) should win or has already won return "SECOND"

4) Otherwise return "DRAW"

In the example above the board position is valid and the first player should win so you would return "FIRST". Note, rule 1 has precedence over the other rules.
 

Definition

    
Class:TicSolver
Method:whoWins
Parameters:String[]
Returns:String
Method signature:String whoWins(String[] board)
(be sure your method is public)
    
 

Constraints

-board will contain exactly 3 elements
-Each element of board will contain exactly 3 characters
-Each character in board will be one of 'X', 'O', or '.' (quotes for clarity)
 

Examples

0)
    
{"OX.",
 "...",
 "..."}
Returns: "FIRST"
If the first player plays the center spot, the second player is forced to block him in the lower right spot:
OX.
.O.
..X
The first player can then play the lower left spot thus giving him two ways to get three in a row. Since this line of play is unstoppable by the second player, the first player should win.
1)
    
{"O..",
 ".X.",
 "..."}
Returns: "DRAW"
Nobody has a line of play that will assure victory.
2)
    
{"OXO",
 "OOX",
 "X.X"}
Returns: "DRAW"
The first player has only one choice leading to a draw.
3)
    
{"OOO",
 "XX.",
 "..."}
Returns: "FIRST"
4)
    
{"...",
 "...",
 "..."}
Returns: "DRAW"
5)
    
{"O..",
 "XX.",
 "..."}
Returns: "INVALID"
The second player has gone twice, but the first player has only gone once.
6)
    
{"XXX",
 "OO.",
 "OO."}
Returns: "INVALID"
Looking at the number of spots occupied it is clear that the first player has just moved. It is impossible then, that the second player has already won.
7)
    
{"OXO",
 "X.X",
 "OXO"}
Returns: "FIRST"

Problem url:

http://www.topcoder.com/stat?c=problem_statement&pm=920

Problem stats url:

http://www.topcoder.com/tc?module=ProblemDetail&rd=4492&pm=920

Writer:

brett1479

Testers:

Logan , lbackstrom , schveiguy

Problem categories:

Recursion, Search