initital commit

This commit is contained in:
wjsjwr 2018-03-11 17:16:26 +08:00
commit 9fd025d3a7
18 changed files with 891 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.DS_Store
graph
wos-data-new
wos-data-casual
*.svg
__pycache__

1
.vscode/database.json vendored Normal file
View File

@ -0,0 +1 @@
{}

0
.vscode/settings.json vendored Normal file
View File

49
actions_after_defect.py Normal file
View File

@ -0,0 +1,49 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-new')
labels = ['link', 'unlink']
percents = [0.0, 0.0]
for m in matches.data:
info = m.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
for row in m.query('action', 'done').where(lambda x: x['act_a'] == 'D' or x['act_b'] == 'D').raw_data:
if row['rno'] == game_end_at:
print(row)
continue
if row['act_a'] == 'D':
a = row['a']
b = row['b']
n = m.query('action', 'done').where(lambda y: ((y['a'] == a and y['b'] == b) or (y['a'] == b and y['b'] == a)) and y['rno'] == row['rno'] + 1).raw_data
if n:
percents[0] += 1
else:
percents[1] += 1
if row['act_b'] == 'D':
a = row['a']
b = row['b']
n = m.query('action', 'done').where(lambda y: ((y['a'] == a and y['b'] == b) or (y['a'] == b and y['b'] == a)) and y['rno'] == row['rno'] + 1).raw_data
if n:
percents[0] += 1
else:
percents[1] += 1
_all = sum(percents) / 100
percents[0] /= _all
percents[1] /= _all
plt.figure()
patches, texts, autotexts = plt.pie(percents, labels=labels, autopct='%1.1f%%', startangle=90)
for t in texts:
t.set_size('xx-large')
plt.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
# plt.savefig('graph/actions_after_defect.png')

61
after_d_link_tr.py Normal file
View File

@ -0,0 +1,61 @@
import json
from matplotlib import pyplot as plt
from matplotlib.ticker import PercentFormatter
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-new')
lx=[]
ly=[]
h = []
for m in matches.data:
info = m.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
for row in m.query('action', 'done').where(lambda x: x['act_a'] == 'D' or x['act_b'] == 'D').raw_data:
if row['rno'] == game_end_at:
print(row)
continue
if row['act_a'] == 'D':
a = row['a']
b = row['b']
n = m.query('action', 'done').where(lambda y: ((y['a'] == a and y['b'] == b) or (y['a'] == b and y['b'] == a)) and y['rno'] == row['rno'] + 1).raw_data
if n:
h.append(n[0]['tr'])
if n[0]['tr'] in lx:
ly[lx.index(n[0]['tr'])] += 1
else:
lx.append(n[0]['tr'])
ly.append(1)
if row['act_b'] == 'D':
a = row['a']
b = row['b']
n = m.query('action', 'done').where(lambda y: ((y['a'] == a and y['b'] == b) or (y['a'] == b and y['b'] == a)) and y['rno'] == row['rno'] + 1).raw_data
if n:
h.append(n[0]['tr'])
if n[0]['tr'] in lx:
ly[lx.index(n[0]['tr'])] += 1
else:
lx.append(n[0]['tr'])
ly.append(1)
al = sum(ly)
ly = map(lambda y: float(y) / float(al), ly)
_bin = [x * 120 for x in range(13)]
fig = plt.figure()
n,b,p = plt.hist(h, _bin, normed=True, ec='k')
ax = fig.gca()
ax.yaxis.set_major_formatter(PercentFormatter(xmax=sum(n)))
print(n)
print(b)
print(p)
print(sum(n))
# plt.show()
plt.savefig('graph/after_d_link_tr.png')

35
calc_winner_pid.py Normal file
View File

@ -0,0 +1,35 @@
import json
from pathlib import Path
from island.match import Match
result = {}
for file in Path('wos-data-new').iterdir():
p = Path(file)
if p.suffix == '.json':
name = p.stem
m = Match.read_from_json(str(file))
info = m.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
players = []
foods = {}
for p in m.query('player', 'join').select('pid').raw_data:
foods[p['pid']] = conf['start_resource']
for i in range(1, game_end_at+1):
for a in m.query('action', 'done').where(lambda x: x['rno'] == i).raw_data:
foods[a['a']] += conf['payoffs']["%s%s"%(a['act_a'], a['act_b'])][0] * a['tr'] / 1440.0
foods[a['b']] += conf['payoffs']["%s%s"%(a['act_a'], a['act_b'])][1] * a['tr'] / 1440.0
for j in foods.keys():
foods[j] -= conf['rounds']['consumption']
for j in foods.keys():
if foods[j] > 0:
players.append(j)
result[name] = players
print(json.dumps(result))

