Advertisement
ttrd5r65r5r5

Untitled

Apr 25th, 2019
1,664
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.97 KB | None | 0 0
  1. open System.IO
  2.  
  3. open ScrabbleServer
  4. open ScrabbleUtil.ServerCommunication
  5.  
  6. module RegEx =
  7.     open System.Text.RegularExpressions
  8.  
  9.     let (|Regex|_|) pattern input =
  10.         let m = Regex.Match(input, pattern)
  11.         if m.Success then Some(List.tail [ for g in m.Groups -> g.Value ])
  12.         else None
  13.  
  14.     let parseMove ts =
  15.         let pattern = @"([-]?[0-9]+[ ])([-]?[0-9]+[ ])([0-9]+)([A-Z]{1})([0-9]+)[ ]?"
  16.         Regex.Matches(ts, pattern) |>
  17.         Seq.cast<Match> |>
  18.         Seq.map
  19.             (fun t ->
  20.                 match t.Value with
  21.                 | Regex pattern [x; y; id; c; p] ->
  22.                     ((x |> int, y |> int), (id |> uint32, (c |> char, p |> int)))
  23.                 | _ -> failwith "Failed (should never happen)") |>
  24.         Seq.toList
  25.  
  26.  module Print =
  27.  
  28.     let printPoints points =
  29.         printfn "Points = %d" points
  30.  
  31.     let printHand pieces hand =
  32.         hand |>
  33.         MultiSet.fold (fun _ x i -> printfn "%d -> (%A, %d)" x (Map.find x pieces) i) ()
  34.  
  35.     let printBoard board radius placed =
  36.  
  37.         let c = ScrabbleUtil.Board.center board
  38.  
  39.         let minX = fst c - radius
  40.         let maxX = fst c + radius
  41.         let minY = snd c - radius
  42.         let maxY = snd c + radius
  43.  
  44.         for y in [minY..maxY] do
  45.             for x in [minX..maxX] do
  46.                 match Map.tryFind (x, y) placed, ScrabbleUtil.Board.tiles board (x, y) with
  47.                 | None, Some (c, _) -> printf "%c " c
  48.                 | Some (c, _), _    -> printf "%c " c
  49.                 | _, None -> printf "# "
  50.             printf "\n"
  51.  
  52. module State =
  53.     open ScrabbleUtil
  54.  
  55.     type state = {
  56.         lettersPlaced       : Map<ScrabbleUtil.coord, char * int>
  57.         hand                : MultiSet.MultiSet<uint32>
  58.         points              : int
  59.         playerTurn          : int
  60.         activePlayerlist    : Map<uint32,int>
  61.     }
  62.  
  63.     let mkState lp h = { lettersPlaced = lp; hand = h;points=0; playerTurn=0; activePlayerlist=Map.empty }
  64.  
  65.     let newState hand = mkState Map.empty hand
  66.  
  67.     let lettersPlaced st = st.lettersPlaced
  68.     let hand st          = st.hand
  69.  
  70.  
  71. open State
  72. let recv play st msg =
  73.    
  74.     match msg with
  75.     | RCM (CMPlaySuccess(ms, points, newPieces)) ->
  76.         (* Successful play by you. Update your state *)
  77.         let stateAfterLettersPlaced = {st with lettersPlaced = ms|>List.fold (fun acc (coordinates,(id,tile)) -> acc|> Map.add coordinates tile ) st.lettersPlaced}
  78.         let stateAfterTilesRemovedFromHand = {stateAfterLettersPlaced with hand = ms|>List.fold (fun acc (coordinates,(id,tile))->acc|> MultiSet.removeSingle id) stateAfterLettersPlaced.hand}
  79.         let stateAfterNewPiecesAdded = {stateAfterTilesRemovedFromHand with hand = newPieces|>List.fold(fun acc (a,b)->acc|>MultiSet.add a b) stateAfterTilesRemovedFromHand.hand}
  80.         let stateAfterPointsAdded = {stateAfterNewPiecesAdded with points = stateAfterNewPiecesAdded.points+points } // This state needs to be updated
  81.         let st' = stateAfterPointsAdded
  82.        play st'
  83.     | RCM (CMPlayed (pid, ms, points)) ->
  84.         (* Successful play by other player. Update your state *)
  85.         let st1 ={st with lettersPlaced = ms|>List.fold (fun acc (coordinates,(id,tile))->acc|> Map.add coordinates tile) st.lettersPlaced }
  86.         let st2 ={st1 with activePlayerlist = Map.add pid ((Map.find pid st1.activePlayerlist)+points) st1.activePlayerlist}
  87.         let st' = st2
  88.      
  89.        
  90.        // This state needs to be updated
  91.        play st'
  92.     | RCM (CMPlayFailed (pid, ms)) ->
  93.         (* Failed play. Update your state *)
  94.         let st' = st // This state needs to be updated
  95.        play st'
  96.     | RCM (CMGameOver _) -> ()
  97.     | RCM (CMPlayerJoined (pid,playerName))->
  98.        ()
  99.     | RCM a -> failwith (sprintf "not implmented: %A" a)
  100.     | RErr err -> printfn "Server Error:\n%A" err; play st
  101.     | RGPE err -> printfn "Gameplay Error:\n%A" err; play st
  102.  
  103. let playGame send board pieces st =
  104.  
  105.     let rec aux st =
  106.         Print.printBoard board 8 (State.lettersPlaced st)
  107.         printfn "\n\n"
  108.         Print.printPoints st.points
  109.         printfn "\n\n"
  110.         Print.printHand pieces (State.hand st)
  111.  
  112.         printfn "Input move (format '(<x-coordinate><y-coordinate> <piece id><character><point-value> )*', note the absence of state between the last inputs)"
  113.         let input =  System.Console.ReadLine()
  114.         let move = RegEx.parseMove input
  115.  
  116.         send (recv aux st) (SMPlay move)
  117.  
  118.     aux st
  119.  
  120.  
  121.  
  122. let startGame send (msg : Response) =
  123.     match msg with
  124.     | RCM (CMGameStarted (board, pieces, playerNumber, hand, playerList)) ->
  125.         let hand' = List.fold (fun acc (v, x) -> MultiSet.add v x acc) MultiSet.empty hand
  126.        playGame send board pieces (State.newState hand')
  127.     | _ -> failwith "No game has been started yet"
  128.      
  129. [<EntryPoint>]
  130. let main argv =
  131.     let send = Comm.connect ()
  132.     send (startGame send) (SMStartGame(1u, "My game", "", "My name"))
  133.     0 // return an integer exit code
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement