see todo
This commit is contained in:
parent
29834696e0
commit
3beaec0cfd
|
@ -16,6 +16,14 @@ let card_type_to_string = function
|
|||
| Pikes-> "Pikes"
|
||||
| Nothing-> "Nothing"
|
||||
|
||||
let string_to_card_type = function
|
||||
| "Hearts" -> Hearts
|
||||
| "Tiles" -> Tiles
|
||||
| "Clovers" -> Clovers
|
||||
| "Pikes" -> Pikes
|
||||
| "Nothing" -> Nothing
|
||||
| _ -> assert false
|
||||
|
||||
type card = { seed: card_type ; value: int }
|
||||
|
||||
let make seed value =
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(executable
|
||||
(name main)
|
||||
(libraries core)
|
||||
(libraries core yojson)
|
||||
)
|
|
@ -1 +0,0 @@
|
|||
open Yojson;;
|
|
@ -4,4 +4,34 @@
|
|||
una volta vista la mano, rimuovi le carte inusabili nel turno;
|
||||
considerata una carta giocabile in mano, considera le carte "prossime", bruteforce;
|
||||
*)
|
||||
open Printer;;
|
||||
open Yojson.Basic.Util;;
|
||||
|
||||
let read_json () =
|
||||
let json = Yojson.Basic.from_channel stdin in let open Yojson.Basic.Util in
|
||||
let make_card l =
|
||||
let hd = List.hd l |> to_string in
|
||||
let tl = List.tl l |> List.hd |> to_int in
|
||||
Cards.make (Cards.string_to_card_type hd) tl in
|
||||
|
||||
let hand = json |> member "hand" |> to_list |>
|
||||
List.map (fun c -> [ c |> to_list |> make_card ] |> Tcards.make) in (* List of tcards `singles *)
|
||||
let table = json |> member "table" |> to_list |>
|
||||
List.map (fun l -> to_list l |> List.map (fun cl -> cl |> to_list |> make_card) |> Tcards.make)
|
||||
|> Table.make
|
||||
in
|
||||
(hand, table)
|
||||
|
||||
let to_json (table:Table.table) =
|
||||
let cards_to_json (cards:Cards.card list) =
|
||||
`List (List.map (fun (c:Cards.card) -> `List [`String (c.seed |> Cards.card_type_to_string); `Int c.value]) cards) in
|
||||
let tcards_to_json (tc:Tcards.tcards) =
|
||||
cards_to_json tc.cards in
|
||||
`List (List.map (fun tcl -> tcards_to_json tcl) table.cards);;
|
||||
|
||||
let open Yojson.Basic.Util in
|
||||
let hand, table = read_json () in
|
||||
let tn = Table.make (table.cards@hand) in
|
||||
let res, _ = Table.alg ~maxiter:14 tn void_printer in
|
||||
(* Printf.printf "%a\n" print_table res;; *)
|
||||
to_json res |> Yojson.Basic.to_channel stdout
|
||||
|
|
1
ono_sendai/demo.json
Normal file
1
ono_sendai/demo.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"hand": [["Clovers", 12], ["Hearts", 12], ["Pikes", 12], ["Tiles", 12], ["Clovers", 13], ["Hearts", 13], ["Pikes", 13], ["Tiles", 13]], "table": [[["Clovers", 2], ["Hearts", 2], ["Pikes", 2], ["Tiles", 2]], [["Clovers", 1], ["Hearts", 1], ["Pikes", 1], ["Tiles", 1]]]}
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
self.events = [ # list of tuples table-hand
|
||||
# (Table([
|
||||
# TaggedCards([
|
||||
# Card("Pikes", 2),
|
||||
# Card("Clovers", 2),
|
||||
# Card("Tiles", 2),
|
||||
# Card("Hearts", 2)]),
|
||||
# TaggedCards([
|
||||
# Card("Hearts", 1),
|
||||
# Card("Clovers", 1),
|
||||
# Card("Pikes", 1),
|
||||
# Card("Tiles", 1)]),
|
||||
# ]), Hand([
|
||||
# Card("Pikes", 12),
|
||||
# Card("Clovers", 12),
|
||||
# Card("Tiles", 12),
|
||||
# Card("Hearts", 12),
|
||||
# Card("Hearts", 13),
|
||||
# Card("Clovers", 13),
|
||||
# Card("Pikes", 13),
|
||||
# Card("Tiles", 13)
|
||||
# ]))
|
|
@ -3,15 +3,18 @@ from picotui.screen import Screen
|
|||
|
||||
from time import sleep
|
||||
import os
|
||||
import json
|
||||
|
||||
from widgets import *
|
||||
from state import Table, Hand
|
||||
from metro_holografix.cardtypes import *
|
||||
import state
|
||||
|
||||
action = ''
|
||||
exit = False
|
||||
ID = "tui"
|
||||
|
||||
game = state.State([ID, "bot1"])
|
||||
game = state.State(["bot1", ID])
|
||||
|
||||
class FrameFactory:
|
||||
titles = ['0x10', '0x11', '0x12', '0x13', '0x14', '0x15', '0x16', '0x17',
|
||||
|
@ -161,32 +164,76 @@ def wrong_play():
|
|||
print(f'{Fore.RED}'+'Wrong play. Retry...'+f'{Style.RESET_ALL}')
|
||||
sleep(2)
|
||||
|
||||
def make_auto_move():
|
||||
def spawn_and_wait(str):
|
||||
import sys
|
||||
from subprocess import PIPE, Popen
|
||||
from animation.octopus import animate
|
||||
|
||||
r, w = os.pipe()
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
# child
|
||||
os.system('sleep 1')
|
||||
os.system('echo DRAW')
|
||||
os.close(r)
|
||||
res = Popen(["../hosaka/_build/default/main.exe"], stdout=PIPE, stdin=PIPE)
|
||||
out, err = res.communicate(str.encode('utf-8'))
|
||||
res.stdin.close()
|
||||
w = os.fdopen(w, 'w')
|
||||
w.write(out.decode('utf-8'))
|
||||
sys.exit()
|
||||
else:
|
||||
os.close(w)
|
||||
p = os.waitpid(pid, os.WNOHANG)
|
||||
while p == (0, 0):
|
||||
animate(10)
|
||||
p = os.waitpid(pid, os.WNOHANG)
|
||||
r = os.fdopen(r)
|
||||
output = r.read()
|
||||
return output
|
||||
|
||||
def validate_auto_play(original, nl):
|
||||
# nl is a nested list of taggedcards, but without type
|
||||
# must reconstruct
|
||||
def make_cards(l):
|
||||
return Card(*l)
|
||||
pp = []
|
||||
for ts in nl:
|
||||
pp.append(TaggedCards([make_cards(cl) for cl in ts]))
|
||||
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:
|
||||
return 'DRAW'
|
||||
else:
|
||||
return table, hand
|
||||
|
||||
|
||||
def make_auto_move(original, game):
|
||||
table, hand = game.last()
|
||||
tstr = state.toJson(table, hand)
|
||||
output = spawn_and_wait(tstr)
|
||||
res = validate_auto_play(original, json.loads(output))
|
||||
if type(res) is str:
|
||||
game.draw()
|
||||
game.next_turn()
|
||||
elif type(res) is tuple:
|
||||
game.advance(*res)
|
||||
game.done()
|
||||
else:
|
||||
assert False, type(res)
|
||||
game.next_turn()
|
||||
|
||||
|
||||
game.next_turn()
|
||||
while not exit:
|
||||
while not exit and not game.hasEnded:
|
||||
while game.cur_player != ID:
|
||||
make_auto_move()
|
||||
make_auto_move(game.last()[0], game)
|
||||
if game.hasEnded == True:
|
||||
break
|
||||
if game.hasEnded == True:
|
||||
break
|
||||
|
||||
table, hand = game.last()
|
||||
with Context():
|
||||
|
||||
table, hand = game.last()
|
||||
Screen.attr_color(C_WHITE, C_GREEN)
|
||||
Screen.cls()
|
||||
Screen.attr_reset()
|
||||
|
@ -210,7 +257,11 @@ while not exit:
|
|||
exit = True
|
||||
elif action == 'MOVE':
|
||||
# TODO: transition effect
|
||||
game.advance(*f.getChoices()) # get them from next
|
||||
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
|
||||
else:
|
||||
continue
|
||||
elif action == 'DRAW':
|
||||
game.draw()
|
||||
game.next_turn()
|
||||
|
@ -227,3 +278,10 @@ while not exit:
|
|||
game.backtrack()
|
||||
else:
|
||||
assert False
|
||||
|
||||
if game.hasEnded:
|
||||
print(f'{Fore.RED}' + "Game has ended, player '" + game.winner + "' has won"+f'{Style.RESET_ALL}')
|
||||
|
||||
print('TODO: ordina per bene KQ12, mostra le carte in mano agli altri')
|
||||
print('LOGGER')
|
||||
print('magari perche` la mossa e` sbagliata')
|
||||
|
|
|
@ -12,7 +12,10 @@ import symbols as sym
|
|||
class Table(Tavolo):
|
||||
|
||||
def is_valid(self):
|
||||
return len(self.singles()) == 0 and len(self.getNonValide()) == 0
|
||||
return len(self.cards) == 0 or (len(self.singles()) == 0 and len(self.getNonValide()) == 0)
|
||||
|
||||
def flatten(self):
|
||||
return [c for tc in self.cards for c in tc.cards]
|
||||
|
||||
def widget_repr(self):
|
||||
for ts in self.cards:
|
||||
|
@ -24,6 +27,17 @@ class Table(Tavolo):
|
|||
seed = card[0].lower()
|
||||
yi.append(sym.sym[seed][card[1]])
|
||||
yield yi
|
||||
|
||||
def equality(self, other):
|
||||
b = set(other.flatten())
|
||||
a = set(self.flatten())
|
||||
gt = a - b
|
||||
lt = b - a
|
||||
if gt == lt and lt == set():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
class Hand:
|
||||
|
@ -57,6 +71,8 @@ class WrongMoveException(Exception):
|
|||
class State:
|
||||
def __init__(self, ids):
|
||||
self.deck = make_deck()
|
||||
self.winner = None
|
||||
self.hasEnded = False
|
||||
self.players = dict()
|
||||
self.table = Table([])
|
||||
self.round = None
|
||||
|
@ -70,6 +86,7 @@ class State:
|
|||
hand = self.players[self.cur_player]
|
||||
nhand = Hand(hand.cards + [self.deck.pop()])
|
||||
self.players[self.cur_player] = nhand
|
||||
assert len(self.players[self.cur_player].cards) == len(hand.cards) + 1
|
||||
self.round = None
|
||||
|
||||
def next_turn(self):
|
||||
|
@ -82,11 +99,15 @@ class State:
|
|||
assert self.round is not None
|
||||
original = self.table
|
||||
table, hand = self.last()
|
||||
if not table.is_valid() or len(set(original.cards) - set(table.cards)) != 0:
|
||||
if not table.is_valid() or len(set(original.flatten()) - set(table.flatten())) != 0:
|
||||
raise WrongMoveException()
|
||||
else:
|
||||
self.table, self.players[self.cur_player] = table, hand
|
||||
self.round = None
|
||||
if len(hand.cards) == 0:
|
||||
# won
|
||||
self.hasEnded = True
|
||||
self.winner = self.cur_player
|
||||
|
||||
def last(self):
|
||||
return self.round[-1]
|
||||
|
@ -100,12 +121,16 @@ class State:
|
|||
def size(self):
|
||||
return len(self.round)
|
||||
|
||||
def advance(self, src, dst):
|
||||
def move_and_advance(self, src, dst):
|
||||
table, hand = self.last()
|
||||
t, h = gioca(table, hand, src, dst)
|
||||
self.round.append((t, h))
|
||||
return t, h
|
||||
|
||||
def advance(self, table, hand):
|
||||
self.round.append((table, hand))
|
||||
return table, hand
|
||||
|
||||
def fromJson(j):
|
||||
hcards = [Card(seed, value) for seed, value in j['hand']]
|
||||
tcards = []
|
||||
|
|
Loading…
Reference in a new issue