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
type letter_tile = { letter : char; points : int } [@@deriving yojson]

type t = Letter of letter_tile | Blank of char option
[@@deriving yojson { exn = true }]

let get_letter = function
  | Letter l -> l.letter
  | Blank None -> '?'
  | Blank (Some c) -> c

let get_points = function Letter l -> l.points | Blank _ -> 0

let equal a b =
  match (a, b) with
  | Blank _, Blank _ -> true
  | Letter la, Letter lb ->
      Char.equal la.letter lb.letter && la.points = lb.points
  | _ -> false
(* | Blank _, Letter _ -> false *)
(* | Letter _, Blank _ -> false *)

let equal_with_expansion t needed =
  match (t, needed) with
  | Blank _, Blank _ -> true
  | Blank _, Letter _ -> true
  | Letter a, Letter b -> Char.equal a.letter b.letter && a.points = b.points
  | Letter _, Blank _ -> false

let make ?(blank_with_letter = false) letter_opt points =
  if blank_with_letter then
    Blank
      (Some
         (letter_opt
         |> Core.Option.value_exn
              ~message:
                "You have to specify a letter when setting blank_with_letter \
                 to true"))
  else
    match letter_opt with
    | None -> Blank None
    | Some letter -> Letter { letter; points }

let is_blank_without_letter = function Blank None -> true | _ -> false
let is_blank = function Blank _ -> true | _ -> false