Training your pets ==================== by Peter Snelling (snelling@bnr.ca), Boudewijn Wayers (kroisos@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.