Files
guandan/views.py
starschen 7d22fdf57f init
2015-07-21 09:32:48 +08:00

205 lines
7.5 KiB
Python

#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)