0

Counter Strike のゲームをシミュレートしようとしています。基本的に、私は異なるプレイヤーを持つ 2 つのチームを持っており (今のところすべてのプレイヤーは同一です)、それらを「戦わせ」、1 つのチームのすべてのプレイヤーが死んだらシミュレーションを終了する必要があります。

実行中のシミュレーションが終わらない理由を理解しようとしています。simpy のコア要素を誤解しているように感じますが、実際には何がわかりません。

すべてのプロセスと simpy 関連のコードは、main.py と player.py にあります。すべてのプレイヤーが「死亡」したら、シミュレーションを終了させようとしています。

基本的に、私はすべてのプレイヤーが周囲の領域 (Hotspot クラスによって表されるノード) を常にチェックして、敵がいるかどうかを確認するプロセスであることを望んでいます。敵がいる場合、敵はランダムに 1 つを選択して「攻撃」します。いずれかのチームのすべてのプレイヤーのヘルスが 0 未満になると、シミュレーションが終了し、勝ったチームの勝数が 1 増えます。

編集: また、pdb で実行したところ、プレイヤーのヘルスが減少しているようには見えず、play メソッドが実行されていないようでした。

編集 2: 問題を見つけるためにすべてのコードを読む必要はないと思います。主にメイン ファイルとプレーヤー ファイルにあると思いますが、コードがエラーなしで無限にループするため、100% 確信が持てません。

これが私のコードです

main.py

from player import Player
from game_map import Game_Map
from team import Team
from sides import Sides
import simpy
import pdb


def main():
  team_a = Team("Team_A", Sides.CT)
  team_b = Team("Team_B", Sides.T)
  gmap = Game_Map()
  gmap.spawn_team(team_a)
  gmap.spawn_team(team_b)

  env = simpy.Environment()
  for team in (team_a, team_b):
    for player in team.players:
      env.process(player.play(env))

  env.run(until=round(team_a, team_b, env))

def round(team_a, team_b, env):

  while True:
    if team_a.all_dead():
      team_b.round_wins += 1
      print team_b
      env.exit()
    if team_b.all_dead():
      team_a.round_wins += 1
      print team_a
      env.exit()



if __name__ == "__main__":
  main()

player.py

import simpy
from sides import Sides
import numpy as np
import pdb

class Player(object):
  """ Class that represents a CSGO player"""

  def __init__(self, steam_id, team, acc, hs_percentage):
    # the player's id
    self.steam_id = steam_id
    # percentage of shots that hit, accuracy
    self.acc = acc
    # percentage of hits that hit the head
    self.hs_percentage = hs_percentage

    # the team 
    self.team = team
    # the player's health, this changes when the teams "fight"
    self.health = 100

    # the current hotspot that the player is in
    self.current_location = 0



    # if the player is alive or dead
    self.is_alive = True



  def play(self, env):
    """Process that simulates the player's actions. This is run once every round until
    the round is over"""
    while(self.is_alive):
      target = self.choose_target()
      if target == -1:
        continue
        yield env.timeout(5)
      else:
        target.inflict_self(self.determine_damage())        
        yield env.timeout(5)


  def determine_damage(self):
    """The amount of damage the player will inflict on the enemy"""
    return 27

  def choose_target(self):
    """Choose a target to attack from the enemies in the hotspot"""

    # 1 - side converts 0 to 1 and 1 to 0
    enemy_list = self.current_location.players[1 - self.team.side]
    num_enemies = len(enemy_list)

    # if there are no enemies currently in the same location of the player
    # simply return 0
    if num_enemies == 0:
      return -1

    # pick an enemy randomly from the list of enemies and return their object
    return enemy_list[np.random.random_integers(0, num_enemies - 1)]


  def get_side(self):
    return self.team.side

  def inflict_self(self, damage):
    """Inflict damage onto own class. If damage moves health below 0, mark the 
    player as "Dead" and remove them from the map"""
    self.health = self.health - damage
    if self.health <= 0:
      self.current_location.players[self.team.side].remove(self)
      self.is_alive = False


  def __str__(self):
    return "Steam id: {0}\tIs Alive: {1}\tCurrent Location: {2}".format(self.steam_id, self.is_alive, self.current_location)


