"""
统计所有的连通子图规模
"""
import csv
import json
import numpy as np
from collections import Counter
from island.matches import Matches
from island.match import Match
from matplotlib import pyplot as plt

class ClusterStat:
    def __init__(self, cb):
        self.detail = {}
        # self.matches = Matches.from_profile_expr(lambda r: True)
        self.matches = Matches.from_profile('SURVIVE')
        self.life = {} # key(size), value(list of cluster-life)
        self.cluster_born = cb


    def stat(self):
        for m in self.matches.data:
            cluster = {}
            dick = {}
            no = 0
            cluster_life = {}
            for r in m.query('player','join').raw_data:
                cluster[r['pid']] = no
                no += 1
            for r in m.query('action', 'done').raw_data:
                if cluster[r['a']] != cluster[r['b']]:
                    if cluster[r['a']] < cluster[r['b']]:
                        cmax, cmin = cluster[r['b']], cluster[r['a']]
                    else:
                        cmax, cmin = cluster[r['a']], cluster[r['b']]
                    if self.cluster_born == 1 or ((cmin,cmax) in dick and dick[(cmin,cmax)] > self.cluster_born - 1):
                        #link
                        lmax = [k for (k,v) in cluster.items() if v == cmax]
                        for k in lmax:
                            cluster[k] = cmin
                    else:
                        if (cmin, cmax) not in dick:
                            dick[(cmin, cmax)] = 1
                        else:
                            dick[(cmin, cmax)] += 1
            info = m.query('game', 'created').select('info').first()['info']
            conf = json.loads(info['config'])
            game_end_at = int(info['game_end_at'])
            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 k,v in foods.items():
                    if -10 < v <= 0:
                        if cluster[k] in cluster_life:
                            if cluster_life[cluster[k]] < i:
                                cluster_life[cluster[k]] = i
                        else:
                            cluster_life[cluster[k]] = i
                        foods[k] = -1000
            for k,v in foods.items():
                if v >= 0:
                    if cluster[k] in cluster_life:
                        if cluster_life[cluster[k]] < game_end_at:
                            cluster_life[cluster[k]] = game_end_at
                    else:
                        cluster_life[cluster[k]] = game_end_at
            counter = Counter(cluster.values())
            for k,v in counter.items():
                if v not in self.life:
                    self.life[v] = []
                self.life[v].append(cluster_life[k])                
            res = [v for v in counter.values()]
            # print(m.name, list(sorted(res, reverse=True)))
            self.detail[m.name] = res


    def output(self):
        data = []
        for r in self.detail.values():
            data.extend(r)
        res = np.zeros(max(data))
        s = sum(data)
        for d in data:
            res[d-1] += d
        res /= s
        # print(res)
        np.save('outputs/cluster.npy', res)
        with open("outputs/cluster_life_%d.json" % self.cluster_born, 'w') as f:
            json.dump(self.life, f)

if __name__ == '__main__':
    for i in range(1, 10):
        c = ClusterStat(i)
        c.stat()
        c.output()
