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
open Core
open Placed_tile

let score_word (word : Word_extraction.t) placed =
  let placed_positions =
    placed |> List.map ~f:(fun pt -> (pt.pos.row, pt.pos.col))
  in
  let is_new pos =
    List.mem placed_positions (pos.row, pos.col)
      ~equal:(fun (r1, c1) (r2, c2) -> r1 = r2 && c1 = c2)
  in
  let word_multiplier = ref 1 in
  let letter_total =
    List.fold word.tiles ~init:0 ~f:(fun acc { tile; pos } ->
        let base = Tile.get_points tile in
        if is_new pos then
          match Board.get_square_type pos with
          | Double_letter -> acc + (base * 2)
          | Triple_letter -> acc + (base * 3)
          | Double_word ->
              word_multiplier := !word_multiplier * 2;
              acc + base
          | Triple_word ->
              word_multiplier := !word_multiplier * 3;
              acc + base
          | Normal -> acc + base
        else acc + base)
  in
  letter_total * !word_multiplier

let calculate_move_score words placed =
  let base_score =
    List.fold words ~init:0 ~f:(fun acc w -> acc + score_word w placed)
  in
  let bingo_bonus = if List.length placed >= 7 then 50 else 0 in
  base_score + bingo_bonus