Skip to content
This repository has been archived by the owner on Oct 14, 2018. It is now read-only.

Commit

Permalink
Add support for disqualified zones.
Browse files Browse the repository at this point in the history
If a zone is DSQ, then it gets zero league points, and it is removed
from contention for any possible tied places.
  • Loading branch information
PeterJCLaw committed Apr 15, 2012
1 parent 1a810c5 commit 4b4fdc5
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 13 deletions.
42 changes: 33 additions & 9 deletions bin/scores.py
Expand Up @@ -176,17 +176,20 @@ def check_match(match):
if buckets > max_buckets:
print('WARNING! Too many buckets in this match! ({0})'.format(buckets))

def calc_positions(zpoints):
def calc_positions(zpoints, dsq_list):
"""
A function to work out the placings of zones in a game, given the game points.
@param zpoints: a dict of zone number to game points.
@param dsq_list: a list of zones that should be considered below last.
@returns: a dict of position to array of zone numbers.
"""

pos_map = {}
points_map = {}

for z, p in zpoints.iteritems():
if z in dsq_list:
p = -1
if not points_map.has_key(p):
points_map[p] = []
points_map[p].append(z)
Expand All @@ -198,16 +201,24 @@ def calc_positions(zpoints):

return pos_map

def calc_league_points(pos_map):
def calc_league_points(pos_map, dsq_list):
"""
A function to work out the league points for each zone, given the rankings within that game.
@param pos_map: a dict of position to array of zone numbers.
@param dsq_list: a list of zones that shouldn't be awarded league points.
@returns: a dict of zone number to league points.
"""

lpoints = {}

for pos, zones in pos_map.iteritems():
# remove any that are dsqaulified
# note that we do this before working out the ties, so that any
# dsq tie members are removed from contention
zones = [ z for z in zones if z not in dsq_list ]
if len(zones) == 0:
continue

# max points is 4, add one because pos is 1-indexed
points = (4 + 1) - pos
# Now that we have the value for this position if it were not a tie,
Expand All @@ -220,33 +231,46 @@ def calc_league_points(pos_map):
for z in zones:
lpoints[z] = points

# those that were dsq get 0
for z in dsq_list:
lpoints[z] = 0.0

return lpoints

def get_league_points(zpoints):
def get_league_points(zpoints, dsq):
"""
A function to work out the league points for each zone, given the game points.
This is a thin convenience wrapper around `calc_positions` and `calc_league_points`.
@param zpoints: a dict of zone number to game points.
@param dsq: a list of zones that shouldn't be awarded league points.
@returns: a dict of zone number to league points.
"""
pos_map = calc_positions(zpoints)
lpoints = calc_league_points(pos_map)
pos_map = calc_positions(zpoints, dsq)
lpoints = calc_league_points(pos_map, dsq)
return lpoints

def match_rank(match,sub):
zpoints = _get_zone_points(match)
lpoints = get_league_points(zpoints)
zpoints, dsq = _get_zone_data(match)
lpoints = get_league_points(zpoints, dsq)
_store_league_points(match, sub, lpoints)

def _get_zone_points(match):
def _get_zone_data(match):
"""
@returns: A tuple of:
a dict that contains the points for each zone
a list that contains any zones that were disqualified
"""
zpoints = dict()
dsq = []
for z in range(4):
zone = actor.hgetall('{0}.scores.match.{1}.{2}'.format(BASE,match,z))
if zone != {}:
zpoints['{0}'.format(z)] = game_points([match,z,zone['trobot'],zone['tzone'],zone['tbucket'],zone['nbuckets']])
if zone.get('disqualified', None) == "True":
dsq.append('{0}'.format(z))
else:
zpoints['{0}'.format(z)] = -1
return zpoints
return zpoints, dsq

def _store_league_points(match, sub, lpoints):
mat = split_match(actor.lindex('{0}.matches'.format(BASE), match))
Expand Down
30 changes: 26 additions & 4 deletions test/test-scores.py
Expand Up @@ -21,29 +21,51 @@
simple_pos = { 1: ['0'], 2: ['1'], 3: ['2'], 4: ['3'] }
simple_points = { '0': 4.0, '1': 3.0, '2': 2.0, '3': 1.0 }

dsq_data = { '0': 3, '1': 2, '2': 1, '3': 0 }
dsq_dsq = [ '0', '2' ]
dsq_pos = { 1: ['1'], 2: ['3'], 3: ['0', '2'] }
dsq_points = { '0': 0.0, '1': 4.0, '2': 0.0, '3': 3.0 }

tie1_data = { '0': 3, '1': 3, '2': 0, '3': 0 }
tie1_pos = { 1: ['1', '0'], 3: ['3', '2'] }
tie1_points = { '0': 3.5, '1': 3.5, '2': 1.5, '3': 1.5 }

tie2_data = { '0': 3, '1': 3, '2': 0, '3': 0 }
tie2_dsq = [ '0', '2' ]
tie2_pos = { 1: ['1'], 2: ['3'], 3: ['0', '2'] }
tie2_points = { '0': 0.0, '1': 4.0, '2': 0.0, '3': 3.0 }

class PositionsTests(unittest.TestCase):

def test_simple(self):
pos = scores.calc_positions(simple_data)
pos = scores.calc_positions(simple_data, [])
util.assertEqual(simple_pos, pos, "Wrong positions")

def test_tie(self):
pos = scores.calc_positions(tie1_data)
pos = scores.calc_positions(tie1_data, [])
util.assertEqual(tie1_pos, pos, "Wrong positions")

def test_dsq(self):
pos = scores.calc_positions(dsq_data, dsq_dsq)
util.assertEqual(dsq_pos, pos, "Wrong positions")

def test_dsq_tie(self):
pos = scores.calc_positions(tie2_data, tie2_dsq)
util.assertEqual(tie2_pos, pos, "Wrong positions")

class LeaguePointsTests(unittest.TestCase):

def test_simple(self):
points = scores.calc_league_points(simple_pos)
points = scores.calc_league_points(simple_pos, [])
util.assertEqual(simple_points, points, "Wrong points")

def test_tie(self):
points = scores.calc_league_points(tie1_pos)
points = scores.calc_league_points(tie1_pos, [])
util.assertEqual(tie1_points, points, "Wrong points")

def test_dsq_tie(self):
points = scores.calc_league_points(tie2_pos, tie2_dsq)
util.assertEqual(tie2_points, points, "Wrong points")

if __name__ == '__main__':
unittest.main(buffer=True)

0 comments on commit 4b4fdc5

Please sign in to comment.