Add files via upload
This commit is contained in:
parent
9232bdb195
commit
f335103e95
411
Ghost.ipynb
411
Ghost.ipynb
@ -6,9 +6,9 @@
|
||||
"source": [
|
||||
"# Ghost\n",
|
||||
"\n",
|
||||
"[*Ghost*](https://en.wikipedia.org/wiki/Ghost_(game)) is a word game in which (quoting Wikipedia):\n",
|
||||
"According to [Wikipedia](https://en.wikipedia.org/wiki/Ghost_(game)):\n",
|
||||
"\n",
|
||||
"> *Ghost is a written or spoken word game in which players take turns adding letters to a growing word fragment, trying not to be the one to complete a valid word. Each fragment must be the beginning of an actual word, and usually some minimum is set on the length of a word that counts, such as three or four letters. The player who completes a word loses.*\n",
|
||||
"> **Ghost** *is a written or spoken word game in which players take turns adding letters to a growing word fragment, trying not to be the one to complete a valid word. Each fragment must be the beginning of an actual word, and usually some minimum is set on the length of a word that counts, such as three or four letters. The player who completes a word loses.*\n",
|
||||
"\n",
|
||||
"I'd like to create a program to allow any two players (human or computer) to play the game, and I'd like to figure out who wins if both players play optimally. The concepts I will need to define, and my implementation choices, are as follows:\n",
|
||||
"\n",
|
||||
@ -446,24 +446,24 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def rational(vocab, fragment): \n",
|
||||
" \"Select a play that makes opponent lose (if there is one), otherwise any play.\"\n",
|
||||
" for play in vocab.legal_plays(fragment):\n",
|
||||
" if not win(vocab, play):\n",
|
||||
" return play\n",
|
||||
" return play # Could return any play here\n",
|
||||
"import random\n",
|
||||
"\n",
|
||||
"def ask(name='Player'):\n",
|
||||
"def rational(vocab, fragment): \n",
|
||||
" \"Select a play that makes opponent not win (if there is one), otherwise a random play.\"\n",
|
||||
" plays = list(vocab.legal_plays(fragment))\n",
|
||||
" return next((play for play in plays if not win(vocab, play)),\n",
|
||||
" random.choice(plays))\n",
|
||||
"\n",
|
||||
"def ask(name):\n",
|
||||
" \"Return a strategy that asks for the next letter.\"\n",
|
||||
" return (lambda _, fragment: \n",
|
||||
" fragment + input(\"{}'s letter to add to '{}'? \".format(name, fragment)))"
|
||||
" return (lambda _, fragment: input('Player {}, given \"{}\", plays? '.format(name, fragment)))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here is a function to play a game:"
|
||||
"Here is a function to play a game. You give it a vocabulary, two (or potentially more) strategies, and optionally a `verbose` keyword to say if you want a line printed for each play or not."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -476,11 +476,14 @@
|
||||
"source": [
|
||||
"from itertools import cycle\n",
|
||||
"\n",
|
||||
"def play(vocab, *strategies):\n",
|
||||
"def play(vocab, *strategies, verbose=True):\n",
|
||||
" \"Return (winner, final_fragment) for a game of Ghost between these strategies.\"\n",
|
||||
" fragment = ''\n",
|
||||
" for strategy in cycle(strategies):\n",
|
||||
" play = strategy(vocab, fragment)\n",
|
||||
" if verbose:\n",
|
||||
" print('Player {}, given \"{}\", plays \"{}\".'\n",
|
||||
" .format(strategies.index(strategy), fragment, play))\n",
|
||||
" if play not in vocab.legal_plays(fragment):\n",
|
||||
" return (winner(fragment + '?'), play) # Player loses for making an illegal play\n",
|
||||
" elif play in vocab.words:\n",
|
||||
@ -496,10 +499,23 @@
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Player 0, given \"\", plays \"s\".\n",
|
||||
"Player 0, given \"s\", plays \"sq\".\n",
|
||||
"Player 0, given \"sq\", plays \"squ\".\n",
|
||||
"Player 0, given \"squ\", plays \"squo\".\n",
|
||||
"Player 0, given \"squo\", plays \"squoo\".\n",
|
||||
"Player 0, given \"squoo\", plays \"squoos\".\n",
|
||||
"Player 0, given \"squoos\", plays \"squoosh\".\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(1, 'ply')"
|
||||
"(1, 'squoosh')"
|
||||
]
|
||||
},
|
||||
"execution_count": 19,
|
||||
@ -518,10 +534,20 @@
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Player 0, given \"\", plays \"h\".\n",
|
||||
"Player 0, given \"h\", plays \"ha\".\n",
|
||||
"Player 0, given \"ha\", plays \"haa\".\n",
|
||||
"Player 0, given \"haa\", plays \"haaf\".\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(0, 'huddle')"
|
||||
"(0, 'haaf')"
|
||||
]
|
||||
},
|
||||
"execution_count": 20,
|
||||
@ -544,15 +570,23 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Player's letter to add to ''? d\n",
|
||||
"Player's letter to add to 'dr'? o\n",
|
||||
"Player's letter to add to 'droi'? d\n"
|
||||
"Player 0, given \"\", plays? d\n",
|
||||
"Player 0, given \"\", plays \"d\".\n",
|
||||
"Player 1, given \"d\", plays \"dw\".\n",
|
||||
"Player 0, given \"dw\", plays? dwa\n",
|
||||
"Player 0, given \"dw\", plays \"dwa\".\n",
|
||||
"Player 1, given \"dwa\", plays \"dwar\".\n",
|
||||
"Player 0, given \"dwar\", plays? dwarv\n",
|
||||
"Player 0, given \"dwar\", plays \"dwarv\".\n",
|
||||
"Player 1, given \"dwarv\", plays \"dwarve\".\n",
|
||||
"Player 0, given \"dwarve\", plays? dwarves\n",
|
||||
"Player 0, given \"dwarve\", plays \"dwarves\".\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(1, 'droid')"
|
||||
"(1, 'dwarves')"
|
||||
]
|
||||
},
|
||||
"execution_count": 21,
|
||||
@ -561,7 +595,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"play(enable1, ask(), rational)"
|
||||
"play(enable1, ask(0), rational)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -655,7 +689,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'nays', 'nene', 'ngultrum', 'nirvanic', 'nolo', 'null', 'nyctalopia'}"
|
||||
"{'nazi', 'nene', 'ngultrum', 'nirvanic', 'nolo', 'null', 'nyctalopia'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 24,
|
||||
@ -700,7 +734,7 @@
|
||||
" 'dreck',\n",
|
||||
" 'drink',\n",
|
||||
" 'droit',\n",
|
||||
" 'drunk',\n",
|
||||
" 'druid',\n",
|
||||
" 'dry',\n",
|
||||
" 'ewe',\n",
|
||||
" 'fjeld',\n",
|
||||
@ -714,7 +748,7 @@
|
||||
" 'mho',\n",
|
||||
" 'nth',\n",
|
||||
" 'oquassa',\n",
|
||||
" 'praam',\n",
|
||||
" 'prase',\n",
|
||||
" 'prequel',\n",
|
||||
" 'prill',\n",
|
||||
" 'pro',\n",
|
||||
@ -737,13 +771,13 @@
|
||||
" 'vroom',\n",
|
||||
" 'wrack',\n",
|
||||
" 'wrest',\n",
|
||||
" 'wrist',\n",
|
||||
" 'wrick',\n",
|
||||
" 'wrong',\n",
|
||||
" 'wrung',\n",
|
||||
" 'wry',\n",
|
||||
" 'xanthic',\n",
|
||||
" 'xanthin',\n",
|
||||
" 'ycleped',\n",
|
||||
" 'yperite',\n",
|
||||
" 'zucchetto'}"
|
||||
]
|
||||
},
|
||||
@ -807,7 +841,7 @@
|
||||
" 'dreck',\n",
|
||||
" 'drink',\n",
|
||||
" 'droit',\n",
|
||||
" 'drunk',\n",
|
||||
" 'druid',\n",
|
||||
" 'drywall',\n",
|
||||
" 'eschatologies',\n",
|
||||
" 'eschatology',\n",
|
||||
@ -826,7 +860,7 @@
|
||||
" 'fjord',\n",
|
||||
" 'gjetost',\n",
|
||||
" 'hyaenic',\n",
|
||||
" 'hybris',\n",
|
||||
" 'hybrid',\n",
|
||||
" 'hydatid',\n",
|
||||
" 'hyena',\n",
|
||||
" 'hyenine',\n",
|
||||
@ -857,7 +891,7 @@
|
||||
" 'plonk',\n",
|
||||
" 'pluck',\n",
|
||||
" 'plyer',\n",
|
||||
" 'quack',\n",
|
||||
" 'quaff',\n",
|
||||
" 'quell',\n",
|
||||
" 'quiff',\n",
|
||||
" 'quomodo',\n",
|
||||
@ -874,13 +908,13 @@
|
||||
" 'vroom',\n",
|
||||
" 'wrack',\n",
|
||||
" 'wrest',\n",
|
||||
" 'wrist',\n",
|
||||
" 'wrick',\n",
|
||||
" 'wrong',\n",
|
||||
" 'wrung',\n",
|
||||
" 'wryly',\n",
|
||||
" 'xanthic',\n",
|
||||
" 'xanthin',\n",
|
||||
" 'ycleped',\n",
|
||||
" 'yperite',\n",
|
||||
" 'zucchetto'}"
|
||||
]
|
||||
},
|
||||
@ -903,7 +937,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(85, ['hyphen', 'ngultrum', 'hyte', 'hybris'])"
|
||||
"(85, ['hyphen', 'ngultrum', 'hybrid', 'hyte'])"
|
||||
]
|
||||
},
|
||||
"execution_count": 28,
|
||||
@ -928,7 +962,7 @@
|
||||
"source": [
|
||||
"# SuperGhost\n",
|
||||
"\n",
|
||||
"In the variant *SuperGhost*, players can add a letter to either the beginning or the end of a fragment, as long as this forms a fragment that is part of some word. I was thinking of SuperGhost when I made the design decision to encapsulate `legal_plays` as a method of `Vocabulary`, rather than as a separate function. Because I did that, I should be able to use all the existing code if I just make a new class, `SuperVocabulary`, that finds *all* fragments (i.e. infixes) rather than just the beginning fragments (i.e. prefixes)."
|
||||
"In the variant *SuperGhost*, players can add a letter to either the beginning or the end of a fragment, as long as this forms a fragment that is part of some word. As Wikipedia says, given the fragment `era`, a player might play `bera` or `erad`. I was thinking of SuperGhost when I made the design decision to encapsulate `legal_plays` as a method of `Vocabulary`, rather than as a separate function. Because I did that, I should be able to use all the existing code if I just make a new class, `SuperVocabulary`, that finds *all* fragments (i.e. infixes) rather than just the beginning fragments (i.e. prefixes), and if I change `legal_plays` to add letters to both ends."
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -981,27 +1015,14 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 35,
|
||||
"execution_count": 31,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[387878, 387844, 1076434, 1076431]"
|
||||
]
|
||||
},
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"enable1s = SuperVocabulary(enable1.words)\n",
|
||||
"enable1_4s = SuperVocabulary(enable1.words, 4)\n",
|
||||
"\n",
|
||||
"[len(v.fragments) for v in [enable1, enable1_4, enable1s, enable1_4s]]"
|
||||
"enable1_4s = SuperVocabulary(enable1.words, 4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -1014,7 +1035,19 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
"{'atresse',\n",
|
||||
" 'ctresse',\n",
|
||||
" 'etresse',\n",
|
||||
" 'itresse',\n",
|
||||
" 'ntresse',\n",
|
||||
" 'otresse',\n",
|
||||
" 'ptresse',\n",
|
||||
" 'rtresse',\n",
|
||||
" 'stresse',\n",
|
||||
" 'tressed',\n",
|
||||
" 'tressel',\n",
|
||||
" 'tresses',\n",
|
||||
" 'ttresse'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 32,
|
||||
@ -1023,9 +1056,8 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Can the first player win in SuperGhost with 3-letter words?\n",
|
||||
"\n",
|
||||
"win(enable1s)"
|
||||
"# Example legal plays\n",
|
||||
"enable1s.legal_plays('tresse')"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -1046,6 +1078,30 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Can the first player win in SuperGhost with 3-letter words?\n",
|
||||
"\n",
|
||||
"win(enable1s)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 34,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# How about with a 4-letter limit?\n",
|
||||
"\n",
|
||||
@ -1061,7 +1117,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"execution_count": 35,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -1070,19 +1126,26 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Peter's fragment, given ''? z\n",
|
||||
"Peter's fragment, given 'zq'? zqu\n",
|
||||
"Peter's fragment, given 'ezqu'? ezqui\n",
|
||||
"Peter's fragment, given 'mezqui'? mezquit\n"
|
||||
"Peter's fragment, given ''? q\n",
|
||||
"Player 0, given \"\", plays \"q\".\n",
|
||||
"Player 1, given \"q\", plays \"mq\".\n",
|
||||
"Peter's fragment, given 'mq'? mqu\n",
|
||||
"Player 0, given \"mq\", plays \"mqu\".\n",
|
||||
"Player 1, given \"mqu\", plays \"umqu\".\n",
|
||||
"Peter's fragment, given 'umqu'? umqua\n",
|
||||
"Player 0, given \"umqu\", plays \"umqua\".\n",
|
||||
"Player 1, given \"umqua\", plays \"kumqua\".\n",
|
||||
"Peter's fragment, given 'kumqua'? kumquat\n",
|
||||
"Player 0, given \"kumqua\", plays \"kumquat\".\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(1, 'mezquit')"
|
||||
"(1, 'kumquat')"
|
||||
]
|
||||
},
|
||||
"execution_count": 34,
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@ -1095,7 +1158,221 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"I would like to give a concise summary of the strategy for SuperGhost, but my existing `outcomes` function won't do it. That's because it is not enough to know that a particular word results in a win; we have to know in what order the letters of the word are added. I'll leave it as an exercise to find a good way to summarize SuperGhost strategies."
|
||||
"I would like to give a concise summary of the strategy for SuperGhost, but my existing `outcomes` function won't do it. That's because it is not enough to know that a particular word results in a win; we have to know in what order the letters of the word are added. I'll leave it as an exercise to find a good way to summarize SuperGhost strategies.\n",
|
||||
"\n",
|
||||
"# SuperDuperGhost\n",
|
||||
"\n",
|
||||
"In the variant *SuperDuperGhost*, players have an option to reverse the fragment before adding a letter to the beginning or end. As Wikipedia says, given the fragment `era`, a player might play `bera, erad, nare,` or `aren`.\n",
|
||||
"Wikipedia is not clear, but I interpret this as meaning that the fragment played must still be a fragment of a word (not a reversed fragment of a word). Again, all we need is a new subclass:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 36,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class SuperDuperVocabulary(SuperVocabulary):\n",
|
||||
" \"Holds a set of legal words and a set of legal infix fragments of those words.\"\n",
|
||||
" \n",
|
||||
" def legal_plays(self, fragment):\n",
|
||||
" \"All plays that form a valid infix; optionally reverse fragment first.\"\n",
|
||||
" return {play for L in alphabet \n",
|
||||
" for play in (fragment + L, fragment[::-1] + L,\n",
|
||||
" L + fragment, L + fragment[::-1])} & self.fragments"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 37,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"enable1sd = SuperDuperVocabulary(enable1.words)\n",
|
||||
"enable1_4sd = SuperDuperVocabulary(enable1.words, 4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 38,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'atresse',\n",
|
||||
" 'ctresse',\n",
|
||||
" 'dessert',\n",
|
||||
" 'esserts',\n",
|
||||
" 'etresse',\n",
|
||||
" 'itresse',\n",
|
||||
" 'ntresse',\n",
|
||||
" 'otresse',\n",
|
||||
" 'ptresse',\n",
|
||||
" 'rtresse',\n",
|
||||
" 'stresse',\n",
|
||||
" 'tressed',\n",
|
||||
" 'tressel',\n",
|
||||
" 'tresses',\n",
|
||||
" 'ttresse'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Example legal plays\n",
|
||||
"enable1sd.legal_plays('tresse')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now we should check who wins. But when I tried `win(enable1sd)`, I didn't get an answer within the first minute; there are just too many paths to get to the same fragment, so we are repeating a lot of work. The standard response to this problem is a `lru_cache`, which brings the time down to 2 seconds."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 39,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from functools import lru_cache\n",
|
||||
"\n",
|
||||
"@lru_cache(None)\n",
|
||||
"def win(vocab, fragment=''):\n",
|
||||
" \"Does the player whose turn it is have a forced win?\"\n",
|
||||
" return (fragment in vocab.words or \n",
|
||||
" fragment not in vocab.fragments or\n",
|
||||
" any(not win(vocab, play) \n",
|
||||
" for play in vocab.legal_plays(fragment)))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 40,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"win(enable1sd)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 41,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 41,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"win(enable1_4sd)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The first player can win with either vocabulary. Here's a sample game."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 42,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Player 0, given \"\", plays \"b\".\n",
|
||||
"Player 0, given \"b\", plays \"sb\".\n",
|
||||
"Player 0, given \"sb\", plays \"msb\".\n",
|
||||
"Player 0, given \"msb\", plays \"msbu\".\n",
|
||||
"Player 0, given \"msbu\", plays \"emsbu\".\n",
|
||||
"Player 0, given \"emsbu\", plays \"gemsbu\".\n",
|
||||
"Player 0, given \"gemsbu\", plays \"gemsbuc\".\n",
|
||||
"Player 0, given \"gemsbuc\", plays \"gemsbuck\".\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(0, 'gemsbuck')"
|
||||
]
|
||||
},
|
||||
"execution_count": 42,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"play(enable1sd, rational, rational)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's see how many fragments each vocabulary takes:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 43,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[387878, 387844, 1076434, 1076431, 1076434, 1076431]"
|
||||
]
|
||||
},
|
||||
"execution_count": 43,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"[len(v.fragments) for v in [enable1, enable1_4, enable1s, enable1_4s, enable1sd, enable1_4sd]]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -1106,12 +1383,14 @@
|
||||
"\n",
|
||||
"Here's a summary of what we have learned. (*Note:* the bold **qursh** means it is a losing word):\n",
|
||||
"\n",
|
||||
"| Game \t| Shortest \t| Winner \t| First Player Outcomes | Second Player Outcomes\n",
|
||||
"|----\t|---\t |---\t |--- |---\n",
|
||||
"| Ghost | 3 \t | Second \t| qaid qiviut qoph **qursh** qurush qwerty | 55 words\n",
|
||||
"| Ghost | 4 \t | First \t| naan nene ngultrum nirvanic nolo null nyctalopia | 85 words\n",
|
||||
"| SuperGhost | 3\t| First \t| ? | ? |\n",
|
||||
"| SuperGhost | 4 \t| First \t| ? | ? |\n",
|
||||
"| Variant \t| Shortest \t| Winner \t| First Player Outcomes | 2nd Outcomes | Fragments\n",
|
||||
"|----\t|---:\t |---\t |--- |--- |---:\n",
|
||||
"| Ghost | 3 \t | Second \t| qaid qiviut qoph **qursh** qurush qwerty | 55 words | 387,878\n",
|
||||
"| Ghost | 4 \t | First \t| naan nene ngultrum nirvanic nolo null nyctalopia | 85 words | 387,844\n",
|
||||
"| Super | 3\t| First \t| ? | ? | 1,076,434\n",
|
||||
"| Super | 4 \t| First \t| ? | ? | 1,076,431\n",
|
||||
"| SuperDuper | 3 | First| ? | ? | 1,076,434\n",
|
||||
"| SuperDuper | 4 | First| ? | ? | 1,076,431\n",
|
||||
"\n",
|
||||
"# Further Work\n",
|
||||
"\n",
|
||||
|
Loading…
Reference in New Issue
Block a user