Package org.gnubridge.search.pruning

Source Code of org.gnubridge.search.pruning.AlphaBetaTest

package org.gnubridge.search.pruning;

import static org.gnubridge.core.Direction.*;

import org.gnubridge.core.Direction;
import org.gnubridge.core.Player;
import org.gnubridge.search.Node;

public class AlphaBetaTest extends PruningTestCase {

  /**
   *
   *      protoRoot      W
   *           \
   *          root       W
   *           / \
   *  (max:1) 0   1      S
   *             / \
   *   (max:0) 1_0  1_1  E       
   */

  public void testOneLevelAlphaPrune1() {
    givenMax(WEST);
    nodeWithPath("0").withTricksForMax(1).withNextTurn(SOUTH);
    nodeWithPath("1").withNextTurn(SOUTH);
    nodeWithPath("1", "0").withNextTurn(EAST).withTricksForMax(0);
    nodeWithPath("1", "1").withNextTurn(EAST);

    whenPruning(nodeWithPath("1", "0"));

    assertTrue(nodeWithPath("1", "0").isAlphaPruned());
    assertTrue(nodeWithPath("1").isAlphaPruned());
  }

  /**     
   *        protoRoot            W
   *           \
   *          root               W
   *             \
   *              0              N
   *             / \
   *   (max:1) 0_0   0_1 (max:0) E
   *       
   */