55
coopr_per_match.py Normal file
View File

@ -0,0 +1,55 @@
import json
from matplotlib import pyplot as plt
import scipy as sp
from island.match import Match
from island.matches import Matches
def error(f,x,y):
return sp.sum((f(x)-y)**2)
matches = Matches('wos-data-new')
max_round = 17
coopr = []
data = {}
x = []
_x = []
survivals = {}
with open('winner.json','r') as f:
survivals = json.load(f)
for j in range(len(matches.data)):
coop = 0
rows = matches.data[j].query('action', 'done').raw_data
info = matches.data[j].query('game', 'created').select('info').raw_data[0]['info']
ns = int(info['next_start'])
for row in rows:
if row['act_a'] == 'C' and row['act_b'] == 'C':
coop += 1
if rows:
data[ns] = float(coop) / len(rows)
x.append(ns)
x = sorted(x)
for i in range(len(x)):
_x.append(i)
coopr.append(data[x[i]])
fig = plt.figure()
plt.scatter(_x, coopr)
ax = fig.gca()
plt.ylim(0,1)
fp1,residuals,rank,sv,rcond = sp.polyfit(_x, coopr, 1, full=True)
print("残差:",residuals)
print('Model parameter:',fp1)
f1 = sp.poly1d(fp1)
print(error(f1, _x, coopr))
fx = sp.linspace(0,_x[-1],1000)
plt.plot(fx,f1(fx),linewidth=1,color='red')
# plt.show()
plt.savefig('graph/co_per_game.png')

45
coopr_per_round.py Normal file
View File

@ -0,0 +1,45 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-new')
max_round = 17
coopr = []
yerr_min = []
yerr_max = []
x = []
bx = []
survivals = {}
with open('winner.json','r') as f:
survivals = json.load(f)
for i in range(max_round):
co = []
for j in range(len(matches.data)):
coop = 0
rows = matches.data[j].query('action', 'done').where(lambda x: x['rno']==i+1).raw_data
for row in rows:
if row['act_a'] == 'C' and row['act_b'] == 'C':
coop += 1
if rows:
co.append(float(coop) / float(len(rows)))
bx.append(co)
if co:
coopr.append(sum(co) / len(co))
yerr_min.append(coopr[-1] - min(co))
yerr_max.append(max(co) - coopr[-1])
print("%f, %f, %f"%(yerr_min[-1], yerr_max[-1], coopr[-1]))
x.append(i+1)
plt.figure()
# plt.errorbar(x, coopr, yerr=[yerr_min, yerr_max], fmt='o', capsize=4)
plt.boxplot(bx, showmeans=True, meanline=True)
# plt.show()
plt.savefig('graph/co_per_round.png')

46
defector_has_neighbor.py Normal file
View File

@ -0,0 +1,46 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-new')
labels = ['has neighbor', 'no neighbor']
percents = [0.0, 0.0]
for m in matches.data:
info = m.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
for row in m.query('action', 'done').where(lambda x: x['act_a'] == 'D' or x['act_b'] == 'D').raw_data:
if row['rno'] == game_end_at:
print(row)
continue
if row['act_a'] == 'D':
a = row['a']
b = row['b']
o = m.query('action', 'done').where(lambda y: (y['b'] == a or y['a'] == a) and y['rno'] == row['rno'] + 1).raw_data
if o:
percents[0] += 1
else:
percents[1] += 1
if row['act_b'] == 'D':
a = row['a']
b = row['b']
o = m.query('action', 'done').where(lambda y: (y['b'] == b or y['a'] == b) and y['rno'] == row['rno'] + 1).raw_data
if o:
percents[0] += 1
else:
percents[1] += 1
_all = sum(percents) / 100
percents[0] /= _all
percents[1] /= _all
plt.figure()
plt.pie(percents, labels=labels, autopct='%1.1f%%', startangle=90)
plt.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
# plt.savefig('graph/unlink_has_neighbor.png')

285
draw_game_history.py Normal file
View File

