我做了一个高级Python后端工程师访谈,涉及到实现一个摇滚剪刀游戏。结果不太好。他们的工程师说我在各地都有笨拙的执行。后来我做了一次升级,但仍然有一个问题让我感到困惑。他们希望我将游戏规则的最初实现改为更好的抽象。
我最初的实现是:
def _outcome(self, player_move, ai_move):
"""Determine the outcome of current round.
Paper beats (wraps) rock.
Rock beats (blunts) scissors.
Scissors beats (cuts) paper.
Parameters
----------
player_move : MoveChoice
Player's move for current round.
ai_move : MoveChoice
AI's move for current round.
Returns
-------
outcome : Outcome
Outcome of the current round.
"""
if player_move == 1 and ai_move == 2 or \
player_move == 2 and ai_move == 3 or \
player_move == 3 and ai_move == 1:
return self.computer.name
elif player_move == 1 and ai_move == 3 or \
player_move == 2 and ai_move == 1 or \
player_move == 3 and ai_move == 2:
return self.player.name
else:
return 'Draw'
通过映射:
MOVE_CHOICE = {
1: 'rock',
2: 'paper',
3: 'scissors',
}
我在其他地方定义了一个role.Player
和role.Computer
类。他们的批评是:
他们的建议如下:
到目前为止,我已经为移动和结果创建了Enum:
class MoveChoice(Enum):
ROCK = auto()
PAPER = auto()
SCISSORS = auto()
class Outcome(Enum):
WIN = auto()
LOSE = auto()
DRAW = auto()
但我很难按照他们的要求抽象游戏规则。我该怎么做?
发布于 2021-12-24 03:09:57
根据您展示的代码和他们给您的建议,我会这样做:
from enum import Enum, auto
class MoveChoice(Enum):
ROCK = auto()
PAPER = auto()
SCISSORS = auto()
class Outcome(Enum):
WIN = auto()
LOSE = auto()
DRAW = auto()
WIN_MAPPING = {
MoveChoice.ROCK: MoveChoice.SCISSORS,
MoveChoice.SCISSORS: MoveChoice.PAPER,
MoveChoice.PAPER: MoveChoice.ROCK,
}
def outcome(player_move, ai_move):
if player_move == ai_move:
return Outcome.DRAW
elif WIN_MAPPING[player_move] == ai_move:
return Outcome.WIN
else:
return Outcome.LOSE
请注意,我已经将您的方法更改为一个函数。这不是关于总体程序结构的建议,它只是将逻辑描述为一个更独立的例子。
正如卢克·纳尔逊在评论中指出的那样,面试官建议win映射每个移动到它要执行的移动列表。我错过了这个细节。虽然它在摇滚剪刀中没有任何实际的区别,但它更具有普遍性,如果他们要求您将规则集扩展到类似石纸剪刀蜥蜴斯波克的内容,则会更容易。
映射的唯一变化是将每个值转换为一个单一元素列表:
WIN_MAPPING = {
MoveChoice.ROCK: [MoveChoice.SCISSORS],
MoveChoice.SCISSORS: [MoveChoice.PAPER],
MoveChoice.PAPER: [MoveChoice.ROCK],
}
然后,outcome
函数将不必检查计算机的移动是否等于该值,而是必须检查它是否在值中(因为该值现在是一个列表)。
def outcome(player_move, ai_move):
if player_move == ai_move:
return Outcome.DRAW
# elif WIN_MAPPING[player_move] == ai_move:
# Above line is replaced with:
elif ai_move in WIN_MAPPING[player_move]:
return Outcome.WIN
else:
return Outcome.LOSE
https://stackoverflow.com/questions/70469062
复制相似问题