  public void testNoAlphaPruneSubsequentChildren() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH);
    nodeWithPath("0", "0").withNextTurn(EAST).withTricksForMax(1);
    nodeWithPath("0", "1").withNextTurn(EAST).withTricksForMax(0);
    whenPruning(nodeWithPath("0", "1"));
    assertFalse(nodeWithPath("0").isAlphaPruned());
  }

  /**
   *       protoRoot          W   not realistic to have one player move 3 times,
   *                              but we can allow any number of nodes between 
   *           \                  protoroot and root to include min moves
   *          root            W   also, if other players have no choice, the nodes may
   *           / \                be collapsed, so one player can appear to move 3 or more times
   * (max:1) 0    1           W
   *             / \
   *  (max:0)  1_0  1_1       E
   *       
   */

  public void testAlphaPruneOnlyMinNodes() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(WEST).withTricksForMax(1);
    nodeWithPath("1").withNextTurn(WEST);
    nodeWithPath("1", "0").withNextTurn(EAST).withTricksForMax(0);
    nodeWithPath("1", "1").withNextTurn(EAST);
    whenPruning(nodeWithPath("1", "0"));
    assertFalse(nodeWithPath("1").isAlphaPruned());
  }

  /**
   *       protoRoot                  W
   *           \
   *           root                   W
   *           / \
   * (max:2)  0   1                   N
   *             / \
   *          1_0   1_1     (max:1)   E
   *               /   \
   *   (max:0)  1_1_0  1_1_1 (max:1)  E 
   */

  public void testAlphaPruneUpstream() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH).withTricksForMax(2);
    nodeWithPath("1").withNextTurn(NORTH);
    nodeWithPath("1", "0").withNextTurn(EAST);
    nodeWithPath("1", "1").withNextTurn(EAST).withTricksForMax(1);
    nodeWithPath("1", "1", "0").withNextTurn(EAST).withTricksForMax(0);
    nodeWithPath("1", "1", "1").withNextTurn(EAST).withTricksForMax(1);
    whenPruning(nodeWithPath("1", "1", "1"));
    assertTrue(nodeWithPath("1").isAlphaPruned());
  }

  /**
   *       protoRoot         W
   *           \
   *           root          W
   *           / \
   * (max:1)  0   1          N
   *              |
   *             1_0         N
   *            /   \
   * (max:0) 1_0_0  1_0_1    E
   *   
   *       
   */

  public void testAlphaPruneToNearestAlphaAncestor() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH).withTricksForMax(2);
    nodeWithPath("1").withNextTurn(NORTH);
    nodeWithPath("1", "0").withNextTurn(NORTH);
    nodeWithPath("1", "0", "0").withNextTurn(EAST).withTricksForMax(0);
    nodeWithPath("1", "0", "1").withNextTurn(EAST);
    whenPruning(nodeWithPath("1", "0", "0"));
    assertTrue(nodeWithPath("1", "0").isAlphaPruned());
    assertTrue(nodeWithPath("1").isAlphaPruned());
  }

  //TODO: this test seems to belong to NodeTest
  public void testLocalAlphaGrows() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH).withTricksForMax(1);
    assertEquals(1, root.getLocalAlpha());
    nodeWithPath("1").withTricksForMax(3);
    assertEquals(3, root.getLocalAlpha());
  }

  //TODO: this test seems to belong to NodeTest
  public void testBetaGetsReduced() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH);
    nodeWithPath("0", "0").withTricksForMax(4);
    assertEquals(4, nodeWithPath("0").getLocalBeta());
    nodeWithPath("0", "1").withTricksForMax(3);
    assertEquals(3, nodeWithPath("0").getLocalBeta());
  }

  //TODO: this test seems to belong to NodeTest
  public void testUnvisitedNodeIgnoredInLocalBeta() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH);
    nodeWithPath("0", "0").withTricksForMax(Node.BETA_UNINIT);
    assertEquals(Node.BETA_UNINIT, nodeWithPath("0").getLocalBeta());
    nodeWithPath("0", "1").withTricksForMax(3);
    assertEquals(3, nodeWithPath("0").getLocalBeta());
  }

  /**                 
   *              protoRoot            W
   *                   |
   *                 root              W
   *                 /
   *                0                  N
   *              /  \
   *     (1,1)  0_0   0_1              E
   *                  /  \          
   *        (2,0)  0_1_0  0_1_1        E      
   */

  public void testOneLevelBetaPrune() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH);
    nodeWithPath("0", "0").withNextTurn(EAST).withTricksForMax(1);
    nodeWithPath("0", "1").withNextTurn(EAST);
    nodeWithPath("0", "1", "0").withNextTurn(EAST).withTricksForMax(2);
    nodeWithPath("0", "1", "1").withNextTurn(EAST);
    whenPruning(nodeWithPath("0", "1", "0"));
    assertTrue(nodeWithPath("0", "1", "0").isBetaPruned());
  }

  /**     
   *         protoRoot                 W
   *             |
   *           root                    W
   *             |
   *            0                      N
   *           / \
   * (max:0) 0_0 0_1                   E
   *             / \
   *        0_1_0  0_1_1               S
   *               /   \
   *  (max:1) 0_1_1_0  0_1_1_1 (max:2) S 
   */

  public void testBetaPruneUpstream() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH);
    nodeWithPath("0", "0").withNextTurn(EAST).withTricksForMax(0);
    nodeWithPath("0", "1").withNextTurn(EAST);
    nodeWithPath("0", "1", "0").withNextTurn(SOUTH);
    nodeWithPath("0", "1", "1").withNextTurn(SOUTH).withTricksForMax(2);
    nodeWithPath("0", "1", "1", "0").withNextTurn(SOUTH).withTricksForMax(1);
    nodeWithPath("0", "1", "1", "1").withNextTurn(SOUTH).withTricksForMax(2);
    whenPruning(nodeWithPath("0", "1", "1", "1"));
    assertTrue(nodeWithPath("0", "1").isBetaPruned());
  }

  /**
   *          protoRoot               W
   *             |
   *           root                   W
   *             |
   *            0                     N
   *           / \
   * (max:0) 0_0  0_1                 E
   *             / \
   *         0_1_0  0_1_1             E
   *               /   \
   *         0_1_1_0  0_1_1_1 (max:2) S 
   */

  public void testBetaPruneToNearestBetaAncestor() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(NORTH);
    nodeWithPath("0", "0").withNextTurn(EAST).withTricksForMax(0);
    nodeWithPath("0", "1").withNextTurn(EAST);
    nodeWithPath("0", "1", "0").withNextTurn(EAST);
    nodeWithPath("0", "1", "1").withNextTurn(EAST);
    nodeWithPath("0", "1", "1", "0").withNextTurn(SOUTH);
    nodeWithPath("0", "1", "1", "1").withNextTurn(SOUTH).withTricksForMax(2);
    whenPruning(nodeWithPath("0", "1", "1", "1"));
    assertTrue(nodeWithPath("0", "1").isBetaPruned());
  }

  /**
   *        protoRoot          W
   *          |
   *         root              W
   *           \
   *            0              W
   *           / \
   *  (max:2) 0_0 0_1          W
   *             / \
   *         0_1_0 0_1_1       N  <- prune alpha
   *               /   \
   *  (max:0) 0_1_1_0  0_1_1_1 W 
   */

  //TODO: make this test pass
  public void zzztestDeepAlphaPrune1() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(WEST);
    nodeWithPath("0", "0").withNextTurn(WEST).withTricksForMax(2);
    nodeWithPath("0", "1").withNextTurn(WEST);
    nodeWithPath("0", "1", "0").withNextTurn(NORTH);
    nodeWithPath("0", "1", "1").withNextTurn(NORTH);
    nodeWithPath("0", "1", "1", "0").withNextTurn(WEST).withTricksForMax(0);
    nodeWithPath("0", "1", "1", "1").withNextTurn(WEST);
    whenPruning(nodeWithPath("0", "1", "1", "0"));
    assertTrue(nodeWithPath("0", "1", "1").isAlphaPruned());
  }

  /**
   *        protoRoot          W
   *          |
   *         root              W
   *           \
   *            0              W
   *           / \
   *  (max:2) 0_0 0_1          N <- do not prune alpha: 0_1_0 may be 4, and 0_1_1_1 may be 4
   *             / \
   *         0_1_0 0_1_1       W 
   *               /   \
   *  (max:0) 0_1_1_0  0_1_1_1 W 
   */

  //TODO: make this test pass
  public void testDeepAlphaPruneInappropriate() {
    givenMax(WEST);
    nodeWithPath("0").withNextTurn(WEST);
    nodeWithPath("0", "0").withNextTurn(WEST).withTricksForMax(2);
    nodeWithPath("0", "1").withNextTurn(NORTH);
    nodeWithPath("0", "1", "0").withNextTurn(WEST);
    nodeWithPath("0", "1", "1").withNextTurn(WEST);
    nodeWithPath("0", "1", "1", "0").withNextTurn(WEST).withTricksForMax(0);
    nodeWithPath("0", "1", "1", "1").withNextTurn(WEST);
    whenPruning(nodeWithPath("0", "1", "1", "0"));
    assertFalse(nodeWithPath("0", "1").isAlphaPruned());
  }

  /**
   *
   *          root       W
   *           / \
   *   (1,1)  0   1      S
   *             / \
   *    (0,2) 1_0   1_1  E
   *       
   */

  public void testDoNotAlphaPruneRootsChildrenSoThatHeuristicsMayBeUsed() {
    Node root = new Node(null, Direction.WEST_DEPRECATED);
    Node node_0 = new Node(root, Direction.SOUTH_DEPRECATED);
    node_0.setTricksTaken(Player.WEST_EAST, 1);
    Node node_1 = new Node(root, Direction.SOUTH_DEPRECATED);
    Node node_1_0 = new Node(node_1, Direction.EAST_DEPRECATED);
    @SuppressWarnings("unused")
    Node node_1_1 = new Node(node_1, Direction.EAST_DEPRECATED);

    node_1_0.setTricksTaken(Player.NORTH_SOUTH, 2);
    node_1_0.setTricksTaken(Player.WEST_EAST, 0);
    AlphaBeta ab = new AlphaBeta();
    ab.prune(node_1_0);
    assertFalse(node_1.isPruned());
  }

  @Override
  protected void whenPruning(NodeWrapper node) {
    AlphaBeta ab = new AlphaBeta();
    ab.prune(node.delegate);

  }

}
TOP

Related Classes of org.gnubridge.search.pruning.AlphaBetaTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.