示例#1
0
    def test_MakeMoveInvalid(self):
        #Arrange
        myBoard = OthelloBoard(8,"_")
        expBoard = copy.deepcopy(myBoard.GameBoard)
        expCnt = {"B":2,"W":2,"_":60}

        #Act
        myBoard.makeMove("B",[5,3])
        actBoard = myBoard.GameBoard  
        actCnt = myBoard.PieceCount

        #Assert
        self.assertEqual(expBoard, actBoard, "An invalid move made a move")
        self.assertEqual(expCnt, actCnt, "Invalid piece count")
示例#2
0
    def test_ValidHorizL(self):
        #Arrange
        myBoard = OthelloBoard(8,"_")
        expBoard = copy.deepcopy(myBoard.GameBoard)

        expBoard[4][5] = "B"
        expBoard[4][4] = "B"
        expCnt = {"B":4,"W":1,"_":59}

        #Act
        myBoard.makeMove("B",[4,5])
        actBoard = myBoard.GameBoard   
        actCnt = myBoard.PieceCount

        #Assert
        self.assertEqual(expBoard, actBoard, "Invalid board")
        self.assertEqual(expCnt, actCnt, "Invalid piece count")
示例#3
0
    def test_GameEnd(self):
        #Arrange
        myBoard = OthelloBoard(8,"_")
        myBoard.PieceCount["W"] = 32
        myBoard.PieceCount["B"] = 32
        myBoard.PieceCount["_"] = 0
        expWinner = "D"

        #Act
        actWinner = myBoard.checkWinner()

        #Assert
        self.assertEqual(expWinner, actWinner)
示例#4
0
    def test_ValidDiagUpR(self):
        #Arrange
        myBoard = OthelloBoard(8,"_")
        myBoard.GameBoard[2][5] = "W"
        myBoard.PieceCount["W"] = 3
        myBoard.PieceCount["_"] = 59
        expBoard = copy.deepcopy(myBoard.GameBoard)

        expBoard[4][3] = "W"
        expBoard[3][4] = "W"
        expBoard[5][2] = "W"
        expCnt = {"B":0,"W":6,"_":58}

        #Act
        myBoard.makeMove("W",[5,2])
        actBoard = myBoard.GameBoard   
        actCnt = myBoard.PieceCount

        #Assert
        self.assertEqual(expBoard, actBoard, "Invalid board")
        self.assertEqual(expCnt, actCnt, "Invalid piece count")
示例#5
0
    def test_Winner2(self):
        #Arrange
        myBoard = OthelloBoard(8,"_")
        myBoard.GameBoard[0] = ["B","B","B","B","B","B","W","W"]
        myBoard.GameBoard[1] = ["B","B","B","B","B","B","W","W"]
        myBoard.GameBoard[2] = ["B","W","B","B","B","B","W","W"]
        myBoard.GameBoard[3] = ["W","B","B","W","B","B","W","W"]
        myBoard.GameBoard[4] = ["W","W","W","W","B","B","W","W"]
        myBoard.GameBoard[5] = ["B","W","W","W","W","B","W","B"]
        myBoard.GameBoard[6] = ["B","B","W","W","W","W","B","_"]
        myBoard.GameBoard[7] = ["B","B","B","B","B","B","B","B"]
        myBoard.PieceCount["W"] = 25
        myBoard.PieceCount["B"] = 38
        myBoard.PieceCount["_"] = 1
        expWinner = "B"

        #Act
        myBoard.makeMove("W",[6,7])
        actWinner = myBoard.checkWinner()

        #Assert
        self.assertEqual(expWinner, actWinner)
示例#6
0
    def test_ValidFourDir(self):
        #Arrange
        myBoard = OthelloBoard(8,"_")
        myBoard.GameBoard[0] = ["_","_","_","_","_","_","_","_"]
        myBoard.GameBoard[1] = ["_","_","_","_","_","_","_","_"]
        myBoard.GameBoard[2] = ["_","_","_","_","_","W","_","_"]
        myBoard.GameBoard[3] = ["W","_","W","W","B","_","_","_"]
        myBoard.GameBoard[4] = ["_","B","B","B","W","_","_","_"]
        myBoard.GameBoard[5] = ["W","B","_","B","W","_","_","_"]
        myBoard.GameBoard[6] = ["_","B","B","B","_","_","_","_"]
        myBoard.GameBoard[7] = ["W","_","W","_","W","_","_","_"]
        myBoard.PieceCount["W"] = 10
        myBoard.PieceCount["B"] = 9
        myBoard.PieceCount["_"] = 45

        expBoard = []
        expBoard.append(["_","_","_","_","_","_","_","_"])
        expBoard.append(["_","_","_","_","_","_","_","_"])
        expBoard.append(["_","_","_","_","_","W","_","_"])
        expBoard.append(["W","_","W","W","W","_","_","_"])
        expBoard.append(["_","W","W","W","W","_","_","_"])
        expBoard.append(["W","W","W","W","W","_","_","_"])
        expBoard.append(["_","W","W","W","_","_","_","_"])
        expBoard.append(["W","_","W","_","W","_","_","_"])
        expCnt = {"B":0,"W":20,"_":44}

        #Act
        myBoard.makeMove("W",[5,2])
        actBoard = myBoard.GameBoard  
        actCnt = myBoard.PieceCount

        #Assert
        self.assertEqual(expBoard, actBoard, "Invalid board")
        self.assertEqual(expCnt, actCnt, "Invalid piece count")
