def getRandomMove():
    state = gameState.getState()
    myPlayerID = gameController.getMyPlayerID(state)
    possibleMoves = gameController.allMoves(state, myPlayerID)

    pawns = list(
        filter(lambda pawn: len(possibleMoves[pawn]) > 0, possibleMoves.keys())
    )  # Get only pawns that have at least 1 possible move
    if len(pawns) == 0:
        print('!!ERROR!! No possible moves for player: ' +
              gameController.getMyPlayerID(state))
    oldField = random.choice(pawns)
    newField = random.choice(possibleMoves[oldField])

    return oldField, newField
예제 #2
0
def evaluate(state): # player 2 maximizes evaluation, player 1 minimizes evaluation
    currentPositions = state['pawns']
    players = state['players']
    centerline = int(7)

    for player in players:
        playerID = player['id']
        boundary = player['boundary']
        maxPlayer = gameController.getMyPlayerID(state)
        vertDist = 0
        horDist = 0
        for pawn in currentPositions[playerID]:
            if pawn not in player['goalFields']:
                vertDist += abs(boundary - const.VERT_POS[int(pawn)])
                horDist += abs(centerline - const.HOR_POS[int(pawn)])
        if playerID == maxPlayer:
            maxPlayerVertDist = vertDist
            maxPlayerHorDist = horDist
        else:
            minPlayerVertDist = vertDist
            minPlayerHorDist = horDist

    endGameMaxPlayer = gameOver(state, maxPlayer)
    endGameMinPlayer = gameOver(state, gameController.getOpponentID(state))
    m = evalWeight
    return m * (minPlayerVertDist - maxPlayerVertDist) + (1 - m) * (minPlayerHorDist - maxPlayerHorDist) + const.E_CONST* (endGameMaxPlayer - endGameMinPlayer)
예제 #3
0
def getBestMove(bestMaxMove):
    state = gameState.getState()
    
    print('Calculating MinMax...\n')
    startTime = time.time()
    minMax(state, maxDepth, -const.M_CONST, const.M_CONST, True)
    calculationTime = time.time() - startTime
    print('Calculated in: ' + str(round(calculationTime, 2)) + ' seconds')
    calculationTimes.append(calculationTime)
    print('Average calculation time so far: ' + str(round(np.mean(calculationTimes), 2)) + ' seconds')
    print('Max calculation time so far: ' + str(round(np.max(calculationTimes), 2)) + ' seconds')
    print('Min calculation time so far: ' + str(round(np.min(calculationTimes), 2)) + ' seconds')
    print('Total calculation time so far: ' + str(round(np.sum(calculationTimes), 2)) + ' seconds\n')

    print('No. of evaluated moves: {0}'.format(nodesEvaluated))
    allNodesEvaluated.append(nodesEvaluated)
    # averageNodesEvaluated = sumNodesEvaluated / mainLoopIterations
    print('Average no. of evaluated moves so far: {0}'.format(round(np.mean(allNodesEvaluated), 0)))
    print('Max no. of evaluated moves so far: {0}'.format(np.max(allNodesEvaluated)))
    print('Min no. of evaluated moves so far: {0}'.format(np.min(allNodesEvaluated)))
    print('Total no. of evaluated moves so far: {0}'.format(np.sum(allNodesEvaluated)))

    if len(bestMaxMove) == 0:
        print('!!ERROR!! No possible moves for player: ' + str(gameController.getMyPlayerID(state)))
    moves = helper.maxes(bestMaxMove, key=lambda x: x[2]) # find all moves that has the same maximum evaluation value
    move = random.choice(moves[1]) # moves[0] - max evaluation value, moves[1] - list of moves with the maximum evaluation value
    oldField = move[0]
    newField = move[1]

    return oldField, newField
