Octopus_Carnival/metro_holografix/scrapes/vecchio.py
2019-08-15 10:24:53 +02:00

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(), [])