from board import Board

import random
import numpy

INF = float('inf')
RANDOM_WALKS = 10

class Chris(object):

    def __init__(self):
        None
    
    def getMove(self, currentBoard):
        assert not currentBoard.isUserTurn()
        legalActions = currentBoard.getLegalActions()
        argMax = None
        best = float('-inf')
        for action in legalActions:
            successor = currentBoard.getSuccessorState(action)
            value = self.miniMax(successor, 3, best, INF, False)
            if value > best:
                best = value
                argMax = action
        print best
        return argMax

    def getRandomWalkScore(self, node):
        curr = Board(node)
        while not curr.isTerminal():
            actions = curr.getLegalActions()
            if actions == []: return 0
            action = random.choice(actions)
            curr.makeMove(action, curr.isUserTurn())
        if curr.isUserTurn(): return 1
        return -1

    def getHeuristic(self, node):
        currentNode = node
        scoreSum = 0.0
        scoreCount = 0
        for _ in range(RANDOM_WALKS):
            score = self.getRandomWalkScore(node)
            scoreSum += score
            scoreCount += 1
        heuristic = scoreSum / scoreCount
        return heuristic

    def miniMax(self, node, depth, alpha, beta, isMax):
        if node.isTerminal():
            if node.isUserTurn(): return 1
            return -1
        if depth == 0:
            return self.getHeuristic(node)
        if isMax:
            for action in node.getLegalActions():
                child = node.getSuccessorState(action)
                value = self.miniMax(child, depth -1, alpha, beta, not isMax)
                alpha = max(alpha, value)
                if beta <= alpha: break
            return alpha
        else:
            for action in node.getLegalActions():
                child = node.getSuccessorState(action)
                value = self.miniMax(child, depth -1, alpha, beta, not isMax)
                beta = min(value, beta)
                if beta <= alpha: break
            return beta
