gpt4 book ai didi

python - pythonic python中的保龄球游戏kata

转载 作者:行者123 更新时间:2023-12-05 07:53:08 25 4
gpt4 key购买 nike

我尝试解决 Uncle Bobs 的保龄球游戏套路 (http://www.butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata),但没有真正找到一个感觉足够 pythonic 的解决方案。

此解决方案或多或少是对 Martins C++ 解决方案的改编,并使用数组索引来计算罢工和备件的分数。它可以工作,但感觉不像我希望的那样像 pythonic。

class Game():

def __init__(self):
self.rolls = []

def roll(self, pins):
self.rolls.append(pins)

def score_c(self):
total_score = 0
frame_index = 0
for frame in range(10):
if self.rolls[frame_index] == 10:
total_score += 10 + self.rolls[frame_index + 1] + self.rolls[frame_index + 2]
frame_index +=1
elif self.rolls[frame_index] + self.rolls[frame_index + 1] == 10:
total_score += 10 + self.rolls[frame_index + 1]
frame_index += 2
else:
total_score += self.rolls[frame_index] + self.rolls[frame_index + 1]
frame_index += 2
return total_score

我本可以为罢工和备用条件使用便利功能,但你明白了。

但我认为必须有一种方法可以做到这一点,而无需通过索引直接访问 rolls 数组。这感觉就像是一种非常类似于 c 的方式,直接递增 frame_index 在 python 中绝对感觉不对。所以我认为必须有一种更简洁的方法来做到这一点。我在下面进行了尝试,但对于完美的游戏并没有真正奏效。

这个使用生成器来提供感觉非常整洁的帧,但这也意味着必须为 strike 添加 0 才能制作完整的 2 个滚动帧。

class Game():

def __init__(self):
self.rolls = []

def _frame_iterator(self):
for i in range(0, 20, 2):
yield (self.rolls[i], self.rolls[i+1])

def roll(self, pins):
self.rolls.append(pins)
if pins == 10:
self.rolls.append(0)

def score(self):
total_score = 0
spare = False
strike = False
for frame in self._frame_iterator():
if spare:
total_score += frame[0]
spare = False
if strike:
total_score += frame[1]
strike = False
if frame[0] + frame[1] == 10:
spare = True
if frame[0] == 10:
strike = True
total_score += frame[0] + frame[1]
return total_score

我的问题基本上是,有没有人以不同于 uncle bobs C++ 解决方案的不同且更 pythonic 的方式解决了 Python 中的保龄球套路?以及如何改进我的尝试的建议?

最佳答案

这绝对是一种不同的方法(在 roll() 中实现大部分规则,而不是在 score() 中实现),我认为它也很 pythonic。

class Game(object):
def __init__(self):
self._score = [[]]

def roll(self, pins):
# start new frame if needed
if len(self._score[-1]) > 1 or 10 in self._score[-1]:
self._score.append([])

# add bonus points to the previous frames
for frame in self._score[-3:-1]:
if sum(frame[:2]) >= 10 and len(frame) < 3:
frame.append(pins)

# add normal points to current frame
for frame in self._score[-1:10]:
frame.append(pins)

def score(self):
return sum(sum(x) for x in self._score)

这里的主要思想不是将所有掷骰子存储在一个列表中,而是制作一个帧列表,其中包含每个帧的掷骰子列表(和奖励积分)。

例如,score 方法中的生成器表达式使其成为 pythonic。

另一个 pythonic 示例是列表切片的使用。以前版本的 roll() 中间部分看起来像:

for i in [2, 3]:
if len(self._score) >= i:
sum(self._score[-i][:2]) >= 10 and len(self._score[-i]) < 3:
self._score[-i].append(pins)

当前版本使用列表切片的优点是您不必检查列表是否足够长以回溯 1 或 2 帧。此外,您还可以免费获得一个不错的局部变量 (frame = self._score[-i]),而无需为其专门写一行。

关于python - pythonic python中的保龄球游戏kata,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33047762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com