@ -0,0 +1,285 @@
import json
import math
from cairo import Context, LineCap, LineJoin, PSSurface, SVGSurface
# from scipy.integrate import quad
from island.match import Match
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def move_to(self, newx, newy):
self.x = newx
self.y = newy
def rel_move_to(self, offx, offy):
self.x += offx
self.y += offy
def new_rel_point(self, offx, offy):
return Point(self.x + offx, self.y + offy)
class Color:
def __init__(self, r = 0, g = 0, b = 0, a = 0):
self.r = r
self.g = g
self.b = b
self.a = a
def shade(self, percentage):
return Color(self.r, self.g, self.b, 0.8 * percentage + 0.2)
def set_color(ctx, color):
"""
:param ctx: context
:param color: the Color
"""
ctx.set_source_rgba(color.r, color.g, color.b, color.a)
def draw_alive_face(ctx, pt, r, w):
"""
:param ctx: context
:param pt: the center point
:param r: radius
:param w: line width
"""
ctx.new_path()
ctx.set_source_rgba(1, 1, 1, 1)
ctx.set_line_width(w)
ctx.arc(pt.x, pt.y, r, 0, 2*math.pi)
ctx.fill()
ctx.set_source_rgba(0, 0, 0, 1)
ctx.arc(pt.x, pt.y, r, 0, 2*math.pi)
ctx.stroke()
ctx.arc(pt.x - r / SQRT2 / 2, pt.y - r / SQRT2 / 2, r / 10, 0, 2 * math.pi)
ctx.fill()
ctx.arc(pt.x + r / SQRT2 / 2, pt.y - r / SQRT2 / 2, r / 10, 0, 2 * math.pi)
ctx.fill()
ctx.set_line_cap(LineCap.ROUND)
ctx.arc(pt.x, pt.y, r * GOLDEN_SECTION, math.pi / 4, math.pi / 4 * 3)
ctx.stroke()
def draw_dead_face(ctx, pt, r, w):
"""
:param ctx: context
:param pt: the center point
:param r: radius
:param w: line width
"""
ctx.set_line_cap(LineCap.ROUND)
ctx.set_line_join(LineJoin.ROUND)
ctx.new_path()
ctx.set_source_rgba(1, 1, 1, 1)
ctx.set_line_width(w)
ctx.arc(pt.x, pt.y, r, 0, 2*math.pi)
ctx.fill()
ctx.set_source_rgba(0.5, 0.5, 0.5, 1)
ctx.arc(pt.x, pt.y, r, 0, 2*math.pi)
ctx.stroke()
offset = r / 6 * SQRT3 / 2
ctx.move_to(pt.x - r / SQRT2 / 2 + offset, pt.y - r / SQRT2 / 2 + r / 6)
ctx.rel_line_to(- r / 6 * SQRT3, - r / 6)
ctx.move_to(pt.x - r / SQRT2 / 2 + offset, pt.y - r / SQRT2 / 2 + r / 6)
ctx.rel_line_to(- r / 6 * SQRT3, r / 6)
ctx.move_to(pt.x + r / SQRT2 / 2 - offset, pt.y - r / SQRT2 / 2 + r / 6)
ctx.rel_line_to(r / 6 * SQRT3, - r / 6)
ctx.move_to(pt.x + r / SQRT2 / 2 - offset, pt.y - r / SQRT2 / 2 + r / 6)
ctx.rel_line_to(r / 6 * SQRT3, r / 6)
ctx.stroke()
a = r * GOLDEN_SECTION
ctx.move_to(pt.x - a / SQRT2, pt.y + a / SQRT2)
step = a / (4 * SQRT2)
for _ in range(4):
ctx.rel_line_to(step, -step)
ctx.rel_line_to(step, step)
ctx.stroke()
def bezier_diff(x, cax, cbx, ccx, cay, cby, ccy):
return math.sqrt((cax + cbx * x + ccx * (x ** 2)) ** 2 + (cay + cby * x + ccy * (x ** 2)) ** 2)
def calc_bezier_diff_angle(p0, p1, p2, p3, al):
"""
f(x) = a - 3ax + 3ax^2 - ax^3 + 3bx - 6bx^2 + 3bx^3 + 3cx^2 - 3cx^3 + dx^3
f'(x) = (-3a+3b) + 2(3a - 6b +3c)x + 3(-a+3b-3c+d)x^2
"""
# cax = -3 * p0.x + 3 * p1.x
# cbx = 6 * p0.x - 12 * p1.x + 6 * p2.x
# ccx = -3 * p0.x + 9 * p1.x - 9 * p2.x + 3 * p3.x
# cay = -3 * p0.y + 3 * p1.y
# cby = 6 * p0.y - 12 * p1.y + 6 * p2.y
# ccy = -3 * p0.y + 9 * p1.y - 9 * p2.y + 3 * p3.y
# s = quad(bezier_diff, 0, 1, args=(cax, cbx, ccx, cay, cby, ccy))
# t = 1 - al / s[0] * 1.1
# bx = p0.x * (1-t) ** 3 + 3 * p1.x * t * (1-t) ** 2 + 3 * p2.x * t ** 2 * (1-t) + p3.x * t ** 3
# by = p0.y * (1-t) ** 3 + 3 * p1.y * t * (1-t) ** 2 + 3 * p2.y * t ** 2 * (1-t) + p3.y * t ** 3
# a = math.asin((by - p3.y) / math.sqrt((bx - p3.x) ** 2 + (by - p3.y) ** 2))
# if bx < p3.x:
# a = math.pi - a
a = math.pi * 5 / 4 if p0.x < p3.x else math.pi / 4
return a - math.pi / 30
def draw_action_arrow(ctx, cf, ct, w, al, r, c):
"""
:param ctx: context
:param cf: from the center point
:param ct: to the center point
:param w: line width
:param al: arrow length
:param r: radius
:param c: Color
"""
ctx.set_source_rgba(c.r, c.g, c.b, c.a)
ctx.set_line_width(w)
ctx.set_line_cap(LineCap.ROUND)
ltr = 1 if cf.x < ct.x else -1
af = Point(cf.x + ltr * r / SQRT2, cf.y - ltr * r / SQRT2)
at = Point(ct.x - ltr * r / SQRT2, ct.y - ltr * r / SQRT2)
ctx.move_to(af.x, af.y)
extend = (ltr * (ct.x - cf.x)) ** 0.7
p1 = Point(af.x + ltr * extend / SQRT2, af.y - ltr * extend / SQRT2)
p2 = Point(at.x - ltr * extend / SQRT2, at.y - ltr * extend / SQRT2)
ctx.curve_to(p1.x, p1.y, p2.x, p2.y, at.x, at.y)
a = calc_bezier_diff_angle(af, p1, p2, at, al)
ctx.move_to(at.x, at.y)
ctx.line_to(at.x + al * math.cos(a - math.pi / 12), at.y + al * math.sin(a - math.pi / 12))
ctx.move_to(at.x, at.y)
ctx.line_to(at.x + al * math.cos(a + math.pi / 12), at.y + al * math.sin(a + math.pi / 12))
ctx.stroke()
def draw_food_bar(ctx, refp, food, foodi, w, h):
"""
:param ctx: context
:param refp: reference point, left bottom
:param food: food
:param foodi: initial food
:param w: bar width
:param h: bar height
"""
ctx.set_line_width(w / 10)
ctx.set_line_cap(LineCap.SQUARE)
ctx.set_line_join(LineJoin.MITER)
if food > 0:
foodh = food / foodi * h
ctx.rectangle(refp.x, refp.y - foodh, w, foodh)
set_color(ctx, TAMAMOROKOSHI)
ctx.fill()
ctx.rectangle(refp.x, refp.y - h, w, h)
ctx.set_source_rgba(0, 0, 0, 1)
ctx.stroke()
def draw_faces(ctx, p, f, r, lw):
"""
:param ctx: context
:param p: positions
:param f: foods
:param r: radius
:param lw: line width
"""
for k in p.keys():
if f[k] > 0:
draw_alive_face(context, p[k], r, lw)
else:
draw_dead_face(context, p[k], r, lw)
draw_food_bar(ctx, p[k].new_rel_point(r / SQRT2 + 20, r / SQRT2), f[k], 5, 10, r * SQRT2)
draw_text(ctx, str(k), Point(p[k].x, p[k].y - r - 15), Point(p[k].x, p[k].y - r - 5), CENTER_ALIGNED|MIDDLE_ALIGNED, 12)
def draw_text(ctx, text, tl, rb, align, font_size=None, font_face=None, font_matrix=None, font_options=None):
"""
draw text
:param ctx: context
:param text: the text
:param tl: the top-left reference point
:param rb: the right-bottom reference point
:param align: alignment
:param font_size: float font size
:param font_face: font face
:param font_matrix: font matrix
:param font_options: font options
"""
if font_size is not None:
ctx.set_font_size(font_size)
if font_face is not None:
ctx.set_font_face(font_face)
if font_matrix is not None:
ctx.set_font_matrix(font_matrix)
if font_options is not None:
ctx.set_font_options(font_options)
te = ctx.text_extents(text)
ha = align & 0b00001111
if ha == CENTER_ALIGNED:
x = (rb.x + tl.x - te.width) / 2 - te.x_bearing / 2
elif ha == RIGHT_ALIGNED:
x = rb.x - te.width
else:# ha == LEFT_ALIGNED
x = tl.x - te.x_bearing
va = align & 0b11110000
if va == MIDDLE_ALIGNED:
y = (rb.y + tl.y + te.height) / 2 - (te.height + te.y_bearing) / 2
elif va == BOTTOM_ALIGNED:
y = rb.y
else: #va == TOP_ALIGNED:
y = tl.y + te.height - (te.height + te.y_bearing)
ctx.move_to(x, y)
ctx.show_text(text)
LEFT_ALIGNED = 0b00000001
CENTER_ALIGNED = 0b00000010
RIGHT_ALIGNED = 0b00000100
TOP_ALIGNED = 0b00010000
MIDDLE_ALIGNED = 0b00100000
BOTTOM_ALIGNED = 0b01000000
GOLDEN_SECTION = 0.6180339887
SQRT2 = 1.4142135623
SQRT3 = 1.7320508076
FACE_WIDTH = 100
FACE_INTERVAL = 50
ROUND_HEIGHT = 300
LINEWIDTH = 4
TAMAMOROKOSHI = Color(0.9098039215686275, 0.7137254901960784, 0.2784313725490196, 1)
AKE = Color(0.8, 0.3294117647058824, 0.2274509803921569, 1)
TOKIWA = Color(0.1058823529411765, 0.5058823529411765, 0.2431372549019608, 1)
if __name__ == '__main__':
M = Match.read_from_json("D:\\code\\python\\swdata\\wos-data-new\\G302.json")
info = M.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
P = {}
F = {}
R = 30
for r in M.query('player', 'join').raw_data:
P[r['pid']] = Point(len(F) * FACE_WIDTH + FACE_INTERVAL, ROUND_HEIGHT / 2)
F[r['pid']] = 5
surface = SVGSurface("example.svg", len(P)*(FACE_WIDTH)+FACE_WIDTH, (game_end_at+2)*ROUND_HEIGHT)
context = Context(surface)
for i in range(1, game_end_at + 2):
next_f = F.copy()
for r in M.query('action', 'done').where(lambda row: row['rno'] == i).raw_data:
draw_action_arrow(context, P[r['a']], P[r['b']], LINEWIDTH, 15, R, AKE.shade(r['tr'] / 1440) if r['act_a'] == 'D' else TOKIWA.shade(r['tr']/1440))
draw_action_arrow(context, P[r['b']], P[r['a']], LINEWIDTH, 15, R, AKE.shade(r['tr'] / 1440) if r['act_b'] == 'D' else TOKIWA.shade(r['tr']/1440))
next_f[r['a']] += conf['payoffs']["%s%s"%(r['act_a'], r['act_b'])][0] * r['tr'] / 1440.0
next_f[r['b']] += conf['payoffs']["%s%s"%(r['act_a'], r['act_b'])][1] * r['tr'] / 1440.0
draw_faces(context, P, F, R, LINEWIDTH)
for k in next_f.keys():
F[k] = next_f[k] - conf['rounds']['consumption']
P[k].rel_move_to(0, ROUND_HEIGHT)
surface.finish()

