choosing a random object that meets a complex condition

I’m working on something where NPCs talk to people about things they’ve seen. The idea is that each NPC has a stored action called a thought (something they’ve witnessed), and if an NPC is in the room with another NPC they might gossip about their thought. But they won’t gossip to another NPC about something that that NPC was involved in.

So I’ve got a few criteria:
the gossiper must have a non-default thought (something other than the action of waiting)
the audience must be in the location of the gossiper
the audience must not be involved in the thought of the gossiper – not the actor or the noun (or the second noun) of that stored action

And I’d like to randomly select a person who fits these criteria.

What I currently have is this terrible hack:

[code]Gossiping to it about is an action applying to one visible thing and one stored action. [This will not ever be invoked directly, but with luck it will allow an NPC to talk about another NPC talking.]

Definition: A person is NPC if she is not the player.

A person has a stored action called the thought.

Definition: a person is thoughtful if his thought is not waiting.

Contemplating relates a person (called X) to a person (called Y) when the thought of X involves Y or X is Y. The verb to contemplate (he contemplates, they contemplate, it contemplated, it is contemplated) implies the contemplating relation.

To decide whether (subject - a person) is involved in (event - a stored action):
if the event involves the subject, yes;
no.

To decide whether (subject - a person) is not involved in (event - a stored action):
if the event involves the subject, no;
yes.

Every turn:
repeat with the tattletale running through thoughtful NPC persons:
if a random chance of 2 in 5 succeeds:
if the tattletale does not contemplate every person in the location of the tattletale:
let the audience be an object;
while the audience is not a person or the tattletale contemplates the audience:
let the audience be a random person in the location of the tattletale;
try the tattletale gossiping to the audience about the thought of the tattletale.[/code]

I would like to say something like “try the tattletale gossiping to a random person in the location of the tattletale that the tattletale does not contemplate,” but this does not compile one tiny bit. Is there a way to accomplish this without relying on a while loop to pick random people in the location of the tattletale until it finds one that the tattletale does not contemplate?

Perhaps something like:

[code]Definition: A person is receptive:
If it is not in the location of the tattletale, no;
if the tattletale contemplates it, no;
yes.

Every turn:
let gossipmonger be a random receptive person;
if gossipmonger is not nothing:
try the tattletale gossiping to gossipmonger.
[/code]

I’d thought I couldn’t do that because the tattletale isn’t a global variable.

You could set a global variable temporarily for the purpose of this phrase.

I was afraid it would turn out to be something like that.

Well, I think I’ll just leave it be for now – it’s working right now, and the inefficiency from using a repeat loop shouldn’t be too bad.

I do think this syntax works:

Every turn:
	repeat with the tattletale running through thoughtful NPC persons:
		let the surroundings be the location of the tattletale;
		let the audience be a random person who is not contemplated by the tattletale in the surroundings;
		try the tattletale gossiping to the audience about the thought of the tattletale.

That does seem to work, thank you Felix! I had tried storing the location of the tattletale in a temporary variable, but perhaps not in combination with using the contemplation relation, or maybe not with the passive voice.

(I included an existence check to make sure there is a person that the tattletale doesn’t contemplate in the surroundings before trying to choose a random one.)

I think that, instead of the existence check, you could also do “if the audience is a person, try …”; if there are no suitable persons to choose from, the random choice will simply return “nothing”.