def test_parseBoardInput_good(self): """ Verify a board description is parsed correctly """ board_description = [ " 1 2 3 4 5 6 7 8 9 0", "0 . b . b b 0", "9 b b . b b 9", "8 b . b . b 8", "7 b b b b b 7", "6 . . . B . 6", "5 . a . . . 5", "4 A . a . a 4", "3 a . a a a 3", "2 . a . . a 2", "1 a a a a a 1", " 1 2 3 4 5 6 7 8 9 0", ] actualResult = boardParser.parseBoardInput(board_description) self.assertEqual(actualResult.getState(coordinate.Coordinate(10, 6)), types.EMPTY) self.assertEqual(actualResult.getState(coordinate.Coordinate(3, 5)), types.PLAYER_A_REGULAR) self.assertEqual(actualResult.getState(coordinate.Coordinate(2, 4)), types.PLAYER_A_KING) self.assertEqual(actualResult.getState(coordinate.Coordinate(4, 10)), types.PLAYER_B_REGULAR) self.assertEqual(actualResult.getState(coordinate.Coordinate(8, 6)), types.PLAYER_B_KING)
def test_getAllMovesForPlayer_good(self): """ Check that capture moves take precedence over non-captures """ board_description = [ " 1 2 3 4 5 6 7 8 9 0", "0 . . . . . 0", "9 . . . . . 9", "8 . . . . . 8", "7 . . . . . 7", "6 . b . . . 6", "5 . . a a . 5", "4 . . . . . 4", "3 . . . . . 3", "2 . . . . . 2", "1 . . . . . 1", " 1 2 3 4 5 6 7 8 9 0", ] board = boardParser.parseBoardInput(board_description) #capturingPiece = coordinate.Coordinate(3, 5) expectedLength = 1 movesList = ai.getAllMovesForPlayer(board, True) actualMovesListLength = len(movesList) self.assertEqual(expectedLength, actualMovesListLength)
def test_getLastMoveInEachDirection(self): """ Test getting furtherst move a king can move in each direction""" # Given board = boardParser.parseBoardInput(helper.kingCapture2) king = coordinate.Coordinate(5, 5) # When actualResult = ai.getLastMoveInEachDirection(board, king) # Then expectedDeltasAndKings = [((-1, -1), coordinate.Coordinate(1, 1)), ((-1, 1), coordinate.Coordinate(3, 7)), ((1, -1), coordinate.Coordinate(9, 1)), ((1, 1), coordinate.Coordinate(10, 10))] expectedLength = len(expectedDeltasAndKings) expectedState = types.PLAYER_A_KING self.assertEqual(expectedLength, len(actualResult)) for i in range(expectedLength): expectedDelta = expectedDeltasAndKings[i][0] actualDelta = actualResult[i].deltaLastMoved actualState = actualResult[i].getState( expectedDeltasAndKings[i][1]) self.assertEqual(expectedDelta, actualDelta) self.assertEqual(expectedState, actualState)
def test_makeCapture_bad_type(self): """ Check TypeError is raised when capturingPiece is empty space """ board = boardParser.parseBoardInput( helper.simpleCaptureBoardDescription) capturingPiece = coordinate.Coordinate(6, 6) endLocation = coordinate.Coordinate(4, 8) self.assertRaises(TypeError, rules.makeCapture, board, capturingPiece, endLocation)
def test_getPossiblePromotedPiece_b_backwards(self): """ Tests retrieval of a regular piece promoting to king for pB """ board = boardParser.parseBoardInput(helper.piecePromotions) expectedPiece = types.PLAYER_B_KING pieceLocation = coordinate.Coordinate(2, 2) pieceDestination = coordinate.Coordinate(1, 1) actualPiece = rules.getPossiblePromotedPiece(board, pieceDestination, pieceLocation) self.assertEqual(expectedPiece, actualPiece)
def test_makeCapture_bad_same_coordinates(self): """ Try to capture where start and end locations are the same """ board = boardParser.parseBoardInput( helper.simpleCaptureBoardDescription) capturingPiece = coordinate.Coordinate(6, 6) board.setState(capturingPiece, types.PLAYER_A_REGULAR) endLocation = coordinate.Coordinate(6, 6) self.assertRaises(ValueError, rules.makeCapture, board, capturingPiece, endLocation)
def test_getDiagonalNonCaptureMovesForKing(self): board = boardParser.parseBoardInput(helper.oneKing) startingPiece = coordinate.Coordinate(5, 5) actualResult = ai.getDiagonalNonCaptureMovesForKing( board, startingPiece, 1, 1) expectedLength = 5 self.assertEqual(expectedLength, len(actualResult))
def test_countPlayerPieces_player_B(self): """ Count player B pieces """ board = boardParser.parseBoardInput( helper.simpleCountPiecesDescription) playerPieces = (types.PLAYER_B_REGULAR, types.PLAYER_B_KING) expectedResult = 1 actualResult = board.countPlayerPieces(playerPieces) self.assertEqual(actualResult, expectedResult)
def test_makeCapture_bad_y_capture(self): """ Try to capture too close along the y axis """ board = boardParser.parseBoardInput( helper.simpleCaptureBoardDescription) capturingPiece = coordinate.Coordinate(6, 6) board.setState(capturingPiece, types.PLAYER_A_REGULAR) endLocation = coordinate.Coordinate(6, 8) self.assertRaises(ValueError, rules.makeCapture, board, capturingPiece, endLocation)
def test_isACaptureP_edges(self): """ Check captures near the edge of the board """ board = boardParser.parseBoardInput( helper.simpleCaptureBoardDescription) capturingPiece = coordinate.Coordinate(2, 8) self.assertFalse(rules.isACaptureP(board, capturingPiece, 8, False)) self.assertTrue(rules.isACaptureP(board, capturingPiece, 2, False)) capturingPiece = coordinate.Coordinate(1, 9) self.assertFalse(rules.isACaptureP(board, capturingPiece, 8, True)) self.assertFalse(rules.isACaptureP(board, capturingPiece, 6, True))
def test_getPossiblePromotedPiece_b_backwards_no_promotion(self): """ Tests retrieval of a regular piece without promoting to king for pB """ board = boardParser.parseBoardInput(helper.piecePromotions) expectedPiece = types.PLAYER_B_REGULAR pieceLocation = coordinate.Coordinate(7, 5) pieceDestination = coordinate.Coordinate(6, 4) actualPiece = rules.getPossiblePromotedPiece(board, pieceDestination, pieceLocation) self.assertEqual(expectedPiece, actualPiece)
def test_getAllMovesForPlayer_king_cap_at_distance_multi_hop(self): """ Test case of king capturing at a distance""" # Given board = boardParser.parseBoardInput(helper.kingCapture4) # When actualResult = ai.getAllMovesForPlayer(board, False) # Then expectedLength = 1 self.assertEqual(len(actualResult), expectedLength)
def test_getAllNoncaptureMovesForKingPiece_4MoveAvailable(self): """ Tests getting noncaptures moves for a king that has 8 available """ board = boardParser.parseBoardInput(helper.multipleKings) pieceLocation = coordinate.Coordinate(3, 3) actualResult = ai.getAllNoncaptureMovesForKingPiece( board, pieceLocation) expectedResultLength = 8 self.assertEqual(expectedResultLength, len(actualResult))
def test_getPositionFromListOfMoves_issue_31(self): """ Tests fix for issue_31 where promotion rows were unselectable""" board = boardParser.parseBoardInput(helper.issue_31) userIsPlayerB = True listOfMoves = ai.getAllMovesForPlayer(board, not userIsPlayerB) actualListOfMoves = interface.getPositionFromListOfMoves( listOfMoves, "51", userIsPlayerB) expectedListLength = 1 self.assertEqual(expectedListLength, len(actualListOfMoves))
def test_countPlayerPieces_nonexistant(self): """ Count pieces that don't exist """ board = boardParser.parseBoardInput( helper.simpleCountPiecesDescription) nonexistantPieceType = 99 playerPieces = (nonexistantPieceType, ) expectedResult = 0 actualResult = board.countPlayerPieces(playerPieces) self.assertEqual(actualResult, expectedResult)
def test_filterForFewestOpposingPieces(self): """ Filter list of boards to one with fewest 'a' pieces, board2 """ board1 = boardParser.parseBoardInput([ " 1 2 3 4 5 6 7 8 9 0", "0 a . . . . 0", "9 . b . . . 9", "8 a . . . . 8", "7 . b . . . 7", "6 a . . . . 6", "5 . b . . . 5", "4 . . . . . 4", "3 . b . . . 3", "2 . . . . . 2", "1 . b . . . 1", " 1 2 3 4 5 6 7 8 9 0", ]) board2 = boardParser.parseBoardInput([ " 1 2 3 4 5 6 7 8 9 0", "0 . . b . . 0", "9 . . a . . 9", "8 . . . . . 8", "7 . . a . . 7", "6 . . . . . 6", "5 . . . . . 5", "4 . . . . . 4", "3 . . . . . 3", "2 . . . . . 2", "1 . . . . . 1", " 1 2 3 4 5 6 7 8 9 0", ]) list_of_boards = [ board1, board2, ] expectedLength = 1 resultList = ai.filterForFewestOpposingPieces(list_of_boards, True) resultingPiece = coordinate.Coordinate(5, 7) self.assertEqual(expectedLength, len(resultList)) self.assertEqual(types.PLAYER_A_REGULAR, resultList[0].getState(resultingPiece))
def test_getNoncaptureMovesForPiece_KingA(self): """ Tests gettting all noncapture moves for a pA king """ board = boardParser.parseBoardInput(helper.getNoncaptureMovesForPiece) pieceLocation = coordinate.Coordinate(2, 8) playerAToPlay = True actualResult = ai.getNoncaptureMovesForPiece(board, pieceLocation, playerAToPlay) expectedResultLength = 7 self.assertEqual(expectedResultLength, len(actualResult))
def test_getAllNoncaptureMovesForKingPiece_corner(self): """ Tests getting noncaptures moves for a king that has none available """ board = boardParser.parseBoardInput(helper.kingCapture4) pieceLocation = coordinate.Coordinate(1, 1) actualResult = ai.getAllNoncaptureMovesForKingPiece( board, pieceLocation) expectedResultLength = 1 self.assertEqual(expectedResultLength, len(actualResult))
def test_getNoncaptureMovesForPiece_None(self): """ Tests gettting all noncapture moves for a piece that has none """ board = boardParser.parseBoardInput(helper.getNoncaptureMovesForPiece) pieceLocation = coordinate.Coordinate(3, 5) playerAToPlay = False actualResult = ai.getNoncaptureMovesForPiece(board, pieceLocation, playerAToPlay) expectedResultLength = 0 self.assertEqual(expectedResultLength, len(actualResult))
def test_evaluationFunction_simple3(self): """ Test evaluation function scoring """ # Given board = boardParser.parseBoardInput(helper.oneKing) # When expectedResult = 59 ai.evaluationFunction(board) actualResult = board.score # Then self.assertEqual(expectedResult, actualResult)
def test_getAllNoncaptureMovesForKingPiece_1MoveAvailable(self): """ Tests getting noncaptures moves for a king that has 3 available """ board = boardParser.parseBoardInput(helper.multipleKings) pieceLocation = coordinate.Coordinate(7, 7) actualResult = ai.getAllNoncaptureMovesForKingPiece( board, pieceLocation) expectedResultLength = 3 self.assertEqual(expectedResultLength, len(actualResult)) self.assertEqual(types.EMPTY, actualResult[0].getState(pieceLocation)) self.assertEqual(types.PLAYER_B_KING, actualResult[0].getState(coordinate.Coordinate(6, 8)))
def test_evaluationFunction_simple(self): """ Test evaluation function scoring """ # Given board = boardParser.parseBoardInput( helper.simpleCountPiecesDescription) # When expectedResult = 13 ai.evaluationFunction(board) actualResult = board.score # Then self.assertEqual(expectedResult, actualResult)
def test_makeCapture_good(self): """ Make a legal capture """ board = boardParser.parseBoardInput( helper.simpleCaptureBoardDescription) capturingPiece = coordinate.Coordinate(8, 8) endLocation = coordinate.Coordinate(6, 10) capturedLocation = coordinate.Coordinate(7, 9) rules.makeCapture(board, capturingPiece, endLocation) self.assertEqual(board.getState(capturingPiece), types.EMPTY) self.assertEqual(board.getState(capturedLocation), types.EMPTY) self.assertEqual(board.getState(endLocation), types.PLAYER_A_KING)
def test_getPieceCount_good_playerB(self): """ Count player B pieces, cached and uncached """ board = boardParser.parseBoardInput( helper.simpleCountPiecesDescription) playerAToPlay = False expectedResult = 1 # Assert uncached value and result self.assertFalse(board.numberOfPiecesForB) actualResult = board.getPieceCount(playerAToPlay) self.assertEqual(actualResult, expectedResult) # Assert cached value self.assertEqual(board.numberOfPiecesForB, expectedResult) actualResult = board.getPieceCount(playerAToPlay) self.assertEqual(actualResult, expectedResult)
def test_getCapturesForRegularPiece_good(self): """ Check valid captures are returned for a regular piece """ board_description = [ " 1 2 3 4 5 6 7 8 9 0", "0 . . . . . 0", "9 . . . . . 9", "8 . . B b . 8", "7 . . . . . 7", "6 A b b b . 6", "5 . a . . . 5", "4 a B . b . 4", "3 . . . . . 3", "2 . . . . . 2", "1 . . . . . 1", " 1 2 3 4 5 6 7 8 9 0", ] board = boardParser.parseBoardInput(board_description) capturingPiece = coordinate.Coordinate(3, 5) expectedLength = 2 movesList = ai.getCapturesForRegularPiece(board, capturingPiece, True) actualMovesListLength = len(movesList) self.assertEqual(expectedLength, actualMovesListLength) # Since we don't want to assume an order of the moves being returned, # just assert here on the common features of both legal moves self.assertEqual(types.EMPTY, movesList[0].getState(coordinate.Coordinate(4, 6))) self.assertEqual(types.EMPTY, movesList[0].getState(coordinate.Coordinate(6, 8))) self.assertEqual(types.EMPTY, movesList[0].getState(coordinate.Coordinate(8, 8))) self.assertEqual(types.EMPTY, movesList[0].getState(coordinate.Coordinate(8, 6))) self.assertEqual(types.EMPTY, movesList[1].getState(coordinate.Coordinate(4, 6))) self.assertEqual(types.EMPTY, movesList[1].getState(coordinate.Coordinate(6, 8))) self.assertEqual(types.EMPTY, movesList[1].getState(coordinate.Coordinate(8, 8))) self.assertEqual(types.EMPTY, movesList[1].getState(coordinate.Coordinate(8, 6)))
def test_isACaptureP_good(self): """ Check validity of various captures """ board_description = [ " 1 2 3 4 5 6 7 8 9 0", "0 . . . . . 0", "9 . . . . . 9", "8 . . . . . 8", "7 . . . . . 7", "6 A b . . . 6", "5 . a . . . 5", "4 a B . . . 4", "3 . . . . . 3", "2 . . . . . 2", "1 . . . . . 1", " 1 2 3 4 5 6 7 8 9 0", ] board = boardParser.parseBoardInput(board_description) capturingPiece = coordinate.Coordinate(3, 5) self.assertTrue(rules.isACaptureP(board, capturingPiece, 2, True)) self.assertTrue(rules.isACaptureP(board, capturingPiece, 4, True)) self.assertFalse(rules.isACaptureP(board, capturingPiece, 6, True)) self.assertFalse(rules.isACaptureP(board, capturingPiece, 8, True))
def test_removeBoardDuplicates(self): """ Dedupe list of 2 identical boards """ board = boardParser.parseBoardInput([ " 1 2 3 4 5 6 7 8 9 0", "0 . . . . . 0", "9 . . . . . 9", "8 . . . . . 8", "7 . . . . . 7", "6 . . . . . 6", "5 . . . . . 5", "4 . . . . . 4", "3 . . . . . 3", "2 . . . . . 2", "1 . . . . . 1", " 1 2 3 4 5 6 7 8 9 0", ]) list_of_boards = [ board, board, ] expectedLength = 1 resultList = ai.removeBoardDuplicates(list_of_boards) self.assertEqual(expectedLength, len(resultList))
""" Check game state to see if a player has won """ game.playerAMoveCount = len(ai.getAllMovesForPlayer(game, True)) game.playerBMoveCount = len(ai.getAllMovesForPlayer(game, False)) if game.playerAWins(): print("Player A wins!") return True elif game.playerBWins(): print("Player B wins!") return True return False if __name__ == '__main__': """ Main game loop. Play alternates between user and computer. """ try: game = boardParser.parseBoardInput(debug.customPosition) except NameError: game = gamenode.GameNode() game.createStartingPosition() firstTurn = True if COMP_IS_PLAYER_A: computersTurn = True else: computersTurn = False while(True): if not firstTurn: game.print_board() print("--------------------------------")