Docco always impresses too, eh?
I really like the use of:
this[key] = value for key, value of options
I'm going to use that for sure :)
I personally like code like this:
countNeighbors: (cell) ->
neighbors = 0
neighbors += @isAlive cell.row+x, cell.col+y for x in [-1..1] when x || y for y in [-1..1]
neighbors
isAlive: (row, col) -> if @world[row] and @world[row][col] and @world[row][col].live then 1 else 0
but you have to be careful, since putting a space before the "+x" will cause some bad stuff to happen. Maybe I shouldn't drop so many parenthesis.@jashkenas can you fix [-10..10] (constant boundary) loops to not check for increasing/decreasing :) I can't think of an edge case that breaks it.
But to be honest, I hate code that tries to do 5 bits of logic on one 100-character-long line, instead of just breaking into two more readable lines. [Edit: looks like that was fixed in the version at http://willbailey.name/conway/docs/conway.html]
Also, can’t your isAlive function look like:
isAlive: (row, col) -> @world[row]?[col]?.liveYes, range comprehensions were recently optimized to remove direction-checking when possible. On CoffeeScript master ...
x for x in [-10..10]
... compiles into: var x;
for (x = -10; x <= 10; x++) {
x;
}
Even if the start/end values are variables, the check can be avoided by specifying the step as a number. It'll go out with the next release. cell.live = false if count < 2 or count > 3
cell.live = true if count == 3
Could become: cell.live = count < 2 or count > 3
cell.live = count == 3
since it's a bit redundant to write "true" since it's already a boolean expression. It's a little bit like saying: if a == true:
return true
else:
return false
instead of: return a // Agreed that a could be a "truth" value without being the real "true". Still:
return !!a // With a hackWhat should happen is that, if count is 3, then cell.live becomes true. If count is 2, then cell.live retains its previous value. For all other values of count, cell.live becomes false.
cell.live = count is 3
no?