initital commit
This commit is contained in:
commit
9fd025d3a7
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
.DS_Store
|
||||
graph
|
||||
wos-data-new
|
||||
wos-data-casual
|
||||
*.svg
|
||||
__pycache__
|
||||
1
.vscode/database.json
vendored
Normal file
1
.vscode/database.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{}
|
||||
0
.vscode/settings.json
vendored
Normal file
0
.vscode/settings.json
vendored
Normal file
49
actions_after_defect.py
Normal file
49
actions_after_defect.py
Normal 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
61
after_d_link_tr.py
Normal 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
35
calc_winner_pid.py
Normal 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
55
coopr_per_match.py
Normal 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
45
coopr_per_round.py
Normal 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
46
defector_has_neighbor.py
Normal 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
285
draw_game_history.py
Normal 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
0
island/__init__.py
Normal file
98
island/match.py
Normal file
98
island/match.py
Normal 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
13
island/matches.py
Normal 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
45
neighbors_per_round.py
Normal 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
43
plot_act_rnd_per_file.py
Normal 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
55
plot_defect_alive.py
Normal 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
53
unlink_has_neighbor.py
Normal 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
1
winner.json
Normal 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": []}
|
||||
Loading…
Reference in New Issue
Block a user