181 lines
6.5 KiB
Python
181 lines
6.5 KiB
Python
def flatten(lst):
|
|
assert type(lst) is list and (type(lst[0]) is set or type(lst[0]) is list)
|
|
return [l for subl in lst for l in subl ]
|
|
|
|
def find_vicini(gioco, composed_tavolo, mano = None):
|
|
def is_vicino(a, b):
|
|
assert type(a) is tuple and type(b) is tuple
|
|
return (a[0] == b[0] and (a[1] == b[1] - 1 or a[1] == b[1] + 1)) or (a[0] != b[0] and a[1] == b[1])
|
|
|
|
assert type(gioco) is list or type(gioco) is set
|
|
results = []
|
|
ricerca = []
|
|
tp = type(composed_tavolo[0])
|
|
tavolo = flatten(composed_tavolo) if tp is list or tp is set else composed_tavolo
|
|
ricerca.extend(tavolo)
|
|
if mano is not None:
|
|
ricerca.extend(mano)
|
|
for g in gioco:
|
|
results += [t for t in ricerca if is_vicino(t, g)]
|
|
|
|
return list(sorted(set(results), key=lambda x: x[1]))
|
|
|
|
carte_test = [('quadri', 3), ('picche', 1), ('fiori', 1), ('cuori', 1)]
|
|
assert set(find_vicini([('quadri', 1)], [carte_test])) == {('fiori', 1), ('cuori', 1), ('picche', 1)}
|
|
mano_test = [('quadri', 2),('quadri', 4)]
|
|
assert set(find_vicini([('quadri', 1), ('quadri', 3)], [carte_test], mano_test)) == set([('fiori', 1), ('picche', 1), ('cuori', 1), ('quadri', 2), ('quadri', 4)])
|
|
|
|
def gioca_vicini(carta, tavolo, mano, giocata_attuale, soluzione):
|
|
def prune(carte_giocate, lst, strategia):
|
|
if strategia == 'tris':
|
|
return [l for l in lst if l[0] not in carte_giocate]
|
|
elif strategia == 'scala':
|
|
l = list(sorted(carte_giocate, key=lambda x: x[1]))
|
|
first, last = l[0], l[1]
|
|
return [l for l in lst if l[1] < first or l[1] > last]
|
|
else:
|
|
assert False
|
|
|
|
giocabili = find_vicini([carta], tavolo)
|
|
if len(giocata_attuale) >= 1:
|
|
l = [c for c in giocata_attuale]
|
|
strategia = 'tris' if l[0][1] == l[0][1] else 'scala'
|
|
giocabili = prune(list(giocata_attuale) + [carta], giocabili, strategia)
|
|
# TODO: fai prune fra gioabili e giocata_attuale
|
|
# ovvero togli vicini che non rispettano la strategia attuale
|
|
# se scala controlli stesso seme e valore minore se carta < giocata_attuale e viceversa
|
|
# se tris controlli no semi doppiioni
|
|
if giocabili == []:
|
|
# piazzamento
|
|
print("DDDDDD: Piazzamento")
|
|
mano.remove(carta)
|
|
giocata_attuale.add(carta)
|
|
return algor(tavolo, mano, giocata_attuale, soluzione)
|
|
else:
|
|
# rimozione
|
|
print("DDDDDD: Rimozione")
|
|
new_carta = giocabili[0]
|
|
len_prima = sum([len(t) for t in tavolo])
|
|
tavolo = list(map(lambda x: x if new_carta not in x else x - set([new_carta]), tavolo)) # remove new_carta from tavolo
|
|
assert sum([len(t) for t in tavolo]) < len_prima or len_prima == 0
|
|
giocata_attuale.add(new_carta)
|
|
return algor(tavolo, mano, giocata_attuale, soluzione)
|
|
|
|
def print_1(tavolo, mano, giocata_attuale, soluzione):
|
|
print("--------") ; print("TAVOLO:", tavolo) ; print("MANO:", mano) ; print("ATTUALE:", giocata_attuale)
|
|
print("SOLUZIONE:", soluzione) ; print("--------\n")
|
|
|
|
def algor(tavolo, mano, giocata_attuale, soluzione):
|
|
print_1(tavolo, mano, giocata_attuale, soluzione)
|
|
for t in tavolo:
|
|
assert type(t) is set
|
|
for m in mano:
|
|
assert type(m) is tuple
|
|
|
|
if giocata_attuale == set():
|
|
for x in mano:
|
|
lanciabili = find_vicini([x], tavolo, mano)
|
|
for carta in lanciabili:
|
|
gioca_vicini(carta, tavolo, mano, giocata_attuale, soluzione)
|
|
else:
|
|
if is_valida(giocata_attuale):
|
|
soluzione, tavolo, mano = aggiorna(tavolo, mano, giocata_attuale, soluzione)
|
|
algor(tavolo, mano, set(), soluzione)
|
|
else:
|
|
rimuovi = non_valide(tavolo)
|
|
tavolo = [t for t in map(lambda x: x if x != rimuovi else None, tavolo) if t is not None] # tavolo - rimuovi
|
|
for r in rimuovi:
|
|
mano.update(r)
|
|
|
|
lanciabili = find_vicini(giocata_attuale, tavolo, mano)
|
|
for carta in lanciabili:
|
|
gioca_vicini(carta, tavolo, mano, giocata_attuale, soluzione)
|
|
|
|
def non_valide(tavolo):
|
|
return [c for c in tavolo if not is_valida(c)]
|
|
|
|
def aggiorna(tavolo, mano, giocata_attuale, soluzione):
|
|
soluzione.append(giocata_attuale)
|
|
tavolo.append(soluzione[-1])
|
|
print("--------> SOLUZIONE:", soluzione, tavolo, mano)
|
|
return soluzione, tavolo, mano
|
|
|
|
def no_double_seed(carte):
|
|
seeds = set([seed for seed, value in carte])
|
|
return len(seeds) == len(carte)
|
|
|
|
def is_only_one_seed(carte):
|
|
seeds = set([seed for seed, value in carte])
|
|
return len(seeds) == 1
|
|
|
|
def no_double_value(carte):
|
|
seeds = set([value for seed, value in carte])
|
|
return len(seeds) == len(carte)
|
|
|
|
def is_tris(carte):
|
|
values = set([value for seed, value in carte])
|
|
if len(values) == 1:
|
|
return no_double_seed(carte)
|
|
else:
|
|
return False
|
|
|
|
def split(values, accum=[]):
|
|
if len(values) > 2:
|
|
a = values[0]
|
|
b = values[1]
|
|
if a == b - 1:
|
|
return split(values[1:], accum + [a])
|
|
else:
|
|
return accum + [a], values[1:]
|
|
else:
|
|
return accum + [a], values[1:]
|
|
|
|
def is_straight(carte):
|
|
def _is_straight(carte):
|
|
if len(carte) == 1:
|
|
return True
|
|
elif len(carte) == 0:
|
|
assert False
|
|
else:
|
|
a = carte[0]
|
|
b = carte[1]
|
|
if a == b - 1:
|
|
return _is_straight(carte[1:])
|
|
else:
|
|
return False
|
|
|
|
if not (no_double_value(carte) and is_only_one_seed(carte)):
|
|
return False
|
|
else:
|
|
last = carte[-1][1]
|
|
carte = [v for s, v in carte]
|
|
if last == 13 and carte[0] == 1:
|
|
head, tail = split(carte)
|
|
return _is_straight(head) and _is_straight(tail)
|
|
else:
|
|
return _is_straight(carte)
|
|
|
|
def is_valida(carte):
|
|
carte = list(sorted(carte, key = lambda x : x[1]))
|
|
if len(carte) < 3:
|
|
return False
|
|
else:
|
|
a = carte[0][1]
|
|
b = carte[1][1]
|
|
if a == b:
|
|
return is_tris(carte)
|
|
else:
|
|
return is_straight(carte)
|
|
|
|
# carte_test = [('quadri', 1), ('picche', 1), ('fiori', 1), ('cuori', 1)]
|
|
# print(is_valida(carte_test))
|
|
|
|
# carte_test = [('picche', 13), ('picche', 12), ('picche', 1)]
|
|
# print(is_valida(carte_test))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
tavolo = [{("picche", 8), ("picche", 9), ("picche", 7)}, {("fiori", 9),("fiori", 8), ("fiori", 7)} ,{("cuori", 10), ("cuori", 9),("cuori", 8), ("cuori", 7)}]
|
|
mano = {("cuori", 11),("cuori", 12), ("quadri", 7)}
|
|
|
|
algor(tavolo, mano, set(), [])
|