How to resolve the algorithm Tic-tac-toe step by step in the F# programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Tic-tac-toe step by step in the F# programming language
Table of Contents
Problem Statement
Play a game of tic-tac-toe. Ensure that legal moves are played and that a winning position is notified.
Tic-tac-toe is also known as:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Tic-tac-toe step by step in the F# programming language
Source code in the fsharp programming language
type Brick =
| Empty
| Computer
| User
let brickToString = function
| Empty -> ' '
| Computer -> 'X'
| User -> 'O'
// y -> x -> Brick
type Board = Map<int, Map<int, Brick> >
let emptyBoard =
let emptyRow = Map.ofList [0,Empty; 1,Empty; 2,Empty]
Map.ofList [0,emptyRow; 1,emptyRow; 2,emptyRow]
let get (b:Board) (x,y) = b.[y].[x]
let set player (b:Board) (x,y) : Board =
let row = b.[y].Add(x, player)
b.Add(y, row)
let winningPositions =
[for x in [0..2] -> x,x] // first diagonal
::[for x in [0..2] -> 2-x,x] // second diagonal
::[for y in [0..2] do
yield! [[for x in [0..2]->(y,x)]; // columns
[for x in [0..2] -> (x,y)]]] // rows
let hasWon player board =
List.exists
(fun ps -> List.forall (fun pos -> get board pos = player) ps)
winningPositions
let freeSpace board =
[for x in 0..2 do
for y in 0..2 do
if get board (x,y) = Empty then yield x,y]
type Evaluation =
| Win
| Draw
| Lose
let rec evaluate board move =
let b2 = set Computer board move
if hasWon Computer b2 then Win
else
match freeSpace b2 with
| [] -> Draw
| userChoices ->
let b3s = List.map (set User b2) userChoices
if List.exists (hasWon User) b3s then Lose
elif List.exists (fun b3 -> bestOutcome b3 = Lose) b3s
then Lose
elif List.exists (fun b3 -> bestOutcome b3 = Draw) b3s
then Draw
else Win
and findBestChoice b =
match freeSpace b with
| [] -> ((-1,-1), Draw)
| choices ->
match List.tryFind (fun c -> evaluate b c = Win) choices with
| Some c -> (c, Win)
| None -> match List.tryFind (fun c -> evaluate b c = Draw) choices with
| Some c -> (c, Draw)
| None -> (List.head choices, Lose)
and bestOutcome b = snd (findBestChoice b)
let bestChoice b = fst (findBestChoice b)
let computerPlay b = set Computer b (bestChoice b)
let printBoard b =
printfn " | A | B | C |"
printfn "---+---+---+---+"
for y in 0..2 do
printfn " %d | %c | %c | %c |"
(3-y)
(get b (0,y) |> brickToString)
(get b (1,y) |> brickToString)
(get b (2,y) |> brickToString)
printfn "---+---+---+---+"
let rec userPlay b =
printfn "Which field do you play? (format: a1)"
let input = System.Console.ReadLine()
if input.Length <> 2
|| input.[0] < 'a' || input.[0] > 'c'
|| input.[1] < '1' || input.[1] > '3' then
printfn "illegal input"
userPlay b
else
let x = int(input.[0]) - int('a')
let y = 2 - int(input.[1]) + int('1')
if get b (x,y) <> Empty then
printfn "Field is not free."
userPlay b
else
set User b (x,y)
let rec gameLoop b player =
if freeSpace b = [] then
printfn "Game over. Draw."
elif player = Computer then
printfn "Computer plays..."
let b2 = computerPlay b
printBoard b2
if hasWon Computer b2 then
printfn "Game over. I have won."
else
gameLoop b2 User
elif player = User then
let b2 = userPlay b
printBoard b2
if hasWon User b2 then
printfn "Game over. You have won."
else
gameLoop b2 Computer
// randomly choose an element of a list
let choose =
let rnd = new System.Random()
fun (xs:_ list) -> xs.[rnd.Next(xs.Length)]
// play first brick randomly
printfn "Computer starts."
let b = set Computer emptyBoard (choose (freeSpace emptyBoard))
printBoard b
gameLoop b User
You may also check:How to resolve the algorithm Compound data type step by step in the 6502 Assembly programming language
You may also check:How to resolve the algorithm AKS test for primes step by step in the AArch64 Assembly programming language
You may also check:How to resolve the algorithm Hello world/Line printer step by step in the Factor programming language
You may also check:How to resolve the algorithm Sum and product of an array step by step in the Rapira programming language
You may also check:How to resolve the algorithm Count occurrences of a substring step by step in the EGL programming language