1 people like it.
Like the snippet!
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 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 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
Full name: Microsoft.FSharp.Collections.Seq.head
val exists : predicate:('T -> bool) -> list:'T list -> bool
Full name: Microsoft.FSharp.Collections.List.exists
val targets : seq<int * int>
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
More information