Skip to content

Instantly share code, notes, and snippets.

@dcollien
Last active August 18, 2017 09:41
Show Gist options
  • Save dcollien/c04f037cb22541815f338874ab781906 to your computer and use it in GitHub Desktop.
Save dcollien/c04f037cb22541815f338874ab781906 to your computer and use it in GitHub Desktop.
infinity = float("inf")
def argmin(seq, fn):
"""Return an element with lowest fn(seq[i]) score; tie goes to first one.
>>> argmin(['one', 'to', 'three'], len)
'to'
"""
best = seq[0]; best_score = fn(best)
for x in seq:
x_score = fn(x)
if x_score < best_score:
best, best_score = x, x_score
return best
def argmax(seq, fn):
"""Return an element with highest fn(seq[i]) score; tie goes to first one.
>>> argmax(['one', 'to', 'three'], len)
'three'
"""
return argmin(seq, lambda x: -fn(x))
def alphabeta_search(state, game, d=4, cutoff_test=None, eval_fn=None):
"""Search game to determine best action; use alpha-beta pruning.
This version cuts off search and uses an evaluation function."""
player = game.to_move(state)
def max_value(state, alpha, beta, depth):
if cutoff_test(state, depth):
return eval_fn(state)
v = -infinity
for (a, s) in game.successors(state):
v = max(v, min_value(s, alpha, beta, depth+1))
if v >= beta:
return v
alpha = max(alpha, v)
return v
def min_value(state, alpha, beta, depth):
if cutoff_test(state, depth):
return eval_fn(state)
v = infinity
for (a, s) in game.successors(state):
v = min(v, max_value(s, alpha, beta, depth+1))
if v <= alpha:
return v
beta = min(beta, v)
return v
# Body of alphabeta_search starts here:
# The default test cuts off at depth d or at a terminal state
cutoff_test = (cutoff_test or
(lambda state,depth: depth>d or game.terminal_test(state)))
eval_fn = eval_fn or (lambda state: game.utility(state, player))
action, state = argmax(game.successors(state),
lambda ((a, s)): min_value(s, -infinity, infinity, 0))
return action
class Game:
"""A game is similar to a problem, but it has a utility for each
state and a terminal test instead of a path cost and a goal
test. To create a game, subclass this class and implement
legal_moves, make_move, utility, and terminal_test. You may
override display and successors or you can inherit their default
methods. You will also need to set the .initial attribute to the
initial state; this can be done in the constructor."""
def legal_moves(self, state):
"Return a list of the allowable moves at this point."
raise NotImplementedError
def make_move(self, move, state):
"Return the state that results from making a move from a state."
raise NotImplementedError
def utility(self, state, player):
"Return the value of this final state to player."
raise NotImplementedError
def terminal_test(self, state):
"Return True if this is a final state for the game."
return not self.legal_moves(state)
def to_move(self, state):
"Return the player whose move it is in this state."
return state.to_move
def display(self, state):
"Print or otherwise display the state."
print state
def successors(self, state):
"Return a list of legal (move, state) pairs."
return [(move, self.make_move(move, state))
for move in self.legal_moves(state)]
def __repr__(self):
return '<%s>' % self.__class__.__name__
from alphabeta import alphabeta_search, Game
def load_words():
with open('words.dic', 'r') as wordfile:
words = [word.strip() for word in wordfile]
return words
def is_neighbour(word_a, word_b):
letters_same = [letter == word_b[i] for i, letter in enumerate(word_a)]
return letters_same.count(False) == 1 # exactly one letter different
def create_adjacencies(words):
return {
key_word: [word for word in words if is_neighbour(key_word, word)]
for key_word in words
}
class WordGame(Game):
def __init__(self, adjacencies, num_players=2):
self.adjacencies = adjacencies
self.num_players = num_players
def legal_moves(self, state):
"Return a list of the allowable moves at this point."
word, used_words, player = state
if word is None:
return [
move for move, words in self.adjacencies.items()
if len(words) > 1
]
else:
candidate_moves = list(set(self.adjacencies[word]) - set(used_words))
return candidate_moves
def make_move(self, move, state):
"Return the state that results from making a move from a state."
word, used_words, player = state
used_words = set(used_words)
used_words.add(word)
return (move, used_words, self.to_move(state))
def to_move(self, state):
_, _, player = state
return (player + 1) % self.num_players
def utility(self, state, player):
"Return the value of this final state to player."
moves = self.legal_moves(state)
word, last_state, curr_player = state
if len(moves) == 0:
if player == curr_player:
return 1
else:
return -1
else:
return 0
def run_game():
print 'loading...'
words = load_words()
adjacencies = create_adjacencies(words)
num_humans = input('Number of Humans: ')
num_ais = input('Number of AIs: ')
num_players = num_humans + num_ais
humans = []
ais_registered = 0
i = 0
while len(humans) < num_humans:
humans.append(i)
i += 1
if ais_registered < num_ais:
ais_registered += 1
i += 1
game = WordGame(adjacencies, num_players)
state = (None, set(), 0)
while True:
word, used_words, player = state
print 'Turn: %s' % chr(player + 65)
if player in humans:
legal_moves = game.legal_moves(state)
while True:
action = raw_input('Your word: ')
if action in used_words:
print '%s has already been used' % action
elif action not in legal_moves:
print '%s is not valid' % action
print 'Try: %s' % ', '.join(legal_moves)
else:
break
else:
if word is None:
action = game.legal_moves(state)[0]
else:
action = alphabeta_search(state, game, d=6)
print 'Their word: %s' % action
state = game.make_move(action, state)
if game.terminal_test(state):
word, _, player = state
print 'Game Over! %s wins.' % word
print '%s has neighbours: %s' % (word, ', '.join(adjacencies[word]))
print 'which have all been used.'
break
run_game()
abet
able
ably
abut
acct
acer
aces
ache
achy
acid
acme
acne
acre
acts
adds
adze
aeon
aero
afar
afro
agar
aged
ages
agog
ague
ahas
ahem
ahoy
aide
aids
ails
aims
airs
airy
ajar
akin
alas
alba
alee
ales
alga
alls
ally
alms
aloe
also
alto
alum
amen
amid
amir
ammo
amok
amps
amyl
anal
anew
ankh
anon
ante
anti
ants
anus
aped
aper
apes
apex
apse
aqua
arch
arcs
area
aren
argy
aria
arid
arks
arms
army
arts
arty
arum
asap
ashy
asks
asps
assn
asst
ates
atom
atop
auks
aunt
aura
auto
aver
aves
avid
avow
away
awed
awes
awls
awns
awry
axed
axes
axil
axis
axle
axon
ayah
ayes
baas
babe
baby
back
bade
bags
bahs
bail
bait
bake
bald
bale
ball
balm
band
bane
bang
bank
bans
barb
bard
bare
barf
bark
barn
bars
base
bash
bask
bass
bast
bate
bath
bats
baud
bawd
bawl
bays
bdrm
bead
beak
beam
bean
bear
beat
beau
beck
beds
beef
been
beep
beer
bees
beet
begs
bell
belt
bely
bend
bent
berg
berm
best
beta
bets
bevy
bias
bibs
bide
bids
bier
bike
bile
bilk
bill
bind
bins
biog
biol
bird
bite
bits
blab
blah
bldg
bled
blew
blip
blob
bloc
blot
blow
blue
blur
blvd
boar
boas
boat
bobs
bock
bode
bods
body
bogs
boil
bola
bold
bole
boll
bolt
bomb
bona
bond
bone
bong
bony
boob
book
boom
boon
boor
boos
boot
bops
bore
born
bosh
boss
both
bots
bout
bowl
bows
boxy
boys
bozo
brad
brae
brag
bran
bras
brat
bray
bred
brew
bric
brig
brim
brio
brow
bubo
buck
buds
buff
bugs
bulb
bulk
bull
bump
bums
bung
bunk
buns
bunt
buoy
burg
burl
burn
burp
burr
burs
bury
bush
busk
bust
busy
buts
butt
buys
buzz
byes
byre
byte
cabs
cads
cage
cake
calf
call
calm
came
camp
cams
cane
cans
cant
cape
capo
caps
card
care
carp
cars
cart
case
cash
cask
cast
cats
cave
caws
cays
cede
cell
cent
cert
chap
char
chat
chef
chem
chew
chge
chic
chin
chip
chit
chop
chow
chub
chug
chum
ciao
cine
cite
city
clad
clam
clan
clap
claw
clay
clef
clew
clip
clod
clog
clop
clot
cloy
club
clue
coal
coat
coax
cobs
coca
cock
coco
coda
code
cods
coed
cogs
coho
coif
coil
coin
coke
cola
cold
coll
cols
colt
coma
comb
come
comm
comp
cone
conk
cons
cont
cony
cook
cool
coop
coos
coot
cope
cops
copy
cord
core
corf
cork
corm
corn
corp
corr
cost
cosy
cote
cots
coup
cove
cowl
cows
crab
crag
cram
crap
craw
crew
crib
crop
crow
crud
crux
cube
cubs
cuds
cued
cues
cuff
cull
cult
cums
cunt
cups
curb
curd
cure
curl
curs
curt
cusp
cuss
cute
cuts
cyan
cyst
czar
dabs
dace
dado
dads
daft
dais
dale
dame
damn
damp
dams
dank
dare
dark
darn
dart
dash
data
date
daub
dawn
days
daze
dead
deaf
deal
dean
dear
debs
debt
deck
deed
deem
deep
deer
deft
defy
deja
deli
dell
demi
demo
dens
dent
deny
desk
dews
dewy
dhow
dial
diam
dibs
dice
dick
didn
died
diem
dies
diet
digs
dike
dill
dime
dims
dine
ding
dins
dint
dips
dire
dirk
dirt
disc
dish
disk
ditz
diva
dive
dock
docs
dodo
doer
does
doff
doge
dogs
dogy
dole
doll
dolt
dome
dona
done
dong
dons
doom
door
dopa
dope
dork
dorm
dory
dose
doss
dost
dote
doth
dots
dour
dove
down
doze
dozy
drab
drag
dram
drat
draw
dray
dreg
drew
drip
drop
drub
drug
drum
dual
dubs
duck
duct
dude
duds
duel
dues
duet
duff
dugs
duke
dull
duly
dumb
dump
dune
dung
dunk
duns
duos
dupe
dusk
dust
duty
dyad
dyed
dyer
dyes
dyke
dyne
each
earl
earn
ears
ease
east
easy
eats
eave
ebbs
echo
ecru
eddy
edge
edgy
edit
educ
eels
egad
eggs
egis
egos
eked
ekes
elks
ells
elms
else
emfs
emir
emit
empt
emus
encl
ends
entr
envy
epic
eras
ergo
ergs
errs
erst
espy
etch
even
ever
eves
evil
ewer
ewes
exam
exec
exit
expo
eyed
eyer
eyes
face
fact
fade
fads
faff
fags
fail
fain
fair
fake
fall
fame
fang
fans
fare
farm
faro
fart
fast
fate
fats
faun
faux
fawn
fays
faze
fear
feat
feed
feel
fees
feet
fell
felt
fend
fens
fern
fess
feta
feud
fiat
fibs
fief
fife
figs
file
fill
film
find
fine
fins
fire
firm
firs
fish
fist
fits
five
fizz
flab
flag
flak
flan
flap
flat
flaw
flax
flay
flea
fled
flee
flew
flex
flip
flit
floe
flog
flop
flow
flue
flux
foal
foam
fobs
foci
foes
fogs
fogy
foil
fold
folk
foll
fond
font
food
fool
foot
fops
fora
ford
fore
fork
form
fort
foul
four
fowl
foxy
frap
fray
free
freq
fret
frig
frog
from
fros
fuck
fuel
full
fume
fumy
fund
funk
furl
furs
fury
fuse
fuss
fuzz
gabs
gads
gaff
gaga
gage
gags
gain
gait
gala
gale
gall
game
gamy
gang
gaol
gape
gaps
garb
gash
gasp
gate
gave
gawk
gays
gaze
gear
geed
gees
geld
gels
gems
gene
gent
geog
geom
germ
gets
ghat
gibe
gift
gigs
gild
gill
gilt
gimp
gins
gird
girl
giro
girt
gist
give
glad
glee
glen
glib
glim
glob
glow
glue
glum
glut
gnat
gnaw
gnus
goad
goal
goat
gobs
gods
goer
goes
gold
golf
gone
gong
good
goof
goon
gore
gory
gosh
gout
gown
grab
gram
grew
grey
grid
grim
grin
grip
grit
grog
grok
grow
grub
guff
gulf
gull
gulp
gums
gunk
guns
guru
gush
gust
guts
guys
gybe
gyms
gyps
hack
hadj
hadn
haem
haft
hags
hail
hair
hajj
hake
hale
half
hall
halo
halt
hams
hand
hang
hank
haps
hara
hard
hare
hark
harm
harp
hart
hash
hasn
hasp
hast
hate
hats
haul
have
hawk
haws
hays
haze
hazy
head
heal
heap
hear
heat
hebe
heck
heed
heel
heft
heir
held
hell
helm
help
hemp
hems
hens
herb
herd
here
hero
hers
hewn
hews
hgwy
hide
hies
high
hike
hill
hilt
hind
hint
hips
hire
hiss
hist
hits
hive
hoar
hoax
hobs
hock
hods
hoed
hoer
hoes
hogs
hold
hole
holy
home
homo
hone
honk
hood
hoof
hook
hoop
hoot
hope
hops
horn
hose
hosp
host
hots
hour
hove
howl
hows
html
http
hubs
hues
huff
huge
hugs
huhs
hula
hulk
hull
hump
hums
hung
hunk
hunt
hurl
hurt
hush
husk
huts
hwyl
hymn
hype
hypo
iamb
ibex
ibid
ibis
iced
ices
icky
icon
idea
idem
ides
idle
idly
idol
iffy
ilea
ilia
ills
illy
imam
imps
inch
info
inks
inky
inly
inns
inst
into
ions
iota
ipso
ired
ires
iris
irks
iron
isle
isms
itch
item
jabs
jack
jade
jags
jail
jamb
jams
jape
jars
jato
jaws
jays
jazz
jean
jeer
jeez
jell
jerk
jess
jest
jets
jibe
jibs
jiff
jigs
jilt
jinn
jinx
jive
jobs
jock
joey
jogs
john
join
joke
joky
jolt
jong
joss
jots
jowl
joys
judo
jugs
jump
junk
jury
just
jute
juts
kale
kart
kayo
kbps
kcal
keel
keen
keep
kegs
kelp
keno
kens
kepi
kept
kerb
keys
khan
kick
kids
kill
kiln
kilo
kilt
kind
kine
king
kink
kins
kips
kiri
kirk
kiss
kite
kith
kits
kiwi
knee
knew
knit
knob
knot
know
kola
kook
kyle
labs
lace
lack
lacs
lacy
lade
lads
lady
lags
laid
lain
lair
lake
lama
lamb
lame
lamp
lams
land
lane
lank
laps
lard
lark
lase
lash
lass
last
late
lath
laud
lava
lave
lawn
laws
lays
laze
lazy
lead
leaf
leak
lean
leap
leas
leek
leer
lees
left
legs
leis
lend
lens
lent
less
lest
lets
levy
lewd
liar
libs
lice
lick
lido
lids
lied
lief
lien
lier
lies
lieu
life
lift
like
lilt
lily
limb
lime
limn
limo
limp
limy
line
ling
link
lino
lint
lion
lips
lira
lire
lisp
list
live
load
loaf
loam
loan
lobe
lobs
loch
loci
lock
loco
lode
loft
loge
logo
logs
loin
loll
lone
long
look
loom
loon
loop
loot
lope
lops
lord
lore
lorn
lose
loss
lost
lots
loud
lour
lout
love
lows
luau
lube
luck
ludo
luff
luge
lugs
lull
lulu
lump
lune
lung
lure
lurk
lush
lust
lute
luxe
lynx
lyre
mace
mack
macs
made
magi
maid
mail
maim
main
make
male
mall
malt
mama
mane
many
maps
mare
mark
marl
mart
masc
mash
mask
mass
mast
mate
mats
matt
maul
maws
maxi
mayn
maze
mazy
mdse
mead
meal
mean
meat
meed
meek
meet
mega
meld
melt
memo
mend
menu
meow
mere
mesa
mesh
mess
meta
mete
mewl
mews
mfrs
mica
mice
midi
mien
miff
mike
mild
mile
milk
mill
milt
mime
mind
mine
mini
mink
mint
minx
mire
miry
misc
miss
mist
mite
mitt
moan
moat
mobs
mock
mode
modi
mods
moil
mole
moll
monk
mono
mood
moon
moor
moos
moot
mope
mops
mopy
more
morn
moss
most
mote
moth
mots
moue
move
mown
mows
much
muck
muds
muff
mugs
mule
mull
mums
muon
murk
muse
mush
musk
must
mute
mutt
myna
myth
nabs
naff
nags
nail
name
nano
nape
naps
nark
nary
natl
nave
navy
nays
neap
near
neat
neck
need
neon
nerd
nest
nets
nett
news
newt
next
nibs
nice
nick
nigh
nine
nips
nits
node
nods
noes
none
nook
noon
nope
norm
nose
nosh
nosy
note
nots
noun
nous
nova
nowt
nubs
nude
nuke
null
numb
nuns
nuts
oafs
oaks
oars
oath
oats
obey
obit
oboe
odds
odes
ogle
ogre
ohms
ohos
oils
oily
oink
okay
okra
oles
omen
omit
omni
once
oner
ones
only
onto
onus
onyx
oohs
oops
ooze
oozy
opal
open
opts
opus
oral
orbs
ores
orgy
orig
ouch
ours
oust
outs
ouzo
oval
oven
over
ovum
owed
owes
owls
owns
oxen
pace
pack
pact
pads
page
paid
pail
pain
pair
pale
pall
palm
pals
pane
pang
pans
pant
papa
para
pare
park
pars
part
pass
past
pate
path
pats
pave
pawl
pawn
paws
pays
peak
peal
pear
peas
peat
peck
peek
peel
peen
peep
peer
pees
pegs
peke
pelf
pell
pelt
pens
pent
peon
peps
perk
perm
pert
peso
pest
pets
pews
phew
phis
phys
pica
pick
pico
pied
pier
pies
pigs
pike
pile
pill
pimp
pine
ping
pink
pins
pint
piny
pion
pipe
pips
piss
pita
pith
pits
pity
plan
plat
play
plea
pleb
plod
plop
plot
ploy
plug
plum
plus
pock
pods
poem
poet
pogo
poke
poky
pole
poll
polo
poly
pomp
pond
pone
pong
pons
pony
poof
pooh
pool
poop
poor
pope
pops
pore
pork
porn
port
pose
posh
post
posy
pots
pour
pout
pram
pray
pref
prep
prey
prig
prim
prod
prof
prom
prop
pros
prow
psst
pubs
puce
puck
puff
pugs
puke
pule
pull
pulp
puma
pump
punk
puns
punt
puny
pupa
pups
pure
purl
purr
push
puss
puts
putt
pyre
quad
quay
quid
quip
quit
quiz
race
rack
racy
raff
raft
raga
rage
rags
raid
rail
rain
rake
ramp
rams
rand
rang
rank
rans
rant
rape
raps
rapt
rare
rash
rasp
rate
rats
rave
rays
raze
read
real
ream
reap
rear
redo
reds
reed
reef
reek
reel
rein
rely
rend
rent
reps
rest
revs
rhea
rial
ribs
rice
rich
rick
ride
rids
rife
riff
rift
rigs
rile
rill
rime
rims
rind
ring
rink
riot
ripe
rips
rise
risk
rite
rive
road
roam
roan
roar
robe
robs
rock
rode
rods
roes
roil
role
roll
roly
romp
rood
roof
rook
room
root
rope
rose
rosy
rota
rote
rots
rout
rove
rows
rubs
ruby
ruck
rude
rued
rues
ruff
rugs
ruin
rule
rump
rums
rune
rung
runs
runt
ruse
rush
rusk
rust
ruts
ryes
sack
safe
saga
sage
sago
sags
said
sail
sake
saki
sale
salt
same
sand
sane
sang
sank
sans
saps
sari
sash
sate
save
sawn
saws
says
scab
scad
scam
scan
scar
scat
scot
scud
scum
seal
seam
sear
seas
seat
sect
seed
seek
seem
seen
seep
seer
sees
self
sell
semi
send
sent
sept
seqq
sera
sere
serf
sets
sett
sewn
sews
sexy
shag
shah
sham
shan
shed
shim
shin
ship
shit
shod
shoe
shoo
shop
shot
show
shun
shut
sick
side
sift
sigh
sign
silk
sill
silo
silt
sine
sing
sink
sins
sips
sire
sirs
site
sits
size
skew
skid
skim
skin
skip
skis
skit
skol
skua
slab
slag
slam
slap
slat
slay
sled
slew
slid
slim
slip
slit
slob
sloe
slog
slop
slot
slow
slue
slug
slum
slur
slut
smog
smug
smut
snag
snap
snip
snob
snot
snow
snub
snug
soak
soap
soar
sobs
sock
soda
sods
sofa
soft
soil
sold
sole
solo
soma
some
song
sons
soon
soot
sops
sore
sort
sots
soul
soup
sour
sous
sown
sows
soya
spam
span
spar
spas
spat
spay
sped
spew
spin
spit
spot
spry
spud
spun
spur
sqrt
stab
stag
star
stay
stem
step
stet
stew
stir
stop
stow
stub
stud
stun
subs
such
suck
suds
sued
suer
sues
suet
suit
sulk
sumo
sump
sums
sung
sunk
suns
sups
surd
sure
surf
suss
swab
swag
swam
swan
swap
swat
sway
swig
swim
swot
swum
sync
tabs
tack
taco
tact
tags
tail
take
talc
tale
talk
tall
tame
tamp
tang
tank
tans
tape
taps
tare
tarn
taro
tars
tart
task
tats
taut
taxi
teak
teal
team
tear
teas
teat
teed
teem
teen
tees
tell
temp
tend
tens
tent
term
tern
test
text
than
that
thaw
thee
them
then
they
thin
this
thou
thud
thug
thus
tick
tide
tidy
tied
tier
ties
tiff
tike
tile
till
tilt
time
tine
ting
tins
tint
tiny
tips
tire
tits
tizz
toad
tock
toed
toes
tofu
toga
togs
toil
told
toll
tomb
tome
toms
tone
tong
tons
took
tool
toot
tops
tore
torn
torr
tort
toss
tote
tots
tour
tout
town
tows
toys
tram
trap
tray
tree
trek
trig
trim
trio
trip
trod
trot
troy
true
tsar
tuba
tube
tubs
tuck
tuft
tugs
tuna
tune
tuns
turd
turf
turn
tush
tusk
tuts
tutu
twee
twig
twin
twit
twos
tyke
type
typo
tyre
tyro
tzar
ugly
ulna
undo
unit
unto
upon
urea
urge
uric
urns
used
user
uses
utan
uucp
vain
vale
vamp
vane
vans
vary
vase
vast
vats
veal
veer
veil
vein
veld
vend
vent
verb
very
vest
veto
vets
vial
vibe
vice
vied
vies
view
viii
vile
vine
vino
viol
visa
vita
viva
void
vole
volt
vote
vows
wade
wads
waft
wage
wags
waif
wail
wait
wake
wale
walk
wall
wand
wane
want
ward
ware
warm
warn
warp
wars
wart
wary
wash
wasn
wasp
wast
watt
wave
wavy
waxy
ways
weak
weal
wean
wear
webs
weds
weed
week
weep
weft
weir
weld
well
welt
wend
went
wept
were
west
wets
wham
what
when
whet
whew
whey
whim
whip
whir
whit
whiz
whoa
whom
whoo
whop
whys
wick
wide
wife
wigs
wild
wile
will
wilt
wily
wimp
wind
wine
wing
wink
wino
wins
winy
wipe
wire
wiry
wise
wish
wisp
with
wits
woad
woes
woke
woks
wolf
womb
wont
wood
woof
wool
woos
wops
word
wore
work
worm
worn
wove
wows
wrap
wren
writ
xiii
yack
yams
yang
yank
yaps
yard
yarn
yawl
yawn
yaws
yeah
year
yeas
yell
yelp
yens
yeti
yews
yobs
yoga
yogi
yoke
yolk
yore
your
yowl
zany
zaps
zeal
zebu
zeds
zero
zest
zeta
zinc
zing
zips
zone
zoom
zoos
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment