1 people like it.

# Reversi Kata

Quick & dirty solution to Reversi kata: http://codingdojo.org/cgi-bin/wiki.pl?KataReversi

 ``` 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: ``` ``````let boardText =" ........ ........ ........ ...BW... ...WB... ........ ........ ........" let board = boardText.Split([|'\r';'\n'|]) |> Array.filter (fun line -> line.Length > 0) let getLegalMoves (board:string[]) color = let width, height = board.[0].Length, board.Length let opposite = match color with | 'B' -> 'W' | 'W' -> 'B' | _ -> invalidOp "" let findDisks color = board |> Seq.mapi (fun y line -> line |> Seq.mapi (fun x item -> if item = color then Some(x,y) else None) ) |> Seq.concat |> Seq.choose id let directions = [-1,-1; 0,-1; 1, -1; -1, 0; 1, 0; -1, 1; 0, 1; 1, 1] let isInside (x,y) = x >= 0 && x < width && y >= 0 && y < height let itemAt (x,y) = board.[y].[x] let findSurroundingPlaces (x,y) = directions |> List.map (fun (dx,dy) -> x+dx, y+dy) |> List.filter isInside let isLegalMove (x,y) = directions |> List.filter (fun (dx,dy) -> isInside (x+dy,y+dy)) |> List.filter (fun (dx,dy) -> opposite = itemAt (x+dx,y+dy)) |> List.map (fun (dx,dy) -> let xs = Seq.initInfinite (fun i -> (x+dx*i, y+dy*i)) |> Seq.skip 1 |> Seq.takeWhile isInside |> Seq.skipWhile (fun (x,y) -> itemAt(x,y) = opposite) if Seq.length xs = 0 then false else Seq.head xs |> itemAt = color ) |> List.exists id let targets = findDisks opposite targets |> Seq.map (fun (x,y) -> findSurroundingPlaces (x,y) |> List.filter (fun (x,y) -> board.[y].[x] = '.') |> List.filter isLegalMove ) |> Seq.concat getLegalMoves board 'B' ``````
val boardText : string

Full name: Script.boardText
val board : string []

Full name: Script.board
System.String.Split([<System.ParamArray>] separator: char []) : string []
System.String.Split(separator: string [], options: System.StringSplitOptions) : string []
System.String.Split(separator: char [], options: System.StringSplitOptions) : string []
System.String.Split(separator: char [], count: int) : string []
System.String.Split(separator: string [], count: int, options: System.StringSplitOptions) : string []
System.String.Split(separator: char [], count: int, options: System.StringSplitOptions) : string []
module Array

from Microsoft.FSharp.Collections
val filter : predicate:('T -> bool) -> array:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.filter
val line : string
property System.String.Length: int
val getLegalMoves : board:string [] -> color:char -> seq<int * int>

Full name: Script.getLegalMoves
val board : string []
Multiple items
val string : value:'T -> string

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

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val color : char
val width : int
val height : int
property System.Array.Length: int
val opposite : char
val invalidOp : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.invalidOp
val findDisks : (char -> seq<int * int>)
module Seq

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

Full name: Microsoft.FSharp.Collections.Seq.mapi
val y : int
val x : int
val item : char
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
val concat : sources:seq<#seq<'T>> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.concat
val choose : chooser:('T -> 'U option) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.choose
val id : x:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.id
val directions : (int * int) list
val isInside : (int * int -> bool)
val itemAt : (int * int -> char)
val findSurroundingPlaces : (int * int -> (int * int) list)
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'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 map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val dx : int
val dy : int
val filter : predicate:('T -> bool) -> list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.filter
val isLegalMove : (int * int -> bool)
val xs : seq<int * int>
val initInfinite : initializer:(int -> 'T) -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.initInfinite
val i : int
val skip : count:int -> source:seq<'T> -> seq<'T>

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

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

Full name: Microsoft.FSharp.Collections.Seq.skipWhile
val length : source:seq<'T> -> int

Full name: Microsoft.FSharp.Collections.Seq.length
val head : source:seq<'T> -> 'T