0
island/__init__.py Normal file
View File

98
island/match.py Normal file
View File

@ -0,0 +1,98 @@
"""
一场比赛的数据
"""
import json
class Match:
"""Match"""
def __init__(self, raw, dtype='json'):
"""
:param json_string: string represents data in json format
"""
if dtype == 'json':
self.raw_data = json.loads(raw)
self.dtype = 'json'
else:
self.raw_data = raw
self.dtype = 'mid'
def query(self, cat, act):
"""
start a query
eg. match.query('game', 'created')
:param cat: category
"param act: action
"""
if self.dtype == 'mid':
raise RuntimeError("Query on intermediate result.")
result = []
for entry in self.raw_data:
if entry['cat'] == cat and entry['act'] == act:
result.append(entry)
return Match(result, dtype='mid')
def where(self, where_expr):
"""
add some condition
eg. match.query('player', 'join').where(lambda i: i['pid']==9527)
"""
if self.dtype != 'mid':
raise RuntimeError("Where query on raw data.")
return Match([item for item in self.raw_data if where_expr(item)], dtype='mid')
def orderby(self, key):
"""
sort it!
eg. match.query('player', 'join').where(lambda i: i['pid']<9527).orderby('created_at')
"""
if self.dtype != 'mid':
raise RuntimeError("Orderby query on raw data.")
return Match(sorted(self.raw_data, key=lambda x: x[key]), dtype='mid')
def select(self, key1, *args):
"""
select some columns
eg. match.query('player', 'join')
.select('pid', 'created_at')
.where(lambda i: i['pid']<9527)
.orderby('created_at')
"""
if self.dtype != 'mid':
raise RuntimeError("select query on raw data.")
result = []
keys = [key1]
for k in args:
keys.append(k)
for entry in self.raw_data:
dct = dict.fromkeys(keys)
for k in keys:
dct[k] = entry[k]
result.append(dct)
return Match(result, dtype='mid')
def first(self):
"""
return first result
"""
if self.dtype != 'mid':
raise RuntimeError("first query on raw data.")
rawl = len(self.raw_data)
return self.raw_data[0] if rawl > 0 else None
@staticmethod
def read_from_json(json_path):
"""
从json_path读取json文件并返回Match
:param json_path: path to json file
"""
json_string = ''
with open(json_path, 'r', encoding='utf-8') as file:
json_string = file.read()
return Match(json_string)

