vimtronner
Version:
A multi-player Vim trainer.
172 lines (148 loc) • 4.96 kB
text/coffeescript
require '../define_property'
require 'moniker'
{ EventEmitter } = require('events')
Moniker = require 'moniker'
directions = require './directions'
playerAttributes = require './player_attributes'
Cycle = require './cycle'
class Game extends EventEmitter
: {
WAITING: 0
COUNTDOWN: 1
STARTED: 2
FINISHED: 3
RESTARTING: 4
}
constructor: (attributes={})->
= Date.now()
= attributes.name ? Moniker.choose()
= attributes.numberOfPlayers ? 1
= (playerAttributes[n] for n in [0...]).reverse()
= attributes.width ? 80
= attributes.height ? 22
= []
= Game.STATES.WAITING
= 6000
'isWaiting', get: -> == Game.STATES.WAITING
'isCountingDown', get: -> == Game.STATES.COUNTDOWN
'isStarted', get: -> == Game.STATES.STARTED
'isFinished', get: -> == Game.STATES.FINISHED
'isRestarting', get: -> == Game.STATES.RESTARTING
'readyCycleCount', get: ->
count = 0
count++ for cycle in when cycle.ready
count
'activeCycleCount', get: ->
count = 0
count++ for cycle in when cycle.state != Cycle.STATES.DEAD
count
'outdated', get: ->
(Date.now() - ) > 180000
touch: =>
= Date.now()
addCycle: ->
return null if or .length == 0
player = .pop()
attributes = {
player: player
game: @
}
cycle = new Cycle(attributes)
.push cycle
cycle
removeCycle: (cycle)->
.push cycle.player
index = .indexOf cycle
.splice index, 1
if
checkForWinner: ->
endGameCount = if then 0 else 1
if <= endGameCount
checkKillGame: ->
if < 1
start: ->
= setInterval , 100
loop: =>
switch
when Game.STATES.WAITING, Game.STATES.RESTARTING
when Game.STATES.COUNTDOWN
when Game.STATES.STARTED
when Game.STATES.FINISHED
'game', @
runGame: =>
for cycle in
cycle?.step()
cycle?.checkCollisions()
countdown: =>
-= 100
if <= 0
= Game.STATES.STARTED
checkIfGameStarts: ->
if ==
= 6000
= Game.STATES.COUNTDOWN
playerPositions =
for cycle, i in
i = Math.floor(Math.random() * playerPositions.length)
playerPosition = playerPositions[i]
playerPositions.splice i, 1
cycle.x = playerPosition['x']
cycle.y = playerPosition['y']
cycle.direction = playerPosition['direction']
checkIfGameRestarting: ->
if .some((cycle)-> cycle.ready)
cycle.walls = [] for cycle in
= Game.STATES.RESTARTING
finishGame: ->
= Game.STATES.FINISHED
(cycle.ready = false for cycle in )
unless
stop: ->
clearInterval
'stopped', @
determineWinner: ->
cycle.makeWinner() for cycle in when cycle.state != Cycle.STATES.DEAD
'inProgress', get: -> != Game.STATES.WAITING and != Game.STATES.RESTARTING
'isPractice', get: -> == 1
'count',
get: -> Math.ceil(/2000.0)
set: (value)-> = 2000.0 * value
calculatePlayerPositions: ->
minXDistance = 3
maxXDistance = - minXDistance
halfXDistance = Math.round( / 2)
minYDistance = 3
maxYDistance = - minXDistance
halfYDistance = Math.round( / 2)
[
{ x: minXDistance, y: minYDistance, direction: directions.RIGHT }
{ x: maxXDistance, y: maxYDistance, direction: directions.LEFT }
{ x: minXDistance, y: maxYDistance, direction: directions.UP }
{ x: maxXDistance, y: minYDistance, direction: directions.DOWN }
{ x: halfXDistance, y: minYDistance, direction: directions.DOWN }
{ x: halfXDistance, y: maxYDistance, direction: directions.UP }
{ x: minXDistance, y: halfYDistance, direction: directions.RIGHT }
{ x: maxXDistance, y: halfYDistance, direction: directions.LEFT }
]
toJSON: -> {
name:
state:
count: ,
numberOfPlayers:
width:
height:
cycles: (cycle.toJSON() for cycle in )
isPractice:
}
module.exports = Game