-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomp_algs.py
167 lines (139 loc) · 5.54 KB
/
comp_algs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import pandas as pd
import numpy as np
import holoviews as hv
import param
import paramnb
import sys
from holoviews.util import Dynamic
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.layouts import layout, widgetbox, column
from bokeh.models import Select
from bokeh.plotting import curdoc
from parsing import parsing
from sorting import diffCalc
hv.extension('bokeh', 'matplotlib')
GAME = sys.argv[1] if len(sys.argv) > 1 else 'leduc3'
PLAYERS = ['P1','P2']
PLAYER = sys.argv[2] if (len(sys.argv) > 2 and sys.argv[2] in PLAYERS) else 'P1'
GAMEFILE = 'games/%s.txt' % GAME
GAME_SEQ = 'json/%s_sequences.json' % GAME
SORTS = ['diff','square']
SORT = sys.argv[3] if ((len(sys.argv) > 3 and sys.argv[3] in SORTS) or
sys.argv[3].startswith('reachIterate=')) else 'diff'
ALGS = sys.argv[4:]
ITERATE = int(SORT[len('reachIterate='):]) if SORT.startswith('reachIterate=') else 500
renderer = hv.renderer('bokeh')
dict_spec = {
'Curve' : {'plot': {'height': 500, 'width': 500}}
}
hv.opts(dict_spec)
def render(obj):
plot = renderer.get_plot(obj)
size = renderer.get_size(plot)
return renderer._figure_data(plot), size
playerData = dict() # map of algName -> (p1,p2)
genFunctions = dict() # map of algName -> genCurvesAlg
tableFunctions = dict() # map of algName -> genTableAlg
def makeGenerator(p1,p2,actions,alg):
def genCurves(infoset=p1.keys()[0],player=PLAYER,**kwargs):
'''
generate the Holoview Curves object corresponding to the infoset
'''
iS = p1[infoset] if player == 'P1' else p2[infoset]
curves = None
for action in actions:
xs = [x+1 for x in range(len(iS.probs))]
ys = [iS.probs[j][action] for j in range(len(iS.probs))]
curve = hv.Curve((xs,ys),('Iterations','Iterations'),
(action,'Probability of '+action),
label=action,
extents=(0.0,0.0,len(iS.probs),1.0),
group=alg)
if curves == None:
curves = curve
else:
curves = curves * curve
return curves
return genCurves
def tableGenerator(p1,p2):
def genTable(infoset=p1.keys()[0],player=PLAYER,**kwargs):
'''
generate a Table object containing the reach of the infoset
'''
iS = p1[infoset] if player == 'P1' else p2[infoset]
label = 'Reach at iterate %d for %s' % (ITERATE, iS.alg)
idx = ITERATE if (0 <= ITERATE and ITERATE < len(iS.reach)) else (len(iS.reach) - 1)
return hv.Table(([iS.reach[idx]],),[label])
return genTable
for curAlg in ALGS:
GAMEDATA = 'json/%s_%s.json' % (GAME, curAlg)
p1,p2,actions = parsing.processInfosets(GAMEFILE)
parsing.processSeqIDs(p1,p2,GAME_SEQ)
parsing.getData(p1,p2,actions,GAMEDATA, curAlg)
playerData[curAlg] = (p1,p2)
genFunctions[curAlg] = makeGenerator(p1,p2,actions,curAlg)
tableFunctions[curAlg] = tableGenerator(p1,p2)
def convDmap(iList, alg):
istream = hv.streams.Stream.define('%s Infoset' % PLAYER,
infoset=iList[0].name)()
f = genFunctions[alg]
g = tableFunctions[alg]
dmap = hv.DynamicMap(f,streams=[istream])
table = hv.DynamicMap(g,streams=[istream])
return iList, istream, dmap, table, alg
depths = dict() # map of algName -> 2D list of infosets at proper depths
dmaps = []
infosetDicts = []
extractTuple = (lambda(x,y): x) if PLAYER == 'P1' else (lambda(x,y): y)
for algName, tup in playerData.items():
infosetDicts.append(extractTuple(tup))
diffCalc(infosetDicts,SORT)
arbitrary = infosetDicts[0]
for j in range(max([i.depth for i in arbitrary.values()]) + 1):
for alg in ALGS:
if alg not in depths:
depths[alg] = []
depths[alg].append([])
for infosetDict in infosetDicts:
for i in infosetDict.values():
depths[i.alg][i.depth].append(i)
arbitraryDepth = depths.values()[0]
for d in range(len(arbitraryDepth)):
dmaps.append([])
for alg in ALGS:
algDepth = depths[alg]
algDepth[d].sort(key=lambda i: i.grad, reverse=True)
curList = algDepth[d]
if len(curList) > 0:
dmaps[d].append(convDmap(curList,alg))
dmaps = filter(lambda l : len(l) > 0, dmaps)
def modify_doc(doc):
# Create HoloViews plot and attach the document
def getPlots(mapList):
n = len(mapList)
iStreams = []
hvplots = []
tables = []
(arbList,arbStream,arbmap,arbTable,arbAlg) = mapList[0]
for (l,s,d,t,a) in mapList:
hvplots += [renderer.get_plot(d, doc)]
tables += [renderer.get_plot(t,doc)]
iStreams += [s]
def update(attname, old, new):
for stream in iStreams:
stream.event(infoset=new)
select = Select(title='%s Infosets at Depth %d' %
(PLAYER, arbList[0].depth),
value=arbList[0].name,
options=[i.name for i in arbList],
width=200,height=100)
select.on_change('value',update)
return select, hvplots, tables
rows = [getPlots(mapList) for mapList in dmaps]
# Combine the holoviews plot and widgets in a layout
matrix = [([widgetbox([s])] + [column([p.state,t.state]) for p,t in zip(plots,tables)]) for (s,plots,tables) in rows]
plot = layout(matrix,sizing_mode='fixed')
doc.add_root(plot)
return doc
doc = modify_doc(curdoc())