Answer to Exercise 55

| ANSWER TO EXERCISE 55
| Firstly, a printing rule to print the state of coins. Coin-objects will have a property called `way_up` which is always either 1 or 2:
    [ Face x; if (x.way_up==1) print "Heads"; else print "Tails"; ];
There are two kinds of coin but we'll implement them with three classes: `Coin` and two sub-categories, `GoldCoin` and `SilverCoin`. Since the coins only join up into trigrams when present in groups of three, we need a routine to detect this:
    [ CoinsTogether cla i x y;
      objectloop (i ofclass cla)
      {   x=parent(i);
          if (y==0) y=x; else { if (x~=y) return 0; }
      }
      return y;
    ];
Thus `CoinsTogether(cla)` decides whether all objects of class `cla` are in the same place. (`cla` will always be either `GoldCoin` or `SilverCoin`.) We must now write the class definitions:
    Class  Coin
      with name "coin" "coins//p",
           way_up 1, article "the",
           after
           [; Drop, PutOn:
                 self.way_up = random(2); print (Face) self;
                 if (CoinsTogether(self.which_class))
                 {   print ". The ";
                     if (self.which_class == GoldCoin)
                         print "gold"; else print "silver";
                     " trigram is now ", (Trigram) self.which_class;
                 }
                 ".";
           ];
    [ CoinLT k i c;
      if (inventory_stage==1)
      {   if (self.which_class == GoldCoin)
              print "the gold"; else print "the silver";
          print " coins ";
          k=CoinsTogether(self.which_class);
          if (k==location  k has supporter)
          {   objectloop (i ofclass self.which_class)
              {   print (name) i;
                  switch(++c)
                  {  1: print ", "; 2: print " and ";
                     3: print " (showing the trigram ",
                        (Trigram) self.which_class, ")";
                  }
              }
              rtrue;
          }
          if (~~(c_style & ENGLISH_BIT))   c_style = c_style + ENGLISH_BIT;
          if (~~(c_style & NOARTICLE_BIT)) c_style = c_style + NOARTICLE_BIT;
          if (c_style & NEWLINE_BIT)       c_style = c_style - NEWLINE_BIT;
          if (c_style & INDENT_BIT)        c_style = c_style - INDENT_BIT;
      }
      rfalse;
    ];
    Class  GoldCoin class Coin
      with name "gold", which_class GoldCoin,
           list_together [; return CoinLT(); ];
    Class  SilverCoin class Coin
      with name "silver", which_class SilverCoin,
           list_together [; return CoinLT(); ];
(There are two unusual points here. Firstly, the `CoinsLT` routine is not simply given as the common `list_together` value in the `coin` class since, if it were, all six coins would be grouped together: we want two groups of three, so the gold and silver coins have to have different `list_together` values. Secondly, if a trigram is together and on the floor, it is not good enough to simply append text like "showing Tails, Heads, Heads (change)'' at `inventory_stage` 2 since the coins may be listed in a funny order: for example, in the order snake, robin, bison. In that event, the order the coins are listed in doesn't correspond to the order their values are listed in, which is misleading. So instead `CoinsLT` takes over entirely at `inventory_stage` 1 and prints out the list of three itself, returning true to stop the list from being printed out by the library as well.) To resume: whenever coins are listed together, they are grouped into gold and silver. Whenever trigrams are visible they are to be described by either `Trigram(GoldClass)` or `Trigram(SilverClass)`:
    Array gold_trigrams -->   "fortune" "change" "river flowing" "chance"
                              "immutability" "six stones in a circle"
                              "grace" "divine assistance";
    Array silver_trigrams --> "happiness" "sadness" "ambition" "grief"
                              "glory" "charm" "sweetness of nature"
                              "the countenance of the Hooded Man";
    [ Trigram cla i k state;
      objectloop (i ofclass cla)
      {   print (Face) i; if (k++<2) print ","; print " ";
          state=state*2 + (i.way_up-1);
      }
      if (cla == GoldCoin) i=gold_trigrams; else i=silver_trigrams;
      print "(", (string) i-->state, ")";
    ];
(These interpretations of the coins are quite bogus.) Finally, we have to make the six actual coins:
    GoldCoin ->   "goat"    with name "goat";
    GoldCoin ->   "deer"    with name "deer";
    GoldCoin ->   "chicken" with name "chicken";
    SilverCoin -> "robin"   with name "robin";
    SilverCoin -> "snake"   with name "snake";
    SilverCoin -> "bison"   with name "bison";

Back to the exercise in section 23

Mechanically translated to HTML from third edition as revised 16 May 1997. Copyright © Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.