import collections.deque as deque
class UnavailableCardError(Exception):
pass
class Card:
def use(self):
raise NotImplementedError()
class CardP(Card):
def use(self, user):
if user.health_point < user.health_point_max:
user.health_point += 1
else:
raise UnavailableCardError("Health point is max.")
class CardK(Card):
# 在使用 K 卡的时候,需要判断该回合是否使用过一次 K 卡。这个判断应该放在 CardK 类内部以保证每个类只做分内之事,但是实现这个判断需要额外的参数,需要改动 Pig.__use_card() 函数调用 CardK.use() 的参数列表。
# CardHelper 类是冗余代码,忽视即可
def use(self, user, pig):
class CardHelper:
def __init__(self, user, pigs):
self.__user = user
self.__pigs = pigs
def run(self):
while True:
card = self.__user.popleft_card()
try:
self.__use(card)
except UnavailableCardError:
self.__user.appendleft_card(card)
break
def __use(self, card):
if isinstance(card, CardK)
class Pig:
def __init__(self, init_cards):
self.__cards = deque(init_cards)
self.__health_point = 4
self.__health_point_max = 4
@property
def health_point(self):
return self.__health_point
@health_point.setter
def set_health_point(self, value):
if 0 <= value <= self.__health_point_max:
self.__health_point = value
else:
raise ValueError(
"Trying to set health_point "
f"{self.__health_point} -> {value}."
)
@property
def health_point_max(self):
return self.__health_point_max
def popleft_card(self):
return self.__cards.popleft()
def appendleft_card(self, card):
return self.__cards.appendleft(card)
def act(self, public_cards, pigs):
self.__get_card(public_cards)
self.__use_card(pigs)
def __get_card(self, public_cards):
num = 2
for _ in range(num):
card = public_cards.pop()
self.__cards.append(card)
def __use_card(self, pigs):
helper = CardHelper(user=self, pigs=pigs)
helper.run()
class Game:
pass
说一下我自己的思路:对题目的每个对象在代码中实现,例如卡牌有 ABC Card 和其子类 CardP, CardK,对于猪有 Pig 类,以及还没有实现的 MajorPig, ZhongPig, FanPig,通用的代码在 Pig 中实现,不通的代码在不同的具体类中具体实现。
遇到的问题是访问控制的问题,具体可以看代码中的注释。简单解释一下就是 Python 中类的成员只有 public 和 private 两个属性,也就是说要么每一个类都能用,要么只有这个类本身能用。而为了最严格控制所有成员的访问权限,同时满足题目的要求,就不得不设计许多辅助类帮助实现访问控制。笔者无法优雅地设计这些类,因此暂时放弃实现。
当然这并不能说明 OOP 解法不合适,只能说明笔者功力不足,没有理解 OOP 的精髓。
写了这么多代码,得到的一个结论:面向对象中的对象绝对不是对客观事物属性和方法的简单抽象,而是对程序中针对不同变量和函数的访问控制。