def tests():
  return

if __name__ == "__main__":
  tests()

game_map.py

import networkx as nx
from hotspot import Hotspot
import matplotlib.pyplot as plt
class Game_Map(object):
  """ Generic map that represents general outline of all counter strike maps"""

  def __init__(self):
    self.graph = nx.Graph()
    self.spawns = [Hotspot()]
    self.graph.add_node(self.spawns[0])

  def add_team(team):
    #side = team.side
    # side is 0 because for testing the simulation
    # we are only using one node
    side = 0
    for player in team.players:
      self.spawns[side].move_into(player)

  def spawn_team(self, team):
    for player in team.players:
      self.spawns[0].move_into(player)


  def draw(self):
    nx.draw(self.graph)
    plt.show()

def tests():
  """Tests to see that Game_Map class works properly"""

  # initialize the map
  gmap = Game_Map()
  gmap.draw()



# if this module is being run explicitly from the command line
# run tests to assure that this module is working properly
if __name__ == "__main__":
  tests()

hotspot.py

import simpy
from player import Player
from team import Team
from sides import Sides
class Hotspot(object):
  """Hotspots are the representation for different areas of the map. This is where players 'fight'."""

  def __init__(self):
    self.players = [[], []]


  def move_into(self, player):
    side = player.get_side()
    self.players[side].append(player)
    player.current_location = self

    return 1


  def __eq__(self, other):
    return id(self) == id(other)

  def __hash__(self):
    return id(self)


def tests():
  """Tests to see that hotspot works properly"""
  hotspot_list = []
  for i in range(5):
    hotspot_list.append(Hotspot())

  for spot in hotspot_list:
    team_a = Team("team_a", Sides.CT)
    team_b = Team("team_b", Sides.T)
    spot.move_into(Player(1, team_a, .5, .5))
    spot.move_into(Player(1, team_b, .5, .5))

    print "Hotspot id = {0}".format(id(spot))
    for team in spot.players:
      for player in team:
        print "player = {0} in team {1}".format(player, player.team)

if __name__ == "__main__":
  tests()

側面.py

class Sides(object):
  """Enum object, simply represents CT (Counter Terrorists) as 0 and 
  T (Terrorists) as 1"""
  CT, T = range(2)

team.py

from player import Player
class Team(object):
  """Class that holds critical team information"""
  def __init__(self, name, side):
    self.round_wins = 0
    self.players = []
    self.name = name
    self.side = side
    self.generate_team()

  def all_dead(self):
    count = 0
    for player in self.players:
      if player.is_alive == False:
        count += 1
    if count == 5:
      return True
    else: 
      return False



  def __str__(self):
    rep = "Team: {0}, Round Wins: {1}\n".format(self.name, self.round_wins)
    for player in self.players:
      rep += player.__str__() + '\n'

    return rep


  def generate_team(self):
    for i in range(5):
      self.players.append(Player(1, self, .5, .2))

  __rep__ = __str__

要件.txt

decorator==3.4.2
matplotlib==1.4.3
mock==1.0.1
networkx==1.9.1
nose==1.3.6
numpy==1.9.2
pyparsing==2.0.3
python-dateutil==2.4.2
pytz==2015.2
scipy==0.15.1
simpy==3.0.7
six==1.9.0
4

2 に答える 2

1

これは無限ループかもしれないと感じています:

while(self.is_alive):
  target = self.choose_target()
  if target == -1:
    continue
    yield env.timeout(5)

おそらく、前に譲りたいと思うでしょうcontinue(とにかく不要です)。

于 2015-04-19T16:20:58.860 に答える