Exemple #1
0
    def testOverlapCheck(self):
        testObject = Board()
        model = ModelBattleship()
        model.placeShip(testObject, 5, [0, 0], 'v')

        actualValue = model.overlapCheck(testObject, 5, [0, 0], 'h')
        expectedValue = False
        assert (actualValue == expectedValue)
Exemple #2
0
    def testBoatLocation(self):
        testObject = Board()
        model = ModelBattleship()

        model.placeShip(testObject, 1, [0, 2], 'v')
        #view = ViewBattleship()
        #view.displayBoard(testObject)
        expectedValue = 'O'
        actualValue = testObject.board[0][2]
        assert (actualValue == expectedValue)
Exemple #3
0
    def testWin(self):
        testObject = Board()
        model = ModelBattleship()
        model.placeShip(testObject, 2, [0, 0], 'v')
        model.placeShot(testObject, [0, 0])

        expectedValue = False
        actualValue = model.checkWin(testObject)
        assert (actualValue == expectedValue)

        model.placeShot(testObject, [1, 0])
        expectedValue = True
        actualValue = model.checkWin(testObject)
        assert (actualValue == expectedValue)
Exemple #4
0
    def testFireShot(self):
        testObject = Board()
        model = ModelBattleship()
        model.placeShip(testObject, 3, [5, 2], 'v')
        model.placeShot(testObject, [5, 2])

        expectedValue = 'X'
        actualValue = testObject.board[5][2]
        assert (actualValue == expectedValue)

        model.placeShot(testObject, [9, 9])
        expectedValue = '*'
        actualValue = testObject.board[9][9]
        assert (actualValue == expectedValue)
Exemple #5
0
    def testScore(self):
        testObject = Board()
        model = ModelBattleship()
        model.placeShip(testObject, 3, [5, 2], 'v')
        model.placeShot(testObject, [5, 2])

        expectedValue = 100
        actualValue = testObject.score
        assert (actualValue == expectedValue)

        model.placeShot(testObject, [9, 9])
        expectedValue = 90
        actualValue = testObject.score
        assert (actualValue == expectedValue)
