more merged changes from server

This commit is contained in:
Curt Hash 2010-01-19 15:31:15 -07:00
parent 1328229708
commit 5f6eeeb1b8
8 changed files with 60 additions and 24 deletions

View File

@ -21,7 +21,9 @@ def main(s=None):
catscores = {} catscores = {}
for cat in s.categories(): for cat in s.categories():
catscores[cat] = s.cat_points(cat) score = s.cat_points(cat)
if score:
catscores[cat] = score
scoresfile = tempfile.NamedTemporaryFile('w') scoresfile = tempfile.NamedTemporaryFile('w')
fn = scoresfile.name fn = scoresfile.name
@ -38,6 +40,8 @@ def main(s=None):
scoresfile.write('\n') scoresfile.write('\n')
for when, cat, team, score in s.log: for when, cat, team, score in s.log:
if not cat in catscores:
continue
if when > now: if when > now:
if now: if now:
write_scores(now) write_scores(now)
@ -59,7 +63,7 @@ set border 3
set xtics nomirror set xtics nomirror
set ytics nomirror set ytics nomirror
set nokey set nokey
set terminal png transparent size 640,200 x000000 xffffff set terminal png transparent size 1200,400 x000000 xffffff
set output "%(pngout)s,tmp" set output "%(pngout)s,tmp"
plot %(plot)s\n''' % {'plot': ','.join(plotparts), plot %(plot)s\n''' % {'plot': ','.join(plotparts),
'pngout': pngout}) 'pngout': pngout})

View File

@ -167,6 +167,8 @@ class Storage:
def team_points(self, team): def team_points(self, team):
points = 0 points = 0
for cat, tot in self.points_by_cat.items(): for cat, tot in self.points_by_cat.items():
if not tot:
continue
team_points = self.team_points_in_cat(cat, team) team_points = self.team_points_in_cat(cat, team)
points += team_points / float(tot) points += team_points / float(tot)
return points return points

View File

@ -3,6 +3,7 @@
import cgitb; cgitb.enable() import cgitb; cgitb.enable()
import os import os
import sys import sys
from cgi import escape as quote
from . import config from . import config
from . import teams from . import teams
from . import points from . import points
@ -14,6 +15,7 @@ def main():
s = points.Storage() s = points.Storage()
categories = [(cat, s.cat_points(cat)) for cat in s.categories()] categories = [(cat, s.cat_points(cat)) for cat in s.categories()]
categories = [(c, p) for (c, p) in categories if p > 0]
print('Refresh: 10') print('Refresh: 10')
print(config.start_html('Scoreboard', cls='wide')) print(config.start_html('Scoreboard', cls='wide'))
@ -28,7 +30,7 @@ def main():
team = open(fn).read() or house_team team = open(fn).read() or house_team
print(' <br/>') print(' <br/>')
print(' <!-- flag: %s --> <span style="color: #%s" title="flag holder">%s</span>' print(' <!-- flag: %s --> <span style="color: #%s" title="flag holder">%s</span>'
% (cat, teams.color(team), team)) % (cat, teams.color(team), quote(team[:15])))
except IOError: except IOError:
pass pass
print('</th>') print('</th>')
@ -41,16 +43,20 @@ def main():
total = s.team_points(team) total = s.team_points(team)
totals.append((total, team)) totals.append((total, team))
for total, team in sorted(totals, reverse=True): for total, team in sorted(totals, reverse=True):
if total < 0.1:
break
print('<li><span style="color: #%s;">%s (%0.3f)</span></li>' print('<li><span style="color: #%s;">%s (%0.3f)</span></li>'
% (teams.color(team), team, total)) % (teams.color(team), quote(team[:15]), total))
print('</ol></td>') print('</ol></td>')
for cat, total in categories: for cat, total in categories:
print('<td>') print('<td>')
scores = sorted([(s.team_points_in_cat(cat, team), team) for team in s.teams]) scores = sorted([(s.team_points_in_cat(cat, team), team) for team in s.teams])
for score, team in scores: for score, team in scores:
if not score:
continue
color = teams.color(team) color = teams.color(team)
print('<div style="height: %f%%; overflow: hidden; background: #%s; color: black;">' % (float(score * 100)/total, color)) print('<div style="height: %f%%; overflow: hidden; background: #%s; color: black;">' % (float(score * 100)/total, color))
print('<!-- category: %s --> %s: %d' % (cat, team, score)) print('<!-- category: %s --> %s: %d' % (cat, quote(team[:15]), score))
print('</div>') print('</div>')
print('</td>') print('</td>')
print('</tr>') print('</tr>')

