lavoro python

This commit is contained in:
Francesco Mecca 2019-08-14 00:30:28 +02:00
parent 52a41690cf
commit 2ff02a9aef
4 changed files with 387 additions and 194 deletions

205
alg.py
View file

@ -1,22 +1,13 @@
from collections import namedtuple;
from copy import deepcopy as copy # FUK from copy import deepcopy as copy # FUK
from cardtypes import *
DO_TESTS = False DO_TESTS = True
DO_PRINT = True DO_PRINT = True
MAX = -1000 MAX = -1000
best = None best = None
DONE = False DONE = False
MEM = set() MEM = set()
def flattenByValue(lst):
return sorted([s for subl in lst for s in subl], key=lambda x: x.value)
def flatten(lst):
return flattenByValue(lst)
def flattenBySeed(lst):
return sorted([s for subl in lst for s in subl], key=lambda x: x.seed)
def print_1(tavolo, n): def print_1(tavolo, n):
if not DO_PRINT: if not DO_PRINT:
return return
@ -27,89 +18,6 @@ def print_1(tavolo, n):
print(t) print(t)
print(st) print(st)
Card = namedtuple('Card', 'seed value')
class Mano:
cards = list() # lista di cards
def __init__(self, carte):
assert type(carte) is list and type(carte[0]) is Card
self.cards = carte # lista di Carte
class TaggedCards:
cards = None
tag = ''
tipo = ''
def __init__(self, carte):
assert type(carte) is list and type(carte[0]) is Card
self.cards = list(sorted(carte, key=lambda x: str(x))) # lista di Carte
self.tag = 'NonValido' if not is_valida(self.cards) else 'Valido'
self.tipo = 'Singolo' if len(carte) == 1 else 'Tris' if is_tris(carte) else 'Scala'
def __hash__(self):
import functools
def cmp(c1, c2):
return c1.value < c2.value if c1.seed == c2.seed else c1.seed < c2.seed
lst = tuple(sorted(self.cards, key=functools.cmp_to_key(cmp)))
return hash(lst)
def __repr__(self):
return "TaggedCards<%s, %s, %s>" % (self.cards, self.tag, self.tipo)
def __iter__(self):
return self.cards.__iter__()
def __eq__(self, other):
assert type(other) is type(self)
if len(other.cards) != len(self.cards) or self.tag != other.tag or self.tipo != other.tipo:
return False
else:
return set(self.cards) == set(other.cards)
def __gt__(self, other):
if self.tipo == 'Tris' and len(self.cards) == 4:
return False
if other.tipo == 'Tris' and len(other.cards) == 4:
return True
elif self.tipo != 'Singolo' and other.tipo == 'Singolo':
return True
elif self.tipo == 'Singolo' and other.tipo != 'Singolo':
return False
elif self.tag == 'NonValido' and other.tag == 'Valido':
return True
else:
return False
class Tavolo:
cards = list() # lista di taggedcards
def __init__(self, cs):
assert type(cs) is list
self.cards = cs
def __hash__(self):
return sum([c.__hash__() for c in self.cards])
def __repr__(self):
return "Tavolo<%s>" % (self.cards,)
def getNonValide(self):
assert type(self.cards[0]) is TaggedCards
f = [c for c in self.cards if c.tag == 'NonValido']
return f
def getValide(self):
assert type(self.cards[0]) is TaggedCards
f = [c for c in self.cards if c.tag == 'Valido']
return f
def getAll(self):
return self.cards
def llen(self):
return len(flatten(self.getAll()))
def punteggio(self):
return len(self.getValide()) - len(self.getNonValide())
def gioca(tavolo, giocata, da_muovere): def gioca(tavolo, giocata, da_muovere):
assert type(da_muovere) is Card assert type(da_muovere) is Card
idx = tavolo.cards.index(giocata) idx = tavolo.cards.index(giocata)
@ -143,7 +51,6 @@ def tavolo_rispettato(start, end):
return False return False
return True return True
def alg(tavolo, tavolo_iniziale, soluzioni, n, punteggio): def alg(tavolo, tavolo_iniziale, soluzioni, n, punteggio):
# qua si presume di avere gia` tutte le carte della mano stese sul tavolo come gruppo singolo # qua si presume di avere gia` tutte le carte della mano stese sul tavolo come gruppo singolo
# di carte non valide (alla prima iterazione) # di carte non valide (alla prima iterazione)
@ -186,103 +93,15 @@ def find_vicini(carte, tavolo):
assert type(tavolo) is Tavolo and type(carte) is TaggedCards assert type(tavolo) is Tavolo and type(carte) is TaggedCards
return _find_vicini(carte, flatten(tavolo.getAll())) return _find_vicini(carte, flatten(tavolo.getAll()))
def no_double_seed(carte):
seeds = set([c.seed for c in carte])
return len(seeds) == len(carte)
def is_only_one_seed(carte):
seeds = set([c.seed for c in carte])
return len(seeds) == 1
def no_double_value(carte):
seeds = set([c.value for c in carte])
return len(seeds) == len(carte)
def is_tris(carte):
values = set([c.value for c in carte])
if len(values) == 1:
return no_double_seed(carte)
else:
return False
def split(values, accum=[]):
a = values[0]
if len(values) > 2:
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):
assert type(carte) is list and type(carte[0]) is Card
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:
values = [v for s, v in sorted(carte, key=lambda x:x.value)]
first, last = values[0], values[-1]
if last == 13 and first == 1:
head, tail = split(values)
return _is_straight(head) and _is_straight(tail)
else:
return _is_straight(values)
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)
if DO_TESTS: if DO_TESTS:
carte_test = [Card('quadri', 1), Card('picche', 1), Card('fiori', 1), Card('cuori', 1)] import test
print(is_valida(carte_test))
carte_test = [Card('picche', 13), Card('picche', 12), Card('picche', 1)]
print(is_valida(carte_test))
carte_test = [Card('quadri', 1), Card('picche', 1)]
print(is_tris(carte_test))
carte_test = [Card('picche', 13), Card('picche', 1)]
print(is_straight(carte_test))
# find_vicini test
tavolo_test = Tavolo([TaggedCards([Card('picche', 1), Card('fiori', 1), Card('cuori', 1)])])
res = find_vicini(TaggedCards([Card('quadri', 1)]), tavolo_test)
assert set(res) == {Card('fiori', 1), Card('cuori', 1), Card('picche', 1)}
# mano_test = [('quadri', 2),('quadri', 4)]
tavolo_test = Tavolo([TaggedCards([Card('picche', 1), Card('fiori', 1), Card('cuori', 1)])])
# assert set(find_vicini([('quadri', 1), ('quadri', 3)], [carte_test], mano_test)) == set([('fiori', 1), ('picche', 1), ('cuori', 1), ('quadri', 2), ('quadri', 4)])
tavolo_test = Tavolo([
TaggedCards([Card(seed='cuori', value=1), Card(seed='fiori', value=1), Card(seed='picche', value=1), Card(seed='quadri', value=1)]),
TaggedCards([Card(seed='quadri', value=12), Card(seed='cuori', value=12), Card(seed='cuori', value=12), Card(seed='cuori', value=13)])])
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), Card('cuori', 2), Card('quadri', 2)])
def riduci(mano, tavolo):
assert type(mano) is Mano and type(tavolo) is Tavolo
tagged_mano = [TaggedCards([c]) for c in mano.cards]
tavolo_e_mano = Tavolo(tavolo.cards+tagged_mano)
return [c.cards[0] for c in tagged_mano if find_vicini(c, tavolo_e_mano) != []]
if __name__ == '__main__': if __name__ == '__main__':
tavolo1 = Tavolo([ tavolo1 = Tavolo([
@ -378,7 +197,7 @@ if __name__ == '__main__':
Card("cuori", 8)]) Card("cuori", 8)])
]) ])
tavolo = tavolo5 tavolo = tavolo1
alg(tavolo, tavolo, [], 0, []) # alg(tavolo, tavolo, [], 0, [])
print('****BEST:') # print('****BEST:')
print_1(best, MAX) # print_1(best, MAX)

