Advertisement
Guest User

Untitled

a guest
Apr 17th, 2015
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.63 KB | None | 0 0
  1. open System
  2. open System.IO
  3.  
  4. type Tree = Node of (int * int * int) * ((string * Tree) list)
  5.  
  6. let initial = Node((0, 0, 0), [])
  7.  
  8. let split (x:string) = x.Split ' ' |> Array.toList
  9.  
  10. let adding_comprehention = function
  11.     | "1-0" -> (fun (a, b, c) -> (a + 1, b, c + 1))
  12.     | "0-1" -> (fun (a, b, c) -> (a, b + 1, c + 1))
  13.     | _ -> (fun (a, b, c) -> (a, b, c + 1))
  14.  
  15. let rec add_sequence_to_tree f activeMoves = function
  16.     | Node(state, moves) ->
  17.         if List.isEmpty activeMoves
  18.         then Node(f state, moves)
  19.         else
  20.             let move = List.head activeMoves
  21.             let lasted = List.tail activeMoves
  22.             match List.tryFindIndex (fst >> ((=) move)) moves with
  23.                 | None -> Node(f state, (move, add_sequence_to_tree f lasted initial)::moves)
  24.                 | Some(index) ->
  25.                     let newmoves = List.mapi (fun i (str, tr) -> if i <> index then (str, tr)
  26.                                                                  else (str, add_sequence_to_tree f lasted tr)) moves
  27.                     Node(f state, newmoves)
  28.  
  29. let add_game_to_tree tree = function
  30.     | result::moves -> add_sequence_to_tree (adding_comprehention result) moves tree
  31.     | _ -> failwith "Invalid sequence"
  32.  
  33. let maxFromSons f moves = List.maxBy (snd >> fst) (List.map (fun (str, tr) -> (str, f tr)) moves)
  34.  
  35. let rec getLongestDebute = function
  36.     | Node((_, _, c), moves) ->
  37.       if c < 2 || (List.isEmpty moves) then (0.0, [])
  38.       else maxFromSons getLongestDebute moves
  39.            |> (fun (a, (b, c)) -> (b + 1.0, a::c))
  40.  
  41. let rec getBestDebute criterium = function
  42.     | Node((_, _, c) as state, moves) ->
  43.         if c < 2 then (0.0, [])
  44.         elif List.isEmpty moves then (criterium state, [])
  45.         else let pretendent = maxFromSons (getBestDebute criterium) moves
  46.              if (snd >> fst) pretendent >= (criterium state)
  47.              then ((snd >> fst) pretendent, (fst pretendent)::((snd >> snd) pretendent))
  48.              else (criterium state, [])
  49.  
  50. let BlackCriterium = function
  51.     | (_, b, c) -> (float b) / (float c)
  52.  
  53. let WhiteCriterium = function
  54.     | (a, _, c) -> (float a) / (float c)
  55.  
  56. let getWorstMove =
  57.     let rec getWorstMove' depth = function
  58.        | Node(state, moves) ->
  59.            if List.isEmpty moves then (0.0, [])
  60.            else let another = maxFromSons (getWorstMove' (depth + 1)) moves
  61.                  let criterium = if (depth % 2 = 0) then WhiteCriterium
  62.                                                     else BlackCriterium
  63.                  let this = List.map (fun (str, Node(newstate, newMoves)) ->
  64.                                         (str, criterium state - criterium newstate)) moves
  65.                             |> List.maxBy snd
  66.                  if (snd this) > ((snd >> fst) another) then (snd this, [fst this])
  67.                                                         else (((snd >> fst) another), (fst another)::((snd >> snd) another))
  68.     getWorstMove' 0
  69.  
  70.  
  71. let printGameList lst =
  72.    List.iteri (fun i str -> if i % 2 = 0 then printf "%d. %s " (i / 2) str else printfn "%s" str) lst
  73.  
  74. [<EntryPoint>]
  75. let main args =
  76.    let logs = ["C:\log_source\1.txt"; "C:\log_source\2.txt";
  77.                "C:\log_source\3.txt"; "C:\log_source\4.txt";
  78.                "C:\log_source\5.txt"]
  79.    let positions =
  80.        logs |> Seq.map (fun f -> async { return(File.ReadAllLines f) |> Array.toList})
  81.        |> Async.Parallel |> Async.RunSynchronously |> Array.toList |> List.concat
  82.    let splittedPositions = List.map split positions
  83.    let gametree = List.fold add_game_to_tree initial splittedPositions
  84.    let tasks = [ async { return (getLongestDebute gametree) };
  85.                  async { return (getBestDebute WhiteCriterium gametree) };
  86.                  async { return (getBestDebute BlackCriterium gametree) };
  87.                  async { return (getWorstMove gametree) }
  88.                ]
  89.    let results = Async.RunSynchronously (Async.Parallel tasks)
  90.    printfn "Самый длинный дебют:\n"
  91.    printGameList (snd results.[0])
  92.    printfn "\n"
  93.    printfn "Наилучший дебют для белых c вероятностью выигрыша %f:\n" (fst results.[1])
  94.    printGameList (snd results.[1])
  95.    printfn "\n"
  96.    printfn "Наилучший дебют для чёрных c вероятностью выигрыша %f:\n" (fst results.[2])
  97.    printGameList (snd results.[2])
  98.    printfn "\n"
  99.    printfn "Наихудший ход:"
  100.    printGameList (snd results.[3])
  101.    printfn " <<-- После последнего хода вероятность выигрыша упала на %f" (fst results.[3])
  102.    0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement