                          Training your pets
                         ====================

                 by Peter Snelling (snelling@bnr.ca),
              Boudewijn Wayers (dedos4@win.tue.nl), and
            Bryan Butler (butler@cluster.gps.caltech.edu).


Boudewijn wrote:
~~~~~~~~~~~~~~~

The standard "safe" method of robbing shops is to let your pet do the
dirty work: when in a shop, stand in the doorway but let your dog
enter. Eventually, he will pick up something (unless everything is
cursed, of course). A while later, he will drop it.

Once in a while, your dog will drop the thing exactly before you (the
first spot INSIDE the shop, next to the door). Anything that lies here
is free for you to take.

Of course, the chance that your dog drops his stuff exactly there is
not very big. What you should do is toss it some food (preferrably
tripe), immediately after it has dropped the item on that spot (that
is: before it had a chance to move off the spot). This is not easy,
because your pet may be faster than you are. When it succeeds, your dog
will have "learned" that it gets fed when it drop something on that
particular spot, and will repeat it. The more often you toss him food,
the sooner he wel learn. Only tossing him food once will probably not
help very much, but twice or thrice will be very helpful.


Peter answered to this:
~~~~~~~~~~~~~~~~~~~~~~

I once wanted to find out *exactly* how this works.
 - Did you have to throw the pet tripe when it is still on the same 
   space as it just dropped something
 - Does it have to be the very next turn?
 - Do you actually have to wait for the pet to drop something?

The only thing I found in the source seemed to indicate that none of
that matters. Basically, whenever you throw something at your pet, it
gets more tame. The more tame it is, the more likely it is to pick up
something and drop it next to you (and every time it does that it gets
a little less tame).

Another minor point is that you don't need to actually throw the tripe
ration at the pet to make it "tamer". Anytime the pet eats something
which you once carried (the game stores it's previous inventory letter
to indicate if you've held it), it gets tamer.

So, if you walk into a general store which contains tripe rations, but
you have no money, just close the door on your pet, pick up all the
tripe then drop it, then let your pet in. It will eat the tripe, get
tamer (since you once held the tripe), and then pick up stuff in the
store and drop it.

To improve this even more, drop something cursed somewhere in the shop,
and pile all the stuff in the shop that you don't want on top of the
cursed thing. That way your pet won't waste time bringing you things
you don't want.

I wanted to find out how many articles a dog will steal for each tripe
ration you give it... The main code is in dogmove.c:

   /* It's a reward if it's DOGFOOD and the player dropped/threw it. */
   /* We know the player had it if invlet is set -dlc */
   if(dogfood(mtmp,obj) == DOGFOOD && obj->invlet)
#ifdef LINT
            edog->apport = 0;
#else
            edog->apport += (unsigned)(200L/
                ((long)edog->dropdist+moves-edog->droptime));

Unfortunately, the formula is kind of complicated. It looks like it
gets harder to tame pets and the game goes on (1/moves). Each time
your dog gives you something, apport gets decrimented.


Brian continued this subject:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Well, the quantity edog->droptime is the # of moves when the dog last
dropped something, so, (moves - edog->droptime) is the number of moves
since the dog last dropped something. So, it doesn't get harder to
train dogs as the game goes on. And, it does help to throw the
tripe/food as soon as the dog drops something, as then (moves -
edog->droptime) is minimized, and edog->apport will be increased that
much more. Edog->dropdist is the distance from you to your pet the last
time he dropped something (which is sort of a measure of how much he
likes you, so, the more he likes you, the more he likes you each time
you feed him... did that make sense?).

The next question is: when does your dog decide to drop things?

The answer is held in 2 tests, which have to be passed (see
dogmove.c):

1. !rn2(udist) || !rn2(edog->apport)

This essentially tests your distance from your dog, and how much he
likes you. If you are very close, or he doesn't like you much, this
test is likely to be passed. Udist is the square of the euclidian
distance from you to your dog, so, if your dog is in adjacent squares,
like:

    d
   d@d
    d

then this test is always passed. Note, if he's in a diagonally adjacent
square:

   d d
    @
   d d

then the square of the euclidean distance is 2, and there's a 50%
chance of the test being passed. Also, it is passed every time if your
dog doesn't like you (the minimum value of edog->apport is 1, so rn2(1)
is always 0).

2. rn2(10) < edog->apport

So, if your dog's love (edog->apport) is >= 10, the dog will always
drop the item. Otherwise, the percent probability that the dog will
drop the item is

  100x(edog->apport)/10 %

thus, if your dog doesn't like you much, there's a 10% chance (minimum
edog->apport is 1) that he'll drop what he's holding wherever he is.

So, assume you're in a shop, you're sitting on the doorstep, and your
dog drops something on the "free" spot. Then, you immediately throw him
a tripe (note, this maximizes your dog's love for you, but may have bad
consequences, as he may immediately pick up the item which he just
dropped). Then, your dog's apport gets increased by

  edog->apport += (200/(1+1))   (edog->apport += 100).

Note, the (moves - edog->droptime) is only 1, because it took you only
1 turn to throw the tripe. Other cases of interest: you wait for the
dog to move away before moving onto the "free" square and throwing the
tripe (in order to make sure he doesn't pick the item right back up):

  edog->apport += (200 / (1 + 2))   (edog->apport += 66)

and, you actually pick the item up before throwing the tripe:

  edog->apport += (200 / (1 + 3))   (edog->apport += 50)

Now, edog->apport only gets decreased by 1 each time the dog drops
something, so it seems that throwing one tripe per store should be
enough to guarantee clearing it out.


