我是新来的。我想模拟足球比赛。如何访问牌手/罪犯/后卫类中的Play实例变量?如果另一种结构更好,请帮忙。
class Player:
def __init__(self, x, y):
self.x = x
self.y = y
def move_to(self, x, y):
self.x = (self.x + x) / 2
self.y = (self.y + y) / 2
## Loop through Play.Players to find nearest. How do I access Play.Players?
def nearest(self):
return nearest
class Offender(Player):
def __init__(self, x, y):
super().__init__(x, y)
# Move to ball.
def strategy():
ball_x = Play.ball_x # how do I access Play.ball_x
ball_y = Play.ball_y # how do I access Play.ball_y
self.move_to(ball_x, ball_y)
class Defender(Player):
def __init__(self, x, y):
super().__init__(x, y)
# Move to nearest player
def strategy(self):
nearest = self.nearest()
self.move_to(nearest)
class Play:
def __init__(self, offense_players, defense_players, ball_x, ball_y):
self.offense = [Offender(player) for player in offense_players]
self.defense = [Defender(player) for player in defense_players]
self.players = self.offense + self.defense
self.ball_x = ball_x
self.ball_y = ball_y
def simulate(self):
while True:
for player in self.players:
player.strategy()
if __name__ == "__main__":
Play().simulate()我没有使用Offender和Defender类,而是为每个职位设置了一个类,即Striker(Player)、Midfielder(Player)、Goalie(Player)等,这就是为什么我希望将它们各自的strategy存储在它们的类中,而不是在Play类中。
发布于 2019-11-01 00:17:55
我只是从马丁诺的注释中详细阐述了这个想法:我们只是将Play实例作为参数传递给Player的相关方法。我还为nearest()方法编写了第一个草案,但您可能希望改进它的逻辑。我只是起草这个演示如何解决您的OOP设计问题。
import typing
class Player:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def move_to(self, x: float, y: float) -> None:
self.x = (self.x + x) / 2
self.y = (self.y + y) / 2
def nearest(self, play: "Play") -> "Player":
# This must yet be adapted to handle the edge case of two players
# having equal distance to the current player. You didn't specify the
# desired output for that case, hence I just ignored that scenario for now.
return min([
p for p in play.players
if p.x != self.x or p.y != self.y, # this is to
# exclude the player itself.
# This is a buggy logic, because it relies on an assumption that is not
# validated in the code (the assumption that two different players never
# have identical coordinates). You might want to introduce a uniqe `id`
# instance variable to the Player class, to handle this identification in a
# clean way.
],
key=lambda p: (self.x - p.x)**2 + (self.y - p.y)**2
)
class Offender(Player):
def __init__(self, x: float, y: float):
super().__init__(x, y)
# Move to ball.
def strategy(self, play: "Play") -> None:
self.move_to(play.ball_x, play.ball_y)
class Defender(Player):
def __init__(self, x: float, y: float):
super().__init__(x, y)
# Move to nearest player
def strategy(self, play: "Play") -> None:
self.move_to(self.nearest(play=play)
class Play:
def __init__(
self,
offense_players: typing.List["Offender"],
defense_players: typing.List["Defender"],
ball_x: float,
ball_y: float,
):
self.offense = offense_players
self.defense = defense_players
self.players = self.offense + self.defense
self.ball_x = ball_x
self.ball_y = ball_y
def simulate(self) -> None:
while True: # this is still a bad condition, you might want to change this. However you didn't specify your desired logic, so I didn't change it.
for player in self.players:
player.strategy(self, play=self)发布于 2019-11-01 01:16:40
不确定这对您有多大的帮助,因为实现是在C++中
您可以为类似的问题语句https://github.com/rimpo/footballcpp签出我的实现。
要了解上面写的bot所用的街机游戏框架实现,请签出http://richard-shepherd.github.io/coding-world-cup/index.html。
发布于 2019-11-01 00:09:20
我要做以下几点:
在另一个(数据)类中跟踪游戏状态:
class GameState:
def __init__(self, offense_players, defense_players, ball_x, ball_y):
self.offense = offense_players
self.defense = defense_players
self.players = self.offense + self.defense
self.ball_x = ball_x
self.ball_y = ball_y您甚至可能希望为此使用python3.7 dataclasses (和一些 其他特性)(尽管它根本不是必要的)。
from dataclasses import dataclass
from typing import List
@dataclass
class GameState:
offense: List[Offender]
defense: List[Defender]
ball_x: float
ball_y: float
@property
def players(self):
return offense + defense 然后玩家在他们的策略中接受这个状态,并被期望更新他们的内部状态(比如位置)。nearest player是通过使用min的键参数获取其他玩家之间的最小l2距离来实现的,该参数接受另一个播放器的函数p,该函数是使用lambda编写的。
class Player:
def __init__(self, x, y):
self.x = x
self.y = y
def move_to(self, x, y, other_players):
self.x = (self.x + x) / 2
self.y = (self.y + y) / 2
def nearest(self):
return nearest
class Offender(Player):
def __init__(self, x, y):
super().__init__(x, y)
# Move to ball.
def strategy(self, game_state):
ball_x = game_sate.ball_x # how do I access Play.ball_x
ball_y = game_state.ball_y # how do I access Play.ball_y
self.move_to(ball_x, ball_y)
class Defender(Player):
def __init__(self, x, y):
super().__init__(x, y)
# Move to nearest player
def strategy(self, game_state):
# we assume you are moving to offensive players - which
# you will not be apart of
nearest = min(
game_state.offense
key=lambda p: (
(self.x - p.x) **2 + (self.y - p.y) ** 2
) ** (1/2) # take the l2 norm to find the "closest" player to you
)
self.move_to(nearest.x, nearest.y) 然后,玩游戏
class Play:
def __init__(self, game_state):
self.game_state = game_state
def simulate(self):
while True:
for player in self.game_state.players:
player.strategy(self.game_state)
if __name__ == "__main__":
Play(GameState(
[Offender(-1, 0), Offender(-1, -1), ...]
[Defender(1, 0), Offender(1, -1), ...]
)).simulate()然后您可以实现一些实际的玩家。
class TiernaDavidson(Defender):
def strategy(self, *args, **kwargs):
return better_strategy(*args, **kwargs)您将不得不向她请求better_strategy的实现;)
https://stackoverflow.com/questions/58652458
复制相似问题