diff --git a/ctf/paths.py b/ctf/paths.py deleted file mode 100644 index 54aa86f..0000000 --- a/ctf/paths.py +++ /dev/null @@ -1,6 +0,0 @@ -VAR = "/opt/ctf/var" -WWW = "/opt/ctf/www" -LIB = "/opt/ctf/lib" -BIN = "/opt/ctf/bin" -SBIN = "/opt/ctf/sbin" -BASE_URL = "/" diff --git a/tanks/Pflanzarr.py b/tanks/Pflanzarr.py index d13b983..95a7cb2 100644 --- a/tanks/Pflanzarr.py +++ b/tanks/Pflanzarr.py @@ -30,17 +30,16 @@ class Pflanzarr: tmpPlayers = os.listdir(self._playerDir) players = [] - for p in tmpPlayers: - p = unquote(p) + AIs = {} + for fn in tmpPlayers: + p = unquote(fn) + print (p, fn) if (not (p.startswith('.') or p.endswith('#') or p.endswith('~')) and teams.exists(p)): players.append(p) - - AIs = {} - for player in players: - AIs[player] = open(os.path.join(self._playerDir, player)).read() + AIs[p] = open(os.path.join(self._playerDir, fn)).read() defaultAIs = self._getDefaultAIs(dir) if len(players) < 1: @@ -48,16 +47,10 @@ class Pflanzarr: # The one is added to ensure that there is at least one house # bot. - cols = math.sqrt(len(players) + 1) - if int(cols) != cols: - cols = cols + 1 - - cols = int(cols) + cols = int(math.ceil(math.sqrt(len(players) + 1))) cols = max(cols, 2) - rows = len(players)/cols - if len(players) % cols != 0: - rows = rows + 1 + rows = int(math.ceil(len(players)/float(cols))) rows = max(rows, 2) self._board = (cols*self.SPACING, rows*self.SPACING) @@ -96,8 +89,13 @@ class Pflanzarr: hdr = StringIO() hdr.write('\n' '\n') # Decide on the winner diff --git a/tanks/Tank.py b/tanks/Tank.py index 1c9b32e..c865564 100644 --- a/tanks/Tank.py +++ b/tanks/Tank.py @@ -433,6 +433,16 @@ class Tank(object): while self._angle > math.pi * 2: self._angle = self._angle - math.pi * 2 + def describe(self, f): + """Output a description of this tank""" + + f.write(' ["%s",[' % self.color) + for i in range(len(self._sensors)): + dist, sensorAngle, width, tSens = self._sensors[i] + + f.write('[%d,%.2f,%.2f,%d],' % (dist, sensorAngle, width, tSens)) + f.write(']],\n') + def draw(self, f): """Output this tank's state as JSON. @@ -440,40 +450,16 @@ class Tank(object): """ - f.write(' [') - f.write(str(int(self.isDead))); - f.write(',') - f.write(repr(self.color)) - f.write(',') - f.write('%d' % self.pos[0]) - f.write(',') - f.write('%d' % self.pos[1]) - f.write(',') - f.write('%.2f' % self._angle) - f.write(',') - f.write('%.2f' % self._tAngle) - f.write(',') - f.write(str(int(self.led))) - f.write(',') - f.write('%d' % (self._fired and self.FIRE_RANGE) or 0) - if not self.isDead: - f.write(',[') - for i in range(len(self._sensors)): - dist, sensorAngle, width, tSens = self._sensors[i] - - # If the angle is tied to the turret, add that. - if tSens: - sensorAngle = sensorAngle + self._tAngle - - f.write('[') - f.write(str(int(dist))) - f.write(',') - f.write('%.2f' % (sensorAngle - width/2)); - f.write(',') - f.write('%.2f' % (sensorAngle + width/2)); - f.write(',') - f.write(str(int(self._sensorState[i]))) - f.write('],') - f.write(']') - - f.write('],\n') + if self.isDead: + f.write(' 0,\n') + else: + flags = (self._fired << 0) | (self.led << 1) + sensors = 0 + for i in range(len(self._sensorState)): + sensors |= self._sensorState[i] << i + f.write(' [%d,%d,%.2f,%.2f,%d,%d],\n' % (self.pos[0], + self.pos[1], + self._angle, + self._tAngle, + flags, + sensors)) diff --git a/www/tanks/tanks.js b/www/tanks/tanks.js index 9e98d89..401dd29 100644 --- a/www/tanks/tanks.js +++ b/www/tanks/tanks.js @@ -1,3 +1,8 @@ +function dbg(o) { + e = document.getElementById("debug"); + e.innerHTML = o; +} + function torgba(color, alpha) { var r = parseInt(color.substring(1,3), 16); var g = parseInt(color.substring(3,5), 16); @@ -6,22 +11,50 @@ function torgba(color, alpha) { return "rgba(" + r + "," + g + "," + b + "," + alpha + ")"; } -function start(turns) { - var canvas = document.getElementById('battlefield'); - var ctx = canvas.getContext('2d'); - var loop_id; +function Tank(ctx, color, sensors) { + var craterStroke = torgba(color, 0.5); + var craterFill = torgba(color, 0.2); + var sensorStroke = torgba(color, 0.4); + this.x = 0; + this.y = 0; + this.rotation = 0; + this.turret = 0; - function crater(color, x, y, rotation) { + // Do all the yucky math up front + this.sensors = new Array(); + for (i in sensors) { + s = sensors[i]; + // r, angle, width, turret + this.sensors[i] = new Array(); + this.sensors[i][0] = s[0]; + this.sensors[i][1] = s[1] - (s[2]/2); + this.sensors[i][2] = s[1] + (s[2]/2); + this.sensors[i][3] = s[3]?1:0; + } + + // Set up our state, for later interleaved draw requests + this.set_state = function(x, y, rotation, turret, flags, sensor_state) { + this.x = x; + this.y = y; + this.rotation = rotation; + this.turret = turret; + this.fire = flags & 1; + this.led = flags & 2; + this.sensor_state = sensor_state; + } + + this.draw_crater = function() { var points = 7; var angle = Math.PI / points; ctx.save(); - ctx.translate(x, y); - ctx.rotate(rotation); + ctx.translate(this.x, this.y); + ctx.rotate(this.rotation); + ctx.lineWidth = 2; - ctx.strokeStyle = torgba(color, 0.5); - ctx.fillStyle = torgba(color, 0.2); + ctx.strokeStyle = craterStroke; + ctx.fillStyle = craterFill; ctx.beginPath(); ctx.moveTo(12, 0); for (i = 0; i < points; i += 1) { @@ -33,64 +66,92 @@ function start(turns) { ctx.closePath() ctx.stroke(); ctx.fill(); + ctx.restore(); } - function sensors(color, x, y, rotation, sensors) { - var sensor_color = torgba(color, 0.4); + this.draw_sensors = function() { ctx.save(); - ctx.translate(x, y); - ctx.rotate(rotation); + ctx.translate(this.x, this.y); + ctx.rotate(this.rotation); + ctx.lineWidth = 1; - for (i in sensors) { - s = sensors[i]; - if (s[3]) { + for (i in this.sensors) { + var s = this.sensors[i]; + var adj = this.turret * s[3]; + + if (self.sensor_state & (1 << i)) { + // Sensor is triggered ctx.strokeStyle = "#000"; } else { - ctx.strokeStyle = sensor_color; + ctx.strokeStyle = sensorStroke; } ctx.beginPath(); ctx.moveTo(0, 0); - ctx.arc(0, 0, s[0], s[1], s[2], false); + ctx.arc(0, 0, s[0], s[1] + adj, s[2] + adj, false); ctx.closePath(); ctx.stroke(); } + ctx.restore(); } - function tank(color, x, y, rotation, turret, led, fire) { + this.draw_tank = function() { ctx.save(); + ctx.translate(this.x, this.y); + ctx.rotate(this.rotation); + ctx.fillStyle = color; - ctx.translate(x, y); - ctx.rotate(rotation); ctx.fillRect(-5, -4, 10, 8); - ctx.fillStyle = "#777777"; + ctx.fillStyle = "#777"; ctx.fillRect(-7, -9, 15, 5); ctx.fillRect(-7, 4, 15, 5); - ctx.rotate(turret); - if (fire) { + ctx.rotate(this.turret); + if (this.fire) { ctx.fillStyle = color; - ctx.fillRect(0, -1, fire, 2); + ctx.fillRect(0, -1, 45, 2); } else { - if (led) { - ctx.fillStyle = "#ff0000"; + if (this.led) { + ctx.fillStyle = "#f00"; } else { - ctx.fillStyle = "#000000"; + ctx.fillStyle = "#000"; } ctx.fillRect(0, -1, 10, 2); } + ctx.restore(); } +} + +function start(game) { + var canvas = document.getElementById('battlefield'); + var ctx = canvas.getContext('2d'); + var loop_id; + + canvas.width = game[0]; + canvas.height = game[1]; + // game[2] is tank descriptions + var turns = game[3]; + + // Set up tanks + var tanks = new Array(); + for (i in game[2]) { + var desc = game[2][i]; + tanks[i] = new Tank(ctx, desc[0], desc[1]); + } var frame = 0; var lastframe = 0; var fps = document.getElementById('fps'); + function update_fps() { fps.innerHTML = (frame - lastframe); lastframe = frame; } + function update() { - var idx = frame % (turns.length + 20); + var idx = frame % (turns.length + 0); + var turn; frame += 1; if (idx >= turns.length) { @@ -103,23 +164,24 @@ function start(turns) { // Draw craters first for (i in turn) { t = turn[i]; - if (t[0]) { - crater(t[1], t[2], t[3], t[4]); + if (! t) { + tanks[i].draw_crater(); } } // Then sensors for (i in turn) { t = turn[i]; - if (! t[0]) { - sensors(t[1], t[2], t[3], t[4], t[8]); + if (t) { + // Surely there's a better way to do this. + tanks[i].set_state(t[0], t[1], t[2], t[3], t[4], t[5]); + tanks[i].draw_sensors(); } } // Then tanks for (i in turn) { t = turn[i]; - if (! t[0]) { - // Surely there's a better way. CBA right now. - tank(t[1], t[2], t[3], t[4], t[5], t[6], t[7]); + if (t) { + tanks[i].draw_tank() } } }