Esempio n. 1
0
def inform_sunken_ship(pl_id, ship_id):
    '''Informs other players when a ship has been sunken
    :param pl_id: id of the player whose ship got sunken
    :param ship_id: id of the ships that has been sunken
    '''
    for index in game.players[int(pl_id) - 1].ships_dict[str(ship_id)]:
        cv.acquire()
        queue.put(
            common.marshal(common.CTRL_SHIP_SUNKEN, index[0], index[1], pl_id))
        cv.notify_all()
        cv.release()
Esempio n. 2
0
def inform_other_clients(x, y, sufferer_id, bomber_id):
    ''' Sends info of the hit to other players with the name of bomber
    :param x: x-coordinate of the hit
    :param y: y-coordinate of the hit
    :param sufferer_id: id of the player who got hit
    :param bomber_id: id of the player who made the hit
    '''
    bomber_name = game.players[int(bomber_id) - 1].get_name()
    cv.acquire()
    queue.put(
        common.marshal(common.CTRL_NOTIFY_HIT, sufferer_id, x, y, bomber_name))
    cv.notify_all()
    cv.release()
Esempio n. 3
0
def start_game(player_id):
    ''' Creates the battleship game board and notifies all players to request
     newly created board.
    :param player_id: id of the player trying to start the game
    :return: OK if player is admin
             NOT_ADMIN if player is not admin
    '''
    for player in game.players:
        if int(player.get_id()) == int(player_id) and player.is_admin():
            global board
            board = game.create_and_populate_board(
            )  # Creates and populates the board after admin starts the game
            cv.acquire()
            queue.put(
                common.marshal(common.CTRL_START_GAME,
                               common.CTRL_ALL_PLAYERS))
            cv.notify_all()
            cv.release()
            global game_not_started
            game_not_started = False  # Stops server from sending broadcasts
            return common.CTRL_OK
    return common.CTRL_NOT_ADMIN
Esempio n. 4
0
def on_request(ch, method, props, body):
    ''' Responds to rpc calls, (receives requests from players and responds to them)
    :param ch:
    :param method:
    :param props:
    :param body: body of the rpc call that a player has made
    '''
    request = common.unmarshal(body)
    CTRL_CODE = int(request[0])

    if CTRL_CODE == common.CTRL_REQ_ID:
        response = request_new_id(request[1], request[2])
    elif CTRL_CODE == common.CTRL_CHECK_ADMIN:
        if game.players[int(request[1]) - 1].is_admin():
            response = 1
        else:
            response = 0
    elif CTRL_CODE == common.CTRL_START_GAME:
        response = start_game(request[1])
    elif CTRL_CODE == common.CTRL_REQ_BOARD:
        board_array = board.get_board(
        )  # Array needed to send board to a client
        board_shape = board_array.shape
        #time.sleep(0.2)
        board_str = board_array.tostring()
        response = common.marshal(board_str, board_shape[0], board_shape[1])
    elif CTRL_CODE == common.CTRL_HIT_SHIP:
        global entered_correct_coords, stop_loop, player_has_hit
        entered_correct_coords = False
        if int(request[2]) == common.CTRL_ERR_HIT or int(
                request[3]) == common.CTRL_ERR_HIT:
            response = common.CTRL_ERR_HIT
            stop_loop = True
        else:
            try:
                value = board.get_value(int(request[2]), int(request[3]))
                if int(value) < 100 and int(
                        value
                ) > 0:  # If that coordinate has not been hit before
                    pl_id = str(value)[0]
                    ship_id = str(value)[1]
                    if int(pl_id) != int(
                            request[1]):  # If player did not hit his own ship
                        game.players[
                            int(pl_id) -
                            1].ships_dmg[ship_id] += 1  # Records the hit
                        # If ship sunk
                        if int(game.players[int(pl_id) -
                                            1].ships_dmg[ship_id]) == int(
                                                game.ships_l[ship_id]):
                            inform_sunken_ship(pl_id, ship_id)
                response, suffer_id = board.hit_ship(int(request[2]),
                                                     int(request[3]),
                                                     int(request[1]))
                entered_correct_coords = True
                check_win()
                if int(response) == 1:  # In case someone got hit, let him know
                    inform_other_clients(request[2], request[3], suffer_id,
                                         request[1])
            except Exception as err:
                logging.info(err)
                response = common.CTRL_ERR_HIT
            player_has_hit = True

    ch.basic_publish(
        exchange='',
        routing_key=props.reply_to,
        properties=pika.BasicProperties(correlation_id=props.correlation_id),
        body=str(response))
    ch.basic_ack(delivery_tag=method.delivery_tag)
Esempio n. 5
0
            if game.get_nof_players(
            ) == 0:  # Not worth sending it, when no clients are connected
                logging.debug("Waiting a player to join")
                game.cv_create_player.wait(timeout=5)
            game.cv_create_player.release()

            if game.get_nof_players() == 0:
                continue
            else:
                time.sleep(5)

            cv.acquire()
            queue.put(
                common.marshal(
                    common.CTRL_BRDCAST_MSG,
                    "Game not started yet, {nof_clients} client(s) connected, {admin} has rights to start the game."
                    .format(nof_clients=game.get_nof_players(),
                            admin=game.get_admin())))
            cv.notify_all()
            cv.release()
    except KeyboardInterrupt:
        bcast_con.close()
        announc_con.close()
        rpc_con.close()
        watchdog_con.close()
        is_running = False
        game_not_finished = False
        logging.debug("Bye bye")
    logging.debug("Exiting initial loop")

    try: