const canvas = document.querySelector('canvas');
const M = `
00000000000000000000
00000110011111110000
00001111111110000000
00011111111111100000
00111111111101110010
01111111101111110010
01111111111111110110
01111111111111111110
01111111111111111100
01111111111111111100
01111111111111111100
01111111111111111000
00111111111111111000
00111111111111110000
00011111111111100000
00000000000000000000
`.trim().split('\n').map(x=>x.trim().split('').map(x=>parseInt(x)))
const mat = ({ x, y }, v) => {
if (v) {
M[y][x] = v
}
return M[y][x]
}
const left = ({x,y}) => ({ x: y, y: -x })
const right = ({x,y}) => ({ x: -y, y: x })
const back = ({x, y}) => ({ x: -x, y: -y})
const front = (pos, { x, y }) => ({ x: pos.x + x, y: pos.y + y })
const splinter = {
pos: {
x: 5,
y: 1
},
orig: {
x: 5,
y: 1
},
dir: { x: 1, y: 0 },
atStart() {
return this.pos.x === this.orig.x && this.pos.y === this.orig.y
},
move () {
if (this.atStart() && mat(this.pos) === 2) { return false }
if (mat(front(this.pos, left(this.dir))) === 0) {
if (mat(front(this.pos, this.dir)) === 0) {
if (mat(front(this.pos, right(this.dir))) === 0) {
this.dir = back(this.dir)
} else {
this.dir = right(this.dir)
}
}
this.poop()
} else {
this.dir = left(this.dir)
}
this.moveForward()
return true
},
moveForward () {
this.pos.x += this.dir.x
this.pos.y += this.dir.y
},
poop () {
mat({ x: this.pos.x, y: this.pos.y }, 2)
},
sprite () {
if (this.atStart()) { return 'X' }
if (this.dir.x === -1 && this.dir.y === 0) { return '←' }
if (this.dir.x === 1 && this.dir.y === 0) { return '→'}
if (this.dir.x === 0 && this.dir.y === 1) { return '↓' }
if (this.dir.x === 0 && this.dir.y === -1) { return '↑' }
}
}
function redraw () {
const ctx = canvas.getContext('2d')
const dw = canvas.width / M[0].length
const dh = canvas.height / M.length
const fill = ({ x, y }, color) => {
ctx.fillStyle = color
ctx.fillRect(x * dw, y * dh, dw, dh)
}
const colors = {
1: 'green',
0: 'black',
2: 'white'
}
M.forEach((row, i) => {
row.forEach((el, j) => {
fill({ x: j, y: i }, colors[el])
})
})
const char = splinter.sprite()
ctx.strokeText(char, (splinter.pos.x + 0.1) * dw, (splinter.pos.y + 0.8) * dh)
}
redraw()
document.querySelector('button').onclick = _ => {
splinter.move(); redraw()
}
document.querySelector('button.allmoves').onclick = _ => {
while(splinter.move()){}
redraw()
}
canvas{background:#eeeeee;}
<canvas width="160" height="160"></canvas>
<button>move, rat</button>
<button class="allmoves">move for your life, rat</button>
color(x+1)
是什么?你是不是想写color(x+1,y)
? - Cris Luengo