13
island/matches.py Normal file
View File

@ -0,0 +1,13 @@
from pathlib import Path
from .match import Match
class Matches:
def __init__(self, logdir):
self.data = []
self.names = []
for file in Path(logdir).iterdir():
if Path(file).suffix == '.json':
self.data.append(Match.read_from_json(str(file)))
self.names.append(Path(file).stem)

45
neighbors_per_round.py Normal file
View File

@ -0,0 +1,45 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-new')
max_round = 17
coopr = []
yerr_min = []
yerr_max = []
x = []
bx = []
survivals = {}
with open('winner.json','r') as f:
survivals = json.load(f)
for i in range(max_round):
co = []
for j in range(len(matches.data)):
nodes = set()
rows = matches.data[j].query('action', 'done').where(lambda x: x['rno']==i+1).raw_data
for row in rows:
nodes.add(row['a'])
nodes.add(row['b'])
if rows:
co.append(float(len(rows) * 2) / float(len(nodes)))
bx.append(co)
if co:
coopr.append(sum(co) / len(co))
yerr_min.append(coopr[-1] - min(co))
yerr_max.append(max(co) - coopr[-1])
print("%f, %f, %f"%(yerr_min[-1], yerr_max[-1], coopr[-1]))
x.append(i+1)
plt.figure()
# plt.errorbar(x, coopr, yerr=[yerr_min, yerr_max], fmt='o', capsize=4)
plt.boxplot(bx, showmeans=True, meanline=True)
plt.show()
# plt.savefig('graph/co_per_round.png')

