swdata/fail_reason.py
2018-08-19 23:26:08 +08:00

129 lines
6.0 KiB
Python

import json
from matplotlib import pyplot as plt
from island.match import Match
from island.matches import Matches
import numpy as np
from scipy.stats import pearsonr
class Solution:
def __init__(self, mode):
self.mode = mode
self.matches = Matches.from_profile_expr(lambda r: mode in r)
self.survivals = {}
with open('survivals.json', 'r') as f:
self.survivals = json.load(f)
self.neighbors = {}
self.read_neighbor()
self.suff = 0
self.insuff = 0
self.detail_suff = [0]*2
self.detail_insuff = [0]*2
def read_neighbor(self):
for i, m in enumerate(self.matches.data):
n = {}
for r in m.query('neighbor', 'create').raw_data:
if r['a'] in n:
n[r['a']].append(r['b'])
else:
n[r['a']] = [r['b']]
if r['b'] in n:
n[r['b']].append(r['a'])
else:
n[r['b']] = [r['a']]
self.neighbors[self.matches.names[i]] = n
def get_reason(self, m, i, target, ttr):
tr = 1440
for k in m.query('action', 'request').where(lambda x: x['rno'] == i and x['from'] == target).raw_data:
tr -= k['tr']
for k in m.query('action', 'cancel').where(lambda x: x['rno'] == i and x['from'] == target).raw_data:
tr += m.query('action', 'request').where(lambda x: x['rno'] == i and x['from'] == target and x['to'] == k['to'] and x['log_id'] < k['log_id']).orderby('log_id').raw_data[-1]['tr']
for k in m.query('action', 'deny').where(lambda x: x['rno'] == i and x['to'] == target).raw_data:
tr += m.query('action', 'request').where(lambda x: x['rno'] == i and x['from'] == target and x['to'] == k['from'] and x['log_id'] < k['log_id']).orderby('log_id').raw_data[-1]['tr']
for k in m.query('action', 'approve').where(lambda x: x['rno'] == i and x['from'] == target).raw_data:
tr -= k['tr']
return tr >= ttr
def new_partner_reason(self):
re_after = [0] * 2 # [c,d]
su_after = [0] * 2
for m in self.matches.data:
info = m.query('game', 'created').select('info').first()['info']
game_end_at = int(info['game_end_at'])
for p in m.query('player', 'join').raw_data:
pid = p['pid']
for i in range(2, game_end_at):
previous_round_partner = []
c, t = 0, 0
for r in m.query('action', 'done').where(lambda x: x['rno'] == i - 1 and (x['a'] == pid or x['b'] == pid)).raw_data:
if r['a'] == pid:
previous_round_partner.append(r['b'])
if r['act_a'] == 'C':
c += 1
else:
previous_round_partner.append(r['a'])
if r['act_b'] == 'C':
c += 1
t += 1
is_coop = 0 if c * 2 >= t else 1
new_partner_requester = {}
for r in m.query('action', 'request').where(lambda x: x['rno'] == i and (x['from'] == pid or x['to'] == pid)).raw_data:
if r['from'] == pid:
if r['to'] not in previous_round_partner:
# new_partner_request += 1
new_partner_requester[r['to']] = r['tr']
else:
if r['from'] not in previous_round_partner:
# new_partner_request += 1
new_partner_requester[r['from']] = r['tr']
if not new_partner_requester:
continue
re_after[is_coop] += len(new_partner_requester)
new_partner_succ = 0
new_partner = []
for r in m.query('action', 'done').where(lambda x: x['rno'] == i and (x['a'] == pid or x['b'] == pid)).raw_data:
if r['a'] == pid:
if r['b'] not in previous_round_partner:
new_partner_succ += 1
new_partner.append(r['b'])
else:
if r['a'] not in previous_round_partner:
new_partner_succ += 1
new_partner.append(r['a'])
su_after[is_coop] += new_partner_succ
for npr, ntr in new_partner_requester.items():
if npr not in new_partner:
if self.get_reason(m, i, npr, ntr):
self.suff += 1
self.detail_suff[is_coop] += 1
else:
self.insuff += 1
self.detail_insuff[is_coop] += 1
for i, _ in enumerate(su_after):
print(su_after[i], re_after[i], su_after[i] / re_after[i])
su_after[i] /= re_after[i]
return su_after
if __name__ == '__main__':
print('CLASSIC')
sc = Solution('CLASSIC')
npc_after = sc.new_partner_reason()
print("reason: ", sc.suff, sc.insuff, sc.insuff / (sc.suff + sc.insuff))
print("reason(c): ", sc.detail_suff[0], sc.detail_insuff[0], sc.detail_insuff[0] / (sc.detail_suff[0] + sc.detail_insuff[0]))
print("reason(d): ", sc.detail_suff[1], sc.detail_insuff[1], sc.detail_insuff[1] / (sc.detail_suff[1] + sc.detail_insuff[1]))
print('SURVIVE')
ss = Solution('SURVIVE')
nps_after = ss.new_partner_reason()
print("reason: ", ss.suff, ss.insuff, ss.insuff / (ss.suff + ss.insuff))
print("reason(c): ", ss.detail_suff[0], ss.detail_insuff[0], ss.detail_insuff[0] / (ss.detail_suff[0] + ss.detail_insuff[0]))
print("reason(d): ", ss.detail_suff[1], ss.detail_insuff[1], ss.detail_insuff[1] / (ss.detail_suff[1] + ss.detail_insuff[1]))