View File

@ -40,20 +40,23 @@ class Pflanzarr:
tmpPlayers = os.listdir(self._playerDir) tmpPlayers = os.listdir(self._playerDir)
players = [] players = []
for p in tmpPlayers: for p in tmpPlayers:
p = unquote(p, safe='') p = unquote(p)
if not (p.startswith('.') or p.endswith('#') or p.endswith('~'))\ if not (p.startswith('.') or p.endswith('#') or p.endswith('~'))\
and p in colors: and p in colors:
players.append(p) players.append(p)
AIs = {} AIs = {}
for player in players: for player in players:
AIs[player] = open(os.path.join(self._playerDir, player)).read() qPlayer = quote(player)
AIs[player] = open(os.path.join(self._playerDir, qPlayer)).read()
defaultAIs = self._getDefaultAIs(dir, difficulty) defaultAIs = self._getDefaultAIs(dir, difficulty)
assert len(players) >= 1, "There must be at least one player." if not players:
self._tanks = []
return
# The one is added to ensure that there is at least one #default bot. # The one is added to ensure that there is at least one #default bot.
cols = math.sqrt(len(players) + 1) cols = math.sqrt(len(players) + 3)
if int(cols) != cols: if int(cols) != cols:
cols = cols + 1 cols = cols + 1
@ -61,7 +64,7 @@ class Pflanzarr:
if cols < 2: if cols < 2:
cols = 2 cols = 2
rows = len(players)/cols rows = (len(players) + 3)/cols
if len(players) % cols != 0: if len(players) % cols != 0:
rows = rows + 1 rows = rows + 1
@ -97,7 +100,11 @@ class Pflanzarr:
def run(self, maxTurns=None): def run(self, maxTurns=None):
print "Starting new game with %d players." % len(self._tanks)
if self._tanks:
print "Starting new game with %d players." % len(self._tanks)
else:
return
kills = {} kills = {}
for tank in self._tanks: for tank in self._tanks:
@ -229,7 +236,7 @@ class Pflanzarr:
# Write a blank file if the winner is a default tank.. # Write a blank file if the winner is a default tank..
if winner.name != None: if winner.name != None:
winnerFile.write(tanks[0].name) winnerFile.write(winner.name)
winnerFile.close() winnerFile.close()
resultsFile.write('\n'.join(html)) resultsFile.write('\n'.join(html))
@ -396,12 +403,12 @@ class Pflanzarr:
try: try:
file = open(self.TEAMS_FILE) file = open(self.TEAMS_FILE)
except: except:
return {}.fromkeys(players, errorColor) return {}
colors = {} colors = {}
for line in file: for line in file:
try: try:
team, passwd, color = map(unquote, line.split('\t'),['']*3) team, passwd, color = map(unquote, line.split('\t'))
colors[team] = '#%s' % color colors[team] = '#%s' % color
except: except:
colors[team] = errorColor colors[team] = errorColor

View File

