0 people like it.

Reversi Kata at ProgFsharp

The Official Solution.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
81: 
82: 
83: 
84: 
85: 
86: 
87: 
88: 
89: 
90: 
91: 
92: 
93: 
94: 
let input = """
  B.......
  ........
  ........
  ...BW...
  ...WB...
  ........
  ........
  ........"""

type color = | White | Black | Nothing

open System

let chartoColor s = 
    s |> Seq.map(function 
                   | 'W' -> White 
                   | 'B' -> Black
                   | '.' -> Nothing )
      |> Seq.toArray

let board = input.Split('\n') 
              |> Array.map(fun s -> s.Trim())
              |> Array.filter(fun s -> s <> "")
              |> Array.map chartoColor 
              |> array2D

let rec move (dx,dy) (x,y)  = seq{ 
    if not(x < 0 || y < 0 || x >= 8 || y >=8) then 
       yield (x,y), (board.[x,y])
       yield! move (dx,dy) (x+dx, y+dy) 
      }

let up = move (-1,0)
up (4,4)         



let otherColor = function
  | Black -> White
  | White -> Black
  | _ -> Nothing

let legalMove color seqmove = 
  let restlist= 
     seqmove 
      |> Seq.skip 1 
      |> Seq.skipWhile(fun ((x,y),c) -> c = otherColor color)
      |> Seq.toList

  match restlist, restlist.Length < (Seq.length seqmove)-1 with 
  | ((x,y), Nothing)::xs, true -> Some (x,y)
  | _ -> None

let directions = [(-1,0);(1,0);(0,-1);(0,1);(1,1);(-1,1);(1,-1);(-1,-1)] 

let moves color pos =
  directions |> List.choose (fun d -> move d pos |> legalMove color)
             |> Set.ofSeq

let generateMoves color = 
    seq {
      for x in 0 .. 7 do
        for y in 0 .. 7 do
          if color = board.[x,y] then
            yield moves color (x,y)
    }
    |> Seq.fold (Set.union) Set.empty


// ---------------------------------

[Black; White; White; Nothing ]
|> Seq.mapi (fun i c -> (0, i), c)
|> legalMove Black 

[Black; White; White ]
|> Seq.mapi (fun i c -> (0, i), c)
|> legalMove Black 

[Black; Nothing ]
|> Seq.mapi (fun i c -> (0, i), c)
|> legalMove Black 

[Black; White; Black; Nothing ]
|> Seq.mapi (fun i c -> (0, i), c)
|> legalMove Black 


moves Black (4, 4)
moves Black (3, 3)
moves Black (0, 0)  

generateMoves Black
val input : string

Full name: Script.input
type color =
  | White
  | Black
  | Nothing

Full name: Script.color
union case color.White: color
union case color.Black: color
union case color.Nothing: color
namespace System
val chartoColor : s:seq<char> -> color []

Full name: Script.chartoColor
val s : seq<char>
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val toArray : source:seq<'T> -> 'T []

Full name: Microsoft.FSharp.Collections.Seq.toArray
val board : color [,]

Full name: Script.board
String.Split([<ParamArray>] separator: char []) : string []
String.Split(separator: string [], options: StringSplitOptions) : string []
String.Split(separator: char [], options: StringSplitOptions) : string []
String.Split(separator: char [], count: int) : string []
String.Split(separator: string [], count: int, options: StringSplitOptions) : string []
String.Split(separator: char [], count: int, options: StringSplitOptions) : string []
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
val s : string
String.Trim() : string
String.Trim([<ParamArray>] trimChars: char []) : string
val filter : predicate:('T -> bool) -> array:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.filter
val array2D : rows:seq<#seq<'T>> -> 'T [,]

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.array2D
val move : dx:int * dy:int -> x:int * y:int -> seq<(int * int) * color>

Full name: Script.move
val dx : int
val dy : int
val x : int
val y : int
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
val up : (int * int -> seq<(int * int) * color>)

Full name: Script.up
val otherColor : _arg1:color -> color

Full name: Script.otherColor
val legalMove : color:color -> seqmove:seq<('a * 'b) * color> -> ('a * 'b) option

Full name: Script.legalMove
Multiple items
val color : color

--------------------
type color =
  | White
  | Black
  | Nothing

Full name: Script.color
val seqmove : seq<('a * 'b) * color>
val restlist : (('a * 'b) * color) list
val skip : count:int -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.skip
val skipWhile : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.skipWhile
val x : 'a
val y : 'b
val c : color
val toList : source:seq<'T> -> 'T list

Full name: Microsoft.FSharp.Collections.Seq.toList
property List.Length: int
val length : source:seq<'T> -> int

Full name: Microsoft.FSharp.Collections.Seq.length
val xs : (('a * 'b) * color) list
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
val directions : (int * int) list

Full name: Script.directions
val moves : color:color -> int * int -> Set<int * int>

Full name: Script.moves
val pos : int * int
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val choose : chooser:('T -> 'U option) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.choose
val d : int * int
Multiple items
module Set

from Microsoft.FSharp.Collections

--------------------
type Set<'T (requires comparison)> =
  interface IComparable
  interface IEnumerable
  interface IEnumerable<'T>
  interface ICollection<'T>
  new : elements:seq<'T> -> Set<'T>
  member Add : value:'T -> Set<'T>
  member Contains : value:'T -> bool
  override Equals : obj -> bool
  member IsProperSubsetOf : otherSet:Set<'T> -> bool
  member IsProperSupersetOf : otherSet:Set<'T> -> bool
  ...

Full name: Microsoft.FSharp.Collections.Set<_>

--------------------
new : elements:seq<'T> -> Set<'T>
val ofSeq : elements:seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.ofSeq
val generateMoves : color:color -> Set<int * int>

Full name: Script.generateMoves
val fold : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State

Full name: Microsoft.FSharp.Collections.Seq.fold
val union : set1:Set<'T> -> set2:Set<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.union
val empty<'T (requires comparison)> : Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Set.empty
val mapi : mapping:(int -> 'T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.mapi
val i : int
Raw view Test code New version

More information

Link:http://fssnip.net/eY
Posted:11 years ago
Author:Nick
Tags: reversi