/
views.py
205 lines (180 loc) · 7.52 KB
/
views.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#encoding: utf8
from flask import request, abort
from flask.ext.admin import BaseView, expose
from bson.objectid import ObjectId
import sys
import random
from operator import attrgetter
sys.path.append('..')
from game_record.models import GameRecord
from game.models import Game
from namelist.models import NameList
from forms import BallotForm, RankForm
import json
class Team:
def __init__(self, namelist):
self.namelist = namelist
self.total_score = 0
self.total_sscore = 0
self.total_diff = 0
self.againsts = []
def get_company(self):
return self.namelist.company.strip()
def has_competed_with(self, against):
if against in self.againsts:
return True
else:
return False
def add_score(self, score):
self.total_score += score
def add_diff(self, diff):
self.total_diff += diff
def add_against(self, against):
self.againsts.append(against)
def compute_sscore(self):
for a in self.againsts:
#计算小分时,弃权所得负分不影响对手小分
if a.total_score >= 0:
self.total_sscore += a.total_score
class Company:
def __init__(self, name):
self.name = name
self.teams = []
self.total_score = 0
self.total_sscore = 0
self.total_diff = 0
def add_team(self, team):
self.teams.append(team)
def compute_score(self):
for team in self.teams:
self.total_score += team.total_score
self.total_sscore += team.total_sscore
self.total_diff += team.total_diff
class BallotView(BaseView):
round = 0
@expose('/', methods=['GET', 'POST'])
def index(self):
form = BallotForm(request.form)
form.game.choices = [(str(Game.objects(name=x).first().id), x) for x in Game.objects.distinct('name')]
if request.method == 'POST' and form.validate():
game = form.game.data
ballot_type = form.ballot_type.data
results = self.ballot(game, ballot_type)
self._template_args['ballot_results'] = results
self._template_args['round'] = self.round
return self.render('ballot.html', form=form)
def first_stage(self, game, ballot_type):
"""首轮抽签"""
results = []
teams = list(NameList.objects(game=game).order_by('no').all())
team_count = len(teams) / 2 * 2
if ballot_type == 'sequence':
for i in range(0, team_count, 2):
result = dict(desk_no=i/2+1, red=teams[i], blue=teams[i+1])
results.append(result)
return results
else:
return self.ballot_by_score(game, ballot_type)
def ballot_by_score(self, game, ballot_type):
"""按照比分抽签"""
results = []
teams = RankView.get_ranked_teams(game)
while len(teams) > 1:
#处理后四名出现同一个单位的情况
if len(teams) == 4 and (teams[0].get_company() == teams[1].get_company() or teams[2].get_company() == teams[3].get_company()):
results.append(dict(desk_no=len(results)+1, red=teams[0].namelist, blue=teams[2].namelist))
results.append(dict(desk_no=len(results)+1, red=teams[1].namelist, blue=teams[3].namelist))
break
t1 = teams[0]
for t2 in teams[1:]:
#找到不同单位并且没有比赛过的对手
if t1.get_company() != t2.get_company() and not t1.has_competed_with(t2):
break
results.append(dict(desk_no=len(results)+1, red=t1.namelist, blue=t2.namelist))
teams.remove(t1)
teams.remove(t2)
return results
def ballot(self, game, ballot_type):
"""抽签算法"""
if GameRecord.objects(game=game).count() == 0:
self.round = 1
return self.first_stage(game, ballot_type)
else:
self.round = max(GameRecord.objects(game=game).distinct('round')) + 1
return self.ballot_by_score(game, ballot_type)
class RankView(BaseView):
@expose('/', methods=['GET', 'POST'])
def index(self):
form = RankForm(request.form)
form.game.choices = [(str(Game.objects(name=x).first().id), x) for x in Game.objects.distinct('name')]
return self.render('rank.html', form=form)
@expose('/team_rank_ajax')
def team_rank_ajax(self):
results = []
game = request.args.get('game', '')
ranked_teams = self.get_ranked_teams(game)
for index, team in enumerate(ranked_teams):
record = {}
record['rank'] = index + 1
record['rank_type'] = unicode(team.namelist)
record['total_score'] = team.total_score
record['total_sscore'] = team.total_sscore
record['total_diff'] = team.total_diff
results.append(record)
return json.dumps(results)
@expose('/company_rank_ajax')
def company_rank_ajax(self):
game = request.args.get('game', '')
ranked_companys = self.get_ranked_companys(game)
results = []
for index, c in enumerate(ranked_companys):
record = {}
record['rank'] = index + 1
record['rank_type'] = c.name
record['total_score'] = c.total_score
record['total_sscore'] = c.total_sscore
record['total_diff'] = c.total_diff
results.append(record)
return json.dumps(results)
@staticmethod
def get_ranked_teams(game):
teams = {x:Team(x) for x in NameList.objects(game=game)}
for record in GameRecord.objects(game=game):
if record.result == u'红方胜':
teams[record.red].add_score(2)
teams[record.red].add_diff(record.diff)
teams[record.blue].add_diff(0 - record.diff)
elif record.result == u'蓝方胜':
teams[record.blue].add_score(2)
teams[record.blue].add_diff(record.diff)
teams[record.red].add_diff(0 - record.diff)
elif record.result == u'平局':
teams[record.blue].add_score(1)
teams[record.red].add_score(1)
elif record.result == u'红方弃权':
teams[record.red].add_score(-1)
teams[record.red].add_diff(-6)
teams[record.blue].add_score(2)
teams[record.blue].add_diff(6)
elif record.result == u'蓝方弃权':
teams[record.blue].add_score(-1)
teams[record.blue].add_diff(-6)
teams[record.red].add_score(2)
teams[record.red].add_diff(6)
teams[record.red].add_against(teams[record.blue])
teams[record.blue].add_against(teams[record.red])
for team in teams.values():
team.compute_sscore()
team_list = teams.values()
random.shuffle(team_list)
return sorted(team_list, key=attrgetter('total_score', 'total_sscore', 'total_diff'), reverse=True)
@staticmethod
def get_ranked_companys(game):
companys = {}
for team in RankView.get_ranked_teams(game):
company_name = team.get_company()
if company_name not in companys:
companys[company_name] = Company(company_name)
companys[company_name].add_team(team)
[c.compute_score() for c in companys.values()]
return sorted(companys.values(), key=attrgetter('total_score', 'total_sscore', 'total_diff'), reverse=True)