Есть ли способ, которым я мог бы оптимизировать несколько Python для циклов? - PullRequest
0 голосов
/ 06 июля 2018

Я пытаюсь сделать многопользовательскую веб-игру, у меня есть сервер на python. Так как игра многопользовательская, мне нужно обновить каждого игрока индивидуально; Это требует циклов for, в настоящий момент мой код использует много циклов for, что вызывает нежелательные побочные эффекты. Побочные эффекты включают замедленную скорость. Еще одна проблема, с которой я сталкиваюсь с циклами for, заключается в том, что они меняют скорость в зависимости от того, через сколько объектов они проходят; Это вызывает проблемы с тем фактом, что количество элементов, которые должен пройти цикл в цикле, изменяется в зависимости от того, сколько игроков подключено, таким образом путая функцию предсказания на стороне клиента, которую я сделал, чтобы скрыть отставание.

Это мой основной код:

      PlayerData = {} 

    for Player in Players:
        if(Player.id > 50):
            PlayerData['playerx' + str(Player.id)] = Player.x
            PlayerData['playery' + str(Player.id)] = Player.y


            PlayerData['playera' + str(Player.id)] = int(Player.angle)

            PlayerData['playerstat' + str(Player.id)] = Player.alive

            if(Player.id > 50):
                if(Player.alive == 0):
                    Players.remove(Player) 

        for ID in clientIds:
            PlayerData['id'] = str(clientIds[len(clientIds) - 1].id)

        PlayerData['players'] = ids




        if(Player.id <= 50):
            hrIds.append(Player.id)
            PlayerData['hx' + str(Player.id)] = Player.x
            PlayerData['hy' + str(Player.id)] = Player.y
            #PlayerData['ha' + str(Player.id)] = int(Player.angle)


    PlayerData['hr'] = hrIds
    PlayerJsonData = json.dumps(PlayerData)
    await websocket.send(PlayerJsonData)
    recivedData = await websocket.receive()
    rData = json.loads(recivedData)

    for ID in clientIds:
        if(rData['id'] == str(ID.id)):
            if(ID.IG == 0):
                 if(rData['playerstat'] == 1):
                    Players.append(player_classes.Basic(-1300, -1300, ID.ws, ID.id, 1)) 
                    ID.IG = 1




    for Player in Players:

        for Player2 in Players:
             if(Player.id > 50):
                Player.detect_collide(Player2)


                if(rData['id'] == str(Player.id)):
                    if(rData['direction'] == "up"):
                            Player.accelerate(rData['direction'])
                            Player.moveUp(Player2)

                    if(rData['direction'] == "left"):
                        Player.accelerate(rData['direction'])
                        Player.moveLeft(Player2)

                    if(rData['direction'] == "down"):
                        Player.accelerate(rData['direction'])
                        Player.moveDown(Player2)

                    if(rData['direction'] == "right"):
                        Player.accelerate(rData['direction'])
                        Player.moveRight(Player2)


                    if(rData['direction'] == "none"):
                        Player.decelerate(rData['direction'])  

РЕДАКТИРОВАТЬ: моя основная проблема скорости зацикливания происходит, когда я добавляю больше классов в Players

1 Ответ

0 голосов
/ 06 июля 2018

Вам следует избегать проверки столкновения одной и той же пары игроков дважды.

Давайте рассмотрим очень простой пример со списком Players, содержащим 0, 1, 2, 3.

С вашим кодом вы получаете много лишних тестов:

  • В цикле 0 вы тестируете 0 против 1, 2 и 3
  • В цикле 1 вы тестируете 1 против 0, 2 и 3 ===> (но 0-1 уже был протестирован)
  • В цикле 2 вы тестируете 2 против 0, 1 и 3 ===> (но 0-2 / 1-2 уже были протестированы)
  • В цикле 3 вы тестируете 3 против 0, 1 и 2 ===> (но 0-3 / 1-3 / 2-3 уже были протестированы)

Так что вместо:

for Player in Players:
    for Player2 in Players:

Do:

for i, Player in enumerate(Players):
    for Player2 in Players[i + 1:]:

Если мы снова используем список, содержащий 0, 1, 2, 3, у нас будет следующее поведение:

  • В цикле 0 вы тестируете 0 против 1, 2, 3
  • В цикле 1 вы тестируете 1 против 2, 3
  • В цикле 2 вы проверяете 2 против 3

Таким образом, оно сокращает количество итераций с N ^ 2 до N (N-1) /2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...