首页 > 解决方案 > 有没有办法可以优化多个 python for 循环?

问题描述

我正在尝试制作多人网络游戏,我有一个用 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

标签: pythonloopsfor-loop

解决方案


您应该避免两次检查同一对玩家的碰撞。

让我们举一个非常简单的例子,Players列表包含 0、1、2、3。

使用您的代码,您会得到很多冗余测试:

  • 在循环 0 中,您针对 1、2 和 3 测试 0
  • 在循环 1 中,您针对 0、2 和 3 测试 1 ===>(但已经测试了 0-1)
  • 在循环 2 中,您针对 0、1 和 3 测试 2 ===>(但 0-2 / 1-2 已经测试过)
  • 在循环 3 中,您针对 0、1 和 2 测试 3 ===>(但已经测试了 0-3 / 1-3 / 2-3)

所以而不是:

for Player in Players:
    for Player2 in Players:

做:

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

如果我们再次使用包含 0、1、2、3 的列表,我们会有以下行为:

  • 在循环 0 中,您针对 1、2、3 测试 0
  • 在循环 1 中,您针对 2、3 测试 1
  • 在循环 2 中,您针对 3 测试 2

这样,它将迭代次数从 N^2 减少到 N(N-1)/2。


推荐阅读