Python Forum
strange behavior of chess library in Python
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
strange behavior of chess library in Python
#2
Your negmax function doesn't make any sense. It appears to be similar to an algorithm I'm used to called minimax with alpha-beta pruning, but I don't see how it could possibly work.

Often you will see this algorithm implemented as two functions. One to pick the best move for the computer player, and the other to predict the move the opponent will take. Somtimes these are called minimize and maximize, but I am going to call the computer() and player(). Computer picks the best move for the computer to make. Player predicts the move the human player would most likely make in response to the computer.
def computer(board, depth=11, alpha=-inf, beta=inf):
    evaluated = evaluate_board(board, depth)
    if evaluated is not None:
        return -evaluated
 
    if depth == 0 or board.is_game_over():
        return 0

    best = (-inf, None)
    for move in board.legal_moves:
        board.push(move)
        eval = player(board, depth - 1, alpha, beta)
        board.pop()
        if eval > best[0]:
            best = (eval, move)
            alpha = max(alpha, eval)
            if alpha >= beta:
                break
 
    return best


def player(board, depth, alpha, beta):
    evaluated = evaluate_board(board, depth)
    if evaluated is not None:
        return evaluated
 
    if depth == 0 or board.is_game_over():
        return 0

    best = (inf, None)
    for move in board.legal_moves:
        board.push(move)
        eval = computer(board, depth - 1, alpha, beta)
        board.pop()
        if eval < best[0]:
            best = (eval, move)
            beta = min(beta, eval)
            if alpha >= beta:
                break
 
    return best
Notice the subtle differences. In computer(), a game winning result is a bad outcome, because it means the last move made by human() resulted in a draw or win for the human. In human(), a game winning result is a good outcome because it means the computer just won. Your negmax() function does this same thing using the color argument, toggling the value between positive (a good outcome) and negative (a bad outcome).

If the game is not over, computer() tries all available moves, and pics the move with the highest score/evaluation. player() does the opposite, searching for the move with the lowest score/evaluation. You try to do both the computer() and the player() function with negmax(), but your negmax code always searches for the highest score/evaluation. As written, your algorithm is always picking the best move for the computer. The computer will pick bad moves because its opponent is trying to throw the game.

You can combine the computer and opponent into one function.
def negmax(board, color=-1, depth=11, alpha=-inf, beta=inf):
    evaluated = evaluate_board(board, depth)
    if evaluated is not None:
        return color * evaluated

    if depth == 0 or board.is_game_over():
        return 0

    color = -color
    best = (color * inf, None)
    for move in board.legal_moves:
        board.push(move)
        eval = negmax(board, color, depth - 1, alpha, beta)
        board.pop()
        if color > 0:
            if eval > best[0]:
                best = (eval, move)
                alpha = max(alpha, eval)
        else:
            if eval < best[0]:
                best = (eval, move)
                beta = min(beta, eval)
        if alpha >= beta:
            break

    return best
Your version of negmax does not implement all the logic that is conditional based on color.

One more thing. Your logic, and the logic in my functions, do nothing to reward winning in fewer moves. A win in 10 moves gets the same evaluation as a win in 1 move. You can use the "depth" to give more value to a faster win by adding the depth to the eval. Like this:
        return color * (evaluated + depth)
Reply


Messages In This Thread
RE: strange behavior of chess library in Python - by deanhystad - Jan-18-2024, 06:35 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Strange behavior list of list mmhmjanssen 3 467 May-09-2024, 11:32 AM
Last Post: mmhmjanssen
  a chess endgame problem, almost solved but not quite max22 0 244 Mar-31-2024, 06:14 PM
Last Post: max22
  optimum chess endgame with D=3 pieces doesn't give an exact moves_to_mate variable max22 1 351 Mar-21-2024, 09:31 PM
Last Post: max22
  Program running on RPi 3b+ Very Strange Behavior - Out of Bound Index MadMacks 26 3,708 Mar-07-2023, 09:50 PM
Last Post: MadMacks
  Strange write()/File behavior kaega2 2 1,778 Jan-28-2022, 02:53 AM
Last Post: kaega2
  Strange problem related to "python service" Pavel_47 1 1,464 Dec-07-2021, 12:52 PM
Last Post: Pavel_47
  Python chess game to detect winner ddddd 1 2,075 Dec-13-2020, 10:24 PM
Last Post: michael1789
  Strange Python Bug Excelsiscelia 2 1,949 Sep-28-2020, 03:12 AM
Last Post: Excelsiscelia
  google-auth requirements.txt strange behavior randalpinto 3 3,872 Dec-21-2018, 02:03 AM
Last Post: Larz60+
  python nested list assignment weird behavior eyalk1 2 4,554 Jan-16-2018, 07:32 PM
Last Post: wavic

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020