Adversarial search

[edit the tree] N8O5EF10BG3H6I9CJ10K1L7M2DA
Alpha-Beta-search(node, maximizing?, α, β, α-node, β-node)
If α and β are undefined:
Set α = −∞ and β = +∞.
If node has children:
For each child child of node:
Set ⟨result_value, result_node⟩ = Alpha-Beta-search(child, not maximizing?, α, β, α-node, β-node)
If maximizing?:
If result_value > α:
Set ⟨α, α-node⟩ = ⟨result_value, result_node⟩.
Else:
If result_value < β:
Set ⟨β, β-node⟩ = ⟨result_value, result_node⟩.
If α ≥ β: // if node can be pruned
Exit the for loop early.
End For.
If maximizing?:
Return ⟨α, α-node⟩.
Else:
Return ⟨β, β-node⟩.
Else:
Return node and the static value of node.
« prev next » auto ↺
Setting α = −∞, by default.
Setting β = +∞, by default.

Visiting node A. (MAX's turn.)
  • At this node, MAX's best outcome so far: α = −∞
    At this node, MIN's best outcome so far: β = +∞
    Does A have children?
    Yes. To determine which move is best for MAX, compute MIN's best response to each one and pick the one with the highest score.
    LOOP: Begin recursively applying alpha-beta to A's children: [B, C, D].
    ↶ Recursively apply alpha-beta to the first child node, B. (with arguments α=−∞, β=+∞)

    Visiting node B. (MIN's turn.)
  • At this node, MAX's best outcome so far: α = −∞
    At this node, MIN's best outcome so far: β = +∞
    Does B have children?
    Yes. To determine which move is best for MIN, compute MAX's best response to each one and pick the one with the lowest score.
    LOOP: Begin recursively applying alpha-beta to B's children: [E, F].
    ↶ Recursively apply alpha-beta to the first child node, E. (with arguments α=−∞, β=+∞)

    Visiting node E. (MAX's turn.)
  • At this node, MAX's best outcome so far: α = −∞
    At this node, MIN's best outcome so far: β = +∞
    Does E have children?
    Yes. To determine which move is best for MAX, compute MIN's best response to each one and pick the one with the highest score.
    LOOP: Begin recursively applying alpha-beta to E's children: [N, O].
    ↶ Recursively apply alpha-beta to the first child node, N. (with arguments α=−∞, β=+∞)

    Visiting node N. (MIN's turn.)
  • At this node, MAX's best outcome so far: α = −∞
    At this node, MIN's best outcome so far: β = +∞
    Does N have children?
    No; compute its score using static evaluation.
    Return this node N and its static value: 8
    ↻ Back up to parent node E (MAX's turn.)
  • [MAX] Is the returned result (= 8) larger than α (= −∞)?
    Yes. Moving to N provides a better guaranteed score for MAX than any move discovered so far.
    Update the value for MAX's best outcome, α. Set α = 8, and remember the node N that goes with it.
    Can we skip looking at the rest of E's children —is α ≥ β? (α=8, β=+∞)
    No, there might still be a better move.
    ↶ Recursively apply alpha-beta to the next child node, O. (with arguments α=8, β=+∞)

    Visiting node O. (MIN's turn.)
  • At this node, MAX's best outcome so far: α = 8
    At this node, MIN's best outcome so far: β = +∞
    Does O have children?
    No; compute its score using static evaluation.
    Return this node O and its static value: 5
    ↻ Back up to parent node E (MAX's turn.)
  • [MAX] Is the returned result (= 5) larger than α (= 8)?
    No.
    Finished iterating over E's children. Return MAX's best option: α = 8 at node N.
    ↻ Back up to parent node B (MIN's turn.)
  • [MIN] Is the returned result (= 8) smaller than β (= +∞)?
    Yes. Moving to N provides a better guaranteed score for MIN than any move discovered so far.
    Update the value for MIN's best outcome, β. Set β = 8, and remember the node N that goes with it.
    Can we skip looking at the rest of B's children —is α ≥ β? (α=−∞, β=8)
    No, there might still be a better move.
    ↶ Recursively apply alpha-beta to the next child node, F. (with arguments α=−∞, β=8)

    Visiting node F. (MAX's turn.)
  • At this node, MAX's best outcome so far: α = −∞
    At this node, MIN's best outcome so far: β = 8
    Does F have children?
    No; compute its score using static evaluation.
    Return this node F and its static value: 10
    ↻ Back up to parent node B (MIN's turn.)
  • [MIN] Is the returned result (= 10) smaller than β (= 8)?
    No.
    Finished iterating over B's children. Return MIN's best option: β = 8 at node N.
    ↻ Back up to parent node A (MAX's turn.)
  • [MAX] Is the returned result (= 8) larger than α (= −∞)?
    Yes. Moving to N provides a better guaranteed score for MAX than any move discovered so far.
    Update the value for MAX's best outcome, α. Set α = 8, and remember the node N that goes with it.
    Can we skip looking at the rest of A's children —is α ≥ β? (α=8, β=+∞)
    No, there might still be a better move.
    ↶ Recursively apply alpha-beta to the next child node, C. (with arguments α=8, β=+∞)

    Visiting node C. (MIN's turn.)
  • At this node, MAX's best outcome so far: α = 8
    At this node, MIN's best outcome so far: β = +∞
    Does C have children?
    Yes. To determine which move is best for MIN, compute MAX's best response to each one and pick the one with the lowest score.
    LOOP: Begin recursively applying alpha-beta to C's children: [G, H, I].
    ↶ Recursively apply alpha-beta to the first child node, G. (with arguments α=8, β=+∞)

    Visiting node G. (MAX's turn.)
  • At this node, MAX's best outcome so far: α = 8
    At this node, MIN's best outcome so far: β = +∞
    Does G have children?
    No; compute its score using static evaluation.
    Return this node G and its static value: 3
    ↻ Back up to parent node C (MIN's turn.)
  • [MIN] Is the returned result (= 3) smaller than β (= +∞)?
    Yes. Moving to G provides a better guaranteed score for MIN than any move discovered so far.
    Update the value for MIN's best outcome, β. Set β = 3, and remember the node G that goes with it.
    Can we skip looking at the rest of C's children —is α ≥ β? (α=8, β=3)
    Yes. MIN's opponent can guarantee a better outcome (α = 8 at node N) by taking a different earlier move.
    Stop iterating over children— exit early.
    Finished iterating over C's children. Return MIN's best option: β = 3 at node G.
    ↻ Back up to parent node A (MAX's turn.)
  • [MAX] Is the returned result (= 3) larger than α (= 8)?
    No.
    Can we skip looking at the rest of A's children —is α ≥ β? (α=8, β=+∞)
    No, there might still be a better move.
    ↶ Recursively apply alpha-beta to the next child node, D. (with arguments α=8, β=+∞)

    Visiting node D. (MIN's turn.)
  • At this node, MAX's best outcome so far: α = 8
    At this node, MIN's best outcome so far: β = +∞
    Does D have children?
    Yes. To determine which move is best for MIN, compute MAX's best response to each one and pick the one with the lowest score.
    LOOP: Begin recursively applying alpha-beta to D's children: [J, K, L, M].
    ↶ Recursively apply alpha-beta to the first child node, J. (with arguments α=8, β=+∞)

    Visiting node J. (MAX's turn.)
  • At this node, MAX's best outcome so far: α = 8
    At this node, MIN's best outcome so far: β = +∞
    Does J have children?
    No; compute its score using static evaluation.
    Return this node J and its static value: 10
    ↻ Back up to parent node D (MIN's turn.)
  • [MIN] Is the returned result (= 10) smaller than β (= +∞)?
    Yes. Moving to J provides a better guaranteed score for MIN than any move discovered so far.
    Update the value for MIN's best outcome, β. Set β = 10, and remember the node J that goes with it.
    Can we skip looking at the rest of D's children —is α ≥ β? (α=8, β=10)
    No, there might still be a better move.
    ↶ Recursively apply alpha-beta to the next child node, K. (with arguments α=8, β=10)

    Visiting node K. (MAX's turn.)
  • At this node, MAX's best outcome so far: α = 8
    At this node, MIN's best outcome so far: β = 10
    Does K have children?
    No; compute its score using static evaluation.
    Return this node K and its static value: 1
    ↻ Back up to parent node D (MIN's turn.)
  • [MIN] Is the returned result (= 1) smaller than β (= 10)?
    Yes. Moving to K provides a better guaranteed score for MIN than any move discovered so far.
    Update the value for MIN's best outcome, β. Set β = 1, and remember the node K that goes with it.
    Can we skip looking at the rest of D's children —is α ≥ β? (α=8, β=1)
    Yes. MIN's opponent can guarantee a better outcome (α = 8 at node N) by taking a different earlier move.
    Stop iterating over children— exit early.
    Finished iterating over D's children. Return MIN's best option: β = 1 at node K.
    ↻ Back up to parent node A (MAX's turn.)
  • [MAX] Is the returned result (= 1) larger than α (= 8)?
    No.
    Finished iterating over A's children. Return MAX's best option: α = 8 at node N.