43
plot_act_rnd_per_file.py Normal file
View File

@ -0,0 +1,43 @@
import json
from pathlib import Path
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.ticker import MultipleLocator
def read_and_plot(json_file):
graph_dir = Path('/Users/wjsjwr/lab/code/swdata/graph/')
dpath = Path(json_file)
with open(json_file, 'r') as f:
data = json.load(f)
actions = ''
rnds = ''
for d in data:
if d['cat'] == 'game' and d['act'] == 'created':
actions = np.zeros((2, int(d['info']['game_end_at'])), dtype=np.int32)
rnds = list(range(1,int(d['info']['game_end_at'])+1))
break
for d in data:
if d['cat'] == 'action' and d['act'] == 'done':
actions[0 if d['act_a'] == 'C' else 1, int(d['rno'])-1] += 1
actions[0 if d['act_b'] == 'C' else 1, int(d['rno'])-1] += 1
plt.clf()
lines = []
lg = ['C', 'D']
l, = plt.plot(rnds, actions[0,:], color='#FF358B', linewidth=1)
lines.append(l)
l, = plt.plot(rnds, actions[1,:], color='#01B0F0', linewidth=1)
lines.append(l)
plt.figlegend(lines, lg, numpoints=1, loc='upper right')
fname = "act_rnd_%s.eps" % str(dpath.stem)
plt.savefig(str(graph_dir / fname))
itr = Path('/Users/wjsjwr/lab/wos-data-new/')
for d in itr.iterdir():
if d.suffix == '.json':
read_and_plot(str(d))
print(str(d))

