forked from crawl/dcss_tourney
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nemelex.py
143 lines (127 loc) · 4.34 KB
/
nemelex.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#! /usr/bin/python
import MySQLdb
import crawl_utils
import random
import sys
import html
import os.path
from datetime import datetime
import time
import query
import combos
from banner import count_recipients
from loaddb import START_TIME
NOMINEE_FILE = 'nemelex-combos.txt'
DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
NEMELEX_USE_LIST = True
def parse_time(when):
return datetime(*(time.strptime(when, DATE_FORMAT)[0:6]))
def find_previous_nominees(targetfile = NOMINEE_FILE):
if os.path.exists(targetfile):
f = open(targetfile)
nominees = [x.strip().split() for x in f.readlines()
if x.strip() and not x.strip().startswith('#')]
f.close()
return [{'combo': x[0],
'time': parse_time(x[1] + ' ' + x[2])}
for x in nominees]
return []
def _fixup_nominee_validity(c):
newcombos = []
for i in range(0, len(c)):
cur = c[i]
next = None
if i < len(c) - 1:
next = c[i + 1]['time']
newcombos.append([cur['combo'], cur['time'], next])
return newcombos
NEMELEX_COMBOS = _fixup_nominee_validity(find_previous_nominees())
NEMELEX_SET = set([x[0] for x in NEMELEX_COMBOS])
def apply_combo(combo, tofile = NOMINEE_FILE):
time = datetime.utcnow()
f = open(tofile, 'a')
f.write("%s %s\n" % (combo, time.strftime(DATE_FORMAT)))
f.close()
global NEMELEX_COMBOS
global NEMELEX_SET
NEMELEX_COMBOS = _fixup_nominee_validity(find_previous_nominees())
NEMELEX_SET = set([x[0] for x in NEMELEX_COMBOS])
def filter_combos(combos, filters):
race_set = set([x[:2] for x in filters])
class_set = set([x[2:] for x in filters])
return [x for x in combos if x[:2] not in race_set and x[2:] not in class_set]
def weight_combos(combos, previous):
weights = []
for x in combos:
w = 1
for y in previous:
if x[:2] == y[:2] or x[2:] == y[2:]:
w *= 10
weights.append(w)
return weights
def current_nemelex_choice():
return NEMELEX_COMBOS and NEMELEX_COMBOS[-1]
def list_nemelex_choices(c):
# Check the file again so that we don't miss one.
combos = _fixup_nominee_validity(find_previous_nominees())
nem_list = []
for x in combos:
ban = 'nemelex:' + x[0]
nem_list.append([x[0], x[1], count_recipients(c, ban, 3)])
return nem_list
def is_nemelex_choice(combo, when):
"""Returns true if the given combo for a game that ended at the given
datetime is a chosen combo for the Nemelex' Choice banner."""
if combo in NEMELEX_SET:
for c in NEMELEX_COMBOS:
if c[0] == combo:
return True
return False
def eligible_combos(c):
# first one is always picked from the special list
if len(NEMELEX_COMBOS) == 0:
return [combos.NEM_ELIGIBLE_COMBOS]
# sometimes look at the special list for the later ones, too
if NEMELEX_USE_LIST:
won_games = query.get_winning_games(c)
won_combos = set([x['charabbrev'] for x in won_games])
eligible = [x for x in combos.NEM_ELIGIBLE_COMBOS
if (x not in won_combos)]
pcombo_names = [x[0] for x in NEMELEX_COMBOS]
weighting = weight_combos(eligible, pcombo_names)
return [eligible,weighting]
# otherwise pick from the valid combos with the lowest high score in the tourney:
else:
eligible = combos.VALID_COMBOS
pcombo_names = [x[0] for x in NEMELEX_COMBOS]
# Try not to use a repeat race or class if possible.
filtered_eligible = filter_combos(eligible, pcombo_names)
if filtered_eligible:
eligible = filtered_eligible
eligible_with_scores = [[combo_name, query.highscore(c, combo_name)] for combo_name in eligible]
eligible_with_scores.sort(key = lambda e: e[1])
l = 19
if l > len(eligible_with_scores)-1:
l = len(eligible_with_scores)-1
candidates = [e[0] for e in eligible_with_scores if e[1] <= eligible_with_scores[l][1]]
return [candidates]
def pick_combo(data):
if data[0]:
eligible = data[0]
if len(data) > 1:
weighting = data[1]
n = len(eligible)
combo = None
while not combo:
i = random.randrange(len(eligible))
if random.randrange(weighting[i]) == 0:
combo = eligible[i]
else:
combo = eligible[random.randrange(len(eligible))]
apply_combo(combo)
def need_new_combo(c):
if not NEMELEX_COMBOS:
nowtime = datetime.utcnow().strftime('%Y%m%d%H%M')
return (nowtime >= START_TIME)
ban = 'nemelex:' + current_nemelex_choice()[0]
return (count_recipients(c, ban, 3) > 0)