diff --git a/cards.ml b/cards.ml index 385df60..fc86727 100644 --- a/cards.ml +++ b/cards.ml @@ -1,5 +1,9 @@ -open Core - +open List;; +open Core;; +open Out_channel;; + +Random.self_init ();; + type card_type = | Hearts | Tiles @@ -18,28 +22,20 @@ type card = { seed: card_type ; value: int } let card_to_string c = String.concat ["{ seed: "; card_type_to_string c.seed; "; value: "; string_of_int c.value; " }"] -let print_card chan card = output_string chan (card_to_string card);; +let print_card chan card = Out_channel.output_string chan (card_to_string card);; +let value_cmp a b = Int.compare a.value b.value +let seed_cmp = fun a b -> if card_type_to_string a.seed > card_type_to_string b.seed then 1 else + if card_type_to_string a.seed = card_type_to_string b.seed then 0 else -1 -(* -let deck = - let ordered_deck = - let make_set tp = - List.map ~f:(fun x->{seed=tp; value=x}) (List.range 1 14) in (* make a set of cards of one seed *) - List.concat [make_set Hearts ; make_set Tiles ; make_set Clovers ; make_set Pikes] in - let nd = List.map ~f:(fun e -> Random.bits (), e) ordered_deck in - let sorted = List.sort ~compare:compare nd in List.map ~f:snd sorted;; -*) let make_set tp = - List.map ~f:(fun x->{seed=tp; value=x}) (List.range 1 14);;(* make a set of cards of one seed *) -let deck = - List.concat [make_set Hearts ; make_set Tiles ; make_set Clovers ; make_set Pikes] |> - List.map ~f:(fun e -> Random.bits (), e) |> List.sort ~compare:compare |> List.map ~f:snd + List.map ~f:(fun x -> { seed=tp; value=x }) (List.range 1 14);; (* make a set of cards of one seed *) +let init = + List.concat [make_set Hearts ; make_set Tiles ; make_set Clovers ; make_set Pikes ; + make_set Hearts ; make_set Tiles ; make_set Clovers ; make_set Pikes] |> + List.map ~f:(fun e -> Random.bits (), e) |> + List.sort ~compare:(fun a b -> if fst a > fst b then 1 else -1) |> + List.map ~f:snd let draw deck = match deck with - | [] -> {seed=Nothing ; value=0}, [] + | [] as l -> {seed=Nothing ; value=0}, l | hd::tl -> hd, tl - -let deck = deck -let card, _ = draw deck;; - -Printf.printf "%a" print_card card diff --git a/main.ml b/main.ml new file mode 100644 index 0000000..bdf52ae --- /dev/null +++ b/main.ml @@ -0,0 +1,126 @@ +open List +open Cards + +type ingame_cards = card list +type player = { name: string ; cards: card list } +type table = { deck: card list ; ingame: ingame_cards; players: player list } + +let deck = Cards.init +let card, _ = draw deck;; +Printf.printf "%a\n" print_card card + +(* Mosse: Aggiunta, spostamento *) +(* + Triplette giocabili in mano, doppie usabili, singole usabili + una volta vista la mano, rimuovi le carte inusabili nel turno; + considerata una carta giocabile in mano, considera le carte "prossime", bruteforce; +*) + +type status = + | Valid + | Invalid + | Unknown ;; + + +let no_double_seed cards = + List.sort_uniq Cards.seed_cmp cards |> List.length = List.length cards + +let is_only_one_seed cards = + List.sort_uniq Cards.seed_cmp cards |> List.length = 1 + +let no_double_value cards = + List.sort_uniq Cards.value_cmp cards |> List.length = List.length cards + +let is_tris cards = + match (List.sort_uniq Cards.value_cmp cards) with + | [_] -> no_double_seed cards (* only one value, check for right seeds *) + | _::_ -> false + | [] -> assert false + +let rec split l fst = + match l with + | hd::hd'::tl when hd=hd'-1 -> split (hd'::tl) (fst@[hd]) + | hd::tl -> fst@[hd], tl + | [] -> assert false + + +let is_scala _cards = + let rec _is_scala cards = + match cards with + | hd::hd'::tl when hd=hd'-1 -> _is_scala (hd'::tl) + | [] -> assert false + | [_] -> true (* list was consumed *) + | _::_ -> false in + + if (not (no_double_value _cards && is_only_one_seed _cards)) then + false + else + let last = List.rev _cards |> hd in + let cards = List.map (fun c -> c.value) _cards (* use only values *) in + if last.value = 13 && (hd cards) = 1 then (* circolare *) + let fst, snd = split cards [] in (_is_scala fst) && (_is_scala snd) + else + _is_scala cards + +let is_valid _cards = + let cards = List.sort Cards.value_cmp _cards in + if length cards < 3 then + false + else + match cards with + | a::b::_ when Cards.value_cmp a b = 0 -> is_tris cards + | _ -> is_scala cards;; + + +let rec play cards = + true + +let start_play ingame cards = + ingame @ cards |> List.sort Cards.value_cmp |> play +;; +(* TESTS TODO: *) +let cards = [{seed=Clovers; value=1}; {seed=Hearts; value=1}; {seed=Pikes; value=1}] in +assert (is_valid cards);; + +let cards = [{seed=Tiles; value=1}; {seed=Clovers; value=1}; {seed=Hearts; value=1}; {seed=Pikes; value=1}] in +assert (is_valid cards);; + +let cards = [{seed=Tiles; value=2}; {seed=Clovers; value=1}; {seed=Hearts; value=1}; {seed=Pikes; value=1}] in +assert (not (is_valid cards));; + +let cards = [{seed=Hearts; value=2}; {seed=Hearts; value=2}; {seed=Hearts; value=4}] +in assert (not (no_double_value cards));; + +let cards = [{seed=Hearts; value=2}; {seed=Hearts; value=2}; {seed=Hearts; value=4}] +in assert (not (no_double_seed cards));; + +let cards = [{seed=Pikes; value=2}; {seed=Clovers; value=2}; {seed=Tiles; value=4}; {seed=Hearts; value=4}] +in assert (no_double_seed cards);; + +let cards = [{seed=Hearts; value=4}; {seed=Hearts; value=3}; {seed=Hearts; value=2}; {seed=Hearts; value=1}] +in assert (is_valid cards);; + +let cards = [{seed=Hearts; value=13}; {seed=Hearts; value=12}; {seed=Hearts; value=2}; {seed=Hearts; value=1}] +in assert (is_valid cards);; + +let cards = [{seed=Pikes; value=13}; {seed=Hearts; value=12}; {seed=Hearts; value=2}; {seed=Hearts; value=1}] +in assert (not (is_valid cards));; + +let cards = [{seed=Pikes; value=13}; {seed=Pikes; value=12}; {seed=Pikes; value=1}] +in assert (is_valid cards);; +let cards = [{seed=Hearts; value=12}; {seed=Pikes; value=12}; {seed=Pikes; value=1}] +in assert (not (is_valid cards));; + +let cards = [{seed=Hearts; value=13}; {seed=Hearts; value=3}; {seed=Hearts; value=2}; {seed=Hearts; value=1}] +in assert (is_valid cards);; + + +let cards = [{seed=Hearts; value=1}] in +let ingame = [{seed=Hearts; value=13}; {seed=Hearts; value=3}; {seed=Hearts; value=2}] +in assert (play ingame cards);; + +let cards = [{seed=Tiles; value=12}; {seed=Tiles; value=13}; {seed=Pikes; value=3}; {seed=Clovers; value=3}] in +let ingame = [{seed=Hearts; value=1}; {seed=Hearts; value=13}; {seed=Hearts; value=12}; + {seed=Pikes; value=1}; {seed=Clovers; value=1}; {seed=Tiles; value=1}; + {seed=Hearts; value=2}; {seed=Pikes; value=2}; {seed=Clovers; value=2}] +in assert (start_play ingame cards);; (* Risultato: scala 1-2-12-13 Hearts; scala 1-2-3 Pikes; scala 1-2-3 Clovers; scala 1-13-12 Tiles *)