| 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"; |