156
cardtypes.py Normal file
View file

@ -0,0 +1,156 @@
from collections import namedtuple;
Card = namedtuple('Card', 'seed value')
class Mano:
cards = list() # lista di cards
def __init__(self, carte):
assert type(carte) is list and type(carte[0]) is Card
self.cards = carte # lista di Carte
class TaggedCards:
cards = None
tag = ''
tipo = ''
def __init__(self, carte):
assert type(carte) is list and type(carte[0]) is Card
self.cards = list(sorted(carte, key=lambda x: str(x))) # lista di Carte
self.tag = 'NonValido' if not is_valida(self.cards) else 'Valido'
self.tipo = 'Singolo' if len(carte) == 1 else 'Tris' if is_tris(carte) else 'Scala'
def __hash__(self):
import functools
def cmp(c1, c2):
return c1.value < c2.value if c1.seed == c2.seed else c1.seed < c2.seed
lst = tuple(sorted(self.cards, key=functools.cmp_to_key(cmp)))
return hash(lst)
def __repr__(self):
return "TaggedCards<%s, %s, %s>" % (self.cards, self.tag, self.tipo)
def __iter__(self):
return self.cards.__iter__()
def __eq__(self, other):
assert type(other) is type(self)
if len(other.cards) != len(self.cards) or self.tag != other.tag or self.tipo != other.tipo:
return False
else:
return set(self.cards) == set(other.cards)
def __gt__(self, other):
if self.tipo == 'Tris' and len(self.cards) == 4:
return False
if other.tipo == 'Tris' and len(other.cards) == 4:
return True
elif self.tipo != 'Singolo' and other.tipo == 'Singolo':
return True
elif self.tipo == 'Singolo' and other.tipo != 'Singolo':
return False
elif self.tag == 'NonValido' and other.tag == 'Valido':
return True
else:
return False
class Tavolo:
cards = list() # lista di taggedcards
def __init__(self, cs):
assert type(cs) is list
self.cards = cs
def __hash__(self):
return sum([c.__hash__() for c in self.cards])
def __repr__(self):
return "Tavolo<%s>" % (self.cards,)
def getNonValide(self):
assert type(self.cards[0]) is TaggedCards
f = [c for c in self.cards if c.tag == 'NonValido']
return f
def getValide(self):
assert type(self.cards[0]) is TaggedCards
f = [c for c in self.cards if c.tag == 'Valido']
return f
def getAll(self):
return self.cards
def llen(self):
return len(flatten(self.getAll()))
def punteggio(self):
return len(self.getValide()) - len(self.getNonValide())
# old ocaml work
def flatten(lst):
return sorted([s for subl in lst for s in subl], key=lambda x: x.value)
def no_double_seed(carte):
seeds = set([c.seed for c in carte])
return len(seeds) == len(carte)
def is_only_one_seed(carte):
seeds = set([c.seed for c in carte])
return len(seeds) == 1
def no_double_value(carte):
seeds = set([c.value for c in carte])
return len(seeds) == len(carte)
def is_tris(carte):
values = set([c.value for c in carte])
if len(values) == 1:
return no_double_seed(carte)
else:
return False
def split(values, accum=[]):
a = values[0]
if len(values) > 2:
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):
assert type(carte) is list and type(carte[0]) is Card
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:
values = [v for s, v in sorted(carte, key=lambda x:x.value)]
first, last = values[0], values[-1]
if last == 13 and first == 1:
head, tail = split(values)
return _is_straight(head) and _is_straight(tail)
else:
return _is_straight(values)
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)

