Example #1
0
def getPlayerUpdate(playerName: str, game: Dungeon):
    """
    PlayerUpdateType is:
    {
      "type": "player-update",
      "layout": (tile-layout), # getLayout?
      "position": (point), # getPlayer.location
      "objects": (object-list), # getLocationsAround.map(if destHasItem || desthasKey -> return object)
        [ { "type": "key", "position": [ 4, 2 ] },
               { "type": "exit", "position": [ 7, 17 ] } ]
      "actors": (actor-position-list) # potentially getLocationsAround.map(if destHasEnemy -> return enemy)
    }

    1. Finds 25 points: surrounding 24 of given point
    2. Layout based on the 25 points
    3. Will check if enemies exist on any of those 25
    4. Will check if key or exit on any of those 25
    """
    player: Player = getPlayer(game.levels[game.currLevel], playerName)
    possMoves = getFieldOfView(player.name, game.levels[game.currLevel])
    output = {
        "type": "player-update",
        "layout": getTileLayout(game, player),
        "position": [player.location[0], player.location[1]],
        "objects": getObjectsAroundPlayer(possMoves, game),
        "actors": getActorsAroundPlayer(possMoves, game)
    }
    return output
Example #2
0
def start(args):
    log = logInFile("Server.py")

    # Global vars
    JSON_LEVELS = args['jsonLevels']
    NUM_LEVELS = args['numLevels']
    NUM_CLIENTS = args['numClients']
    WAIT = args['wait']
    OBSERVE = args['observe']
    ADDRESS = args['address']
    PORT = args['port']

    # Ready to begin

    CONNS = {}
    SOCK = None

    try:
        SOCK = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        SOCK.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        SOCK.settimeout(WAIT)
        SOCK.bind((ADDRESS, PORT))
        SOCK.listen(NUM_CLIENTS)

        CONNS = registerPlayers(NUM_CLIENTS, SOCK)

        # Setup game (Convert levels, populate players, populate enemies,
        # create dungeon)
        GAME, playerNames = setupGame(list(CONNS.keys()), JSON_LEVELS)

        # Broadcast initial game state
        broadcast(startLevelMsg(1, playerNames), CONNS)

        # Send initial player update msgs
        broadcastPlayerUpdates(CONNS, GAME)

        log("GAME INITIALIZED!")

        # Enter main loop
        while True:

            # Obtain the current level
            currLevel: Level = GAME.levels[GAME.currLevel]

            # Check if the level has been completed
            if isLevelOver(currLevel):
                GAME = advanceLevel(GAME)
                broadcastLevelOver(GAME, CONNS)

            # Check if game is over
            if GAME.isGameOver:
                broadcastGameOver(GAME, CONNS)
                broadcast("disconnect", CONNS)

            # Execute player turns
            for playerName in playerNames:
                try:
                    player = getPlayer(currLevel, playerName)
                    if player:
                        initLoc = player.location
                        playerTurn = GAME.levels[GAME.currLevel].playerTurn
                        MAX_TRIES = 5
                        for tries in range(MAX_TRIES):
                            time.sleep(1)
                            playerMove = executeTurn(CONNS[playerName])
                            GAME = move(playerName, playerMove, GAME)
                            playerAfter = getPlayer(currLevel, playerName)
                            moveMade = not playerAfter or playerTurn != \
                                       GAME.levels[
                                           GAME.currLevel].playerTurn
                            if moveMade:
                                break
                            # last turn and still no valid move made
                            if not moveMade:
                                if tries == (MAX_TRIES - 1):
                                    GAME = move(playerName, None, GAME)
                                else:
                                    sendPlayer(playerName,
                                               "Invalid move. Try again...",
                                               CONNS)

                        broadcastPlayerUpdates(CONNS, GAME)
                except PlayerDisconnect:
                    # TODO broadcast??
                    log("PLAYER DISCONNECTED")
                    player: Player = getPlayer(currLevel, playerName)
                    playerBoardNum = whichBoardInLevel(currLevel,
                                                       player.location)
                    GAME = removePlayer(playerName, playerBoardNum, GAME)
                    # TODO reset playerNames
                    continue

            # Execute enemy turns
            currLevel: Level = GAME.levels[GAME.currLevel]
            for enemy in getEnemiesInLevel(currLevel):
                nextMove = enemyNextMove(enemy, GAME)
                GAME = move(enemy.name, nextMove, GAME, isPlayer=False)
                broadcastPlayerUpdates(CONNS, GAME)
                # for playerName in playerNames:
                # msg = enemy.name + " moved"
                # broadcast(playerUpdateMsg(playerName, GAME, msg), CONNS)

    except json.JSONDecodeError:
        print("Malformed level file. Check your formatting")
        closeConns(CONNS)
        if SOCK:
            SOCK.close()
        sys.exit(1)
    except KeyboardInterrupt:
        print("\nExiting...")
        closeConns(CONNS)
        if SOCK:
            SOCK.close()
        sys.exit(0)
Example #3
0
def broadcastPlayerUpdates(conns: dict, game: Dungeon):
    for playerName in conns.keys():
        if getPlayer(game.levels[game.currLevel], playerName):
            msg = "--> Player Update: {}\n".format(playerName)
            msg += formatted(getPlayerUpdate(playerName, game))
            sendPlayer(playerName, msg, conns)