示例#7
0
class Othello(Game):

    turn = "B"
    delimeter = "_"
    boardSize = 8

    # CONSTRUCTORS

    @MyLogger.log(["File"])
    def __init__(self, gameMode=None, skipPlay=False):
        """
        Create Othello game class. Optional to pass in gameMode (1 to play vs CPU, 2 to play vs Humans), dont't pass for user prompt
        """
        print("\nWelcome to Othello!")

        # Get and validate game parameters from user or init
        try:
            self.numPlayers = self.getGameMode(gameMode, '^[1-2]$')
        except InvalidParameterException as IPEx:
            # Log and Quit
            MyLogger.logException(["DB"], IPEx)
            print(IPEx)
            raise

        self._initGame()

        # For testing dont want to start user prompts so skip
        if not skipPlay:
            self._playGame()

    # DEPRECATED, use __init__ with kwargs, leaving for info purposes only
    # ClassMethod constructor that does not call __init__
    # used for testing to get around user input
    @classmethod
    @MyLogger.log(["File"])
    def init(cls, gameMode):
        """
        Alternate Othello constructor to pass in gameMode (1 to play vs CPU, 2 to play vs Humans)
        """
        objOT = cls.__new__(cls)
        objOT.numPlayers = gameMode
        # cant do kwargs.get("gameMode", self.getGameMode()) because getGameMode method still runs to get default value
        #super(Othello, objOT).__init__(Othello.turn, Othello.boardSize, Othello.delimeter)

        objOT._initGame()

        return objOT

    # PROTECTED METHODS

    # Method to init game parameters common to all constructors
    @MyLogger.log(["File"])
    def _initGame(self):
        super().__init__(Othello.turn, Othello.boardSize, Othello.delimeter)
        self.board = OthelloBoard(self.boardSize, self.delimeter)

        self._addPlayer("B", "Black")
        self._addPlayer("W", "White")

    # get next move from user or generate for cpu until game has ended
    @MyLogger.log(["File"])
    def _playGame(self):
        self.board.printBoard()

        gameEnd = 0
        while (not (gameEnd)):
            if self.numPlayers == 2 or self.turn == "B":
                coord = self._getMoveHuman()
            else:
                coord = self._getMoveCPU()

            print(
                f"{self.players[self.turn]} placed piece at {coord[0]} {coord[1]}\n"
            )

            self.board.makeMove(self.turn, coord)
            self.board.printBoard()

            gameEnd = self.board.checkWinner()

            if gameEnd == "D":
                print("It's a DRAW!\n")
            elif gameEnd:
                print(f"{self.players[gameEnd]} WINS!\n")
            else:
                self.turn = self.board.Opp(self.turn)

    # Player chooses next move
    @MyLogger.log(["File"])
    def _getMoveHuman(self):
        success = 0
        while (not (success)):
            userInput = input(
                f"Enter coordinates for {self.players[self.turn]}: ")
            coord = userInput.split()

            if len(coord) != 2:
                print("You didnt enter 2 coordinates")
            else:
                Y = coord[0]
                X = coord[1]

                if (not (X.isdigit()) or int(X) >= self.boardSize):
                    print(
                        f"First coordinate is not an integer or less than {str(self.boardSize)}"
                    )
                elif (not (Y.isdigit()) or int(Y) >= self.boardSize):
                    print(
                        f"Second coordinate is not an integer or less than {str(self.boardSize)}"
                    )
                elif (not (self.board.validateMove(self.turn, coord))):
                    print(f"Invalid move at coordinates: {str(coord)}")
                else:
                    success = 1

        return coord

    # get CPU move
    @MyLogger.log(["File"])
    def _getMoveCPU(self):
        return self.board.getBestMove(self.turn)
示例#8
0
    def _initGame(self):
        super().__init__(Othello.turn, Othello.boardSize, Othello.delimeter)
        self.board = OthelloBoard(self.boardSize, self.delimeter)

        self._addPlayer("B", "Black")
        self._addPlayer("W", "White")