55
plot_defect_alive.py Normal file
View File

@ -0,0 +1,55 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-new')
max_round = 17
alive = []
yerr_min = []
yerr_max = []
x = []
al_al = []
survivals = {}
with open('winner.json','r') as f:
survivals = json.load(f)
for i in range(max_round):
defects = []
for j in range(len(matches.data)):
defector = set()
for row in matches.data[j].query('action', 'done').where(lambda x: x['rno']==i+1 and (x['act_a']=='D' or x['act_b']=='D')).raw_data:
if row['act_a']=='D':
defector.add(row['a'])
if row['act_b'] == 'D':
defector.add(row['b'])
if defector:
# print("[%d,%d] %s" % (i,j,str(defector)))
incr = 0
for k in survivals[matches.names[j]]:
if k in defector:
incr += 1
# print(k)
defects.append(float(incr) / float(len(defector)))
print(i)
print(defects)
if defects:
al_al.append(defects)
alive.append(sum(defects) / len(defects))
yerr_min.append(alive[-1] - min(defects))
yerr_max.append(max(defects) - alive[-1])
print("%f, %f, %f"%(yerr_min[-1], yerr_max[-1], alive[-1]))
x.append(i+1)
else:
al_al.append([])
plt.figure()
# plt.errorbar(x, alive, yerr=[yerr_min, yerr_max], fmt='o', capsize=4)
plt.boxplot(al_al, showmeans=True, meanline=True)
plt.show()
# plt.savefig('graph/survive_after_defect.png')

53
unlink_has_neighbor.py Normal file
View File

@ -0,0 +1,53 @@
import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
matches = Matches('wos-data-new')
labels = ['has neighbor', 'no neighbor']
percents = [0.0, 0.0]
for m in matches.data:
info = m.query('game', 'created').select('info').first()['info']
conf = json.loads(info['config'])
game_end_at = int(info['game_end_at'])
for row in m.query('action', 'done').where(lambda x: x['act_a'] == 'D' or x['act_b'] == 'D').raw_data:
if row['rno'] == game_end_at:
print(row)
continue
if row['act_a'] == 'D':
a = row['a']
b = row['b']
n = m.query('action', 'done').where(lambda y: ((y['a'] == a and y['b'] == b) or (y['a'] == b and y['b'] == a)) and y['rno'] == row['rno'] + 1).raw_data
if n:
pass
else:
o = m.query('action', 'done').where(lambda y: (y['b'] == b or y['a'] == b) and y['rno'] == row['rno'] + 1).raw_data
if o:
percents[0] += 1
else:
percents[1] += 1
if row['act_b'] == 'D':
a = row['a']
b = row['b']
n = m.query('action', 'done').where(lambda y: ((y['a'] == a and y['b'] == b) or (y['a'] == b and y['b'] == a)) and y['rno'] == row['rno'] + 1).raw_data
if n:
pass
else:
o = m.query('action', 'done').where(lambda y: (y['b'] == a or y['a'] == a) and y['rno'] == row['rno'] + 1).raw_data
if o:
percents[0] += 1
else:
percents[1] += 1
_all = sum(percents) / 100
percents[0] /= _all
percents[1] /= _all
plt.figure()
plt.pie(percents, labels=labels, autopct='%1.1f%%', startangle=90)
plt.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
# plt.savefig('graph/unlink_has_neighbor.png')

1
winner.json Normal file
View File

@ -0,0 +1 @@
{"G153": [], "G203": [], "G254": [], "G272": [3170], "G285": [], "G295": [], "G299": [3558, 3559, 3563, 3575], "G302": [3649], "G307": [3896, 3901], "G318": [3965, 3967, 3970, 3973], "G337": [], "G341": [4462, 4463, 4464, 4476], "G349": [4558, 4559], "G354": [4614, 4615, 4616, 4618, 4623, 4624], "G54": [], "G68": [], "G72": [], "G75": [], "G86": []}