-
Notifications
You must be signed in to change notification settings - Fork 2
/
snake.js
79 lines (63 loc) · 2.38 KB
/
snake.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// polyfill bind
Function.prototype.bind=Function.prototype.bind||function(b){if(typeof this!=="function"){throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");}var a=Array.prototype.slice,f=a.call(arguments,1),e=this,c=function(){},d=function(){return e.apply(this instanceof c?this:b||window,f.concat(a.call(arguments)));};c.prototype=this.prototype;d.prototype=new c();return d;};
_ = Bacon._
function bindInputs() {
var keys = $(document).asEventStream('keyup').map('.keyCode')
var lefts = keys.filter(function(x) { return x === 37 })
var rights = keys.filter(function(x) { return x === 39 })
var restart = keys.filter(function(x) { return x === 82 })
var tick = Bacon.interval(100)
return { left: lefts, right: rights, tick: tick, restart: restart}
}
function getPosition(input, tick) {
var actions =
input.left.map(function() { return rotateLeft }).merge(
input.right.map(function() { return rotateRight }))
var startDirection = new Pos(0,1),
startPosition = new Pos(0,0)
var direction = actions.scan(startDirection, function(x, f) { return f(x) })
return direction
.sampledBy(input.tick)
.scan(startPosition, function(x,y) { return x.add(y) });
}
function apple(position) {
var applePos = randomPos()
return position
.filter(function(p) { return p.equals(applePos) })
.take(1)
.flatMapLatest(apple.bind(null, position))
.toProperty(applePos)
}
function game(position) {
var pos = position()
var appl = apple(pos)
var length = appl.map(1).scan(10, function(x,y) { return x + y })
var score = appl.map(1).scan(0, function(x,y) { return x + y })
var snake = pos.slidingWindowBy(length)
var dead = snake.filter(function(snake) {
return contains(_.tail(snake), _.head(snake)) })
var game = Bacon.combineTemplate({
snake: snake,
apple: appl,
score: score
})
return game.takeUntil(dead)
}
var repeated = function(game, restart) {
var gm = function() {
var tmp = game()
tmp.onEnd(logRestart);
return tmp;
}
restart.onValue(logClear)
return Bacon.separateBy(restart, gm)
}
drawGame(size);
var inputs = bindInputs()
var position = getPosition.bind(null, inputs)
var newGame = game.bind(null, position)
repeated(newGame, inputs.restart).onValue(function(e) {
drawSnake(e.snake)
drawApple([e.apple])
setScore(e.score)
})