Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- open System.IO
- open ScrabbleServer
- open ScrabbleUtil.ServerCommunication
- module RegEx =
- open System.Text.RegularExpressions
- let (|Regex|_|) pattern input =
- let m = Regex.Match(input, pattern)
- if m.Success then Some(List.tail [ for g in m.Groups -> g.Value ])
- else None
- let parseMove ts =
- let pattern = @"([-]?[0-9]+[ ])([-]?[0-9]+[ ])([0-9]+)([A-Z]{1})([0-9]+)[ ]?"
- Regex.Matches(ts, pattern) |>
- Seq.cast<Match> |>
- Seq.map
- (fun t ->
- match t.Value with
- | Regex pattern [x; y; id; c; p] ->
- ((x |> int, y |> int), (id |> uint32, (c |> char, p |> int)))
- | _ -> failwith "Failed (should never happen)") |>
- Seq.toList
- module Print =
- let printPoints points =
- printfn "Points = %d" points
- let printHand pieces hand =
- hand |>
- MultiSet.fold (fun _ x i -> printfn "%d -> (%A, %d)" x (Map.find x pieces) i) ()
- let printBoard board radius placed =
- let c = ScrabbleUtil.Board.center board
- let minX = fst c - radius
- let maxX = fst c + radius
- let minY = snd c - radius
- let maxY = snd c + radius
- for y in [minY..maxY] do
- for x in [minX..maxX] do
- match Map.tryFind (x, y) placed, ScrabbleUtil.Board.tiles board (x, y) with
- | None, Some (c, _) -> printf "%c " c
- | Some (c, _), _ -> printf "%c " c
- | _, None -> printf "# "
- printf "\n"
- module State =
- open ScrabbleUtil
- type state = {
- lettersPlaced : Map<ScrabbleUtil.coord, char * int>
- hand : MultiSet.MultiSet<uint32>
- points : int
- playerTurn : int
- activePlayerlist : Map<uint32,int>
- }
- let mkState lp h = { lettersPlaced = lp; hand = h;points=0; playerTurn=0; activePlayerlist=Map.empty }
- let newState hand = mkState Map.empty hand
- let lettersPlaced st = st.lettersPlaced
- let hand st = st.hand
- open State
- let recv play st msg =
- match msg with
- | RCM (CMPlaySuccess(ms, points, newPieces)) ->
- (* Successful play by you. Update your state *)
- let stateAfterLettersPlaced = {st with lettersPlaced = ms|>List.fold (fun acc (coordinates,(id,tile)) -> acc|> Map.add coordinates tile ) st.lettersPlaced}
- let stateAfterTilesRemovedFromHand = {stateAfterLettersPlaced with hand = ms|>List.fold (fun acc (coordinates,(id,tile))->acc|> MultiSet.removeSingle id) stateAfterLettersPlaced.hand}
- let stateAfterNewPiecesAdded = {stateAfterTilesRemovedFromHand with hand = newPieces|>List.fold(fun acc (a,b)->acc|>MultiSet.add a b) stateAfterTilesRemovedFromHand.hand}
- let stateAfterPointsAdded = {stateAfterNewPiecesAdded with points = stateAfterNewPiecesAdded.points+points } // This state needs to be updated
- let st' = stateAfterPointsAdded
- play st'
- | RCM (CMPlayed (pid, ms, points)) ->
- (* Successful play by other player. Update your state *)
- let st1 ={st with lettersPlaced = ms|>List.fold (fun acc (coordinates,(id,tile))->acc|> Map.add coordinates tile) st.lettersPlaced }
- let st2 ={st1 with activePlayerlist = Map.add pid ((Map.find pid st1.activePlayerlist)+points) st1.activePlayerlist}
- let st' = st2
- // This state needs to be updated
- play st'
- | RCM (CMPlayFailed (pid, ms)) ->
- (* Failed play. Update your state *)
- let st' = st // This state needs to be updated
- play st'
- | RCM (CMGameOver _) -> ()
- | RCM (CMPlayerJoined (pid,playerName))->
- ()
- | RCM a -> failwith (sprintf "not implmented: %A" a)
- | RErr err -> printfn "Server Error:\n%A" err; play st
- | RGPE err -> printfn "Gameplay Error:\n%A" err; play st
- let playGame send board pieces st =
- let rec aux st =
- Print.printBoard board 8 (State.lettersPlaced st)
- printfn "\n\n"
- Print.printPoints st.points
- printfn "\n\n"
- Print.printHand pieces (State.hand st)
- printfn "Input move (format '(<x-coordinate><y-coordinate> <piece id><character><point-value> )*', note the absence of state between the last inputs)"
- let input = System.Console.ReadLine()
- let move = RegEx.parseMove input
- send (recv aux st) (SMPlay move)
- aux st
- let startGame send (msg : Response) =
- match msg with
- | RCM (CMGameStarted (board, pieces, playerNumber, hand, playerList)) ->
- let hand' = List.fold (fun acc (v, x) -> MultiSet.add v x acc) MultiSet.empty hand
- playGame send board pieces (State.newState hand')
- | _ -> failwith "No game has been started yet"
- [<EntryPoint>]
- let main argv =
- let send = Comm.connect ()
- send (startGame send) (SMStartGame(1u, "My game", "", "My name"))
- 0 // return an integer exit code
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement