#1 Mark for including all classes given by the UML class diagram (ETO) #1 Mark if all class attributes are made private/public/protected as specified by the UML class diagram #1 Mark if all class methods are made private/public/protected as specified by the UML class diagram class Board(): #1 Mark for defining a constructor for the class Board with appropriate attributes def __init__(self, width, height): self.__columns = width self.__rows = height self.__board = [[0]*self.__columns for i in range(self.__rows)] #1 Mark for implementing the display method as described (ETO) def display(self): for i in range(self.__rows): for x in self.__board[i]: print('|' + str(x), end='') print('|') #1 Mark for implementing the columnFull method as described def columnFull(self, column): if self.__board[0][column - 1] == 0: return False else: return True #1 Mark for implementing the boardFull method as described def boardFull(self): for c in range(self.__columns): if not self.columnFull(c): return False return True #1 Mark for creating relevant accessor methods to access Board's private attributes def getWidth(self): return self.__columns #1 Mark for implementing the addToken method as described def addToken(self, number, column): for i in range(self.__rows - 1): if self.__board[i + 1][column - 1] != 0: self.__board[i][column - 1] = number return self.__board[self.__rows - 1][column - 1] = number #1 Mark for implementing the boardFull method as described def checkWinner(self): winner = self.__checkVertical() if winner == 0: winner = self.__checkHorizontal() if winner == 0: winner = self.__checkRightDiagonal() if winner == 0: winner = self.__checkLeftDiagonal() return winner #1 Mark for implementing the checkVertical method as described (ETO) def __checkVertical(self): for c in range(self.__columns): for r in range(self.__rows - 3): if self.__board[r][c] != 0 and self.__board[r][c] == self.__board[r+1][c] and self.__board[r+1][c] == self.__board[r+2][c] and self.__board[r+2][c] == self.__board[r+3][c]: return self.__board[r][c] return 0 #1 Mark for implementing the checkHorizontal method as described (ETO) def __checkHorizontal(self): for r in range(self.__rows): for c in range(self.__columns - 3): if self.__board[r][c] != 0 and self.__board[r][c] == self.__board[r][c+1] and self.__board[r][c+1] == self.__board[r][c+2] and self.__board[r][c+2] == self.__board[r][c+3]: return self.__board[r][c] return 0 #1 Mark for implementing the checkRightDiagonal method as described (ETO) def __checkRightDiagonal(self): for r in range(self.__rows - 3): for c in range(self.__columns - 3): if self.__board[r][c] != 0 and self.__board[r][c] == self.__board[r+1][c+1] and self.__board[r+1][c+1] == self.__board[r+2][c+2] and self.__board[r+2][c+2] == self.__board[r+3][c+3]: return self.__board[r][c] return 0 #1 Mark for implementing the checkLeftDiagonal method as described (ETO) def __checkLeftDiagonal(self): for r in range(self.__rows - 3): for c in range(self.__columns - 3): if self.__board[r][(self.__columns - 1) - c] != 0 and self.__board[r][(self.__columns - 1) - c] == self.__board[r+1][(self.__columns - 2) - c] and self.__board[r+1][(self.__columns - 2) - c] == self.__board[r+2][(self.__columns - 3) - c] and self.__board[r+2][(self.__columns - 3) - c] == self.__board[r+3][(self.__columns - 4) - c]: return self.__board[r][(self.__columns - 1) - c] return 0 class Player(): #1 Mark for defining a constructor for the class Player with appropriate attributes def __init__(self, name, number): self.__playerName = name self.__playerNumber = number #1 Mark for creating relevant accessor methods to access Board's private attributes def getName(self): return self.__playerName def getNumber(self): return self.__playerNumber def makeMove(self, board): validMove = False #1 Mark for getting valid move from the player while not validMove: try: column = int(input("Enter the column you would like to add your token to (your token is " + str(self.__playerNumber) + "):")) if column > board.getWidth() or column < 1: print("You must enter a column number from 1-" + str(board.getWidth()) + ". Please try again.") else: if not board.columnFull(column): validMove = True else: print("Column " + str(column) + " is full. Please try again.") except: print("You must enter a column number from 1-" + str(board.getWidth()) + ". Please try again.") #1 Mark for adding the token to the column on the board board.addToken(self.__playerNumber, column) #1 Mark for implementing the checkWinner method as described def checkWinner(self, board): winner = board.checkWinner() if winner == self.__playerNumber: return self.__playerName else: return "Nobody" def main(): widthSet = False heightSet = False while not widthSet: try: width = int(input("Enter the width of your game board (4-10):")) if width >= 4 and width <= 10: widthSet = True else: print("The width must be an integer from 4-10. Please try again.") except: print("The width must be an integer from 4-10. Please try again.") while not heightSet: try: height = int(input("Enter the height of your game board (4-10):")) if height >= 4 and height <= 10: heightSet = True else: print("The height must be an integer from 4-10. Please try again.") except: print("The height must be an integer from 4-10. Please try again.") board = Board(width, height) allPlayersAdded = False players = [] while not allPlayersAdded: validName = False while not validName: name = input("Enter this player's name:") validName = True for player in players: if player.getName() == name: validName = False print("There is already a player called " + name + ". Please try again.") if name == "Nobody": validName = False print("You cannot use the name \"Nobody\". Please try again.") newPlayer = Player(name, len(players) + 1) players.append(newPlayer) print("Player " + str(newPlayer.getNumber()) + " is: " + name) if len(players) > 1 and len(players) < 4: addMore = input("Keep adding players (y/n)") if addMore.lower() != "y" and addMore.lower() != "yes": allPlayersAdded = True elif len(players) == 4: allPlayersAdded = True print() print("This game has " + str(len(players)) + " players:") for player in players: print(player.getName()) gameOver = False winner = "Nobody" while not gameOver: for player in players: print() print(player.getName() + ", it's your turn:") board.display() player.makeMove(board) winner = player.checkWinner(board) if winner != "Nobody" or board.boardFull(): gameOver = True break board.display() input(winner + " wins the game!") if __name__ == '__main__': main()