swdata/island/match.py
2022-07-22 21:36:39 +08:00

173 lines
5.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
一场比赛的数据
"""
import json
class Match:
"""Match"""
def __init__(self, raw, dtype='json'):
"""
:param json_string: string represents data in json format
"""
self.name = ''
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')
if cat or act is `None', the corresponding field matches anything
:param cat: category
:param act: action
"""
if self.dtype == 'mid':
raise RuntimeError("Query on intermediate result.")
result = []
for entry in self.raw_data:
if (cat == None or entry['cat'] == cat) and (act == None or 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 the 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
def count(self):
"""
return the amount of results
"""
if self.dtype != 'mid':
raise RuntimeError("count query on raw data.")
return len(self.raw_data)
def get_tr(self, i, target, nb, sv):
"""
# 计算tau_f的方式是统计周围邻居剩余的tr
# 本函数计算第i轮所有有消耗tr的player最后剩余的tr
# 由于是计算剩余tr所以不能计算和target之间的交互
# nb是target的邻居
# 2018/08/31 更新即便是已经交互过的邻居他的剩余时间资源依旧应该计算入tau_f中使得公式完整。
# 2018/09/01 更新不应该算在tau_P中尝试单独列成一项因为优化目标不同。
# 2018/09.01 更新将tau_p更改为tau_f
"""
trs = {}
req = self.query('action', 'request').where(lambda x: x['rno'] == i+1)
app = self.query('action', 'approve').where(lambda x: x['rno'] == i+1).raw_data
can = self.query('action', 'cancel').where(lambda x: x['rno'] == i+1).raw_data
den = self.query('action', 'deny').where(lambda x: x['rno'] == i+1).raw_data
fr = []
for r in self.query('action', 'done').where(lambda x: x['rno'] == i and (x['a'] == target or x['b'] == target)).raw_data:
if r['a'] == target:
fr.append(r['b'])
elif r['b'] == target:
fr.append(r['a'])
truenb = []
for r in nb:
if r not in fr and r in sv:
truenb.append(r)
trs[r] = 1440
for r in req.raw_data:
if r['from'] in truenb and r['to'] != target :
if r['from'] not in trs:
trs[r['from']] = 1440
trs[r['from']] -= r['tr']
for r in app:
if r['from'] in truenb and r['to'] != target:
if r['from'] not in trs:
trs[r['from']] = 1440
trs[r['from']] -= r['tr']
for r in can:
if r['from'] in trs and r['to'] != target:
trs[r['from']] += req.where(lambda x: x['from'] == r['from'] and x['to'] == r['to'] and x['log_id'] < r['log_id']).orderby('log_id').raw_data[-1]['tr']
for r in den:
if r['to'] in trs and r['from'] != target:
trs[r['to']] += req.where(lambda x: x['from'] == r['to'] and x['to'] == r['from'] and x['log_id'] < r['log_id']).orderby('log_id').raw_data[-1]['tr']
return trs
def network_type(self):
"""
返回网络类型如果找不到则返回None
"""
try:
return json.loads(self.query('game', 'created').first()['info']['config'])['network']['type']
except:
print("Can't get network: %s" % json.loads(self.query('game', 'created').first()))
return 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)