def makeMove(self, state): # if there is just 1 action (PASS), avoid the comptutation actions = self.getAllActions(state) res_actions = [] if len(actions) == 1: return actions[0] # do the sampling x times, then pick most common action x = 10 for i in xrange(x): time_start = time.time() cardsLeft = cards.diff(cards.allCards(), [state.playedCards, self.hand]) otherRemaining = list(state.numRemaining) del otherRemaining[self.idx] hands = cards.dealHands(cardsLeft, otherRemaining) hands.insert(self.idx, dict(self.hand)) root = mctsNode(state.playedCards, self.idx, hands, self.idx, None, 0, state.topCard, state.lastPlayed, state.finished) loop_count = 0 while time.time() < time_start + budget: loop_count += 1 nextNode = self.selection(root) result = self.simulation(nextNode) self.backpropagation(nextNode, result) sorted_children = sorted( root.children, key=lambda child: child.score / child.visits) res_actions.append(sorted_children[-1].lastMove) numActions = Counter(res_actions).most_common() return numActions[0][0]
def makeMove(self, state): # if there is just 1 action (PASS), avoid the comptutation actions = self.getAllActions(state) res_actions = [] if len(actions) == 1: return actions[0] # do the sampling x times, then pick most common action x = 10 for i in xrange(x): time_start = time.time() cardsLeft = cards.diff(cards.allCards(), [state.playedCards, self.hand]) otherRemaining = list(state.numRemaining) del otherRemaining[self.idx] hands = cards.dealHands(cardsLeft , otherRemaining) hands.insert(self.idx, dict(self.hand)) root = mctsNode(state.playedCards, self.idx, hands, self.idx, None, 0, state.topCard, state.lastPlayed, state.finished) loop_count = 0 while time.time() < time_start + budget: loop_count += 1 nextNode = self.selection(root) result = self.simulation(nextNode) self.backpropagation(nextNode, result) sorted_children = sorted(root.children, key = lambda child: child.score/child.visits) res_actions.append(sorted_children[-1].lastMove) numActions = Counter(res_actions).most_common() return numActions[0][0]
def newGame(self, ordering): deck = cards.allCards() hands = cards.dealHands(deck, 52/self.numPlayers) for i in xrange(self.numPlayers): self.agents[i].hand = hands[i] # swap cards if ordering: for i in xrange(2): high = ordering.index(i) low = ordering.index(self.numPlayers - i - 1) cards.swapCards(hands[high], hands[low], 2 - i) threes = collections.Counter() for p, hand in enumerate(hands): threes[p] += hand[0] whosTurn = np.random.choice(cards.cardDictToList(threes)) playedCards = [cards.noCards() for i in xrange(self.numPlayers)] self.initialState = state.State(playedCards, whosTurn, None, None, [])
def __init__(self, agents, hands=None, playedCards=None, whosTurn=None, topCard=None, lastPlayed=None, finished=[]): """Initializes the game with the agents listed as the players. :agents: Either a list of agent objects or a list of agent constructors. If constructors, the dealing and ID assignment will be done here; if objects, we simply assign the list to self.agents. :hands: list of hand dicts; if supplied, will be used as the hands for the agents. :playedCards: list of played card dicts; if supplied, will be used for the playedCards for the initialState. :whosTurn: index of agent whose turn it is; if supplied, the game will start with this player. topCard, lastPlayed, and finished are all parameters passed on to the initial state; for more information, see state.State's __init__. """ self.numPlayers = len(agents) if hands is None: deck = cards.allCards() hands = cards.dealHands(deck, 52/self.numPlayers) # if agents is a list of agent objects, set that to self.agents if all(isinstance(a, agent.Agent) for a in agents): self.agents = agents # otherwise, construct the agents from the list of agent constructors else: self.agents = [agentConstructor(i, hand) for i, (agentConstructor,hand) in enumerate(zip(agents, hands))] if whosTurn is None: # randomly choose a player with a 3 to start # (proportional to how many 3's they have) threes = collections.Counter() for p, hand in enumerate(hands): threes[p] += hand[0] whosTurn = np.random.choice(cards.cardDictToList(threes)) if playedCards is None: playedCards = [cards.noCards() for i in xrange(self.numPlayers)] self.initialState = state.State(playedCards, whosTurn, topCard, lastPlayed, finished)
def simulate(args): """Function to simulate the other players' cards randomly and play out the paranoid game tree based on those hands. Returns the best action. """ global nodesExpanded nodesExpanded = 0 trial, state, index, hand = args # subtract played cards and your own hand from cards remaining cardsLeft = cards.diff(cards.allCards(), [state.playedCards, hand]) # get number of remaining cards for everyone else and deal hands withoutMe = list(state.numRemaining) del withoutMe[index] hands = cards.dealHands(cardsLeft, withoutMe) # put my hand back in hands.insert(index, hand) agents = map(lambda (i,h): ParanoidAgent(i, h), zip(xrange(state.numPlayers), hands)) res = paranoid(state, 1, agents, -(sys.maxint -1), sys.maxint) return res[0], nodesExpanded
def simulate(args): """Function to simulate the other players' cards randomly and play out the paranoid game tree based on those hands. Returns the best action. """ global nodesExpanded nodesExpanded = 0 trial, state, index, hand = args # subtract played cards and your own hand from cards remaining cardsLeft = cards.diff(cards.allCards(), [state.playedCards, hand]) # get number of remaining cards for everyone else and deal hands withoutMe = list(state.numRemaining) del withoutMe[index] hands = cards.dealHands(cardsLeft, withoutMe) # put my hand back in hands.insert(index, hand) agents = map(lambda (i, h): ParanoidAgent(i, h), zip(xrange(state.numPlayers), hands)) res = paranoid(state, 1, agents, -(sys.maxint - 1), sys.maxint) return res[0], nodesExpanded
def simulate(args): """Function to simulate the other players' cards randomly and play out the max^n tree based on those hands. Returns the best action. :trialNum: Trial number (for debugging and unique identification). :node: The current State object. :idx: The index of the current player. :hand: The current player's hand, which is known. :returns: The action tuple corresponding to the best action to take. """ trialNum, node, idx, hand = args # subtract played cards and your own hand from cards remaining cardsLeft = cards.diff(cards.allCards(), [node.playedCards, hand]) # get number of remaining cards for everyone else and deal hands withoutMe = list(node.numRemaining) del withoutMe[idx] hands = cards.dealHands(cardsLeft, withoutMe) # put my hand back in hands.insert(idx, hand) agents = map(lambda (i,h): MaxNAgent(i, h), zip(xrange(node.numPlayers), hands)) bestAct, bestVal = maxN(node, agents, 0, 2*node.numPlayers) return bestAct
import cards, dummyAgent, maxN, paranoid, mcts, state from collections import Counter cs = cards.allCards() hand = Counter({0: 1, 5: 1, 7: 1, 10: 1, 12: 1}) playedCards = [ {c: 1 for c in xrange(13)} for i in xrange(3) ] + [cards.noCards() for i in xrange(0)] node = state.State( whosTurn=0, playedCards=playedCards, topCard = (1, 4), ) dummy = dummyAgent.DummyAgent(0, hand) maxn = maxN.MaxNAgent(0, hand) para = paranoid.ParanoidAgent(0, hand) mct = mcts.mctsAgent(0, hand) readablehand = Counter({cards.cardRepr[k]: v for k, v in hand.iteritems()}) print 'Given hand:', readablehand dumMove = list(dummy.makeMove(node)) dumMove[1] = cards.cardRepr[dumMove[1]] movestr = lambda m: 'Play {} {}'.format(m[0], m[1]) print 'Initial move chosen by dummy:', movestr(dumMove) maxMove = list(maxn.makeMove(node)) maxMove[1] = cards.cardRepr[maxMove[1]] print 'Initial move chosen by max^n:', movestr(maxMove) paraMove = list(para.makeMove(node))