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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
open Core
open Placed_tile
type square_type =
| Normal
| Double_letter
| Triple_letter
| Double_word
| Triple_word
type direction = Horizontal | Vertical
module IntPair = struct
type t = int * int [@@deriving compare, sexp]
end
module BoardMap = Map.Make (IntPair)
type t = Tile.t BoardMap.t
let to_yojson board =
`Assoc
(Map.to_alist board
|> List.map ~f:(fun ((row, col), tile) ->
(Printf.sprintf "%d,%d" row col, Tile.to_yojson tile)))
let of_placed_tile_list_exn (placed_tiles : Placed_tile.t list) : t =
BoardMap.of_alist_exn
@@ List.map placed_tiles ~f:(fun pt -> ((pt.pos.row, pt.pos.col), pt.tile))
let board_size = 15
let triple_word_squares =
[
{ row = 0; col = 0 };
{ row = 0; col = 7 };
{ row = 0; col = 14 };
{ row = 7; col = 0 };
{ row = 7; col = 14 };
{ row = 14; col = 0 };
{ row = 14; col = 7 };
{ row = 14; col = 14 };
]
let double_word_squares =
[
{ row = 1; col = 1 };
{ row = 2; col = 2 };
{ row = 3; col = 3 };
{ row = 4; col = 4 };
{ row = 1; col = 13 };
{ row = 2; col = 12 };
{ row = 3; col = 11 };
{ row = 4; col = 10 };
{ row = 13; col = 1 };
{ row = 12; col = 2 };
{ row = 11; col = 3 };
{ row = 10; col = 4 };
{ row = 13; col = 13 };
{ row = 12; col = 12 };
{ row = 11; col = 11 };
{ row = 10; col = 10 };
{ row = 7; col = 7 };
]
let triple_letter_squares =
[
{ row = 1; col = 5 };
{ row = 1; col = 9 };
{ row = 5; col = 1 };
{ row = 5; col = 5 };
{ row = 5; col = 9 };
{ row = 5; col = 13 };
{ row = 9; col = 1 };
{ row = 9; col = 5 };
{ row = 9; col = 9 };
{ row = 9; col = 13 };
{ row = 13; col = 5 };
{ row = 13; col = 9 };
]
let double_letter_squares =
[
{ row = 0; col = 3 };
{ row = 0; col = 11 };
{ row = 2; col = 6 };
{ row = 2; col = 8 };
{ row = 3; col = 0 };
{ row = 3; col = 7 };
{ row = 3; col = 14 };
{ row = 6; col = 2 };
{ row = 6; col = 6 };
{ row = 6; col = 8 };
{ row = 6; col = 12 };
{ row = 7; col = 3 };
{ row = 7; col = 11 };
{ row = 8; col = 2 };
{ row = 8; col = 6 };
{ row = 8; col = 8 };
{ row = 8; col = 12 };
{ row = 11; col = 0 };
{ row = 11; col = 7 };
{ row = 11; col = 14 };
{ row = 12; col = 6 };
{ row = 12; col = 8 };
{ row = 14; col = 3 };
{ row = 14; col = 11 };
]
let get_square_type pos =
let matches l =
List.exists l ~f:(fun p -> p.row = pos.row && p.col = pos.col)
in
if matches triple_word_squares then Triple_word
else if matches double_word_squares then Double_word
else if matches triple_letter_squares then Triple_letter
else if matches double_letter_squares then Double_letter
else Normal
let is_valid_position { row; col } =
row >= 0 && row < board_size && col >= 0 && col < board_size
let get_tile_at board pos = Map.find board (pos.row, pos.col)
let is_board_empty board = Map.is_empty board
let create_empty_board () = BoardMap.empty
let place_tile_on_board board pos tile =
Map.set board ~key:(pos.row, pos.col) ~data:tile