(tads 3)
Imagine that I have a Container called ‘tube’. It starts out empty, but then I do this with it:
ball1.moveInto( tube );
ball2.moveInto( tube );
ball3.moveInto( tube );
ball4.moveInto( tube );
Am I guaranteed that now the order of tube.contents is something predictable, meaning I can treat the contents like a data type of stack or queue, or should I conceptually treat tube like it’s a “bag” data structure, where I can’t assume anything about the order of items inside it?
Where this is coming into play is that I’m having a very hard time trying to implement a container that behaves like a stack. The rules of the container are supposed to be that only the most recently added item can be removed or even looked at. The stack hides the objects underneath it, and using the archetypical “key under welcome mat” hidden item construct doesn’t work because that allows you to peek under the top item and take the items underneath without actually removing the covering item out of place. This is something I’m trying to do so I can make a poker deck in-game, where “take card from deck” automatically resolves to the topmost card in the deck without a disambiguator asking “did you mean one of these other 51 cards? [big list follows]”
This is made more problematic by the fact that the poker deck is allowed to be in a “face up” or “face down” state by a boolean variable, and if it’s face down, you’re not supposed to see the real names of the cards. All the cards are meant to look identical from the backside, so when drawing a card from the deck, the disambiguator will make the silly question: “did you mean the poker card, the poker card, the poker card, the poker card, the poker card, the…” etc for all 52 cards, and not only does this not make sense, there’s no way for the player to actually disambiguate that anyway because when they’re face down they all have the same vocabulary, and the vocabulary only shifts to things like ‘8/eight (of) hearts card’ when they’re face up.
Any ideas what’s the best way to implement this? Here’s a list of what I already tried that seems to be messy:
1 - Make the deck be a Dispenser.
Problem: A Dispenser dispenses new instances of items, and decides what they are based on what the player asked for. There doesn’t seem to be a way for the player to ask for a generic “card” and then have the dispenser decide what card they end up with. Instead it seems like the player has to ask for a named card “8 of spades” and then the dispenser can check to see if that’s a thing it allows itself to dispense. This might still be the right answer, but I’m not understanding how to do it. Keep in mind that total randomness is not a solution. I need the deck to remember the order of the cards that are in it and have it dispense the next one in the list, then adjust the list to remove the card it just dispensed. This does not seem to be compatible with how a Dispenser works because a dispenser lets the player tell it what object the player is pulling from it.
2 - Make the deck a RestrictedContainer that only holds objects of type “PlayingCard”, and then also make it contain an “inner” secret hidden RestrictedContainer that has no vocabulary (so a player can’t name it in a command). The inner secret container is what holds the inaccessable part of the deck, and the main container on top only holds the accessable part of the container (the top card in the deck). Then do some ugly re-mapping of its internal behavior via the notifyRemove and notifyInsert methods so that when someone takes the one card from the outer container, it moves the first item from the “inner” container out to the “outer container” to represent the next card coming up and becoming accessable. Then it does the reverse when a new card is added to the top of the deck - it moves the card that was there into the inner container instead. This messy behavior is designed to make the parser stop asking “which card do you mean” and giving 52 choices, because only 1 card is reachable, and the other 51 cards are inside the inner secret container. The problem I’m having here is the accidental recursion I cause when I try to use moveItem() to move objects between the inner and outer containers, and thus re-trigger the very same notifyInsert and notifyRemove routines that were causing those moves to happen. I tried basicMoveItem() instead to avoid this but it just doesn’t seem to actually have any effect and doesn’t really move the items at all.
It seems to me that some sort of a StackContainer would be a really useful addition to the standard library. Not only could it implement decks of cards, but it could also implement things like a stack of crates, or a Pez™ dispenser, or a life-size towers of Hanoi problem where you have to lift the rings off the giant spindles, and so on. Basically it could be useful for any pile of things where only the topmost thing is accessible. The material of the container itself would determine whether or not you can at least see the items under the top even though you can’t manipulate them. I.e. an opaque container only lets you sense the top item, and only if it’s “open”, while a transparent one lets you sense all the items in the stack but you still can only use the top item in a non-sense verb.