mostly working
This commit is contained in:
parent
ba3758e93f
commit
71c277853d
10 changed files with 223 additions and 67 deletions
|
@ -20,4 +20,4 @@
|
|||
|
||||
|
||||
|
||||
LOADING...
|
||||
WAIT...
|
||||
|
|
|
@ -20,4 +20,4 @@
|
|||
Φ╚╫╫╫╫` ▀╬╫N╨▌
|
||||
▒╩╫╫╫▌ ▀╫╫╧*
|
||||
|
||||
LOADING...
|
||||
WAIT...
|
||||
|
|
|
@ -20,4 +20,4 @@
|
|||
"╩Ñ╬▌ ╙ÑÑ╨`
|
||||
|
||||
|
||||
LOADING...
|
||||
WAIT...
|
||||
|
|
|
@ -20,4 +20,4 @@
|
|||
` .╬]╫╫╫╫╛ ╙▓╫╫N╨╫⌐ `
|
||||
"╩Ñ╣▀ ╙ÑÑ"
|
||||
|
||||
LOADING...
|
||||
WAIT...
|
||||
|
|
|
@ -20,4 +20,4 @@
|
|||
'╝╨'"╜▀ßM^` ▒╨╫╫╫╫⌐ ▀╬╫Ñ╙╫⌐ └╝╧╙└` ╜┘
|
||||
"╩ÑÑ╩ ▀ÑÑ"`
|
||||
|
||||
LOADING...
|
||||
WAIT...
|
||||
|
|
BIN
ono_sendai/animation/__pycache__/octopus.cpython-36.pyc
Normal file
BIN
ono_sendai/animation/__pycache__/octopus.cpython-36.pyc
Normal file
Binary file not shown.
|
@ -11,12 +11,12 @@ from state import Table, Hand
|
|||
from metro_holografix.cardtypes import *
|
||||
import state
|
||||
|
||||
logging.basicConfig(level=logging.INFO, filename='game.log', filemode='a', format='%(levelname)s - %(message)s')
|
||||
logging.basicConfig(level=logging.DEBUG, filename='/tmp/game.log', filemode='a', format='%(levelname)s - %(message)s')
|
||||
logging.info("START")
|
||||
|
||||
action = ''
|
||||
exit = False
|
||||
ID = "you"
|
||||
ID = "YOU"
|
||||
|
||||
class FrameFactory:
|
||||
titles = ['0x10', '0x11', '0x12', '0x13', '0x14', '0x15', '0x16', '0x17',
|
||||
|
@ -101,7 +101,16 @@ class FrameFactory:
|
|||
self.hand = w
|
||||
|
||||
def getChoices(self):
|
||||
src = (None, None); dst = None
|
||||
def make_card(w):
|
||||
s = w.items[w.choice][1]
|
||||
if s == ' ':
|
||||
s = w.items[1][1]; assert w.choice == 2
|
||||
v = w.items[w.choice][-3]
|
||||
ve = 13 if v == 'K' else 12 if v == 'Q' else 11 if v == 'J' else 10 if v == '0' else int(v)
|
||||
se = 'Pikes' if s == '♠' else 'Hearts' if s == '♥' else 'Tiles' if s == '♦' else 'Clovers'
|
||||
return Card(se, ve)
|
||||
|
||||
src = (None, None); dst = None; card = None
|
||||
|
||||
if self.widgets[0].choice == 0:
|
||||
dst = 'Empty'
|
||||
|
@ -111,11 +120,15 @@ class FrameFactory:
|
|||
for i, w in enumerate(self.widgets[1:]):
|
||||
if w.choice == 0:
|
||||
assert dst != 'Empty'
|
||||
logging.debug(f'{w.items} , {i}: {w.choice}')
|
||||
dst = i
|
||||
elif w.choice > 1:
|
||||
assert src[0] != 'Hand'
|
||||
logging.debug(f'{w.items} , {i}: {w.choice}')
|
||||
src = i, w.choice-2
|
||||
return src, dst
|
||||
card = make_card(w)
|
||||
|
||||
return src, dst, card
|
||||
|
||||
def makeButtons(dialog, stats):
|
||||
buttonSend = WColoredButton(7, "SND", C_RED)
|
||||
|
@ -196,7 +209,7 @@ def spawn_and_wait(tstr, difficulty):
|
|||
output = r.read()
|
||||
return output
|
||||
|
||||
def validate_auto_play(original, nl):
|
||||
def validate_auto_play(otable, ohand, nl):
|
||||
# nl is a nested list of taggedcards, but without type
|
||||
# must reconstruct
|
||||
def make_cards(l):
|
||||
|
@ -207,17 +220,39 @@ def validate_auto_play(original, nl):
|
|||
hand = Hand([c for cards in [p.cards for p in pp if p.tag == 'NonValido'] for c in cards])
|
||||
table = Table([p for p in pp if p.tag == 'Valido'])
|
||||
assert len(table.cards) == 0 or table.is_valid()
|
||||
if original.equality(table) == True:
|
||||
assert len(otable.flatten()) + len(ohand.cards) == len(hand.cards) + len(table.flatten())
|
||||
if otable.equality(table) == True:
|
||||
return 'DRAW'
|
||||
else:
|
||||
return table, hand
|
||||
|
||||
|
||||
def dispatchMove(game, src, dst, to_move):
|
||||
if src[0] is None or src[1] is None or dst is None:
|
||||
return
|
||||
else:
|
||||
table, hand = game.last()
|
||||
t, h = None, None
|
||||
if src[0] == 'Hand' and dst == 'Empty':
|
||||
t, h = state.fromHandToEmpty(table, hand, src[1])
|
||||
elif src[0] == 'Hand' and type(dst) is int:
|
||||
t, h = state.fromHandToTable(table, hand, src[1], dst)
|
||||
elif type(src[0]) is int and dst == 'Empty':
|
||||
t, h = state.fromTableToEmpty(table, hand, src, to_move)
|
||||
elif type(src[0]) is int and type(dst) is int:
|
||||
t, h = state.fromTableToTable(table, hand, src, dst, to_move)
|
||||
else:
|
||||
assert False
|
||||
|
||||
assert t is not None and h is not None
|
||||
logging.info(f"MOVE ({game.nrounds}): {game.cur_player} = {src}:{dst}")
|
||||
return game.advance(t, h)
|
||||
|
||||
def make_auto_move(original, game, difficulty):
|
||||
table, hand = game.last()
|
||||
tstr = state.toJson(table, hand)
|
||||
output = spawn_and_wait(tstr, difficulty)
|
||||
res = validate_auto_play(original, json.loads(output))
|
||||
res = validate_auto_play(table, hand, json.loads(output))
|
||||
if type(res) is str:
|
||||
logging.info(f"BOT-DRAW ({game.nrounds}): {game.cur_player} = {game.last()}")
|
||||
game.draw()
|
||||
|
@ -230,10 +265,12 @@ def make_auto_move(original, game, difficulty):
|
|||
game.next_turn()
|
||||
|
||||
|
||||
def main(difficulty):
|
||||
def main(difficulty, dbg=False):
|
||||
global exit, action
|
||||
|
||||
game = state.State(["bot1", ID])
|
||||
dbgCnt = 0
|
||||
|
||||
game = state.State(ID, ["PVR", ID])
|
||||
# game = state.State([ID, "bot1"])
|
||||
|
||||
game.next_turn()
|
||||
|
@ -243,8 +280,11 @@ def main(difficulty):
|
|||
make_auto_move(game.last()[0], game, difficulty)
|
||||
if game.hasEnded == True:
|
||||
break
|
||||
if game.hasEnded == True:
|
||||
break
|
||||
|
||||
if dbgCnt >= 3:
|
||||
dbgCnt = 0
|
||||
from IPython import embed as fuck
|
||||
fuck()
|
||||
|
||||
with Context():
|
||||
|
||||
|
@ -256,6 +296,9 @@ def main(difficulty):
|
|||
f = FrameFactory(dialog)
|
||||
|
||||
stats = f' Round: {game.nrounds} - '
|
||||
if game.hasEnded:
|
||||
stats += f'Winner: {game.winner}'
|
||||
else:
|
||||
for idp, h in game.players.items():
|
||||
stats += f'{idp}: {len(h.cards)}, '
|
||||
stats = stats[:-2] + ' ' # remove last comma
|
||||
|
@ -271,17 +314,16 @@ def main(difficulty):
|
|||
res = dialog.loop()
|
||||
if res == 1001 or res == 9: # or res == KEY_END or res == KEY_ESC: # 1001 is exit? # 9 is ctrl-c
|
||||
exit = True
|
||||
elif game.hasEnded:
|
||||
pass
|
||||
else:
|
||||
if action == 'EXIT':
|
||||
exit = True
|
||||
elif action == 'MOVE' or res == KEY_ENTER or res == b'm':
|
||||
# TODO: transition effect
|
||||
src, dst = f.getChoices()
|
||||
if src[0] is not None and src[1] is not None and dst is not None:
|
||||
game.move_and_advance(src, dst) # get them from next
|
||||
logging.info(f"MOVE ({game.nrounds}): {game.cur_player} = {src}:{dst}")
|
||||
else:
|
||||
continue
|
||||
src, dst, ccard = f.getChoices()
|
||||
logging.debug(ccard)
|
||||
dispatchMove(game, src, dst, ccard)
|
||||
elif action == 'DRAW' or res == b'd':
|
||||
logging.info(f"DRAW ({game.nrounds}): {game.cur_player} = {game.last()}")
|
||||
game.draw()
|
||||
|
@ -303,27 +345,40 @@ def main(difficulty):
|
|||
elif action == 'BACK':
|
||||
game.backtrack()
|
||||
logging.info(f"BACK ({game.nrounds}): {game.cur_player}")
|
||||
elif res == b'p' and dbg == True:
|
||||
dbgCnt += 1
|
||||
else:
|
||||
pass
|
||||
|
||||
if game.hasEnded:
|
||||
print(f'{Fore.RED}' + "Game has ended, player '" + game.winner + "' has won"+f'{Style.RESET_ALL}')
|
||||
|
||||
else:
|
||||
s = input(f'{Fore.MAGENTA}Do you want to save the game? (y/n)\n')
|
||||
while s.lower() not in ['y', 'yes', 'n', 'no']:
|
||||
s = input(f"{Fore.MAGENTA}Please write 'y' or 'n'\n")
|
||||
print(f'{Style.RESET_ALL}')
|
||||
if s.lower() == 'y' or s.lower() == 'yes':
|
||||
game.dump()
|
||||
|
||||
if __name__ == '__main__':
|
||||
from sys import argv
|
||||
|
||||
print(argv[1])
|
||||
diff = argv[1]
|
||||
dbg = 'DEBUG' in argv
|
||||
if diff == 'easy':
|
||||
main(7)
|
||||
main(7, dbg)
|
||||
elif diff == 'medium':
|
||||
main(14)
|
||||
main(14, dbg)
|
||||
elif diff == 'hard':
|
||||
main(21)
|
||||
main(21, dbg)
|
||||
else:
|
||||
try:
|
||||
diff = int(diff)
|
||||
except:
|
||||
print('Wrong argument for difficulty')
|
||||
main(int(diff))
|
||||
main(int(diff), dbg)
|
||||
|
||||
|
||||
print('cli interface')
|
||||
print('initial screen')
|
1
ono_sendai/save.final
Normal file
1
ono_sendai/save.final
Normal file
|
@ -0,0 +1 @@
|
|||
{"table": [[["Clovers", 3], ["Hearts", 3], ["Pikes", 3], ["Tiles", 3]], [["Clovers", 8], ["Hearts", 8], ["Pikes", 8]], [["Clovers", 13], ["Hearts", 13], ["Tiles", 13]], [["Clovers", 2], ["Hearts", 2], ["Tiles", 2]], [["Clovers", 1], ["Hearts", 1], ["Tiles", 1]], [["Clovers", 4], ["Pikes", 4], ["Tiles", 4]], [["Hearts", 5], ["Hearts", 6], ["Hearts", 7], ["Hearts", 8]], [["Clovers", 10], ["Clovers", 11], ["Clovers", 9]], [["Hearts", 2], ["Hearts", 3], ["Hearts", 4]], [["Pikes", 1], ["Pikes", 12], ["Pikes", 13]], [["Hearts", 10], ["Hearts", 11], ["Hearts", 12]]], "PVR": [["Clovers", 2], ["Pikes", 5], ["Clovers", 6], ["Hearts", 7], ["Pikes", 7], ["Pikes", 7], ["Pikes", 9], ["Tiles", 9], ["Tiles", 11], ["Tiles", 11]], "YOU": [["Tiles", 6], ["Clovers", 7], ["Tiles", 9], ["Hearts", 10], ["Pikes", 10], ["Pikes", 11], ["Tiles", 12], ["Tiles", 13]], "nrounds": 25, "players": ["PVR", "YOU"]}
|
|
@ -88,7 +88,9 @@ class WrongMoveException(Exception):
|
|||
pass
|
||||
|
||||
class State:
|
||||
def __init__(self, ids):
|
||||
def __init__(self, human, ids):
|
||||
assert human in ids
|
||||
self.humanPlayer = human
|
||||
self.deck = make_deck()
|
||||
self.winner = None
|
||||
self.hasEnded = False
|
||||
|
@ -124,8 +126,8 @@ class State:
|
|||
if original.equality(table):
|
||||
raise WrongMoveException()
|
||||
elif not table.is_valid() or len(set(original.flatten()) - set(table.flatten())) != 0:
|
||||
if self.cur_player != 'you':
|
||||
fuck() # debug
|
||||
if self.cur_player != self.humanPlayer:
|
||||
fuck() # debug # TODO: should remove
|
||||
raise WrongMoveException()
|
||||
else:
|
||||
self.table, self.players[self.cur_player] = table, hand
|
||||
|
@ -147,16 +149,34 @@ class State:
|
|||
def size(self):
|
||||
return len(self.turn)
|
||||
|
||||
def move_and_advance(self, src, dst):
|
||||
table, hand = self.last()
|
||||
t, h = gioca(table, hand, src, dst)
|
||||
self.turn.append((t, h))
|
||||
return t, h
|
||||
|
||||
def advance(self, table, hand):
|
||||
self.turn.append((table, hand))
|
||||
return table, hand
|
||||
|
||||
def dump(self):
|
||||
j = dict()
|
||||
j['table'] = [tc.cards for tc in self.table.cards]
|
||||
for pl, hand in self.players.items():
|
||||
j[pl] = hand.cards
|
||||
j['nrounds'] = self.nrounds
|
||||
j['players'] = list(self.players.keys())
|
||||
with open('save.machiavelli', 'w') as f:
|
||||
f.write(json.dumps(j))
|
||||
return j
|
||||
|
||||
def load(self):
|
||||
with open('save.machiavelli', 'r') as f:
|
||||
j = json.loads(f.read())
|
||||
self.nrounds = j['nrounds']
|
||||
tcards = []
|
||||
for tc in j['table']:
|
||||
tcards.append(TaggedCards([Card(seed, value) for seed, value in tc]))
|
||||
self.table = Table(tcards)
|
||||
self.players = dict()
|
||||
for pl in j['players']:
|
||||
self.players[pl] = Hand([Card(seed, value) for seed, value in j[pl]])
|
||||
|
||||
|
||||
def fromJson(j):
|
||||
hcards = [Card(seed, value) for seed, value in j['hand']]
|
||||
tcards = []
|
||||
|
@ -172,30 +192,110 @@ def toJson(table, hand):
|
|||
j['table'].append(tc.cards)
|
||||
return json.dumps(j)
|
||||
|
||||
# TODO: refactor language
|
||||
def gioca(tavolo, hand, src, dst):
|
||||
giocata = [] if dst == 'Empty' else tavolo.cards[dst]
|
||||
da_muovere = hand.cards[src[1]] if src[0] == 'Hand' else tavolo.cards[src[0]].cards[src[1]]
|
||||
hcards = hand.cards[:src[1]] + hand.cards[src[1]+1:] if src[0] == 'Hand' else hand.cards
|
||||
assert src[0] != 'Hand' or len(hcards) == len(hand.cards) - 1
|
||||
# def gioca(tavolo, hand, src, dst):
|
||||
# giocata = [] if dst == 'Empty' else tavolo.cards[dst]
|
||||
# da_muovere = hand.cards[src[1]] if src[0] == 'Hand' else tavolo.cards[src[0]].cards[src[1]]
|
||||
# hcards = hand.cards[:src[1]] + hand.cards[src[1]+1:] if src[0] == 'Hand' else hand.cards
|
||||
# assert src[0] != 'Hand' or len(hcards) == len(hand.cards) - 1
|
||||
|
||||
assert type(dst) is int or dst == 'Empty'
|
||||
assert type(src[0]) is int or src[0] == 'Hand'
|
||||
assert type(da_muovere) is Card
|
||||
assert type(giocata) is TaggedCards or giocata == []
|
||||
# assert type(dst) is int or dst == 'Empty'
|
||||
# assert type(src[0]) is int or src[0] == 'Hand'
|
||||
# assert type(da_muovere) is Card
|
||||
# assert type(giocata) is TaggedCards or giocata == []
|
||||
|
||||
idx = -1 if dst == 'Empty' else tavolo.cards.index(giocata)
|
||||
news = [TaggedCards([da_muovere])] if type(giocata) is list else []
|
||||
rimpiazzata = False
|
||||
for i, t in enumerate(tavolo.cards):
|
||||
if i == idx:
|
||||
p = TaggedCards(giocata.cards + [da_muovere])
|
||||
news.append(p)
|
||||
elif not rimpiazzata and da_muovere in t.cards:
|
||||
t = [c for c in t.cards if c != da_muovere]
|
||||
if t != []:
|
||||
news.append(TaggedCards(t))
|
||||
rimpiazzata = True
|
||||
# idx = -1 if dst == 'Empty' else tavolo.cards.index(giocata)
|
||||
# if type(giocata) is list: # we want a new empty cell
|
||||
# news = [TaggedCards([da_muovere])]
|
||||
# else:
|
||||
# news = []
|
||||
|
||||
def fromHandToEmpty(table, hand, src):
|
||||
assert type(src) is int
|
||||
to_move = hand.cards[src]
|
||||
hcards = hand.cards[:src] + hand.cards[src+1:]
|
||||
assert len(hcards) == len(hand.cards) - 1
|
||||
|
||||
assert type(to_move) is Card
|
||||
|
||||
news = [TaggedCards([to_move])] + table.cards
|
||||
newTable = Table(news)
|
||||
assert len(newTable.flatten()) + len(hcards) == len(hand.cards) + len(table.flatten()), fuck()
|
||||
return newTable, Hand(hcards)
|
||||
|
||||
def fromHandToTable(table, hand, src, dst):
|
||||
assert type(dst) is int
|
||||
assert type(src) is int
|
||||
|
||||
in_play = table.cards[dst]
|
||||
to_move = hand.cards[src]
|
||||
hcards = hand.cards[:src] + hand.cards[src+1:]
|
||||
assert len(hcards) == len(hand.cards) - 1
|
||||
|
||||
assert type(to_move) is Card
|
||||
assert type(in_play) is TaggedCards or in_play == []
|
||||
|
||||
idx = table.cards.index(in_play)
|
||||
news = []
|
||||
news = table.cards[:dst] + table.cards[dst+1:] + [TaggedCards(table.cards[dst].cards + [to_move])]
|
||||
newTable = Table(news)
|
||||
assert len(newTable.flatten()) + len(hcards) == len(hand.cards) + len(table.flatten()), fuck()
|
||||
return newTable, Hand(hcards)
|
||||
|
||||
def removeFromTcards(t, to_move):
|
||||
# tmp = []
|
||||
# for j, c in enumerate(t.cards):
|
||||
# if c == to_move:
|
||||
# break
|
||||
# tmp.append(c)
|
||||
# tmp.extend(t.cards[j+1:])
|
||||
# return tmp
|
||||
cards = copy(t.cards)
|
||||
cards.remove(to_move)
|
||||
return cards
|
||||
|
||||
def fromTableToEmpty(table, hand, src, to_move):
|
||||
assert type(src) is tuple # TODO: unused src[1], even in other TableToTable
|
||||
in_play = []
|
||||
tpos, cpos = src
|
||||
hcards = hand.cards
|
||||
|
||||
assert type(src[0]) is int
|
||||
assert type(to_move) is Card
|
||||
|
||||
news = [TaggedCards([to_move])]
|
||||
|
||||
for i, t in enumerate(table.cards):
|
||||
if tpos == i:
|
||||
tmp = removeFromTcards(t, to_move)
|
||||
if tmp != []:
|
||||
news.append(TaggedCards(tmp))
|
||||
else:
|
||||
news.append(t)
|
||||
return Table(news), Hand(hcards)
|
||||
newTable = Table(news)
|
||||
assert len(newTable.flatten()) + len(hcards) == len(hand.cards) + len(table.flatten()), fuck()
|
||||
return newTable, Hand(hcards)
|
||||
|
||||
def fromTableToTable(table, hand, src, dst, to_move):
|
||||
assert type(src) is tuple
|
||||
in_play = table.cards[dst]
|
||||
tpos, cpos = src
|
||||
# to_move = table.cards[tpos].cards[cpos]
|
||||
hcards = hand.cards
|
||||
assert type(to_move) is Card
|
||||
assert type(in_play) is TaggedCards
|
||||
|
||||
news = []
|
||||
rimpiazzata = False
|
||||
for i, t in enumerate(table.cards):
|
||||
if i == dst:
|
||||
p = TaggedCards(in_play.cards + [to_move])
|
||||
news.append(p)
|
||||
elif tpos == i:
|
||||
tmp = removeFromTcards(t, to_move)
|
||||
if tmp != []:
|
||||
news.append(TaggedCards(tmp))
|
||||
else:
|
||||
news.append(t)
|
||||
newTable = Table(news)
|
||||
assert len(newTable.flatten()) + len(hcards) == len(hand.cards) + len(table.flatten()), fuck()
|
||||
return newTable, Hand(hcards)
|
||||
|
|
|
@ -30,7 +30,7 @@ class WColoredButton(WButton):
|
|||
return r
|
||||
|
||||
def handle_key(self, inp):
|
||||
if inp in [KEY_ENTER, b's', b'd', b'm']:
|
||||
if inp in [KEY_ENTER, b's', b'd', b'm', b'p']:
|
||||
return inp
|
||||
pass
|
||||
|
||||
|
@ -46,7 +46,7 @@ class WColoredFrame(WFrame):
|
|||
self.color = color
|
||||
|
||||
def handle_key(self, inp):
|
||||
if inp in [KEY_ENTER, b's', b'd', b'm']:
|
||||
if inp in [KEY_ENTER, b's', b'd', b'm', b'p']:
|
||||
return inp
|
||||
pass
|
||||
|
||||
|
@ -91,7 +91,7 @@ class WCardRadioButton(WRadioButton):
|
|||
self.id = id
|
||||
|
||||
def handle_key(self, inp):
|
||||
if inp in [KEY_ENTER, b's', b'd', b'm']:
|
||||
if inp in [KEY_ENTER, b's', b'd', b'm', b'p']:
|
||||
return inp
|
||||
pass
|
||||
|
||||
|
|
Loading…
Reference in a new issue