@ -29,21 +29,37 @@ functions. If all the conditions are satisfactory (true), all of the actions
are given as orders. Conditions are separated by ampersands, actions separated are given as orders. Conditions are separated by ampersands, actions separated
by periods. Here are some examples of AI commands: by periods. Here are some examples of AI commands:
<pre class="docs"> <pre class="docs">
sensor(1) & sensor(2) & fireready() : fire(); sense(1) & sense(2) & fireready() : fire();
sensor(0,0)&sin(5): move(40, 30) . turretcw(50); sense(0,0)&sin(5): move(40, 30) . turretcw(50);
sensor(4) & random(4,5) : led(1).settoggle(0,1);</pre> sense(4) & random(4,5) : led(1).settoggle(0,1);</pre>
Your tank will check its program each turn, and attempt to the best of its Your tank will execute its program each turn(frame), and attempt to
the best of its
abilities to carry out its orders (or die trying). Like any military mind, abilities to carry out its orders (or die trying). Like any military mind,
your tank may receive a plethora of often conflicting orders and information. your tank may receive a plethora of often conflicting orders and information.
This a SMART TANK, however. It knows that the proper thing to do with each This a SMART TANK, however. It knows that the proper thing to do with each
subsystem is to have that subsystem follow only the last order given each turn. subsystem is to have that subsystem follow only the last order given each turn.
<pre class="docs">
#Setup commands define your tank when your program compiles
>addsensor(50, 0, 5, 1); # 0-Fire Sensor
>addsensor(30, 0, 180); # 1-Anti-collision sensor
# These commands execute each frame.
# Blank condition sections are true.
: move(90, 100).
turretset(0);
sense(0) : fire();
sense(1) : move(-100, 100)
</pre>
""" """
import conditions import conditions
import actions import actions
import setup import setup
import traceback
class Statement(object): class Statement(object):
"""Represents a single program statement. If all the condition Functions """Represents a single program statement. If all the condition Functions
evaluate to True, the actions are all executed in order.""" evaluate to True, the actions are all executed in order."""
@ -82,8 +98,8 @@ class Program(object):
try: try:
action(tank) action(tank)
except Exception, msg: except Exception, msg:
self.errors.append("Bad setup action, line %d, msg: %s" % \ self.errors.append("Bad setup action, line %d, msg: %s, %s" % \
(action.lineNum, msg)) (action.lineNum, msg, traceback.format_exc()))
def __call__(self, tank): def __call__(self, tank):
"""Execute this program on the given tank.""" """Execute this program on the given tank."""

View File

@ -57,7 +57,8 @@ class TurretSet(Function.Function):
class Fire(Function.Function): class Fire(Function.Function):
"""fire() """fire()
Attempt to fire the tanks laser cannon.""" Attempt to fire the tanks laser cannon.
It's range is 50% of your sensor range."""
def __call__(self, tank): def __call__(self, tank):
tank.setFire() tank.setFire()

View File

@ -31,7 +31,7 @@ Returns True if the given toggle is set, False otherwise. """
def __init__(self, toggle): def __init__(self, toggle):
self._toggle = toggle self._toggle = toggle
def __call__(self, tank): def __call__(self, tank):
return tank.toggles[toggle] return tank.toggles[self._toggle]
class TimerCheck(Function.Function): class TimerCheck(Function.Function):
"""timer(#, [invert]) """timer(#, [invert])

View File

@ -14,7 +14,7 @@ Sensors are numbered, starting at 0, in the order they are added.
<p> <p>
range - The range of the sensor, as a percent of the tanks max range. range - The range of the sensor, as a percent of the tanks max range.
angle - The angle of the center of the sensor, in degrees. angle - The angle of the center of the sensor, in degrees.
width - The width of the sensor, in percent (100 is a full circle). width - The width of the sensor, in degrees.
turretAttached - Normally, the angle is relative to the front of the turretAttached - Normally, the angle is relative to the front of the
tank. When this is set, the angle is relative to the current turret tank. When this is set, the angle is relative to the current turret
direction. direction.
@ -53,7 +53,7 @@ starting at 0.
if len(tank.toggles) >= tank.SENSOR_LIMIT: if len(tank.toggles) >= tank.SENSOR_LIMIT:
raise ValueError('You can not have more than 10 toggles.') raise ValueError('You can not have more than 10 toggles.')
tank.toggles.append[self._state] tank.toggles.append(self._state)
class AddTimer(Function.Function): class AddTimer(Function.Function):
"""addtimer(timeout) """addtimer(timeout)