mirror of
https://github.com/correl/hackerrank.git
synced 2024-11-23 11:09:53 +00:00
Level 1 - Tic Tac Toe
This commit is contained in:
parent
5623a927ae
commit
f9bb4cf869
1 changed files with 74 additions and 0 deletions
74
TicTacToe.hs
Normal file
74
TicTacToe.hs
Normal file
|
@ -0,0 +1,74 @@
|
|||
module Main where
|
||||
|
||||
import Data.List (sort, findIndices)
|
||||
import System.Random (randomRIO)
|
||||
|
||||
testboard :: String
|
||||
testboard = "O_X_X_O__"
|
||||
|
||||
getList :: Int -> IO [String]
|
||||
getList n = if n==0 then return [] else do i <- getLine; is <- getList(n-1); return (i:is)
|
||||
|
||||
findEmpty :: String -> [Int]
|
||||
findEmpty board = findIndices (\c -> c == '_') board
|
||||
|
||||
sets :: [[Int]]
|
||||
sets = [[0,1,2],
|
||||
[3,4,5],
|
||||
[6,7,8],
|
||||
|
||||
[0,3,6],
|
||||
[1,4,7],
|
||||
[2,5,8],
|
||||
|
||||
[0,4,8],
|
||||
[2,4,6]]
|
||||
|
||||
findMoves :: String -> Char -> [(Int, Int)]
|
||||
findMoves board player = moves
|
||||
where moves = [(scoreIndex i, i) | i <- indexes]
|
||||
indexes = findEmpty board
|
||||
scoreIndex x = sum $ map (scoreSet player) $ findSets board x
|
||||
|
||||
bestMoves :: [(Int, Int)] -> [Int]
|
||||
bestMoves [] = []
|
||||
bestMoves moves = [snd m | m <- sortedMoves, bestScore == fst m]
|
||||
where sortedMoves = reverse.sort $ moves
|
||||
bestScore = fst $ head sortedMoves
|
||||
|
||||
findSets :: String -> Int -> [String]
|
||||
findSets board index = sets''
|
||||
where sets' = filter (\x -> elem index x) sets
|
||||
sets'' = map chars' sets'
|
||||
chars' = map (\x -> board !! x)
|
||||
|
||||
scoreSet :: Char -> String -> Int
|
||||
scoreSet player set
|
||||
| (elem 'O' set) && (elem 'X' set) = 0
|
||||
| otherwise = 2 ^ (length.filter (\x -> x /= '_') $ set)
|
||||
|
||||
otherPlayer :: Char -> Char
|
||||
otherPlayer 'X' = 'O'
|
||||
otherPlayer 'O' = 'X'
|
||||
|
||||
coords :: Int -> (Int, Int)
|
||||
coords index = (y, x)
|
||||
where y = index `div` 3
|
||||
x = index `rem` 3
|
||||
|
||||
main = do
|
||||
|
||||
-- If player is X, I'm the first player.
|
||||
-- If player is O, I'm the second player.
|
||||
player <- getLine
|
||||
|
||||
-- Read the board now. The board is a list of strings filled with X, O or _.
|
||||
board <- getList 3
|
||||
|
||||
let moves = bestMoves $ findMoves (concat board) (player !! 0)
|
||||
r <- randomRIO (1, length(moves))
|
||||
let nextMove = coords $ moves !! (r - 1)
|
||||
|
||||
-- Proceed with processing and print 2 integers separated by a single space.
|
||||
putStrLn.(\(x, y) -> show x ++ " " ++ show y) $ nextMove
|
||||
|
Loading…
Reference in a new issue