fuk
This commit is contained in:
parent
23d38adf7f
commit
52a41690cf
5 changed files with 235 additions and 147 deletions
164
alg.py
164
alg.py
|
@ -1,6 +1,8 @@
|
|||
from collections import namedtuple;
|
||||
from copy import deepcopy as copy # FUK
|
||||
|
||||
DO_TESTS = False
|
||||
DO_PRINT = True
|
||||
MAX = -1000
|
||||
best = None
|
||||
DONE = False
|
||||
|
@ -16,6 +18,8 @@ def flattenBySeed(lst):
|
|||
return sorted([s for subl in lst for s in subl], key=lambda x: x.seed)
|
||||
|
||||
def print_1(tavolo, n):
|
||||
if not DO_PRINT:
|
||||
return
|
||||
global MEM, MAX
|
||||
st = ('------------- '+str(n)+':'+str(tavolo.punteggio())+':'+str(MAX)+' -------------'+'='+str(len(MEM)))
|
||||
print(st)
|
||||
|
@ -30,10 +34,6 @@ class Mano:
|
|||
def __init__(self, carte):
|
||||
assert type(carte) is list and type(carte[0]) is Card
|
||||
self.cards = carte # lista di Carte
|
||||
def cardsByValue(self):
|
||||
return sorted(self.cards, key=lambda c: c.value)
|
||||
def cardsBySeed(self):
|
||||
return sorted(self.cards, key=lambda c: c.seed)
|
||||
|
||||
class TaggedCards:
|
||||
cards = None
|
||||
|
@ -79,12 +79,6 @@ class TaggedCards:
|
|||
else:
|
||||
return False
|
||||
|
||||
def cardsByValue(self):
|
||||
return sorted(self.cards, key=lambda c: c.value)
|
||||
def cardsBySeed(self):
|
||||
return sorted(self.cards, key=lambda c: c.seed)
|
||||
|
||||
|
||||
class Tavolo:
|
||||
cards = list() # lista di taggedcards
|
||||
def __init__(self, cs):
|
||||
|
@ -100,13 +94,11 @@ class Tavolo:
|
|||
def getNonValide(self):
|
||||
assert type(self.cards[0]) is TaggedCards
|
||||
f = [c for c in self.cards if c.tag == 'NonValido']
|
||||
# return list(flattenByValue(f))
|
||||
return f
|
||||
|
||||
def getValide(self):
|
||||
assert type(self.cards[0]) is TaggedCards
|
||||
f = [c for c in self.cards if c.tag == 'Valido']
|
||||
# return list(flattenByValue(f))
|
||||
return f
|
||||
|
||||
def getAll(self):
|
||||
|
@ -129,11 +121,8 @@ def gioca(tavolo, giocata, da_muovere):
|
|||
if not rimpiazzata and da_muovere in t.cards:
|
||||
t = [c for c in t.cards if c != da_muovere]
|
||||
if t != []:
|
||||
# tavolo.cards[i] = TaggedCards(t)
|
||||
news.append(TaggedCards(t))
|
||||
rimpiazzata = True
|
||||
# tavolo.cards[idx] = TaggedCards(giocata.cards + [da_muovere])
|
||||
# return tavolo
|
||||
else:
|
||||
news.append(t)
|
||||
return Tavolo(news)
|
||||
|
@ -181,12 +170,10 @@ def alg(tavolo, tavolo_iniziale, soluzioni, n, punteggio):
|
|||
for v in vicini:
|
||||
next_tavolo = gioca(tavolo, carte, v)
|
||||
assert startL == next_tavolo.llen()
|
||||
# recur
|
||||
alg(next_tavolo, tavolo_iniziale, soluzioni, n+1, copy(punteggio))
|
||||
|
||||
def find_vicini(carte, tavolo):
|
||||
def _find_vicini(carte, all):
|
||||
# all = flatten(tavolo.getAll())
|
||||
if carte.tipo == 'Singolo':
|
||||
return [a for a in all if is_tris(carte.cards+[a]) or is_straight(carte.cards+[a])]
|
||||
elif carte.tipo == 'Tris':
|
||||
|
@ -267,6 +254,7 @@ def is_valida(carte):
|
|||
else:
|
||||
return is_straight(carte)
|
||||
|
||||
if DO_TESTS:
|
||||
carte_test = [Card('quadri', 1), Card('picche', 1), Card('fiori', 1), Card('cuori', 1)]
|
||||
print(is_valida(carte_test))
|
||||
|
||||
|
@ -291,77 +279,76 @@ tavolo_test = Tavolo([
|
|||
res = find_vicini(TaggedCards([Card(seed='quadri', value=13)]), tavolo_test)
|
||||
assert set(res) == {Card('quadri', 1), Card('quadri', 12), Card('cuori', 13)}
|
||||
|
||||
assert TaggedCards([Card('picche', 2)]) < TaggedCards([Card('picche',2), Card('fiori', 2)])
|
||||
assert TaggedCards([Card('picche', 2)]) < TaggedCards([Card('picche',2), Card('fiori', 2)])
|
||||
assert TaggedCards([Card('picche', 2)]) > TaggedCards([Card('picche',2), Card('fiori', 2), Card('cuori', 2), Card('quadri', 2)])
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# tavolo = Tavolo([
|
||||
# TaggedCards([
|
||||
# Card("picche", 2),
|
||||
# Card("fiori", 2),
|
||||
# Card("cuori", 2)]),
|
||||
# TaggedCards([
|
||||
# Card("cuori", 1),
|
||||
# Card("fiori", 1),
|
||||
# Card("picche", 1),
|
||||
# Card("quadri", 1)]),
|
||||
# # mano
|
||||
# TaggedCards([
|
||||
# Card("quadri", 13)]),
|
||||
# TaggedCards([
|
||||
# Card("quadri", 12)]),
|
||||
# TaggedCards([
|
||||
# Card("cuori", 13)]),
|
||||
# TaggedCards([
|
||||
# Card("cuori", 12)]),
|
||||
# TaggedCards([
|
||||
# Card("fiori", 3)]),
|
||||
# TaggedCards([
|
||||
# Card("picche", 3)]),
|
||||
# TaggedCards([
|
||||
# Card("cuori", 12)])
|
||||
# ])
|
||||
# tavolo = Tavolo([
|
||||
# TaggedCards([
|
||||
# Card("picche", 2),
|
||||
# Card("fiori", 2),
|
||||
# Card("quadri", 2),
|
||||
# Card("cuori", 2)]),
|
||||
# TaggedCards([
|
||||
# Card("cuori", 1),
|
||||
# Card("fiori", 1),
|
||||
# Card("picche", 1),
|
||||
# Card("quadri", 1)]),
|
||||
# # mano
|
||||
# TaggedCards([
|
||||
# Card("picche", 3)]),
|
||||
# ])
|
||||
# tavolo = Tavolo([
|
||||
# TaggedCards([
|
||||
# Card("fiori", 7),
|
||||
# Card("fiori", 8),
|
||||
# Card("fiori", 9)]),
|
||||
# TaggedCards([
|
||||
# Card("picche", 7),
|
||||
# Card("picche", 8),
|
||||
# Card("picche", 9)]),
|
||||
# TaggedCards([
|
||||
# Card("cuori", 7),
|
||||
# Card("cuori", 8),
|
||||
# Card("cuori", 9),
|
||||
# Card("cuori", 10)]),
|
||||
# # mano
|
||||
# TaggedCards([
|
||||
# Card("cuori", 11)]),
|
||||
# TaggedCards([
|
||||
# Card("cuori", 12)]),
|
||||
# TaggedCards([
|
||||
# Card("quadri", 7)])
|
||||
# ])
|
||||
tavolo = Tavolo([
|
||||
tavolo1 = Tavolo([
|
||||
TaggedCards([
|
||||
Card("picche", 2),
|
||||
Card("fiori", 2),
|
||||
Card("cuori", 2)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 1),
|
||||
Card("fiori", 1),
|
||||
Card("picche", 1),
|
||||
Card("quadri", 1)]),
|
||||
# mano
|
||||
TaggedCards([
|
||||
Card("quadri", 13)]),
|
||||
TaggedCards([
|
||||
Card("quadri", 12)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 13)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 12)]),
|
||||
TaggedCards([
|
||||
Card("fiori", 3)]),
|
||||
TaggedCards([
|
||||
Card("picche", 3)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 12)])
|
||||
])
|
||||
tavolo2 = Tavolo([
|
||||
TaggedCards([
|
||||
Card("picche", 2),
|
||||
Card("fiori", 2),
|
||||
Card("quadri", 2),
|
||||
Card("cuori", 2)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 1),
|
||||
Card("fiori", 1),
|
||||
Card("picche", 1),
|
||||
Card("quadri", 1)]),
|
||||
# mano
|
||||
TaggedCards([
|
||||
Card("picche", 3)]),
|
||||
])
|
||||
tavolo3 = Tavolo([
|
||||
TaggedCards([
|
||||
Card("fiori", 7),
|
||||
Card("fiori", 8),
|
||||
Card("fiori", 9)]),
|
||||
TaggedCards([
|
||||
Card("picche", 7),
|
||||
Card("picche", 8),
|
||||
Card("picche", 9)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 7),
|
||||
Card("cuori", 8),
|
||||
Card("cuori", 9),
|
||||
Card("cuori", 10)]),
|
||||
# mano
|
||||
TaggedCards([
|
||||
Card("cuori", 11)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 12)]),
|
||||
TaggedCards([
|
||||
Card("quadri", 7)])
|
||||
])
|
||||
tavolo4 = Tavolo([
|
||||
TaggedCards([
|
||||
Card("fiori", 7),
|
||||
Card("fiori", 8),
|
||||
|
@ -381,6 +368,17 @@ if __name__ == '__main__':
|
|||
TaggedCards([
|
||||
Card("cuori", 8)])
|
||||
])
|
||||
tavolo5 = Tavolo([
|
||||
# mano
|
||||
TaggedCards([
|
||||
Card("cuori", 7)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 6)]),
|
||||
TaggedCards([
|
||||
Card("cuori", 8)])
|
||||
])
|
||||
|
||||
tavolo = tavolo5
|
||||
alg(tavolo, tavolo, [], 0, [])
|
||||
print('*************************************')
|
||||
print('****BEST:')
|
||||
print_1(best, MAX)
|
||||
|
|
14
hashset.ml
Normal file
14
hashset.ml
Normal file
|
@ -0,0 +1,14 @@
|
|||
open Hashtbl;;
|
||||
|
||||
(* This is a mess but I need sets for memoization.
|
||||
* This is my best effort as of now *)
|
||||
(* let null = ()
|
||||
*
|
||||
* let s = Hashtbl.create 1024
|
||||
*
|
||||
* let add key =
|
||||
* Hashtbl.add s key null;
|
||||
* false
|
||||
*
|
||||
* let has key =
|
||||
* Hashtbl.mem s key *)
|
72
main.ml
72
main.ml
|
@ -5,8 +5,10 @@ open Cards;;
|
|||
open Tcards;;
|
||||
open Table;;
|
||||
|
||||
let card_to_string c = String.concat ["{ seed: "; card_type_to_string c.seed;
|
||||
"; value: "; string_of_int c.value; " }"]
|
||||
(* let card_to_string c = String.concat ["{ seed: "; card_type_to_string c.seed;
|
||||
* "; value: "; string_of_int c.value; " }"] *)
|
||||
|
||||
let card_to_string c = String.concat ["{"; card_type_to_string c.seed;":"; string_of_int c.value; "}"]
|
||||
let print_card chan card = Out_channel.output_string chan (card_to_string card);;
|
||||
|
||||
let tcards_to_string c = "TCards: <"::
|
||||
|
@ -17,42 +19,15 @@ let tcards_to_string c = "TCards: <"::
|
|||
"]"::[] |> String.concat
|
||||
let print_tcards chan tcards = Out_channel.output_string chan (tcards_to_string tcards);;
|
||||
|
||||
let table_to_string c = "Table: <"::
|
||||
(List.map ~f:(fun c -> tcards_to_string c) c.cards |> String.concat)::
|
||||
let table_to_string c = ""::
|
||||
(List.map ~f:(fun c -> tcards_to_string c) c.cards |> String.concat ~sep:";\n")::
|
||||
">"::[] |> String.concat ;;
|
||||
let print_table chan table = Out_channel.output_string chan (table_to_string table);;
|
||||
|
||||
|
||||
let t = play (make [
|
||||
Tcards.make [
|
||||
Cards.make Pikes 2;
|
||||
Cards.make Tiles 2;
|
||||
Cards.make Hearts 2;
|
||||
];
|
||||
Tcards.make [
|
||||
Cards.make Hearts 2;
|
||||
]
|
||||
]) (* table_cards *)
|
||||
(Tcards.make [
|
||||
Cards.make Pikes 2;
|
||||
Cards.make Tiles 2;
|
||||
Cards.make Hearts 2;
|
||||
]) (* in_play *)
|
||||
(Cards.make Hearts 2) (* to_move *)
|
||||
(* in make [
|
||||
* Tcards.make [
|
||||
* Cards.make Pikes 2;
|
||||
* Cards.make Tiles 2;
|
||||
* Cards.make Hearts 2;
|
||||
* Cards.make Hearts 2;
|
||||
* ]
|
||||
* ] ;; *)
|
||||
in
|
||||
Printf.printf "%a\n" t
|
||||
|
||||
let deck = Cards.init
|
||||
let card, _ = draw deck;;
|
||||
Printf.printf "%a\n" print_card card
|
||||
(* Printf.printf "%a\n" print_card card *)
|
||||
|
||||
(* Mosse: Aggiunta, spostamento *)
|
||||
(*
|
||||
|
@ -62,4 +37,37 @@ Printf.printf "%a\n" print_card card
|
|||
*)
|
||||
|
||||
(* TESTS TODO: *)
|
||||
let printer table =
|
||||
Printf.printf "********\n%a\n********\n" print_table table;;
|
||||
|
||||
|
||||
(* let rec alg table original_table n (scores:int list) best max_score (dbg: table -> unit) = *)
|
||||
open Hashtbl;;
|
||||
let table = Table.make [
|
||||
Tcards.make [
|
||||
Cards.make Hearts 7;
|
||||
Cards.make Hearts 8;
|
||||
Cards.make Hearts 9;
|
||||
];
|
||||
Tcards.make [
|
||||
Cards.make Pikes 7;
|
||||
Cards.make Pikes 8;
|
||||
Cards.make Pikes 9;
|
||||
];
|
||||
Tcards.make [
|
||||
Cards.make Hearts 7;
|
||||
Cards.make Hearts 8;
|
||||
Cards.make Hearts 9;
|
||||
Cards.make Hearts 10;
|
||||
];
|
||||
Tcards.make [
|
||||
Cards.make Hearts 6;
|
||||
];
|
||||
Tcards.make [
|
||||
Cards.make Hearts 8;
|
||||
]
|
||||
] in
|
||||
let new_tables = Table.alg table 0 [] in
|
||||
(* List.iter ~f:(fun (t,_,_) -> printer t) new_table *)
|
||||
|
||||
Table.prova table [] [] (-1000) printer new_tables []
|
||||
|
|
75
table.ml
75
table.ml
|
@ -10,6 +10,9 @@ type table = { cards: tcards list}
|
|||
let make tcards =
|
||||
{ cards=tcards }
|
||||
|
||||
let empty =
|
||||
{ cards = [] }
|
||||
|
||||
let valids table =
|
||||
List.filter (fun ts -> ts.tag == Valid) table.cards;;
|
||||
|
||||
|
@ -27,17 +30,22 @@ let size table =
|
|||
List.map (fun tl -> Tcards.length tl) table.cards |>
|
||||
List.fold_left sum 0 ;;
|
||||
|
||||
let flatten table =
|
||||
let flatten table : card list=
|
||||
List.map (fun (ts:tcards) -> ts.cards) table.cards |>
|
||||
List.concat ;;
|
||||
|
||||
let neighbors tcs table =
|
||||
let contains tc table =
|
||||
List.mem tc table.cards
|
||||
|
||||
let neighbors tcs table : card list=
|
||||
let all = flatten table in
|
||||
match tcs.strategy with
|
||||
| Tris -> List.filter (fun (x:tcards) -> tcs.cards@x.cards |> Cards.is_tris) table.cards
|
||||
| Straight -> List.filter (fun (x:tcards) -> tcs.cards@x.cards |> Cards.is_straight) table.cards
|
||||
| Single -> List.filter (fun (x:tcards) ->
|
||||
tcs.cards@x.cards |> Cards.is_straight || tcs.cards@x.cards |> Cards.is_tris)
|
||||
table.cards
|
||||
| Tris -> List.filter (fun x -> tcs.cards@[x] |> Cards.is_tris) all
|
||||
| Straight -> List.filter (fun x -> tcs.cards@[x] |> Cards.is_straight) all
|
||||
| Single -> all |>
|
||||
List.filter (fun x -> let cs = tcs.cards@[x] in
|
||||
Cards.is_straight cs || Cards.is_tris cs)
|
||||
|
||||
|
||||
let constraints start eend =
|
||||
let hand = List.filter (fun ts -> ts.strategy == Single) start.cards in
|
||||
|
@ -59,11 +67,60 @@ let play table in_play to_move =
|
|||
| hd::tl when hd = in_play -> _play tl in_play to_move ((Tcards.make (to_move::in_play.cards))::accum)
|
||||
| [] -> accum (* generate a new table *)
|
||||
| hd::tl -> if hd |> Tcards.contains to_move then
|
||||
let filtered = List.filter (fun x -> x != to_move) hd.cards in
|
||||
_play tl in_play to_move ((Tcards.make filtered)::accum)
|
||||
match (Tcards.remove to_move hd) with
|
||||
| None -> _play tl in_play to_move accum
|
||||
| Some x -> _play tl in_play to_move (x::accum)
|
||||
else
|
||||
_play tl in_play to_move (hd::accum)
|
||||
in
|
||||
assert (table |> contains in_play) ;
|
||||
_play table.cards in_play to_move [] |> make
|
||||
;;
|
||||
|
||||
let update best max_score original newt score =
|
||||
if score > max_score && (constraints original newt) then
|
||||
score, newt
|
||||
else
|
||||
max_score, best
|
||||
|
||||
let is_best_outcome table =
|
||||
(invalids table |> List.length) == 0
|
||||
|
||||
(* let rec alg table original_table n (scores:int list) best max_score (dbg: table -> unit) =
|
||||
* dbg table ;
|
||||
* let ascore = score table in
|
||||
* (\* if Hashset.has (hash table) then () *\)
|
||||
* (\* else ( *\)
|
||||
* (\* Hashset.add (hash table) ; *\)
|
||||
* let mmax, bbest = update best max_score original_table table ascore in
|
||||
* if is_best_outcome table || n > 14 || doesnt_improve (scores@[ascore]) then
|
||||
* ()
|
||||
* else
|
||||
* table.cards |>
|
||||
* List.map (fun tcs -> neighbors tcs table |> List.map (fun v -> (tcs,v))) |> (\* lista di carta:vicini *\)
|
||||
* List.concat |> (\* flatten *\)
|
||||
* List.map (fun (card, neigh) -> play table card neigh) |> (\* list of new_tables *\)
|
||||
* List.iter (fun new_table -> alg new_table original_table (n+1) (scores@[ascore]) bbest mmax dbg)
|
||||
* (\* ) *\) *)
|
||||
|
||||
let alg table n (scores:int list) : (table * int * int list) list =
|
||||
table.cards |>
|
||||
List.map (fun tcs -> neighbors tcs table |> List.map (fun v -> (tcs,v))) |> (* lista di carta:vicini *)
|
||||
List.concat |> (* flatten *)
|
||||
List.map (fun (card, neigh) -> (play table card neigh), (n+1), (scores@[score table]) )
|
||||
|
||||
let condizioni table n scores set =
|
||||
if List.mem (hash table) set || doesnt_improve scores ||
|
||||
is_best_outcome table || n > 14 then
|
||||
true
|
||||
else false
|
||||
|
||||
let rec prova original_table set best max_score (dbg: table -> unit) (accum: (table*int*int list) list)
|
||||
(sols: (table*int*int list) list) =
|
||||
match accum with
|
||||
| [] -> sols
|
||||
| (table, n, scores)::tl -> dbg table ;
|
||||
if condizioni table n scores set then
|
||||
prova original_table ((hash table)::set) best max_score dbg tl ([table, n, scores]@sols)
|
||||
else
|
||||
prova original_table ((hash table)::set) best max_score dbg ((alg table n scores)@tl) sols
|
||||
|
|
13
tcards.ml
13
tcards.ml
|
@ -33,7 +33,7 @@ let make cards =
|
|||
let contains needle haystack = List.mem needle haystack.cards
|
||||
|
||||
let (=) a b =
|
||||
if List.length a.cards != List.length b.cards || a.tag != b.tag || a.strategy != b.strategy then
|
||||
if List.length a.cards <> List.length b.cards || a.tag != b.tag || a.strategy != b.strategy then
|
||||
false
|
||||
else
|
||||
a.cards = b.cards
|
||||
|
@ -58,3 +58,14 @@ let hash ts =
|
|||
ts.cards |>
|
||||
List.sort (fun a b -> if a.seed == b.seed then Cards.value_cmp a b else Cards.seed_cmp a b) |>
|
||||
Hashtbl.hash;;
|
||||
|
||||
let remove card tcards =
|
||||
assert (List.mem card tcards.cards);
|
||||
match (List.filter (fun x -> x <> card) tcards.cards) with
|
||||
| [] -> None
|
||||
| (hd::tl) as lst -> Some (make lst) ;;
|
||||
|
||||
let r = remove (Cards.make Hearts 7) (make [Cards.make Hearts 7; Cards.make Clovers 7; Cards.make Pikes 7;]) in
|
||||
match r with
|
||||
| None -> assert false
|
||||
| Some x -> if x <> (make [Cards.make Clovers 7; Cards.make Pikes 7]) then assert false
|
||||
|
|
Loading…
Reference in a new issue