From: dsc Date: Sat, 20 Nov 2010 01:48:04 +0000 (-0800) Subject: Adds config to show grid coords. X-Git-Url: http://git.less.ly:3516/?a=commitdiff_plain;h=5016d87787fda1e222b03878a066c8ae13f57419;p=tanks.git Adds config to show grid coords. --- diff --git a/ai-challenge.md b/ai-challenge.md new file mode 100644 index 0000000..3aa28d7 --- /dev/null +++ b/ai-challenge.md @@ -0,0 +1,27 @@ +# The Tank AI Challenge + +Your goal is to design an AI tank which does its best to: 1) stay alive; 2) kill all enemy tanks. + +Rules: +- All tanks have 1hp. +- Tanks shoot bullets. Bullets explode on contact with tanks and other bullets, and bounce once on contact with a wall. +- Each tank can have up to 5 bullets in the air at a time. + +Each tick, you get a bunch of inputs: +- A pathmap of the level (which you can ask whether an area is passable) +- A list of friendly and enemy units (including bullets), each with its attributes (trajectory, position, hp, speed, power, shots, etc) +- Your attributes (position, hp, speed, power, etc) + +Ticks occur 30 times per second. When called, you'll return one action, which can be: +- Move toward (x,y) +- Fire a projectile toward (x,y) +- Do nothing +That is all. + +An AI script looks like a list of ordered (test, action) pairs. The game will consider each test in turn, and the first matching will be the action taken. Here's an example: + +- If there is a bullet that will collide with me in less than 15 ticks, shoot a bullet at its location. +- If there is a bullet that will collide with me in less than 30 ticks, move perpendicular to its trajectory. +- If there is an enemy within 100 pixels, shoot a bullet at it. +- Finally, move toward the closest enemy tank. + diff --git a/css/lttl.css b/css/lttl.css index ee4764c..08cc5b0 100644 --- a/css/lttl.css +++ b/css/lttl.css @@ -5,6 +5,15 @@ h1 { position:fixed; top:0; right:0; margin:0; padding:0; font-size:3em; color:# h2, h3, h4, h5 { margin:0; margin-bottom:0.5em; } ul, ol, li { list-style: none ! important; margin:0; padding:0; } +table { border-spacing:0; } +td { text-align:center; vertical-align:middle; } + +table.grid { position:absolute; top:0; left:0; z-index:10; } +table.grid, +table.grid td { outline:1px solid rgba(255,255,255,0.1); color:transparent; font: 18pt monospace; + margin:0; padding:0; white-space:nowrap; overflow:hidden; } +.gridShowCoords table.grid td:hover { color:rgba(255,255,255,0.1); } + .rounded { border-radius:1em; -moz-border-radius:1em; -webkit-border-radius:1em; } .box { padding:0.5em; background-color:rgba(0,0,0, 0.1); color:#787878; @@ -17,7 +26,7 @@ ul, ol, li { list-style: none ! important; margin:0; padding:0; } border:0; background-color:rgba(0,0,0, 0.1) ! important; color:#5c5c5c; } #config input[type=checkbox] { top:0.33em; } -#viewport { position:relative; top:1em; width:500px; height:500px; margin:0 auto; overflow:hidden; } +#viewport { position:relative; top:1em; width:500px; height:500px; margin:0 auto; /* overflow:hidden; */ } #info { position:fixed; bottom:10px; right:1em; } #info #state { font-weight:bold; } #info label { display:block; float:left; width:3em; margin-right:0.5em; color:#787878; } diff --git a/index.php b/index.php index 54d1905..9dc4ce9 100644 --- a/index.php +++ b/index.php @@ -23,6 +23,7 @@
+
diff --git a/notes.md b/notes.md index 9b04c89..9596a07 100644 --- a/notes.md +++ b/notes.md @@ -1,43 +1,24 @@ # Bugs - +- Tanks seem to get stuck on some corners # TODOs +- How-to overlay +- Restart level button +- AI: Line-of-sight for dodging, firing +- AI: Don't shoot if it'll kill you or your friends +- AI: Lead shots on moving targets +- Config-driven unit-types (name, stats, properties; pointers to behavior scripts, assets) +- DSL for AI scripts +- Countdown to start +- User system (so I know whose scripts are whose) +- Game scoring - Move game objects into namespace `tanks` - Move portal into namespace (ideas: `portal`, canvas tools... `easel`, or `ezl`) -- Classes should have generalize()-ed version of instance methods on them. +- Support touch events (for iPad?) # Notes - Replace *2 and /2 with shifts at compile-time - Clipping will suck (masking is easy -- overflow:hidden) - - - - -# The Tank AI Challenge - -Your goal is to design an AI tank which does its best to: 1) stay alive; 2) kill all enemy tanks. - -Rules: -- All tanks have 1hp. -- Tanks shoot bullets. Bullets explode on contact with tanks and other bullets, and bounce once on contact with a wall. -- Each tank can have up to 5 bullets in the air at a time. - -Each tick, you get a bunch of inputs: -- A pathmap of the level (which you can ask whether an area is passable) -- A list of friendly and enemy units (including bullets), each with its attributes (trajectory, position, hp, speed, power, shots, etc) -- Your attributes (position, hp, speed, power, etc) - -Ticks occur 30 times per second. When called, you'll return one action, which can be: -- Move toward (x,y) -- Fire a projectile toward (x,y) -- Do nothing -That is all. - -An AI script looks like a list of ordered (test, action) pairs. The game will consider each test in turn, and the first matching will be the action taken. Here's an example: - -- If there is a bullet that will collide with me in less than 15 ticks, shoot a bullet at its location. -- If there is a bullet that will collide with me in less than 30 ticks, move perpendicular to its trajectory. -- If there is an enemy within 100 pixels, shoot a bullet at it. -- Finally, move toward the closest enemy tank. +- Classes should have generalize()-ed version of instance methods on them. diff --git a/src/tanks/config.js b/src/tanks/config.js index 304ea63..948c6d0 100644 --- a/src/tanks/config.js +++ b/src/tanks/config.js @@ -6,6 +6,7 @@ tanks.config = { traceTrajectories : false }, debug : { - tanks : 1 + gridShowCoords : true + } }; \ No newline at end of file diff --git a/src/tanks/game/game.js b/src/tanks/game/game.js index 7e6d0df..08f57cb 100644 --- a/src/tanks/game/game.js +++ b/src/tanks/game/game.js @@ -13,7 +13,7 @@ tanks.Game = new Y.Class('Game', { this.root = this.grid = - new Grid(COLUMNS,ROWS, CELL_SIZE) + new Grid(COLUMNS,ROWS, REF_SIZE) .appendTo(this.viewport); this.level = diff --git a/src/tanks/main.js b/src/tanks/main.js index 2b26232..d4c5efa 100644 --- a/src/tanks/main.js +++ b/src/tanks/main.js @@ -15,7 +15,7 @@ function main(){ LBT = new tanks.Game(); ctx = LBT.level.ctx; - P = LBT.addUnit(new PlayerTank(1), 6,9); + P = LBT.addUnit(new PlayerTank(1), 5,9); E = LBT.addUnit(new Tank(2), 0,1); LBT.addUnit(new Tank(2), 1,0); @@ -95,6 +95,9 @@ function initConfig(){ $('#config [name=aipaths]').attr('checked', p.overlayAIPaths); $('#config [name=trajectories]').attr('checked', p.traceTrajectories); + $('#config [name=gridCoords]').attr('checked', tanks.config.debug.gridShowCoords); + $('#viewport .layer.grid')[(tanks.config.debug.gridShowCoords ? 'add' : 'remove')+'Class']('gridShowCoords'); + // $('#config [name=bullets]').val(c.debug.projectiles); // updateBullets( c.debug.projectiles ); } @@ -104,6 +107,9 @@ function updateConfig(evt){ p.overlayPathmap = $('#config [name=pathmap]').attr('checked'); p.overlayAIPaths = $('#config [name=aipaths]').attr('checked'); p.traceTrajectories = $('#config [name=trajectories]').attr('checked'); + tanks.config.debug.gridShowCoords = $('#config [name=gridCoords]').attr('checked'); + + $('#viewport .layer.grid')[(tanks.config.debug.gridShowCoords ? 'add' : 'remove')+'Class']('gridShowCoords'); } function spawnBullet(x,y, atX,atY){ diff --git a/src/tanks/map/level.js b/src/tanks/map/level.js index 1cfd7d8..efef86b 100644 --- a/src/tanks/map/level.js +++ b/src/tanks/map/level.js @@ -1,4 +1,5 @@ Level = Rect.subclass('Level', { + _cssClasses : 'portal layer level', init : function init(game, w,h){ Rect.init.call(this, w,h); @@ -7,6 +8,7 @@ Level = Rect.subclass('Level', { this.walls = []; this.setup(); + this.canvas.remove(); }, setup : function setup(){ diff --git a/src/tanks/thing/tank.js b/src/tanks/thing/tank.js index b206889..5b8d4b5 100644 --- a/src/tanks/thing/tank.js +++ b/src/tanks/thing/tank.js @@ -109,7 +109,7 @@ Tank = Thing.subclass('Tank', { } // Try to blow up nearby tanks - var t = this.nearLike(66, 'Y.is(Tank, _) && _.align !== '+this.align).shift(); + var t = this.nearLike(66, 'Y.is(Tank, _) && _.align !== this.align').shift(); if (t) { // console.log('I gotcha!', t); this.shoot(t.loc.x, t.loc.y); @@ -140,7 +140,7 @@ Tank = Thing.subclass('Tank', { }, recalculatePath : function recalculatePath(){ - var t = this.nearLike(10000, 'Y.is(Tank, _) && _.align !== '+this.align).shift() + var t = this.nearLike(10000, 'Y.is(Tank, _) && _.align !== this.align').shift() , pm = this.game.pathmap ; @@ -192,7 +192,7 @@ Tank = Thing.subclass('Tank', { , x1 = bb.x1 - within, y1 = bb.y1 - within , x2 = bb.x2 + within, y2 = bb.y2 + within ; - return this.game.pathmap.get(x1,y1, x2,y2).filter(fn || Y.op.K(true)); + return this.game.pathmap.get(x1,y1, x2,y2).filter(fn || Y.op.K(true), this); }, shoot : function shoot(x,y){ diff --git a/src/tanks/ui/grid.js b/src/tanks/ui/grid.js index 22cf5c1..4eefd43 100644 --- a/src/tanks/ui/grid.js +++ b/src/tanks/ui/grid.js @@ -12,6 +12,33 @@ Grid = new Y.Class('Grid', Rect, { }, drawShape : function drawShape(ctx){ + var tbody = $('') + , cols = this.cols, rows = this.rows, size = this.size + ; + + Y(0, rows).forEach(function(y){ + var row = $('').appendTo(tbody); + Y(0, cols).forEach(function(x){ + $(''+x+','+y+'') + .width(size).height(size) + .appendTo(row); + }, this); + }, this); + + + this.table = + $('') + .width(this.layerWidth) + .height(this.layerHeight) + .append(tbody) + .prependTo( this.layer ); + + this.canvas.remove(); + + return this; + }, + + _drawShape : function drawShape(ctx){ var size = this.size , rows = this.rows , cols = this.cols