[verified] Snake 0.8: circular arena and larger 32px tiles
This commit is contained in:
+17
-12
@@ -40,13 +40,12 @@ test('retired timer callbacks cannot advance a resumed or restarted run', () =>
|
||||
})
|
||||
test('filling the board wins without null food crashes and retry clears the result', () => {
|
||||
const {p, timers} = page()
|
||||
// A serpentine Hamilton path, head (14,0), final food (15,0).
|
||||
const path = []
|
||||
for (let y=0;y<16;y++) for (let k=0;k<16;k++) path.push({x:y%2 ? k : 15-k,y})
|
||||
p.model = path.slice(1); p.dir = {x:1,y:0}; p.foodModel = {x:15,y:0}
|
||||
// Legal occupancy fixture isolates final-cell victory from pathfinding.
|
||||
p.model = [{x:5,y:0}, ...snake.ARENA.cells.filter(c=>!(c.y===0 && (c.x===5 || c.x===6)))]
|
||||
p.dir = {x:1,y:0}; p.foodModel = {x:6,y:0}
|
||||
p.tick(); assert.equal(p.over, true); assert.equal(p.endText, 'YOU WIN')
|
||||
assert.equal(p.scoreText, 'SCORE 253'); assert.equal(p.bestText, 'BEST 253')
|
||||
assert.equal(p.hasFood, false); assert.equal(p.snake.length, 256); assert.equal(timers.size, 0)
|
||||
assert.equal(p.scoreText, 'SCORE 86'); assert.equal(p.bestText, 'BEST 86')
|
||||
assert.equal(p.hasFood, false); assert.equal(p.snake.length, 89); assert.equal(timers.size, 0)
|
||||
p.tick(); p.onShow(); assert.equal(timers.size, 0)
|
||||
p.restart(); assert.equal(p.hasFood, true); assert.equal(p.endText, 'GAME OVER'); assert.equal(p.model.length, 3)
|
||||
assert.match(ux, /show="\{\{ hasFood \}\}"/)
|
||||
@@ -58,11 +57,11 @@ test('select modes while paused or over, resetting safely, and retry keeps mode'
|
||||
p.selectMode('wrap'); assert.equal(p.mode, 'classic', 'no mid-run mode change')
|
||||
p.onTap(); p.selectMode('garbage'); assert.equal(p.mode, 'classic')
|
||||
p.selectMode('wrap'); assert.equal(p.mode, 'wrap'); assert.equal(p.paused, true); assert.equal(timers.size, 0)
|
||||
p.onTap(); p.model = [{x:15,y:7},{x:14,y:7},{x:13,y:7}]; p.tick()
|
||||
assert.equal(p.model[0].x, 0); assert.match(p.snake[1].src, /body_h/)
|
||||
p.onTap(); p.model = [{x:9,y:7},{x:8,y:7},{x:7,y:7}]; p.tick()
|
||||
assert.equal(p.model[0].x, 1); assert.match(p.snake[1].src, /body_h/)
|
||||
p.restart(); assert.equal(p.mode, 'wrap'); assert.equal(timers.size, 1)
|
||||
p.onTap(); p.selectMode('classic'); p.onTap()
|
||||
p.model = [{x:15,y:7},{x:14,y:7},{x:13,y:7}]; p.tick()
|
||||
p.model = [{x:9,y:7},{x:8,y:7},{x:7,y:7}]; p.tick()
|
||||
assert.equal(p.over, true); assert.equal(timers.size, 0)
|
||||
p.onShow(); p.onTap(); assert.equal(p.over, true); assert.equal(timers.size, 0)
|
||||
p.restart(); assert.equal(p.over, false); assert.equal(timers.size, 1)
|
||||
@@ -95,7 +94,7 @@ test('Wrap crosses every edge, still collides with body and renders seam connect
|
||||
assert.deepEqual(snake.renderPieces([{x:0,y:7},{x:15,y:7}], dirs[0], 16), ['head_e','tail_w'])
|
||||
})
|
||||
function eatTo(p, score) {
|
||||
p.model = [{x:6,y:7}, ...Array.from({length:score+1}, (_,i) => ({x:i%16,y:12+Math.floor(i/16)}))]
|
||||
p.model = [{x:6,y:7}, ...snake.ARENA.cells.filter(c=>c.y!==7).slice(0,score+1)]
|
||||
p.dir = {x:1,y:0}; p.foodModel = {x:7,y:7}; p.tick()
|
||||
}
|
||||
test('late best read cannot lower local record; writes are serialized', () => {
|
||||
@@ -124,12 +123,18 @@ test('storage throws and corrupt values never crash or poison gameplay', () => {
|
||||
assert.equal(p.bestText, 'BEST 0'); eatTo(p, 1); assert.equal(p.bestText, 'BEST 1')
|
||||
}
|
||||
})
|
||||
test('legacy 0.7 records above the new arena maximum survive', () => {
|
||||
const writes=[]
|
||||
const {p}=page({get(o){o.success('253')},set(o){writes.push(o)}})
|
||||
eatTo(p,20); p.restart()
|
||||
assert.equal(p.bestText,'BEST 253'); assert.equal(writes.length,0)
|
||||
})
|
||||
test('best score loads raw storage value and persists only new records', () => {
|
||||
let get; const writes = []
|
||||
const {p} = page({get(o) { get=o }, set(o) { writes.push(o) }})
|
||||
assert.ok(get, 'best score requested'); assert.equal(get.default, '0')
|
||||
get.success('4'); assert.equal(p.bestText, 'BEST 4')
|
||||
p.model = [{x:6,y:7}, ...Array.from({length:6}, (_,i) => ({x:i,y:12}))]
|
||||
p.model = [{x:6,y:7}, ...snake.ARENA.cells.filter(c=>c.y!==7).slice(0,6)]
|
||||
p.foodModel = {x:7,y:7}; p.tick()
|
||||
assert.equal(p.bestText, 'BEST 5'); assert.equal(writes.length, 1)
|
||||
assert.equal(writes[0].value, '5'); assert.equal(writes[0].key, get.key)
|
||||
@@ -141,7 +146,7 @@ test('eating updates live score and accelerates to a capped 120ms', () => {
|
||||
const {p, timers} = page()
|
||||
assert.equal([...timers.values()][0].ms, 300)
|
||||
for (let score = 1; score <= 20; score++) {
|
||||
p.model = [{x:6,y:7}, ...Array.from({length:score+1}, (_,i) => ({x:i%16,y:12+Math.floor(i/16)}))]
|
||||
p.model = [{x:6,y:7}, ...snake.ARENA.cells.filter(c=>c.y!==7).slice(0,score+1)]
|
||||
p.dir = {x:1,y:0}; p.foodModel = {x:7,y:7}; p.tick()
|
||||
assert.equal(p.scoreText, 'SCORE ' + score)
|
||||
assert.equal(timers.size, 1); assert.equal([...timers.values()][0].ms, Math.max(120, 300-score*10))
|
||||
|
||||
Reference in New Issue
Block a user