#!/usr/bin/env python from __future__ import print_function import capnp import state_capnp as game from mcts import GameNode # https://blog.theofekfoundation.org/artificial-intelligence/2016/06/27/what-is-the-monte-carlo-tree-search/ class State(): def initBoard(self): self.board = [[None]*6 for _ in range(6)] for card in self.state.cardlist: if (card.location.board): x = card.location.board.x y = card.location.board.y self.board[x][y] = card def __init__(self, state): self.state = state self.initBoard() pass def display(self): map = { "empty": " ", "varys": "*", "tully": "U", "tyrell": "Y", "baratheon": "B", "targaryen": "T", "lannister": "L", "greyjoy": "G", "stark": "S", } for row in self.board: for card in row: house = str(card.house) print(map[house], end='') print() print() def playMove(self, move): (xx, yy) = move picked_card = self.board[xx][yy] varys = self.findVarys() vx = varys.board.x vy = varys.board.y if (vx == xx): left = min(yy, vy) right = max(yy, vy) # We want this to be inclusive cards_attempted = [(vx, y) for y in range(left, right + 1)] elif(vy == yy): top = min(xx, vx) bottom = max(xx, vx) # We want this to be inclusive cards_attempted = [(x, vy) for x in range(top, bottom + 1)] else: raise Exception("Invalid move") picked_cards = [] # TODO: switch this to a filter on cards_attempted for (row, col) in cards_attempted: card = self.board[row][col] # If it is of the same house as declared if (card.house == picked_card.house): # Pick it up picked_cards.append(card) empty_card = game.Card.new_message() empty_card.house = game.House.empty self.board[row][col] = empty_card self.display() return self def findVarys(self): for card in self.state.cardlist: if card.house == 'varys': return card.location """ Returns true if the game has reached the final state ie there are no legal possible moves """ def gameOver(self): return (len(self.getPossibleMoves()) == 0) def getPossibleMoves(self): moves = [] for x in range(0, 5): for y in range(0, 5): if (self.isLegalMoveLocation(x, y)): moves.append((x, y)) print(len(moves)) return moves def isLegalMoveLocation(self, x, y): varys = self.findVarys() vx = varys.board.x vy = varys.board.y # Row/Column must match if (vx == x and vy == y): return False if (vx == x): # Generate all y between y and vy # See if this is the furthest for this card type # newCardType = self.board if (vy > y): l = [(x, i) for i in range(0, vy)] else: l = [(x, i) for i in range(vy+1, 6)] l.reverse() elif (vy == y): # Generate all x between x and vx if (vx > x): l = [(i, y) for i in range(0, vx)] else: l = [(i, y) for i in range(vx+1, 6)] l.reverse() pass else: return False seen = {} for (xx, yy) in l: # print(self.board[xx][yy]) house = self.board[xx][yy].house if str(house) in seen: return False # We stop testing as soon as we reach the new location if (x == xx and y == yy): return True seen[str(house)] = True if(__name__ == "__main__"): f = open('state.bin', 'rb') initial_state = game.State.read_packed(f) s = State(initial_state) s.display() root_node = GameNode(s, None) print(root_node.chooseChild())