Design decision for a game

Discussion in 'Java' started by pek, May 20, 2008.

  1. pek

    pek Guest

    I am currently developing the House Of Cards card game (I can't seem
    to find any relative info on the internet), but it doesn't really
    matter. My problem is a design problem.

    Say you have a class that holds a set of cards. When a card is added
    it has to obey certain rules. For example, if it is full and no other
    cards can be added, an exception should be thrown. If the card is not
    the correct suite, again, an exception should be thrown etc.

    Now, depending on the options of the game, some rules apply and some
    don't. So clearly, the rules aren't inside the class itself, but they
    are added by the engine using an addRule method. So I thought that I
    could create an interface called Rule with a method called addCard.
    The class holds a list of rules and every time a card is added it
    calls them in the added order.

    But, in order for this to work, I found two problems:
    A) the class that implements the Rule has to have a lot of information
    (the list of cards, if it is already closed etc.). How do I work
    around this? Should the method of the interface have a list of the
    needed information in parameters? Should the class pass itself in all
    rules and provide getters for all attributes?

    B) because different rules have different reactions, I also create a
    Listener for that class. Every time something important happens, the
    registered listeners get informed. But I have no idea how the class
    that implements the Rule can inform the other class to fire an event
    to the registered listeners.

    Just in case I'm not clear at all, let me explain a little more.

    The class I am talking about is called House. This holds a set of
    cards. A card has points depending on it's suite. The house can hold
    up to 31 points. When a card is added and the sum of the points are
    EXACTLY 31, the player wins 20 points in his total score and the house
    empties so cards can be added once again. If the sum of points exceed
    31, the house closes and no more cards can be added. The game has four
    houses.

    Those are the standard rules. Additionally:
    a) if a house has a total of six cards (not so common), the player
    wins 50 points in his total score and the house empties.
    b) each house is of a particular suite. If a joker of the same suite
    (the jokers have suites in this game) is added, any card in the house
    are erased and the player wins 50 points in his total score. But if it
    doesn't the game is over.

    Now, the rule with the six cards fires an event to the listeners that
    the rule was satisfied. One of the listeners is the GUI and it reacts
    by displaying information. The same thing goes for the 31 points rule
    and any rule that others need to know about.

    These are events that are fired and listeners react to. But these also
    are the rules for the house.

    So everything comes down to design decision. Because the rules vary,
    and could be expanded, they need to be outside of the House. And
    because the events depend on the rules, there has to be a bridge
    between them.

    Any suggestions?

    Thank you very much in advance.

    Regards,
    P. Peikidis
     
    pek, May 20, 2008
    #1
    1. Advertising

  2. pek

    Stefan Ram Guest

    pek <> writes:
    >A) the class that implements the Rule has to have a lot of information


    (I have not understood read all details.)

    A class should have high cohesion, which usually means that
    it have to be small. It should not have dozens of fields when
    these can be seperated into sets of related fields that can
    be factored out to seperate classes.

    But sometimes there is an exception to the rule of small classes.

    When there are dozens of fields and they all form one big lump,
    sometimes a large class is appropriate.

    If you see this and you seen no obvious meands to split the
    class then implement it as one large class.

    In the course of developement sometimes later, an idea will
    pop up how to split this large class that was not visible
    at the start of the design.

    Let me add a story about how you sometimes encounter paths
    in the course of action you did not see initially:

    »What often happens to me when climbing is that I look as
    hard as I can for a hold to move my hand up to and I see
    nothing. Nothing I can easily reach, nothing I can nearly
    reach and not even anything I might reach if I was just a
    bit taller or if I jumped. I feel utterly stuck and begin
    to contemplate the immanent defeat of falling off.

    But then I remember to look for new footholds.

    Sometimes I've already had a go at this and haven't seen
    anything promising, but in desperation I move one foot to
    a new hold, perhaps one that is only an inch or so further
    up the wall. And this is when something magical happens.
    Although I am now only able to reach an inch further, I
    can suddenly see a new hold for my hand, something I'm
    able to grip firmly and use to pull myself to freedom and
    triumph (or at least somewhere higher up to get stuck).
    Even though I looked with all my desperation at the wall
    above me, this hold remained completely invisible until I
    moved my foot an inch --- what a difference that inch
    made.«

    http://www.mindhacks.com/blog/2008/03/rock_climbing_hacks.html

    So, you might be able to see how you can split the class later.

    You do not see this way now. BUt you might see it later.

    Then, you can split the class by a refactoring.

    Finding the natural positions for a split sometimes needs
    experience:

    »Life is limited, but knowledge is unlimited. To drive the
    limited to the unlimited without stop is impossible. In
    doing good, avoid fame. In doing bad, avoid disgrace.
    Pursuing a middle course is a reasonable choice.

    Prince Huai's cook was cutting up a bullock. Every blow of
    his hand, every heave of his shoulders, every tread of his
    foot, every thrust of his knee, all were in perfect
    rhythm, like the harmonious music intended for the Emperor.

    "Well done!" cried the Prince. "Your skill has advanced to
    such an extent!"

    "Sir", replied the cook laying down his chopper. "I have
    always devoted to Tao which is higher than mere skill.
    When I first began to cut up bullocks, I saw before me
    whole bullocks. After three years of practice, I saw no
    more whole animals. And now I work with my mind, not with
    my eyes. I glide through joints and cavities in the
    natural constitution of the animal. I do not even touch
    the convolution of muscles or tendon, and never attempt to
    cut through large bones.

    A good cook changes the chopper once a year because he
    cuts. An ordinary cook once a month because he hacks. But
    I have had this chopper for 19 years. Although I have cut
    thousands of bullocks, its edge is still like new. For at
    the joints there are always intestines, and insert a blade
    without thickness into the intestine leaves plenty of room
    for the blade to move about.

    Nevertheless, when I come upon a knotty part which is
    difficult to tackle, I am all caution. Fixing my eyes on
    it, I stay my hand and gently apply my blade, until the
    part yields like earth crumbling to the ground. Then I
    take out my chopper and stand up, look around, and pause
    with an air of triumph. Then wiping my chopper, I put it
    carefully away."

    "Bravo!" cried the Prince. "From the words of this cook I
    have now learned how to take care of my life."«

    http://www.networkchinese.com/others/note_sub6.html
     
    Stefan Ram, May 20, 2008
    #2
    1. Advertising

  3. pek

    Tom Anderson Guest

    On Tue, 20 May 2008, pek wrote:

    > Say you have a class that holds a set of cards. When a card is added it
    > has to obey certain rules. For example, if it is full and no other cards
    > can be added, an exception should be thrown. If the card is not the
    > correct suite, again, an exception should be thrown etc.


    Tiny comment: the word is 'suit', like a set of clothes, not 'suite'. I'm
    guessing english is not your first language - although this is the only
    error i noticed in your post!

    > Now, depending on the options of the game, some rules apply and some
    > don't. So clearly, the rules aren't inside the class itself, but they
    > are added by the engine using an addRule method. So I thought that I
    > could create an interface called Rule with a method called addCard. The
    > class holds a list of rules and every time a card is added it calls them
    > in the added order.


    Okay. Firstly, you have two different kinds of rules here. The first kind
    is a permissibility rule: it says whether a card can be added to a house
    or not. The second kind is an action rule: it says that when a certain
    situation comes to pass, something should happen.

    I wouldn't try and handle both kinds of rule within one framework myself.
    I'd deal with permissibility and action rules separately.

    If your only permissibility rules are about matching suit and not
    exceeding 31 points, i don't think i'd reify these. I'd just write two
    guard clauses at the top of House.addCard to check for those conditions
    and throw an exception if they apply. If there are further permissibility
    rules, or if they can change (say between variants of the game), i'd
    reify.

    (Incidentally, are people familiar with the term 'reify'? It's an old OO
    term, but one that seems not to be used much these days - it simply means
    to make something into an object.)

    The second kind of rule, i would reify, since there are quite a few of
    them.

    > But, in order for this to work, I found two problems: A) the class that
    > implements the Rule has to have a lot of information (the list of cards,
    > if it is already closed etc.). How do I work around this? Should the
    > method of the interface have a list of the needed information in
    > parameters? Should the class pass itself in all rules and provide
    > getters for all attributes?


    That's what i'd do:

    public interface Rule {
    public int apply(House house) ;
    }

    Specifically, i wouldn't have rules apply to cards, but to houses. When
    you add a card, you're not going to each rule and asking it what it thinks
    of that card, you're really saying "here's the state of the house - is
    there anything you want to do?". A rule could then use getters on the
    House to examine it, and mutators to make any changes; it would return the
    number of points awarded. House then looks like:

    public class House {
    public static final int MAX_POINTS = 31 ;

    private Set<Card> cards ;
    private List<Rule> rules ; // shared with other houses
    private Suit suit ;
    private int points ;

    public int addCard(Card card) throws CardException {
    if (points > MAX_POINTS) throw new HouseClosedException(this) ;
    if (suit != null)
    if (card.suit() != suit) throw new WrongSuitException(card, this) ;
    else suit = card.suit() ;
    cards.add(card) ;
    points += card.points() ;
    int score = 0 ;
    for (Rule rule : rules)
    score += rule.apply(this) ;
    return score ;
    }
    public int getPoints() {
    return points ;
    }
    public int numCards() {
    return cards.size() ;
    }
    public Suit getSuit() {
    return suit ;
    }
    public boolean hasCard(Card card) {
    return cards.contains(card) ;
    }
    public void empty() {
    cards.clear() ;
    suit = null ;
    points = 0 ;
    }
    }

    And the rules:

    public class ThirtyOnePointRule implements Rule {
    public int apply(House house) {
    if (house.getPoints() == House.MAX_POINTS) {
    house.empty() ;
    return 20 ;
    }
    return 0 ;
    }
    }

    public class SixCardRule implements Rule {
    public int apply(House house) {
    if (house.numCards() == 6) {
    house.empty() ;
    return 50 ;
    }
    return 0 ;
    }
    }

    public class JokerRule implements Rule {
    public int apply(House house) {
    if (house.hasCard(house.getSuit().JOKER)) {
    house.empty() ;
    return 50 ;
    }
    return 0 ;
    }
    }

    I leave Card and Suit to your imagination. They aren't complicated.

    > B) because different rules have different reactions, I also create a
    > Listener for that class. Every time something important happens, the
    > registered listeners get informed. But I have no idea how the class that
    > implements the Rule can inform the other class to fire an event to the
    > registered listeners.


    I'm not sure that a listener mechanism is the right way to do this. Who
    are the listeners? Is it just the GUI? Can rules trigger other rules?

    If there's only one listener, then a listener mechanism is probably
    overkill. Instead, if you need to present a list of which rules have
    applied, i'd modify House.addCard so that it builds up a List<Rule> of
    rules which were applied, and returns those to the caller, which will be
    the GUI.

    In fact, i'd refactor my above design. I'd add a method int score() to
    Rule, which gives the number of points that rule is worth, and a String
    name(), which gives the rule's description (eg "house reached 31 points").
    I'd modify Rule.apply to return a boolean, simply indicating whether that
    rule applies. In House.addCard, rather than adding up a score, i'd just
    build a List<Rule> of rules which applied (ie returned true from
    Rule.apply), and return that instead of a score. In the GUI, or some kind
    of controller object, i'd then iterate over the list of rules, printing
    out the rule's description and score, and totalling up the score as it
    went. This not only separates presentation from game logic, but card
    movement from scoring logic!

    > b) each house is of a particular suite. If a joker of the same suite
    > (the jokers have suites in this game) is added, any card in the house
    > are erased and the player wins 50 points in his total score. But if it
    > doesn't the game is over.


    If it doesn't what?

    > Now, the rule with the six cards fires an event to the listeners that
    > the rule was satisfied. One of the listeners is the GUI and it reacts
    > by displaying information. The same thing goes for the 31 points rule
    > and any rule that others need to know about.
    >
    > These are events that are fired and listeners react to. But these also
    > are the rules for the house.
    >
    > So everything comes down to design decision. Because the rules vary,
    > and could be expanded, they need to be outside of the House. And
    > because the events depend on the rules, there has to be a bridge
    > between them.


    I think you should closely examine the idea that you need an event
    mechanism. If you can remove that, you remove a lot of complexity.

    tom

    --
    see im down wid yo sci fi crew
     
    Tom Anderson, May 21, 2008
    #3
  4. pek

    pek Guest

    On May 21, 12:50 am, "Peter Duniho" <>
    wrote:
    > On Tue, 20 May 2008 14:25:22 -0700, pek <> wrote:
    > > I am currently developing the House Of Cards card game (I can't seem
    > > to find any relative info on the internet), but it doesn't really
    > > matter. My problem is a design problem.

    >
    > > Say you have a class that holds a set of cards. When a card is added
    > > it has to obey certain rules. For example, if it is full and no other
    > > cards can be added, an exception should be thrown. If the card is not
    > > the correct suite, again, an exception should be thrown etc.

    >
    > > Now, depending on the options of the game, some rules apply and some
    > > don't. So clearly, the rules aren't inside the class itself, but they
    > > are added by the engine using an addRule method.

    >
    > I don't know about the "clearly" part...no doubt someone could come up
    > with a design in which the card container (the "House") actually knows all
    > the rules and handles them accordingly. :)
    >

    Yeap, you're right. Someone could actually hard code the Rules in the
    House class. But personally I try to abstract things as much as
    possible. And detaching the rules is "clearly" a step of
    scalability. ;)

    > > So I thought that I
    > > could create an interface called Rule with a method called addCard.
    > > The class holds a list of rules and every time a card is added it
    > > calls them in the added order.

    >
    > I think you're on the right track, but instead of the Rule interface
    > having a specific method to be called, I think you could abstract further
    > by having your Rule interface implementation implement a listener
    > interface, and add itself as a listener to the container class to be
    > notified of changes to the container state.
    >
    > You could do it the other way, but if you're going to go for the
    > listener-driven API, why not go whole-hog? :)
    >
    > > But, in order for this to work, I found two problems:
    > > A) the class that implements the Rule has to have a lot of information
    > > (the list of cards, if it is already closed etc.). How do I work
    > > around this? Should the method of the interface have a list of the
    > > needed information in parameters? Should the class pass itself in all
    > > rules and provide getters for all attributes?

    >
    > It seems to me that the rule interface should _be_ a listener for the
    > container's listener interface, and provide a listener interface for
    > monitoring changes in the rule-centric state of the game.
    >
    > Then, you'd create the container, create one or more rules that are added
    > to the container as listeners, and then attach your GUI to the rules as
    > listeners, and optionally also to the container (if you want to present to
    > the user container state as well as rule state...which seems like a
    > natural thing to do).
    >
    > The container's listener interface could as simple as "hey, the container
    > state changed" and then let the listeners query the container for its
    > current state. Alternatively, the listener interface could report exactly
    > what change happened. If you want to get really fancy, you could have the
    > listener interface manage things like thresholds for certain state
    > changes. For example, the container could have an "add listener" method
    > that also takes a point threshold so that the listener is only notified
    > when the points in the container meet the threshold requirement.
    >
    > The container would provide methods for managing its state, such as adding
    > a card, emptying the container, closing the container, etc. Rule
    > implementations would use these methods to manage their own reactions to
    > the events that occur. Of course, you need some mechanism for dealing
    > with conflicts between rule implementations; it's not clear from your post
    > how this would be dealt with, though you seem to imply that you could have
    > multiple rule implementations attached at any given moment.
    >


    OK.. I think I understand some things here. I won't be fancy, so
    threshold is a little overkill (although I did like the idea). What I
    see problematic here is this:
    class House {
    ...
    public void addCard(Card card) {
    // do some things, or probably nothing because the rules would
    take care of it
    ...
    // inform listeners
    for (HouseListener lstnr : listeners) {
    lstnr.cardAdded(this, card);
    }
    }
    ...
    }
    class SixCardsRule implements HouseListener {
    ...
    public void cardAdded(House house, Card card) {
    if ( house.getCards().size() == 5 ) {
    // then adding this card satisfies this Rule. So,
    house.setCards(new ArrayList<Card>());
    // Now notify everyone. The 50 is for the score to be added
    for (RuleListener lstnrs : listeners) {
    lstnrs.ruleSatisfied("Six cards in total",50);
    }
    }
    }
    ...
    }

    Does this look OK? Because I think it does, although I think that
    adding the score to the RuleListener is a little odd. What if nobody
    is listening and the score isn't added anywhere? What if the rule,
    although satisfied, has nothing to do with scoring?
    :S
    Am I complicating things more than they should be or is it my idea?

    > > B) because different rules have different reactions, I also create a
    > > Listener for that class. Every time something important happens, the
    > > registered listeners get informed. But I have no idea how the class
    > > that implements the Rule can inform the other class to fire an event
    > > to the registered listeners.

    >
    > It seems to me that the rule implementation simply manages the container
    > state as appropriate, and the container provides the appropriate listener
    > interface so that listeners can be notified of changes to the container.
    > The classes that implement the rule interface don't so much "inform" the
    > container to "fire an event" as they simply do what they need to do to the
    > container, and the container itself recognizes the specific changes in
    > state that require notification to listeners added to the container.
    >
    > > Just in case I'm not clear at all, let me explain a little more.

    >
    > > The class I am talking about is called House. This holds a set of
    > > cards. A card has points depending on it's suite. The house can hold
    > > up to 31 points. When a card is added and the sum of the points are
    > > EXACTLY 31, the player wins 20 points in his total score and the house
    > > empties so cards can be added once again. If the sum of points exceed
    > > 31, the house closes and no more cards can be added. The game has four
    > > houses.

    >
    > > Those are the standard rules. Additionally:
    > > a) if a house has a total of six cards (not so common), the player
    > > wins 50 points in his total score and the house empties.

    >
    > What happens if the sixth card brings the total to exactly 31? How do you
    > decide which rule implementation deals with the points? Or does the
    > player get 70 points total in that case? (In which case there wouldn't be
    > a conflict).


    Great question! I have no idea! :S What do you suggest? I also find it
    easier to simply add 70 points, but finding a way to prioritize the
    rules sounds more challenging. Any suggestions?

    >
    > > b) each house is of a particular suite. If a joker of the same suite
    > > (the jokers have suites in this game) is added, any card in the house
    > > are erased and the player wins 50 points in his total score. But if it
    > > doesn't the game is over.

    >
    > What's the difference between "any card in the house are erased" and "the
    > house empties"?

    Sorry for my english. It is the exact same thing. The list of cards in
    a house is simply emptied in both cases.

    > How does the game end other than adding a joker of the
    > wrong suit to a house?

    The game starts with a standard 52 card deck and 4 jokers. So it also
    ends when there are no other cards to deal.

    > Is it possible for this other game-ending
    > condition to occur at the same time a joker of the correct suit is added
    > to a house?
    > And similar to above, what happens if a joker rule is
    > satisfied at the same time as another (adding up to 31 points, reaching
    > six cards)?

    The joker never stays in a house. Either the game is over or the house
    is cleared and no cards are left (adding 50 to the score).

    Great questions by the way! Very good feedback! That's more than I
    expected! Thank you for this too ;)

    >
    > > Now, the rule with the six cards fires an event to the listeners that
    > > the rule was satisfied. One of the listeners is the GUI and it reacts
    > > by displaying information. The same thing goes for the 31 points rule
    > > and any rule that others need to know about.

    >
    > > These are events that are fired and listeners react to. But these also
    > > are the rules for the house.

    >
    > > So everything comes down to design decision. Because the rules vary,
    > > and could be expanded, they need to be outside of the House. And
    > > because the events depend on the rules, there has to be a bridge
    > > between them.

    >
    > It seems to me that you need a way of managing multiple controllers of the
    > house container class, to impose some structure on the precedence of
    > operations and of rules. Once you do that, then the "rules for the house"
    > are really just operations that the rule implementations perform based on
    > events raised by the container. That'd then be your bridge right there.
    >
    > Pete


    So what do you think about the code I posted previously with the
    Listeners? Am I doing it OK?

    Thank you very much for your help!
     
    pek, May 22, 2008
    #4
  5. pek

    pek Guest

    On May 21, 4:40 am, Tom Anderson <> wrote:
    > On Tue, 20 May 2008, pek wrote:
    > > Say you have a class that holds a set of cards. When a card is added it
    > > has to obey certain rules. For example, if it is full and no other cards
    > > can be added, an exception should be thrown. If the card is not the
    > > correct suite, again, an exception should be thrown etc.

    >
    > Tiny comment: the word is 'suit', like a set of clothes, not 'suite'. I'm
    > guessing english is not your first language - although this is the only
    > error i noticed in your post!

    Thank you for pointing it out so politely. ;) I'm from Greece, so
    indeed, my first language isn't English.

    >
    > > Now, depending on the options of the game, some rules apply and some
    > > don't. So clearly, the rules aren't inside the class itself, but they
    > > are added by the engine using an addRule method. So I thought that I
    > > could create an interface called Rule with a method called addCard. The
    > > class holds a list of rules and every time a card is added it calls them
    > > in the added order.

    >
    > Okay. Firstly, you have two different kinds of rules here. The first kind
    > is a permissibility rule: it says whether a card can be added to a house
    > or not. The second kind is an action rule: it says that when a certain
    > situation comes to pass, something should happen.
    >
    > I wouldn't try and handle both kinds of rule within one framework myself.
    > I'd deal with permissibility and action rules separately.

    Hmmm.. Good idea! I'll do that! So by now I have two types of
    interfaces: PermissibilityHouseRule and ActionHouseRule. Stupid
    question: Are they any way inherited by a HouseRule interface?
    Although I can't find any reason why, I feel it could be.

    >
    > If your only permissibility rules are about matching suit and not
    > exceeding 31 points, i don't think i'd reify these. I'd just write two
    > guard clauses at the top of House.addCard to check for those conditions
    > and throw an exception if they apply. If there are further permissibility
    > rules, or if they can change (say between variants of the game), i'd
    > reify.


    I'm probably gonna add more and more permissibility rules, so I'll
    reify.
    >
    > (Incidentally, are people familiar with the term 'reify'? It's an old OO
    > term, but one that seems not to be used much these days - it simply means
    > to make something into an object.)

    Nope. Never heard of! Nice to know though! Thanks for sharing. ;)

    >
    > The second kind of rule, i would reify, since there are quite a few of
    > them.
    >
    > > But, in order for this to work, I found two problems: A) the class that
    > > implements the Rule has to have a lot of information (the list of cards,
    > > if it is already closed etc.). How do I work around this? Should the
    > > method of the interface have a list of the needed information in
    > > parameters? Should the class pass itself in all rules and provide
    > > getters for all attributes?

    >
    > That's what i'd do:
    >
    > public interface Rule {
    > public int apply(House house) ;
    >
    > }
    >
    > Specifically, i wouldn't have rules apply to cards, but to houses. When
    > you add a card, you're not going to each rule and asking it what it thinks
    > of that card, you're really saying "here's the state of the house - is
    > there anything you want to do?". A rule could then use getters on the
    > House to examine it, and mutators to make any changes; it would return the
    > number of points awarded. House then looks like:
    >
    > public class House {
    > public static final int MAX_POINTS = 31 ;
    >
    > private Set<Card> cards ;
    > private List<Rule> rules ; // shared with other houses
    > private Suit suit ;
    > private int points ;
    >


    > public int addCard(Card card) throws CardException {
    > if (points > MAX_POINTS) throw new HouseClosedException(this) ;
    > if (suit != null)
    > if (card.suit() != suit) throw new WrongSuitException(card, this) ;
    > else suit = card.suit() ;
    > cards.add(card) ;
    > points += card.points() ;
    > int score = 0 ;
    > for (Rule rule : rules)
    > score += rule.apply(this) ;
    > return score ;
    > }
    > public int getPoints() {
    > return points ;
    > }
    > public int numCards() {
    > return cards.size() ;
    > }
    > public Suit getSuit() {
    > return suit ;
    > }
    > public boolean hasCard(Card card) {
    > return cards.contains(card) ;
    > }
    > public void empty() {
    > cards.clear() ;
    > suit = null ;
    > points = 0 ;
    > }
    >
    > }
    >
    > And the rules:
    >
    > public class ThirtyOnePointRule implements Rule {
    > public int apply(House house) {
    > if (house.getPoints() == House.MAX_POINTS) {
    > house.empty() ;
    > return 20 ;
    > }
    > return 0 ;
    > }
    >
    > }
    >
    > public class SixCardRule implements Rule {
    > public int apply(House house) {
    > if (house.numCards() == 6) {
    > house.empty() ;
    > return 50 ;
    > }
    > return 0 ;
    > }
    >
    > }
    >
    > public class JokerRule implements Rule {
    > public int apply(House house) {
    > if (house.hasCard(house.getSuit().JOKER)) {
    > house.empty() ;
    > return 50 ;
    > }
    > return 0 ;
    > }
    >
    > }
    >
    > I leave Card and Suit to your imagination. They aren't complicated.
    >
    > > B) because different rules have different reactions, I also create a
    > > Listener for that class. Every time something important happens, the
    > > registered listeners get informed. But I have no idea how the class that
    > > implements the Rule can inform the other class to fire an event to the
    > > registered listeners.

    >
    > I'm not sure that a listener mechanism is the right way to do this. Who
    > are the listeners? Is it just the GUI? Can rules trigger other rules?
    >
    > If there's only one listener, then a listener mechanism is probably
    > overkill. Instead, if you need to present a list of which rules have
    > applied, i'd modify House.addCard so that it builds up a List<Rule> of
    > rules which were applied, and returns those to the caller, which will be
    > the GUI.
    >
    > In fact, i'd refactor my above design. I'd add a method int score() to
    > Rule, which gives the number of points that rule is worth, and a String
    > name(), which gives the rule's description (eg "house reached 31 points").
    > I'd modify Rule.apply to return a boolean, simply indicating whether that
    > rule applies. In House.addCard, rather than adding up a score, i'd just
    > build a List<Rule> of rules which applied (ie returned true from
    > Rule.apply), and return that instead of a score. In the GUI, or some kind
    > of controller object, i'd then iterate over the list of rules, printing
    > out the rule's description and score, and totalling up the score as it
    > went. This not only separates presentation from game logic, but card
    > movement from scoring logic!
    >
    > > b) each house is of a particular suite. If a joker of the same suite
    > > (the jokers have suites in this game) is added, any card in the house
    > > are erased and the player wins 50 points in his total score. But if it
    > > doesn't the game is over.

    >
    > If it doesn't what?
    >
    > > Now, the rule with the six cards fires an event to the listeners that
    > > the rule was satisfied. One of the listeners is the GUI and it reacts
    > > by displaying information. The same thing goes for the 31 points rule
    > > and any rule that others need to know about.

    >
    > > These are events that are fired and listeners react to. But these also
    > > are the rules for the house.

    >
    > > So everything comes down to design decision. Because the rules vary,
    > > and could be expanded, they need to be outside of the House. And
    > > because the events depend on the rules, there has to be a bridge
    > > between them.

    >
    > I think you should closely examine the idea that you need an event
    > mechanism. If you can remove that, you remove a lot of complexity.
    >
    > tom
    >
    > --
    > see im down wid yo sci fi crew


    This whole implementation sounds like a great and easy idea. But I
    have one question. What if an ActionHouseRule ends the game? Like in
    the case of the Joker:
    If a Joker of Spades is enter in a House of Hearts, the game is over.
    If a Joker of Spades is added to a House of Spades, then the cards in
    the house are emptied and the player gains points.
    This isn't a permissibility rule, and there is case where the game is
    over. So how do I implement the game over?

    Thank you for your time.
     
    pek, May 22, 2008
    #5
  6. pek

    Tom Anderson Guest

    On Thu, 22 May 2008, pek wrote:

    > On May 21, 4:40 am, Tom Anderson <> wrote:
    >> On Tue, 20 May 2008, pek wrote:
    >>> If the card is not the correct suite

    >>
    >> Tiny comment: the word is 'suit', like a set of clothes, not 'suite'.
    >> I'm guessing english is not your first language - although this is the
    >> only error i noticed in your post!

    >
    > Thank you for pointing it out so politely. ;) I'm from Greece, so
    > indeed, my first language isn't English.


    Aha. I thought someone whose english was as good as yours would appreciate
    an opportunity to improve it even further, even if only in a small way!

    >>> Now, depending on the options of the game, some rules apply and some
    >>> don't. So clearly, the rules aren't inside the class itself, but they
    >>> are added by the engine using an addRule method.

    >>
    >> Okay. Firstly, you have two different kinds of rules here. The first kind
    >> is a permissibility rule: it says whether a card can be added to a house
    >> or not. The second kind is an action rule: it says that when a certain
    >> situation comes to pass, something should happen.
    >>
    >> I wouldn't try and handle both kinds of rule within one framework myself.
    >> I'd deal with permissibility and action rules separately.

    >
    > Hmmm.. Good idea! I'll do that! So by now I have two types of
    > interfaces: PermissibilityHouseRule and ActionHouseRule. Stupid
    > question: Are they any way inherited by a HouseRule interface? Although
    > I can't find any reason why, I feel it could be.


    Trust your feelings! It doesn't do any harm to inherit them from a common
    interface, and it helps to document the code.

    Also, both kinds of rules will need a getName() or getDescription()
    method, so you can declare that in the root interface.

    >> (Incidentally, are people familiar with the term 'reify'? It's an old OO
    >> term, but one that seems not to be used much these days - it simply means
    >> to make something into an object.)

    >
    > Nope. Never heard of! Nice to know though! Thanks for sharing. ;)


    No problem. I'm sorry it's from a latin root, and not greek!

    > This whole implementation sounds like a great and easy idea. But I
    > have one question. What if an ActionHouseRule ends the game? Like in
    > the case of the Joker:
    > If a Joker of Spades is enter in a House of Hearts, the game is over.
    > If a Joker of Spades is added to a House of Spades, then the cards in
    > the house are emptied and the player gains points.
    > This isn't a permissibility rule, and there is case where the game is
    > over. So how do I implement the game over?


    I'd add a method to the ActionRule interface through which a rule can
    indicate it ends the game. This is after applying the refactoring i
    mention, so the interface looks like:

    interface ActionRule extends Rule {
    public String description() ;
    public boolean endsGame() ;
    public int score() ;
    public boolean applies(House h) ;
    }

    With the addCard looking like:

    public List<Rule> addCard(Card card) {
    // do permissibility checks here - i omit them
    List<ActionRule> applied = new ArrayList<ActionRule> ;
    for (Rule rule: rules) {
    if (rule.apply(this)) applied.add(rule) ;
    }
    return applied ;
    }

    And the game controller having code like:

    List<Rule> applied = house.addCard(card) ;
    for (Rule rule : applied) {
    if (rule.endsGame()) {
    tellUser("GAME OVER: " + rule.description() + "!") ;
    gameOver = true ;
    }
    else
    tellUser("rule applied: " + rule.description() + "; scored " + rule.score()) ;
    score += rule.score() ;
    }
    tellUser("total score: " + score) ;
    }

    But if there's a permissibility rule that says you can't put a card in a
    house whose suit doesn't match, how can you get to the situation where you
    put a joker of spades in a house of hearts?

    tom

    --
    :-( bad :) bad :-| good
     
    Tom Anderson, May 23, 2008
    #6
  7. pek

    Tom Anderson Guest

    On Thu, 22 May 2008, Peter Duniho wrote:

    > I think ultimately I'd go with _some_ variation on this last approach
    > (that is, the one where the Rule supports listeners for events separated
    > into appropriate categories, whether in the same interface or in two or
    > more), but any of the above would probably work (including what you
    > posted, if you really want to do it that way).


    I'm thinking having a list of listeners on each Rule is overkill - are
    there ever cases where you'd want to listen to one Rule but not others?
    How about putting the listeners on the House, and having the rule call a
    method on the House which gets it to dispatch the event? You might even
    want the listeners to be on the Game object.

    tom

    --
    :-( bad :) bad :-| good
     
    Tom Anderson, May 23, 2008
    #7
  8. pek

    pek Guest

    On May 23, 12:17 am, "Peter Duniho" <>
    wrote:
    > On Thu, 22 May 2008 13:28:37 -0700, pek <> wrote:
    > > [...]
    > > OK.. I think I understand some things here. I won't be fancy, so
    > > threshold is a little overkill (although I did like the idea). What I
    > > see problematic here is this:
    > > class House {
    > > ...
    > > public void addCard(Card card) {
    > > // do some things, or probably nothing because the rules would
    > > take care of it
    > > ...
    > > // inform listeners
    > > for (HouseListener lstnr : listeners) {
    > > lstnr.cardAdded(this, card);
    > > }
    > > }
    > > ...
    > > }

    >
    > That part seems fine, as far as it goes.
    >
    > > class SixCardsRule implements HouseListener {
    > > ...
    > > public void cardAdded(House house, Card card) {
    > > if ( house.getCards().size() == 5 ) {
    > > // then adding this card satisfies this Rule. So,
    > > house.setCards(new ArrayList<Card>());
    > > // Now notify everyone. The 50 is for the score to be added
    > > for (RuleListener lstnrs : listeners) {
    > > lstnrs.ruleSatisfied("Six cards in total",50);
    > > }
    > > }
    > > }
    > > ...
    > > }

    >
    > This part I'm not so sure of.
    >
    > Without seeing your whole architecture, it's hard to say for sure. But it
    > seems to me that someone other than the Rule should be maintaining the
    > score. I'm not sure if this is the House, or if you have some other class
    > that's the entire Game. But it seems to me that the Rule should not
    > necessarily be raising score-change events itself, but rather should be
    > calling some method somewhere that adds 50 points to the score. Objects
    > that need to be notified of score changes would be attached as a listener
    > to _that_ object.
    >

    Correct, I forgot to mention that indeed I do have a different class
    that handles the game logic called Engine. It contains an int for the
    game's score.

    > Now, if you _also_ want to provide for notification of when a specific
    > rule is satisfied, your Rules could allow those listeners to be added.
    > And they would be notified much as you show above. Except that the score
    > would not necessarily be part of the method parameters, at least not in my
    > view.
    >
    > Alternatively, if you _do_ want the Rule notifications to include the
    > score, then either _all_ rule-satisfying conditions should affect the
    > score, or you need to expand your RuleListener interface so that there are
    > different methods, some of which include a point total to be added to the
    > score, and others that don't. Or perhaps you provide just one method in
    > the interface that is the "score changed" notification", and that's sent
    > separately from other notifications, like "rule satisfied".
    >
    > Any of these could work. Which is "best" is hard to say. For my tastes,
    > I'd prefer either the first suggestion or the last. If you intend for
    > there only to ever be a single scoring object, then the first might be
    > more appropriate. Then each Rule would have to know which object was that
    > single scoring object and would directly call a method on that object to
    > update the score.
    >
    > On the other hand, if you want your design to be more flexible, such that
    > you can have multiple scorers present, then it probably makes more sense
    > for the Rules to use the RuleListener interface to report score changes.
    > Each scoring object can then subscribe as appropriate to the rules
    > relevant for that scoring object.
    >

    I am thinking about implementing online support, but currently I'll
    stick to the single player. I think I don't have time. I'll keep this
    in mind though.

    > As an example of this, consider something like (following your previous
    > listener interface pattern...you may want to consider instead following
    > the usual Java model, where an "Event" class is defined that includes all
    > of the relevant data, including the source and the specifics of the event):
    >
    > public interface RuleListener
    > {
    > void ruleSatisfied(Rule sender, string ruleName);
    > void scoreChange(Rule sender, int points);
    > }
    >

    This sounds interesting. I'll totally give it a try.

    > Then scoring objects can subscribe to the Rules as needed, and the UI and
    > other interested objects can also subscribe. If it turns out that there's
    > little or no overlap between these two types of subscribers, you might
    > even break the interface into two, with one interface dedicated to things
    > that are just "activity notification" sorts of things, and the other
    > dedicated to things that actually change the game state. Often one event
    > from each might be raised, but only objects of the appropriate
    > functionality would subscribe to the specific listener group. That way
    > you don't waste a lot of time having, for example, having UI objects
    > receiving and ignoring notifications for game state changes, and having
    > game state objects receiving and ignoring notifications for UI events.
    >

    Yes, there should be two types of interfaces.

    > I think ultimately I'd go with _some_ variation on this last approach
    > (that is, the one where the Rule supports listeners for events separated
    > into appropriate categories, whether in the same interface or in two or
    > more), but any of the above would probably work (including what you
    > posted, if you really want to do it that way).
    >
    > By the way, I'm not sure that the House should expose the collection
    > implementation. That is, rather than a "setCards" method that takes the
    > actual collection, it probably makes more sense to have a "clearCards"
    > method that resets the internal implementaton. If you really need a way
    > to add or set multiple cards at once from a non-empty collection, you
    > could still have a more general-purpose method that takes a List<Card>
    > instead of some specific collection type.


    Yeap, I totally agree. I added clearCards().
    >
    > Pete
     
    pek, May 23, 2008
    #8
  9. pek

    pek Guest

    On May 23, 3:40 am, Tom Anderson <> wrote:
    > On Thu, 22 May 2008, pek wrote:
    > > On May 21, 4:40 am, Tom Anderson <> wrote:
    > >> On Tue, 20 May 2008, pek wrote:
    > >>> If the card is not the correct suite

    >
    > >> Tiny comment: the word is 'suit', like a set of clothes, not 'suite'.
    > >> I'm guessing english is not your first language - although this is the
    > >> only error i noticed in your post!

    >
    > > Thank you for pointing it out so politely. ;) I'm from Greece, so
    > > indeed, my first language isn't English.

    >
    > Aha. I thought someone whose english was as good as yours would appreciate
    > an opportunity to improve it even further, even if only in a small way!
    >

    Thank you (again). ;) Well, what really annoys is when people take for
    granted that English is the only language on earth and if you make a
    mistake your retarded. That's why I liked it when you said "I'm
    guessing english is not your first language". ;)

    >
    >
    > >>> Now, depending on the options of the game, some rules apply and some
    > >>> don't. So clearly, the rules aren't inside the class itself, but they
    > >>> are added by the engine using an addRule method.

    >
    > >> Okay. Firstly, you have two different kinds of rules here. The first kind
    > >> is a permissibility rule: it says whether a card can be added to a house
    > >> or not. The second kind is an action rule: it says that when a certain
    > >> situation comes to pass, something should happen.

    >
    > >> I wouldn't try and handle both kinds of rule within one framework myself.
    > >> I'd deal with permissibility and action rules separately.

    >
    > > Hmmm.. Good idea! I'll do that! So by now I have two types of
    > > interfaces: PermissibilityHouseRule and ActionHouseRule. Stupid
    > > question: Are they any way inherited by a HouseRule interface? Although
    > > I can't find any reason why, I feel it could be.

    >
    > Trust your feelings! It doesn't do any harm to inherit them from a common
    > interface, and it helps to document the code.
    >
    > Also, both kinds of rules will need a getName() or getDescription()
    > method, so you can declare that in the root interface.

    Great idea! ;)

    >
    > >> (Incidentally, are people familiar with the term 'reify'? It's an old OO
    > >> term, but one that seems not to be used much these days - it simply means
    > >> to make something into an object.)

    >
    > > Nope. Never heard of! Nice to know though! Thanks for sharing. ;)

    >
    > No problem. I'm sorry it's from a latin root, and not greek!
    >
    > > This whole implementation sounds like a great and easy idea. But I
    > > have one question. What if an ActionHouseRule ends the game? Like in
    > > the case of the Joker:
    > > If a Joker of Spades is enter in a House of Hearts, the game is over.
    > > If a Joker of Spades is added to a House of Spades, then the cards in
    > > the house are emptied and the player gains points.
    > > This isn't a permissibility rule, and there is case where the game is
    > > over. So how do I implement the game over?

    >
    > I'd add a method to the ActionRule interface through which a rule can
    > indicate it ends the game. This is after applying the refactoring i
    > mention, so the interface looks like:
    >
    > interface ActionRule extends Rule {
    > public String description() ;
    > public boolean endsGame() ;
    > public int score() ;
    > public boolean applies(House h) ;
    >
    > }
    >
    > With the addCard looking like:
    >
    > public List<Rule> addCard(Card card) {
    > // do permissibility checks here - i omit them
    > List<ActionRule> applied = new ArrayList<ActionRule> ;
    > for (Rule rule: rules) {
    > if (rule.apply(this)) applied.add(rule) ;
    > }
    > return applied ;
    >
    > }
    >
    > And the game controller having code like:
    >
    > List<Rule> applied = house.addCard(card) ;
    > for (Rule rule : applied) {
    > if (rule.endsGame()) {
    > tellUser("GAME OVER: " + rule.description() + "!") ;
    > gameOver = true ;
    > }
    > else
    > tellUser("rule applied: " + rule.description() + "; scored " + rule.score()) ;
    > score += rule.score() ;
    > }
    > tellUser("total score: " + score) ;
    >
    > }
    >

    That sounds really good! I'll definitely try this.

    > But if there's a permissibility rule that says you can't put a card in a
    > house whose suit doesn't match, how can you get to the situation where you
    > put a joker of spades in a house of hearts?

    First, the rule that looks for wrong suit in a house can first look if
    it is a joker card and permit it to be added.
    Then the Rule would look something like this:
    class JokerRule implements ActionRule {
    private boolean gameOver = false;
    private int score = 0;

    public String description() { return "Joker Rule"; }
    public boolean endsGame() { return gameOver; }
    public int score() { return score; }
    public boolean applies(House h) {
    Card tmp = house.getCards().get( house.getCards().size() -
    1 );
    if ( tmp.getRank() == CardRank.JOKER ) {
    if ( tmp.getSuit() == house.getSuit() )
    house.emptyCards();
    this.score = 50;
    } else {
    this.gameOver = true;
    }
    }

    }

    What do you think?
    >
    > tom
    >
    > --
    > :-( bad :) bad :-| good
     
    pek, May 23, 2008
    #9
  10. pek

    pek Guest

    On May 23, 4:48 am, "Peter Duniho" <>
    wrote:
    > On Thu, 22 May 2008 18:38:22 -0700, Peter Duniho
    >
    > <> wrote:
    > >>> I think ultimately I'd go with _some_ variation on this last approach
    > >>> (that is, the one where the Rule supports listeners for events
    > >>> separated into appropriate categories, whether in the same interface
    > >>> or in two or more), but any of the above would probably work
    > >>> (including what you posted, if you really want to do it that way).

    >
    > >> I'm thinking having a list of listeners on each Rule is overkill - are
    > >> there ever cases where you'd want to listen to one Rule but not others?

    >
    > > Hard to say. I'm not the OP and so it's difficult for me to comment
    > > what must or must not be characteristic of his ultimate implementation.
    > > But I'm not sure I see much of a downside.

    >
    > Sorry, I sort of got distracted by one part of the question, and ignored
    > another part.
    >
    > In particular, at least part of what I'm thinking of in the above is the
    > possibility that at least some of the RuleListener interface(s) are there
    > to support UI. In that respect, I definitely can see how some of the UI
    > would want to subscribe to only some subset of the rules, assuming that
    > part of the UI only presents information about that subset.
    >
    > But this all depends on the exact way that the members of the RuleListener
    > interface(s) are defined, as well as how the rest of the program is
    > modularized (I'm mainly thinking UI here, but there could be other aspects
    > as well for all I know).
    >
    > One crazy example: suppose we want to be able to run multiple games at
    > once with the same set of cards. I don't know if this is even possible,
    > given that some rule-based actions can affect the "houses" of cards, and
    > so at first blush it seems like it's not possible for the rules to be
    > treated as mutually independent. But let's say it is. :) Then, you
    > could have multiple UI presentations, one for each actual game, all hooked
    > to the same collection of cards.
    >
    > A less crazy example: you've got "lights" in the UI that blink,
    > illuminate, or otherwise indicate to the user what happens based on the
    > rules interpretations. They just want to show when specific actions in
    > specific rules are triggered. Well, inasmuch as some actions are unique
    > for a specific rule, there's no need for a UI component specific to a
    > given rule to need to be subscribed to every other rule as well.
    >
    > Again, all this depends a lot on details I don't have. I can't say for
    > sure what _is_ appropriate. I can only make suggestions as to what might
    > be appropriate. The OP will have to filter the advice and use only what's
    > applicable to his specific scenario. :)
    >
    > Pete


    OK, so I finally made it and it works........awesome! I mean, I
    practically jumped from my seat when it worked. Software development
    (along with it's design phase) is art! :p And it's all thanks to you
    two, Peter Duniho and Tom Anderson. I can't thank you enough.

    Here is what I did, in case you are wondering:

    I combined both of your architectures. The game has:
    A class Engine that controls all the logic of the game
    A class House that controls the House logic
    A class Main which is the GUI
    A class JHouse which is a wrapper JPanel for a House
    Two listeners for raising events (HouseListener and EngineListener)
    Two interfaces for the Rules (ActionRule and PermissionRule)
    And various Rules that implement them

    When the Main GUI starts, it initializes an Engine and adds itself as
    an EngineListener. Every action that the Engine does that results in a
    game state change, it notifies it's listeners. So the Main GUI updates
    it's components appropriately.

    When the game starts, the startNewGame method of the Engine is called
    from the Main GUI given some parameters for which rules should be
    applied. The Engine then adds those rules to each of the four Houses
    it creates and generally initializes the game state. Once finished
    initializing, it notifies the EngineListeners that there is a new
    game. The Main GUI (as an EngineListener) then initializes the
    components.

    It also initializes four JHouses with their appropriate House. The
    Main GUI then registers as a MouseListeners to each of them. That way,
    when a JHouse was clicked, it calls it's getHouse() method to obtain
    which House in the game it is and then calls the Engine to add the
    player's hand card to that house. The Engine simply obeys and doesn't
    care about the Rules (it only cares if the game hasn't started or if
    the player doesn't have a card etc.). The Engine is also a
    HouseListener, so when the state of a House changes (score, closed
    etc.) it gets informed to start calculating the general score of the
    game, if it ended etc.

    The best part of this architecture is that it is based on listeners
    and rules that practical do everything automatically. The Engine
    doesn't do any card checking when it needs to add it to the House, it
    just adds it. The House then runs all the rules and again doesn't care
    what happened. The Rules do all the work. Some close the House while
    others end the game. Either way, the Engine will get informed from the
    House that something changed and it will do the rest. Later on the
    Main GUI (as an EngineListener) is informed from the Engine that
    something has changed and changes the components appropriately.

    That's it! Simply and elegant! :p OK OK, I know, I am very happy with
    the results. Again, I can't thank you enough. I couldn't have thought
    any of these without your help. Hell, I didn't even know where to
    start, or how to implement a Rule architecture.

    Thanks again (and again and again...).

    Panagiotis Peikidis
     
    pek, May 25, 2008
    #10
  11. pek

    andreas Guest

    Why you complicate so much a so simple problem ?
    I think that you forgot analyze the problem before to proceed to
    design decisions, my advice is to model whole game (rules, stacks of
    cards etc) in a more abstracted way, e.g. forget about classes methods
    and all stuff specific to the particular programming language and
    attack the problem starting from its conceptual view, then apply any
    analysis technique you, divide and conquer or a la guerrilla warfare
    way. Anyways the objective is to make a crystal clear picture of your
    problem.

    My personal opinion is that most of card games can be modeled as
    states e.g. any combination of cards in various lists of cards (e.g.
    stack, closed, open etc) representing a particular state, the state
    may be valid or invalid one (this is where rules apply), in other
    words imagine rules as a function that has as it's domain any possible
    state of the game and the range true|false; this function validates if
    cards are in correct place.

    By applying the validation function on every change of the state (for
    example card put in specific stack) you can keep rules of the game in
    order.

    If you want to validate the state partially (maybe for speed reasons)
    you can brake up the domain in smaller parts and for each part apply
    function validating the part, again by applying validation piecewise
    all outcomes should be true in order to ensure the validity of whole
    game.

    Now let's see possible design in Java that will implement all the
    above. Abstractly. You have two parts (where each part may consist of
    many objects) :

    1. The state
    2. The Rules

    Let's suppose we have a class Rules providing a method

    bool validate(State)

    each time the state changes you give it to the validate() method and
    get a result if everything is ok or awry.
    If rules are correct and the State represents the domain clearly and
    correctly you have a bulletproof game.

    If you want to complicate things more you can apply more complex
    validation techniques (consult GoF book :)) but it seems there is no
    reason to complicate them in such problem.
     
    andreas, May 28, 2008
    #11
  12. pek

    pek Guest

    On May 28, 10:54 am, andreas <> wrote:
    > Why you complicate so much a so simple problem ?
    > I think that you forgot analyze the problem before to proceed to
    > design decisions, my advice is to model whole game (rules, stacks of
    > cards etc) in a more abstracted way, e.g. forget about classes methods
    > and all stuff specific to the particular programming language and
    > attack the problem starting from its conceptual view, then apply any
    > analysis technique you, divide and conquer or a la guerrilla warfare
    > way. Anyways the objective is to make a crystal clear picture of your
    > problem.
    >
    > My personal opinion is that most of card games can be modeled as
    > states e.g. any combination of cards in various lists of cards (e.g.
    > stack, closed, open etc) representing a particular state, the state
    > may be valid or invalid one (this is where rules apply), in other
    > words imagine rules as a function that has as it's domain any possible
    > state of the game and the range true|false; this function validates if
    > cards are in correct place.
    >
    > By applying the validation function on every change of the state (for
    > example card put in specific stack) you can keep rules of the game in
    > order.
    >
    > If you want to validate the state partially (maybe for speed reasons)
    > you can brake up the domain in smaller parts and for each part apply
    > function validating the part, again by applying validation piecewise
    > all outcomes should be true in order to ensure the validity of whole
    > game.
    >
    > Now let's see possible design in Java that will implement all the
    > above. Abstractly. You have two parts (where each part may consist of
    > many objects) :
    >
    > 1. The state
    > 2. The Rules
    >
    > Let's suppose we have a class Rules providing a method
    >
    > bool validate(State)
    >
    > each time the state changes you give it to the validate() method and
    > get a result if everything is ok or awry.
    > If rules are correct and the State represents the domain clearly and
    > correctly you have a bulletproof game.
    >
    > If you want to complicate things more you can apply more complex
    > validation techniques (consult GoF book :)) but it seems there is no
    > reason to complicate them in such problem.


    So, if I understood correctly, you are saying that House should add
    the card anyway, and then run all the rules. Each rule will examine
    the state of the house as it thinks and return true (if the state is
    ok or the rule doesn't make sense) or false (if the state is erroneous
    according to the rule).

    Is this correct? If yes, that means that the House will add the card
    first and then run the rules. If any rules reports an erroneous state,
    what will the house do? Will it remove the card and throw an exception?
     
    pek, May 28, 2008
    #12
  13. pek

    pek Guest

    On May 29, 12:53 am, pek <> wrote:
    > On May 28, 10:54 am, andreas <> wrote:
    >
    >
    >
    > > Why you complicate so much a so simple problem ?
    > > I think that you forgot analyze the problem before to proceed to
    > > design decisions, my advice is to model whole game (rules, stacks of
    > > cards etc) in a more abstracted way, e.g. forget about classes methods
    > > and all stuff specific to the particular programming language and
    > > attack the problem starting from its conceptual view, then apply any
    > > analysis technique you, divide and conquer or a la guerrilla warfare
    > > way. Anyways the objective is to make a crystal clear picture of your
    > > problem.

    >
    > > My personal opinion is that most of card games can be modeled as
    > > states e.g. any combination of cards in various lists of cards (e.g.
    > > stack, closed, open etc) representing a particular state, the state
    > > may be valid or invalid one (this is where rules apply), in other
    > > words imagine rules as a function that has as it's domain any possible
    > > state of the game and the range true|false; this function validates if
    > > cards are in correct place.

    >
    > > By applying the validation function on every change of the state (for
    > > example card put in specific stack) you can keep rules of the game in
    > > order.

    >
    > > If you want to validate the state partially (maybe for speed reasons)
    > > you can brake up the domain in smaller parts and for each part apply
    > > function validating the part, again by applying validation piecewise
    > > all outcomes should be true in order to ensure the validity of whole
    > > game.

    >
    > > Now let's see possible design in Java that will implement all the
    > > above. Abstractly. You have two parts (where each part may consist of
    > > many objects) :

    >
    > > 1. The state
    > > 2. The Rules

    >
    > > Let's suppose we have a class Rules providing a method

    >
    > > bool validate(State)

    >
    > > each time the state changes you give it to the validate() method and
    > > get a result if everything is ok or awry.
    > > If rules are correct and the State represents the domain clearly and
    > > correctly you have a bulletproof game.

    >
    > > If you want to complicate things more you can apply more complex
    > > validation techniques (consult GoF book :)) but it seems there is no
    > > reason to complicate them in such problem.

    >
    > So, if I understood correctly, you are saying that House should add
    > the card anyway, and then run all the rules. Each rule will examine
    > the state of the house as it thinks and return true (if the state is
    > ok or the rule doesn't make sense) or false (if the state is erroneous
    > according to the rule).
    >
    > Is this correct? If yes, that means that the House will add the card
    > first and then run the rules. If any rules reports an erroneous state,
    > what will the house do? Will it remove the card and throw an exception?


    In case anyone is wondering, I finished the game and uploaded it to my
    site. It's at http://treazy.com/apps/javacorner. The game is called
    House of Cards.

    Again, thank you for all your advises. I couldn't have done it without
    you.
     
    pek, May 29, 2008
    #13
  14. pek

    Tom Anderson Guest

    On Wed, 28 May 2008, andreas wrote:

    > Why you complicate so much a so simple problem ?
    >
    > [snip]


    Andreas, your suggestion is not only every bit as complicated as the
    solution Pek chose, it doesn't actually solve the problems his did!

    tom

    --
    It's almost over now.
     
    Tom Anderson, May 29, 2008
    #14
  15. pek

    pek Guest

    On May 29, 6:11 pm, Tom Anderson <> wrote:
    > On Wed, 28 May 2008, andreas wrote:
    > > Why you complicate so much a so simple problem ?

    >
    > > [snip]

    >
    > Andreas, your suggestion is not only every bit as complicated as the
    > solution Pek chose, it doesn't actually solve the problems his did!
    >
    > tom
    >
    > --
    > It's almost over now.


    One more thing before this discussion dies..
    Remember the Joker rule? If a joker enters a house with a different
    suit, the game is over, otherwise the cards in a house clear and the
    player gains points (in this game, jokers have suit). A house of cards
    can also close if the sum of card points in it exceeds 31 (each cards
    has a number of points). The player wins if he uses all 56 cards in
    the deck without losing. If you think about it, if a House closes and
    the joker with the same suit is still in the deck, eventually the
    player will lose. So it is pointless.

    Currently my system goes like this:
    The house has a list of rules which every time a card is going to be
    added, it runs them and gets the results (whether the card can enter,
    it reached 31 etc.). When a player wants to add a card to the house,
    he clicks a component in the GUI. The GUI then calls the engine to add
    the card in a house and the engine simply calls the corresponding
    house to add the card. In other words, the Engine (although it
    contains all the game logic - starts new games, checks for game over
    etc.) it doesn't care about entering a card in the house since the
    house has this functionality.

    Now, determining whether the deck contains a joker of a certain suit
    cannot be done in this system simply because the house isn't aware of
    such things as other houses or decks. The solution I can think is
    passing the rules responsibility to the Engine and leaving the House
    to be simply a data type. So then the Engine can check other houses
    etc.

    What do you think about this? Any comments/suggestions..?
     
    pek, Jun 3, 2008
    #15
  16. pek

    pek Guest

    On Jun 3, 9:20 pm, "Peter Duniho" <>
    wrote:
    > On Tue, 03 Jun 2008 03:54:21 -0700, pek <> wrote:
    > > [...]
    > > Now, determining whether the deck contains a joker of a certain suit
    > > cannot be done in this system simply because the house isn't aware of
    > > such things as other houses or decks. The solution I can think is
    > > passing the rules responsibility to the Engine and leaving the House
    > > to be simply a data type. So then the Engine can check other houses
    > > etc.

    >
    > > What do you think about this? Any comments/suggestions..?

    >
    > I'm not exactly clear on what "rules responsibility" means. Just because
    > a Rule has subscribed to a House's event, I don't see how that means that
    > the House is _responsible_ for the Rule per se.
    >
    > But yes, it seems to me that Rules are not a House-level construct, but
    > rather a whole game- (Engine-) level construct, and as such would have
    > access to all House instances, through the Engine. I would, in fact,
    > expect that the Engine is the class that's actually managing the Rule
    > instances, even as each Rule instance may have subscribed to multiple
    > House instances to receive events that affect game state, etc.
    >
    > Pete


    Yes, that where my thoughts exactly. Thanks for your feedback..
     
    pek, Jun 9, 2008
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. tubby

    Help with design decision

    tubby, Dec 2, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    353
    cbDevelopment
    Dec 4, 2005
  2. Marcus Reiter

    [JSP] Help with Design decision

    Marcus Reiter, Dec 29, 2004, in forum: Java
    Replies:
    1
    Views:
    415
    Ryan Stewart
    Dec 30, 2004
  3. Jeff Marder

    Feedback on a design decision?

    Jeff Marder, Oct 5, 2006, in forum: Java
    Replies:
    15
    Views:
    564
    Christopher Benson-Manica
    Oct 9, 2006
  4. __PPS__

    Class design decision

    __PPS__, Dec 7, 2006, in forum: C++
    Replies:
    5
    Views:
    340
  5. koranthala

    A Twisted Design Decision

    koranthala, Jan 27, 2009, in forum: Python
    Replies:
    0
    Views:
    245
    koranthala
    Jan 27, 2009
Loading...

Share This Page