예제 #4
0
def printAllPossibleMoves(possibleMoves):
    state = gameState.getState()
    myPlayerID = gameController.getMyPlayerID(state)
    if showMoveEvaluation:
        print('Current evaluation: {0}'.format(evaluate(state)))
    for key, value in possibleMoves.items():
        nextFields = []
        for newField in value:
            if showMoveEvaluation:
                nextFields.append(
                    evaluatePossibleMove((key, newField), myPlayerID))
            else:
                nextFields.append(newField)
        print('Pawn {0} can move to {1}'.format(key, nextFields))
    print('')
예제 #5
0
def getRandomBestMove(bestMaxMove):
    state = gameState.getState()
    
    print('Calculating MinMax...')
    startTime = time.time()
    minMax(state, maxDepth, -const.M_CONST, const.M_CONST, True)
    calculationTime = time.time() - startTime
    print('Calculated in: ' + str(round(calculationTime, 2)) + ' seconds')
    calculationTimes.append(calculationTime)
    print('Average calculation time so far:' + str(round(mean(calculationTimes), 2)))

    if len(bestMaxMove) == 0:
        print('!!ERROR!! No possible moves for player: ' + str(gameController.getMyPlayerID(state)))
    move = random.choice(bestMaxMove)
    oldField = move[0]
    newField = move[1]

    return oldField, newField
예제 #6
0
def minMax(state,depth,alpha,beta,maximizingPlayersTurn): # MinMax algorithm
    global nodesEvaluated
    maxPlayer = gameController.getMyPlayerID(state)
    minPlayer = gameController.getOpponentID(state)

    # TODO: most often the game is over, bc in the previous move the opponent won the game
    # can it be that we won the game bc of the previous move of the opponent?
    if depth == 0 or gameOver(state,maxPlayer) or gameOver(state,minPlayer):
        return evaluate(state)

    if maximizingPlayersTurn:
        playerId = maxPlayer
        bestEval = -const.M_CONST
    else:
        playerId = minPlayer
        bestEval = const.M_CONST

    possibleMoves = gameController.allMoves(state, playerId)

    # Evaluate first level
    # TODO: refactor
    if depth == maxDepth and maximizingPlayersTurn:
        sortedMoves = []
        for pawn,move in ((p,i) for p in possibleMoves for i in possibleMoves[p]):
            newState = copy.deepcopy(state)
            newState = gameController.makeMove(newState, pawn, move, playerId)
            nodesEvaluated += 1
            sortedMoves.append((evaluate(newState), pawn, move))
        sortedMoves.sort(reverse = True)
        possibleMoves = list(map(lambda x : (x[1], x[2]), sortedMoves))

        for possibleMove in possibleMoves:
            pawn = possibleMove[0]
            move = possibleMove[1]
            newState = copy.deepcopy(state)
            newState = gameController.makeMove(newState, pawn, move, playerId)
            nodesEvaluated += 1
            evaluation = minMax(newState, depth - 1, alpha, beta, not maximizingPlayersTurn)

            if maximizingPlayersTurn:
                if maxDepth == depth and evaluation >= bestEval:
                    bestMaxMove.append((pawn, move, evaluation))

            bestEval, alpha, beta = updateEvaluation(maximizingPlayersTurn, bestEval, evaluation, alpha, beta)

            if pruning and beta < alpha:
                break
    else:
        for pawn,move in ((p,i) for p in possibleMoves for i in possibleMoves[p]):
            newState = copy.deepcopy(state)
            newState = gameController.makeMove(newState, pawn, move, playerId)
            nodesEvaluated += 1
            evaluation = minMax(newState, depth - 1, alpha, beta, not maximizingPlayersTurn)

            if maximizingPlayersTurn:
                if maxDepth == depth and evaluation >= bestEval:
                    bestMaxMove.append((pawn, move, evaluation))

            bestEval, alpha, beta = updateEvaluation(maximizingPlayersTurn, bestEval, evaluation, alpha, beta)

            if pruning and beta < alpha:
                break

    return bestEval
예제 #7
0
def getPossibleMoves():
    state = gameState.getState()
    myPlayerID = gameController.getMyPlayerID(state)
    possibleMoves = gameController.allMoves(state, myPlayerID)

    return possibleMoves