37
test.py Normal file
View file

@ -0,0 +1,37 @@
from cardtypes import *
from alg import *
carte_test = [Card('quadri', 1), Card('picche', 1), Card('fiori', 1), Card('cuori', 1)]
print(is_valida(carte_test))
carte_test = [Card('picche', 13), Card('picche', 12), Card('picche', 1)]
print(is_valida(carte_test))
carte_test = [Card('quadri', 1), Card('picche', 1)]
print(is_tris(carte_test))
carte_test = [Card('picche', 13), Card('picche', 1)]
print(is_straight(carte_test))
# find_vicini test
tavolo_test = Tavolo([TaggedCards([Card('picche', 1), Card('fiori', 1), Card('cuori', 1)])])
res = find_vicini(TaggedCards([Card('quadri', 1)]), tavolo_test)
assert set(res) == {Card('fiori', 1), Card('cuori', 1), Card('picche', 1)}
# mano_test = [('quadri', 2),('quadri', 4)]
tavolo_test = Tavolo([TaggedCards([Card('picche', 1), Card('fiori', 1), Card('cuori', 1)])])
# assert set(find_vicini([('quadri', 1), ('quadri', 3)], [carte_test], mano_test)) == set([('fiori', 1), ('picche', 1), ('cuori', 1), ('quadri', 2), ('quadri', 4)])
tavolo_test = Tavolo([
TaggedCards([Card(seed='cuori', value=1), Card(seed='fiori', value=1), Card(seed='picche', value=1), Card(seed='quadri', value=1)]),
TaggedCards([Card(seed='quadri', value=12), Card(seed='cuori', value=12), Card(seed='cuori', value=12), Card(seed='cuori', value=13)])])
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), Card('cuori', 2), Card('quadri', 2)])
tavolo_test = Tavolo([TaggedCards([Card('picche', 1), Card('fiori', 1), Card('cuori', 1)])])
mano_test = Mano([Card('picche', 3)])
assert riduci(mano_test, tavolo_test) == []
mano_test = Mano([Card('picche', 1)])
assert set(riduci(mano_test, tavolo_test)) == set([Card('picche', 1)])
mano_test = Mano([Card('picche', 4), Card('picche', 5), Card('picche', 3) ])
assert set(riduci(mano_test, tavolo_test)) == set([Card('picche', 5), Card('picche', 4), Card('picche', 3)])

181
vecchio.py Normal file
View file

@ -0,0 +1,181 @@
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(), [])