TAKE ALL with multiple identical things

I have a situation where there are 5 items of the same description - Beacons - in an open box

I am using the technique (based on an example in the Inform 7 Handbook) as follows:

Instead of taking a Beacon: let P be a random Beacon; now the player carries P; if player is carrying more than one Beacon: say "You're carrying another Beacon."; otherwise: say "You've got a Beacon."; stop the action.

Taking the beacons one at a time is fine.
And TAKE ALL reports:
You’ve got a Beacon
You’re carrying another Beacon
You’re carrying another Beacon
You’re carrying another Beacon
You’re carrying another Beacon

But an inventory shows I’ve only got 4 beacons and there’s one left in the box.

What am I doing wrong?

I’m using the Android Inform 7 version that uses Inform 7 6L38.

Oh, sorry. I think I fixed it.

When I asked for a random beacon, I think it sometimes gave me one I was already holding.

I changed the code to:

Instead of taking a Beacon: let P be a random Beacon; while player is carrying P: let P be a random Beacon; now the player carries P; if player is carrying more than one Beacon: say "You're carrying another Beacon."; otherwise: say "You've got a Beacon."; stop the action.

You could do this test more easily with “let P be a random Beacon not carried by the player” and then testing whether P is nothing. Your solution will loop infinitely (i.e. crash the game) if the player already has all the Beacons; it is still possible to generate the “taking a Beacon” action in this situation.

Additionally, if there are Beacons in multiple places, both of these solutions will steal a random one from a random place, not necessarily one of the ones the player is standing in front of and trying to grab. This probably isn’t what you intended. (If it is, feel free to ignore the rest of this reply, but I personally would be very surprised by a story that did this.) I assume you adapted this from example 376 “Pizza Prince” (or possibly 124 “Extra Supplies”, which works the same way), but you left out the phrase “in Pizza Limbo”, which is actually pretty important. Are you actually trying to avoid having the Beacons really present in the box? The point of “Pizza Prince” is that the author didn’t want however many slices of pizza to be present and visible; he only wanted you to be able to take a near-infinite number of them from the dispenser (but only 10 at a time). Is this how you want the box of Beacons to work? If the player somehow… disposes… of some of the beacons, should he be able to come back and get replacements? Or is it just a box, with five actual Beacons inside? It sounds like you currently have the latter situation, since you’re expecting ALL to work.

The root cause of all this confusion is that you are subverting the normal action processing system: you’re saying “Instead of doing the normal thing, do this other thing” which in your case turns out to be mostly the same as the normal thing. But this means you have to deal with all the edge cases that the normal thing normally takes care of for you, such as preventing the player from taking things he already has, or things that aren’t nearby, or inside a locked safe. In this case, the only thing you’re trying to change is the message printed after a successful take (or remove from, which this solution might not even get). Fortunately, this is much easier to do than what you’re trying. You can just add a custom Report rule, and the rest of the action (including checks on whether the player can see and/or reach the beacon, whether the beacon is movable, and many others) will proceed normally.

Report taking a Beacon when the player is carrying more than one Beacon: say "[We]['ve] got another Beacon."
Report taking a Beacon: say "[We]['re] carrying a Beacon."

This should (I think) even prevent the standard “Taken.” message, because they print something else. You may also have to create rules for “Report removing a Beacon from something” because you have them in a box, but try this first; it might be enough.

Backing up: I7 already handles identical things in a natural way by default. Is there something about it that you want to customize? If it’s just the displayed message, then zahariel’s last example does that.

Of course, you are right.

I just wanted to have five beacons in the box, all with same description, and not have to disambiguate them when I picked them out. I have over-complicated the situation. You are saying I can have 5 beacons in a box and if I say TAKE A BEACON, I won’t have WHICH ONE? shot back.

I only put in the different responses to TAKE A BEACON as a sort of trace, as I tried ten and two before five. And I sure didn’t want to fetch beacons which weren’t local to me.

I’m going to try the simple approach.

This is my first Inform project. In the mists of yesteryear (like 1990) I was a particularly enthusiastic AGT user. (The Sir Ramic Hobbs games). That’s my excuse! Also, the tortuous development route forced on me by Android Inform makes trial and error rather lengthy.

Thank you both. With my clarified view of the situation, I shall set about removing other instances of ‘let P be a random [noun]…’ Groan.