Jeu Monopoly dans OOD?

J'ai trouvé cet article de blog intéressant via CodingHorror: Ma Question D'entrevue préférée . En un mot, il parle des défis de conception orientée objet de la conception du jeu de Monopoly, en mettant l'accent sur la façon de modéliser les règles du jeu. Par exemple, " si un joueur possède Baltic Avenue, peut-elle y ajouter une maison?"

Fait intéressant, près du bas du message, il écrit alors:

, Vous pouvez probablement vous épargner beaucoup de temps d'entrevue. Au lieu de tous les ce cerceau, demander au candidat de décrire quand ils ont effectivement utilisé la stratégie, visiteur, et les modèles de commande en dehors d'un cadre.)

...ce qui signifie probablement que vous pouvez utiliser des modèles de conception pour modéliser les règles du jeu (voir ci-dessus). Personne n'a jamais fait cela? Conçu le jeu de Monopoly en utilisant des modèles de conception? Si oui, comment se fait-il fonctionner?

21
demandé sur Bob Aman 2011-01-02 02:19:31

3 réponses

Voici comment je concevrais Monopoly. J'ai pris la liberté d'assumer un langage typé dynamiquement car cela rend tout plus facile. Ruby spécifiquement.

Vous avez un objet Game simple qui est principalement un wrapper autour d'un Array de taille 40, plus quelques méthodes de commodité. L'objet Game suit également le nombre de houses et hotels disponibles ainsi que les deux piles de cartes Chance et Community Chest. Quelques méthodes de commodité comme current_turn et next_turn! sont fournies - les deux renvoient un Player objet; next_turn! incrémente l'index de tour, en l'enveloppant à 0 si nécessaire.

Tous les emplacements sur lesquels le Joueur peut atterrir doivent hériter d'une superclasse de Property. Le Property classe définit un peu de choses en commun comme rent, owner, set, houses, purchasable?, et upgradeable?. Les propriétés rent et owner peuvent être nil. La propriété set renvoie un Array contenant toutes les propriétés du groupe. La taille de la propriété set peut varier de 1 à 4. La propriété houses représente un hôtel comme 5 "maisons".

Le Game objet a un Array de Player objets, chacun avec des champs comme position (un entier de 0 à 39), money (pas de limite supérieure - la banque techniquement jamais "à court d'argent'), get_out_of_jail_frees, et in_jail? (depuis la position est insuffisante pour cette). L'objet Game a également un index pour suivre son tour.

Les règles spécifiques aux propriétés sont toutes codées dans leurs sous-classes respectives. Ainsi, par exemple, l'implémentation de rent sur un Railroad serait être:

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

Les cartes Chance et Community Chest peuvent être simplement implémentées avec un tas de fermetures qui prennent un jeu et un objet joueur comme paramètres. Par exemple:

# 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

Et ainsi de suite. La méthode advance_token! gère évidemment des choses comme passer go.

Évidemment, il y a plus de détails-c'est un jeu assez compliqué, mais j'espère que cela vous donne la bonne idée. Il serais certainement plus que suffisant pour une entrevue.

Mettre à jour

Règles de la maison pourrait être allumé ou éteint en ajoutant un house_rules Array à l'objet Game. Cela permettrait à la propriété FreeParking d'être implémentée comme ceci:

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
24
répondu Bob Aman 2011-01-28 23:35:12

Je pense que vous prenez le mauvais chemin ici.

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

Je pense que cela montre juste que vous ne comprenez pas vraiment ce que sont les modèles de conception. Les Modèles de conception connus ne sont que des noms que nous donnons à des situations récurrentes lors du codage. Dans votre vie de tous les jours, vous ne dites jamais "je me suis réveillé à 8h pour aller à 9h pour placer X, programmant toute la journée jusqu'à 17h, donc ils me paient d'ici la fin du mois". Vous dites: "Aujourd'hui, je suis parti travailler". Vous avez le problème de vouloir gagner de l'argent, et un récurrent les solutions à ce problème vont fonctionner. Si... nous avons un modèle ici! Appelons ça "travailler"!

Les modèles de conception ne sont qu'un tas de solutions étudiées à des problèmes communs. Chacune de ces solutions a un nom associé (stratégie, visiteur, etc.).

Revenir à

...which probably means that you can use design patterns to model the rules of the game 

Cela ne signifie pas que vous pouvez utiliser des modèles de conception pour modéliser les règles du jeu, cela signifie que quoi que vous fassiez dans votre solution, il tombera probablement sur certains des modèles de conception connus. Il est plus facile de penser alors à votre solution comme un ensemble de modèles interconnectés que d'avoir à tout décrire à partir du sol.

5
répondu devoured elysium 2011-01-05 07:42:55

Je n'ai jamais conçu de règles Monopoly (trop facile, me semble-t-il), mais j'ai tâté d'écrire des moteurs pour d'autres jeux bien connus pour le plaisir personnel et avec la compréhension que tout cela est un exercice académique.

Les deux jeux que j'ai essayé de modèle (et de continuer à essayer) sont , D&D et M:tG.

Avec D & D, l'accent est mis sur de très bonnes classes de conception OO et des hiérarchies de classes qui ont du sens.

Avec M: tG, vous réalisez essentiellement que le le paradigme oo droit est incomplet pour ce genre de chose. Vous finissez par travailler avec des agents, des courtiers d'événements et créer des ensembles de règles vraiment compliqués.

Tout cela n'a pas de sens sauf si vous êtes un concepteur de jeu. Bon amusement, bien que.

1
répondu Dmitri Nesteruk 2011-01-01 23:31:30