← Back

Text Based Zendo

Text-Zendo is a game about guessing a rule. One person thinks of a rule, then people try to figure it out by guessing and reverse-engineering it based on what fits it. Guesses can be any series of letters and numbers, with spaces separating words. When someone makes a rule, they should provide an example which fits and one which does not. Here's an example game:

Person 1: I have a rule
Person 1: "the the the" fits the rule
Person 1: "the a the" does not fit the rule

Person 2: Does a a a fit the rule?
Person 1: Yes
Person 3: Does b a a fit the rule?
Person 1: No
Person 2: Is the rule that all words in the guess have to be the same?
Person 1: Yes

I've set up a discord bot which can automate the process of checking people's guesses against the rule.

Example Game

!t is a way to test a guess against the rule

Example Game Picture

The discord bot can only interpret rules a very specific way, so here's a description of how to format rules:

Let's look at a basic rule: "word is subset of dictionary"
There are three elements to this rule: "word", "is subset of", and "dictionary".
"word" is the list of words that are in the guess. If someone guessed "Hello My Name Is Matthew", word would be the set: ["Hello", "My", "Name", "Is", "Matthew"]
dictionary is the entire list of words, ["a", "aa", "aaa", "aachen", "aardvark" ...]
"<Set1> is subset of <Set2>" is a rule. It returns True if everything in <Set1> is also in <Set2>, ignoring case.
In this case, "Matthew" is not in the dictionary, so our guess does not fit the rule

A more formal look at rule creation:
Every rule takes some type of value, and returns some type of value.
The return value in the outermost rule should be a boolean.
Parentheses encase all rules except the outermost one.

Formal Definitions

Set: Dictionary Animals Nouns Verbs Adjectives Countries States Python Reserved Words Uppercase Lowercase Vowel Consonant User defined set = {"element_1", "element_2" ...} Find the contents of predefined sets at: https://github.com/mdzirbel/ZendoBot/tree/master/Sets Conditions: True False <Set> is palindrome | Whether every element in <Set> is a palindrome <Number> == <Number> <Set> == <Set> <Number> >= <Number> <Number> <= <Number> <Number> > <Number> <Number> < <Number> <Condition> and <Condition> <Condition> or <Condition> not <Condition> <Set1> contains <Set2> | Whether any element of <Set2> can be found anywhere in <Set1> eg. {'hello'} contains {'hell'} -> True <Set1> contains <Set2> case sensitive <Set1> is subset of <Set2> | <Set1> is subset of <Set2> eg. ["dog", "cat", "llama"] is subset of animals -> True <Set1> is case sensitive subset of <Set2> <Set> is lowercase | Checks whether everything in <Set> is lowercase. Ignores numbers <Set> is uppercase | Checks whether everything in <Set> is uppercase. Ignores numbers Operations: Output | How to use | Description <Set> | every (n)th <Set> | eg. every 2nd word - ["the", "quick", "brown", "fox"] -> ["quick", "fox"] <Set> | (n)th <Set> | <Set>[n] <Set> | letters of <Set> | ["the", "he"] -> ["t", "h", "e", "h", "e"] <Number> | length of <Set> | Length of set. length of sentence -> 1, length of words -> number of words <Number> | sum of <Set> | Sum of letters in set, a=A=1, b=B=2, 1=1, 2=2 <Number> | location of <Set1> in <Set2> | Case sensitive location of <Set1> in <Set2>, or -1 if it's not inside <Set> | <Set1> intersect <Set2> | <Set1> n <Set2> (case sensitive) <Set> | <Set1> union <Set2> | <Set1> U <Set2> Repeats are added a second time (case sensitive) <Set> | <Set1> - <Set2> | <Set1> \ <Set2> <Number> | <Number1> - <Number2> <Number> | <Number> + <Number> <Number> | <Number1> mod <Number2> | <Number1> % <Number2> <Number> | (<Set> s#)[Condition] | Checks condition for any s, eg. (word s1)[s1 is palindrome] <Set> | lowercase of <Set> | Makes <Set> lowercase <Set> | uppercase of <Set> | Makes <Set> uppercase <Number> | (<Set> s#, <Location> l#)[<Condition>] | Checks <Condition> for any s and related l, eg. (word s1, next l1)[(sum of s1) > (sum of l1)], and returns the number of times the <Condition> is satisfied Number: ... -1 0 1 2 ... Level: Sentence | The entire sentence | "The quick brown" -> {"The quick brown"} Word | Every word in sentence | "The quick brown" -> {"The", "quick", "brown"} Letter | Every letter in sentence | "The quick brown" -> {'T', 'h', 'e', 'q', 'u' ...} Words | Same as Word, and can be used interchangeably Letters | Same as Letter, and can be used interchangeably Location: Next Previous Last First Opposite

What if we want to make a more complicated rule?
Let's make the rule "Every second word must contain a vowel".
First, we get every second word in the guess, by using a Set operation "every 2nd word"
We need to check for each word, so we'll use (<Set> s#, <Location> l#)[Condition]. This is a powerful operation which goes through the <Set>, using s# as each element in turn, with l# relative to s#. It then returns the number of times the condition was met.
s# and l# are how we decide to refer to the nth element and relative location, eg. (<Set> s1, <Location> l1)[some condition with s1 and l1]
To set up the part inside parentheses:
 We will put "(every 2nd word)" as the <Set>.
 We can decide to reference the element as s1
 We're not using the relative location, so we can just skip it
 The condition is that the word has a vowel, so "s1 contains vowel"
So now we have "((every 2nd word) s1)[s1 contains vowel]"
We now need a boolean value, by checking if the number of matches equals the number of words we're checking.
Adding this together: ((every 2nd word) s1)[s1 contains vowel] == (length of (every 2nd word))

A quick note about using (<Set> s#, <Location> l#)[<Condition>]: The maximum value, which is what it returns if the condition is met every time, will be one less when using Locations next and previous. This is because it can't check the last value when using Next, or the first value when using Previous, else there would be no location to compare to. Because of this, be sure to check against ((length of word) - 1) or less when using either of these <Location>s

The bot commands are the user's way of interfacing with the bot. These can be found through Discord commands but are also below if you'd like to see a list and short description.

Bot Commands

The bot commands are the user's way of interfacing with the bot. Commands begin with an '!' or '?'

Help Command

When every user enters the Server, they are added to a private work area where they can create and test rules without others being able to see them. When they are ready, they can use the "makekey" rule to get a key which points to that rule. They can then use that key to set the rule in other channels without typing the rule into that channel, which would defeat the point of guessing.

Here's an example of someone using the "overview" command:

Overview Command

← Back