class Server:
    # Member Variables
    m_port = 5000
    m_host = socket.gethostbyname(socket.gethostname())
    client_lobby = []  # username, addr
    clients = []
    in_game = [()]
    buffer = 1024
    server_end = False
    boards_received = False
    model = ModelBattleship()
    view = ViewBattleship()
    # Open the socket
    server_i = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # JSON template
    # result = '{"username": "", "action": "result", "data": { "success_flag": "", "response": ""} }'

    def sendResult(self, addr, string):
        self.server_i.sendto(string, addr)

    def parseBoard(
        self, string
    ):  # because JSONs are strings, we must parse the board and create a new board
        temp = Board()
        string = string.replace(',', '')
        string = string.replace('[', '')
        string = string.replace(']', '')
        string = string.replace('\'', '')
        for i in range(1, len(string)):
            string = string[:i] + string[i + 1:]
        s = 0
        for i in range(0, 10):
            for j in range(0, 10):
                temp.board[i][j] = string[s]
                s += 1
        return temp

    # Member Functions
    def __init__(self):
        # Bind to the port
        try:
            self.server_i.bind((Server.m_host, Server.m_port))
            print("Server started. Listening for incoming connections...")
        except:
            pass
        # Main loop to add new clients
        while True:
            data, addr = self.server_i.recvfrom(self.buffer)
            # print(str(addr) + ": " + data.decode('utf-8'))
            data = data.decode('utf-8')
            if addr not in self.clients:
                self.clients.append(addr)
                self.client_lobby.append((data, addr))
                print(data + ' has joined the server.')
                if len(self.client_lobby) == 2:
                    p1 = Player(self.client_lobby[0][0],
                                self.client_lobby[0][1], 1)
                    p2 = Player(self.client_lobby[1][0],
                                self.client_lobby[1][1], 1)
                    self.client_lobby = []
                    self.in_game[0] = (p1, p2)
                    print(self.in_game[0][0].username + ' and ' +
                          self.in_game[0][1].username +
                          ' have started a game together.')
                    index = 0
                    d1 = 'player 1'
                    t = threading.Thread(target=Server.receiving_thread,
                                         args=(self, index, d1, True))
                    t.start()
                    d2 = 'player 2'
                    t1 = threading.Thread(target=Server.receiving_thread,
                                          args=(self, index, d2, True))
                    t1.start()
                connected = "Connected to the server. Waiting for another player..."
                Server.sendResult(self, addr, str.encode(connected))
            else:
                index = self.clients.index(addr)
                t = threading.Thread(target=Server.receiving_thread,
                                     args=(self, index, data, False))
                t.start()

    def receiving_thread(self, i, data, welc):
        addr = Server.clients[i]
        data_j = ''
        try:
            data_j = json.loads(data)
        except:
            pass
        if data == '>:(':
            os._exit(0)  # RAGE QUIT!!
        elif welc:
            if data == 'player 1':
                send_back = "You have been connected with " + self.in_game[i][
                    1].username
                Server.sendResult(self, self.in_game[i][0].address,
                                  str.encode(send_back))
            if data == 'player 2':
                send_back = "You have been connected with " + self.in_game[i][
                    0].username
                Server.sendResult(self, self.in_game[i][1].address,
                                  str.encode(send_back))
        elif data_j['action'] == 'board':
            for j in range(0, 2):
                if self.in_game[0][j].address == addr:
                    self.in_game[0][j].board = deepcopy(
                        self.parseBoard(data_j['data']['board']))
                    print("Updated board stored for " +
                          self.in_game[0][j].username)
                    self.view.displayBoard(self.in_game[0][j].board)
                    self.in_game[0][j].board_filled = True
            if self.in_game[0][0].board_filled and self.in_game[0][
                    1].board_filled:
                self.boards_received = True
            if self.boards_received:
                print('Both user boards submitted. Time to fire!')
                self.server_i.sendto(str.encode('Game begin'),
                                     self.in_game[0][0].address)
                self.server_i.sendto(str.encode('Game begin'),
                                     self.in_game[0][1].address)

        elif data_j['action'] == 'outgoing shot' and data_j['data'][
                'result'] == 'awaiting response':
            result = 'miss'
            username = data_j['username']
            location = data_j['data']['coordinate']
            location = tuple(map(int, location.split(' ')))
            print(username + ' fired on: ' + str(location))
            for i in range(0, 2):
                if self.in_game[0][i].address != addr:
                    board = deepcopy(self.in_game[0][i].board)
                    # print(board.board[1][3])
                    name = self.in_game[0][i].username
                    self.model.placeShot(board, location)
                    if board.board[location[0]][location[1]] == 'X':
                        result = 'hit'
                    elif board.board[location[0]][location[1]] == '*':
                        result = 'miss'
                    server_shot = '{"username":"******", "action":"server shot", "data":{"coordinate":"' + str(
                        location) + '", "result":"' + result + '"}}'
                    self.server_i.sendto(str.encode(server_shot),
                                         self.in_game[0][0].address)
                    self.server_i.sendto(str.encode(server_shot),
                                         self.in_game[0][1].address)
                    self.in_game[0][i].board = deepcopy(board)
                    break
        elif data_j['action'] == 'win request':
            if self.model.checkWin(self.in_game[0][0].board):
                win_c = '{"username":"******", "action":"win request", "data":{"win_c":"true"}}'
                # print(win_c)
                self.server_i.sendto(str.encode(win_c),
                                     self.in_game[0][0].address)
                self.server_i.sendto(str.encode(win_c),
                                     self.in_game[0][1].address)
            elif self.model.checkWin(self.in_game[0][1].board):
                win_c = '{"username":"******", "action":"win request", "data":{"win_c":"true"}}'
                self.server_i.sendto(str.encode(win_c),
                                     self.in_game[0][0].address)
                self.server_i.sendto(str.encode(win_c),
                                     self.in_game[0][1].address)
            else:
                win_c = '{"username":"******", "action":"win request", "data":{"win_c":"false"}}'
                # print(win_c)
                self.server_i.sendto(str.encode(win_c),
                                     self.in_game[0][0].address)
                self.server_i.sendto(str.encode(win_c),
                                     self.in_game[0][1].address)

        else:
            print(data)
            send_back = "Server received your message, but did nothing because you suck!"
            Server.sendResult(self, addr, str.encode(send_back))
Exemple #7
0
    def testMaskBoard(self):
        testObject = Board()
        model = ModelBattleship()
        model.placeShip(testObject, 5, [0, 0], 'v')
        model.placeShip(testObject, 4, [0, 1], 'v')
        model.placeShip(testObject, 3, [0, 2], 'v')
        model.placeShip(testObject, 2, [0, 3], 'v')
        model.placeShip(testObject, 1, [0, 4], 'v')
        model.placeShot(testObject, [0, 0])

        maskedBoard = model.maskBoard(testObject)
        actualValue = testObject
        expectedValue = maskedBoard
        assert (actualValue != expectedValue)
