OOD的垄断游戏?

jas*_*ogd 24 architecture oop design-patterns

我通过CodingHorror找到了这篇有趣的博文:My Favorite Interview Question.简而言之,他谈到了设计垄断游戏的面向对象设计挑战,重点是如何模拟游戏规则.例如,"如果一名球员拥有波罗的海大道,她可以加一个房子吗?"

有趣的是,在帖子底部附近,他写道:

你可以节省很多面试时间.而不是所有这些喧嚣,请求候选人描述他们何时实际使用框架之外的策略,访问者和命令模式.)

...这可能意味着你可以使用设计模式来模拟游戏规则(见上文).有没有人这样做过?使用设计模式设计垄断游戏?如果是这样,它是如何运作的?

Bob*_*man 27

这就是我如何设计垄断.我冒昧地采用动态类型语言,因为这样可以使一切变得更容易.特别是Ruby.

你有一个简单的Game对象,主要是一个Array大小为40 的包装器,加上一些方便的方法.该Game对象还跟踪可用的数量houses以及hotels两堆Chance和Community Chest卡.一些方便的方法,如current_turnnext_turn!提供-都返回一个Player对象; next_turn!增加转弯指数,必要时换行为0.

玩家可以登陆的所有位置都必须从超类中继承Property.在Property类定义像一些共同的东西rent,owner,set,houses,purchasable?,和upgradeable?.的rentowner特性可以是nil.该set属性返回Array包含组内所有属性的内容.该set属性的尺寸可变化,从1至4所述的houses属性表示的宾馆5"房屋".

所述Game对象具有ArrayPlayer对象,每个对象与像场position(从0到39的整数), money(没有上限-银行技术上从不"用完的钱"),get_out_of_jail_freesin_jail?(因为位置是不够的这一点).该Game对象还有一个索引来跟踪它的转向.

特定于属性的规则都在其各自的子类中编码.所以,举例来说,执行rentRailroad会是:

def rent
  owned_count = self.set.select { |rr| rr.owner == self.owner }.size
  return 25 * 2 ** (owned_count - 1)
end
Run Code Online (Sandbox Code Playgroud)

机会和公共胸卡可以通过一系列闭包来实现,这些闭合将游戏和玩家对象作为参数.例如:

# Second place in a beauty contest
COMMUNITY_CHEST_CARDS << lambda do |game, player|
  player.money += 10
end

# Advance token to Boardwalk
CHANCE_CARDS << lambda do |game, player|
  game.advance_token!(player, 39)
end

# Advance token to nearest railroad, pay double
CHANCE_CARDS << lambda do |game, player|
  new_position = [5, 15, 25, 35].detect do |p|
    p > player.position
  end || 5
  game.advance_token!(player, new_position)
  # Pay rent again, no-op if unowned
  game.properties[new_position].pay_rent!(player)
end
Run Code Online (Sandbox Code Playgroud)

等等.该advance_token!方法显然处理像go go这样的事情.

显然,有更多的细节 - 这是一个相当复杂的游戏,但希望这给你正确的想法.面试当然是绰绰有余的.

更新

可以通过向对象添加a house_rules Array来打开或关闭House规则Game.这将允许FreeParking属性像这样实现:

class Game
  def house_rules
    @house_rules ||= []
  end

  def kitty
    # Initialize the kitty to $500.
    @kitty ||= 500
  end

  def kitty=(new_kitty)
    @kitty = new_kitty
  end
end

class FreeParking < Property
  def rent
    if self.game.house_rules.include?(:free_parking_kitty)
      # Give the player the contents of the kitty, and then reset it to zero.
      return -(_, self.game.kitty = self.game.kitty, 0)[0]
    else
      return 0
    end
  end
end
Run Code Online (Sandbox Code Playgroud)


dev*_*ium 5

我认为您在这里走错了路。

...which probably means that you can use design patterns to model the rules of the game (see above). 
Run Code Online (Sandbox Code Playgroud)

我认为这表明您并不真正了解什么是设计模式。已知的设计模式只是我们在编码时经常出现的情况下的名称。在您的日常生活中,您永远不会说“我从早上8点起床,到早上9点放置X,整天编程到下午5点,所以他们要在月底前付钱给我”。您说:“今天我去上班了”。您有想要赚钱的问题,并且针对该问题的周期性解决方案将起作用。所以...我们这里有一个模式!我们称之为“工作中”!

设计模式只是一堆针对常见问题的研究解决方案。这些解决方案中的每一个都有一个关联的名称(策略,访客等)。

回到

...which probably means that you can use design patterns to model the rules of the game 
Run Code Online (Sandbox Code Playgroud)

这并不意味着您可以使用设计模式为游戏规则建模,而是意味着您在解决方案中所做的任何事情都可能会落入某些已知的设计模式中。然后,将您的解决方案视为一组相互关联的模式,比必须从头开始描述所有内容都容易。