Exemple #8
0
 def testOutofBounds(self):
     testObject = Board()
     model = ModelBattleship()
Exemple #9
0
 def testCheckShot(self):
     testObject = Board()
     model = ModelBattleship()
     model.placeShip(testObject, 5, [0, 0], 'v')
     model.placeShip(testObject, 4, [0, 1], 'v')
     model.placeShip(testObject, 3, [0, 2], 'v')
     model.placeShip(testObject, 2, [0, 3], 'v')
     model.placeShip(testObject, 1, [0, 4], 'v')
     model.placeShot(testObject, [0, 0])
     actualValue = model.checkShot(testObject, [0, 0])
     expectedValue = False
     assert (actualValue == expectedValue)
Exemple #10
0
class Client:
    # client data
    shutdown = False
    host = socket.gethostbyname(socket.gethostname())
    port = 5000
    server = (host, port)
    buffer = 1024
    player_board = Board()
    player_shot = False
    enemy_board = Board()
    enemy_shot = False
    view = ViewBattleship()
    model = ModelBattleship()
    username = view.get_username()

    def __init__(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            sock.connect((self.host, self.port))
        except socket.error:
            self.view.display("Error connecting to the server.")
            os._exit(1)

        sock.sendto(str.encode(self.username), self.server)
        data, server = sock.recvfrom(self.buffer)
        data = data.decode('utf-8')
        self.view.display(data)
        # start here
        data, server = sock.recvfrom(self.buffer)
        data = data.decode('utf-8')
        self.view.display(data)
        self.view.displayBoard(self.player_board)
        self.inputShips()
        send_board = '{"username":"******", "action":"board", "data":{"board":"' + str(
            self.player_board.board) + '"}}'
        sock.sendto(str.encode(send_board), server)
        data, server = sock.recvfrom(self.buffer)
        data = data.decode('utf-8')
        if data == 'Game begin':
            while 1:
                send = '{"username":"******", "action":"win request", "data":{"win_c":""}}'
                sock.sendto(str.encode(send), server)
                win_c, server = sock.recvfrom(self.buffer)
                win_c = json.loads(win_c.decode('utf-8'))
                if win_c['data']['win_c'] == 'true' and win_c[
                        'username'] == self.username:
                    self.view.display("Congrats you won!!")
                    break
                if win_c['data']['win_c'] == 'true' and win_c[
                        'username'] != self.username:
                    self.view.display("Oh no you lost!!")
                    break
                shot = self.view.getShot()
                out_shot = '{"username":"******", "action":"outgoing shot", "data":{"coordinate":"' + str(
                    shot[0]) + ' ' + str(
                        shot[1]) + '", "result":"awaiting response"}}'
                if self.model.checkShot(self.enemy_board, shot):
                    sock.sendto(str.encode(out_shot), self.server)
                    self.getShot(sock)
                else:
                    self.view.display(
                        "Shot already placed in this location. Try again: \n")
                self.view.displayScore(self.enemy_board)

    def inputShips(
            self):  # copied from the Controller to please the Python gods.
        self.view.display(
            "Time to place your ships! Please input coordinates of the head. e.g. A6 or E2 "
        )
        for i in range(0, 5):
            while 1:
                loc = self.view.getShips(i)
                if self.model.boundaryCheck(
                        5 - i, [int(loc[0][0]), int(loc[0][1])],
                        loc[1]) and self.model.overlapCheck(
                            self.player_board, 5 - i,
                            [int(loc[0][0]), int(loc[0][1])], loc[1]):
                    self.model.placeShip(
                        self.player_board, 5 - i,
                        [int(loc[0][0]), int(loc[0][1])], loc[1])
                    self.view.displayBoard(self.player_board)
                    break
                else:
                    self.view.display("Invalid ship location. Try again. \n")

    def getShot(self,
                sock):  # copied from the Controller to please the Python gods.
        while True:
            if self.enemy_shot and self.player_shot:
                self.view.display("Your board: ")
                self.view.displayBoard(self.player_board)
                self.view.display("Enemy Board: ")
                self.view.displayBoard(self.enemy_board)
                self.enemy_shot = False
                self.player_shot = False
                break
            data, server = sock.recvfrom(self.buffer)
            data = json.loads(data.decode('utf-8'))
            if data['action'] == 'server shot' and data[
                    'username'] != self.username:
                result = (data['data']['coordinate'], data['data']['result'])
                coord = (int(result[0][1]), int(result[0][4]))

                if result[1] == 'hit':
                    self.enemy_board.board[coord[0]][coord[1]] = 'X'
                    self.enemy_board.score = self.enemy_board.score + 100
                elif result[1] == 'miss':
                    self.enemy_board.board[coord[0]][coord[1]] = '*'
                    self.enemy_board.score = self.enemy_board.score - 10
                self.player_shot = True
            if data['action'] == 'server shot' and data[
                    'username'] == self.username:
                result = (data['data']['coordinate'], data['data']['result'])
                coord = (int(result[0][1]), int(result[0][4]))
                if result[1] == 'hit':
                    self.player_board.board[coord[0]][coord[1]] = 'X'
                elif result[1] == 'miss':
                    self.player_board.board[coord[0]][coord[1]] = '*'
                self.enemy_shot = True
class ControllerBattleship:
    playerBoard = Board()
    enemyBoard = Board()
    view = ViewBattleship()
    model = ModelBattleship()

    def inputShips(self):
        print(
            "Time to place your ships! Please input coordinates of the head. e.g. A6 or E2 "
        )
        for i in range(0, 5):
            while 1:
                loc = self.view.getShips(i)
                if self.model.boundaryCheck(
                        5 - i, [int(loc[0][0]), int(loc[0][1])],
                        loc[1]) and self.model.overlapCheck(
                            self.playerBoard, 5 - i,
                            [int(loc[0][0]), int(loc[0][1])], loc[1]):
                    self.model.placeShip(
                        self.playerBoard, 5 - i,
                        [int(loc[0][0]), int(loc[0][1])], loc[1])
                    self.view.displayBoard(self.playerBoard)
                    break
                else:
                    self.view.display("Invalid ship location. Try again. \n")

    def getShot(self):
        while True:
            shot = self.view.getShot()
            if self.model.checkShot(self.enemyBoard, shot):
                self.model.placeShot(self.enemyBoard, shot)
                break
            else:
                self.view.display(
                    "Shot already placed in this location. Try again: \n")
        self.view.displayScore(self.enemyBoard)

    def makeAIBoard(self):
        for i in range(0, 5):
            while 1:
                start = [random.randint(0, 9), random.randint(0, 9)]
                orient = random.choice(['v', 'h'])
                loc = (start, orient)
                if self.model.boundaryCheck(
                        i + 1, [int(loc[0][0]), int(loc[0][1])],
                        loc[1]) and self.model.overlapCheck(
                            self.enemyBoard, i + 1,
                            [int(loc[0][0]), int(loc[0][1])], loc[1]):
                    try:
                        self.enemyBoard.board[start[0]][start[1]] = str(i + 1)
                        if orient == 'v':
                            for j in range(0, i + 1):
                                self.enemyBoard.board[start[0] +
                                                      j][start[1]] = 'O'
                            break
                        elif orient == 'h':
                            for j in range(0, i + 1):
                                self.enemyBoard.board[start[0]][start[1] +
                                                                j] = 'O'
                            break
                    except:
                        pass

                    break
        '''
        self.model.placeShip(self.enemyBoard, 5, [0, 0], 'v')
        self.model.placeShip(self.enemyBoard, 4, [0, 1], 'v')
        self.model.placeShip(self.enemyBoard, 3, [0, 2], 'v')
        self.model.placeShip(self.enemyBoard, 2, [0, 3], 'v')
        self.model.placeShip(self.enemyBoard, 1, [0, 4], 'v')
        '''


if __name__ == '__main__':
    flag = True
    while flag:
        controller = ControllerBattleship()
        controller.playerBoard = Board()
        controller.enemyBoard = Board()
        view = ViewBattleship()
        model = ModelBattleship()
        userInput = view.displayMenu()
        if userInput[0] == '1':
            controller.makeAIBoard()
            view.displayBoard(controller.playerBoard)
            controller.inputShips()
            if userInput[1] == '1':
                while 1:
                    view.display("Enemy Board: ")
                    view.displayBoard(model.maskBoard(controller.enemyBoard))
                    controller.getShot()
                    if model.checkWin(controller.enemyBoard):
                        view.display("Congrats you won!!")
                        break
                    else:
                        model.randAI(controller.playerBoard)