HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Flood game implementation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
implementationgameflood

Problem

There is the implementation of flood game on my GitHub.

The app.coffee is the main part of project:

class Square
  colors = [
    'orange',
    'green',
    'red',
    'blue',
    'violet',
    'yellow',
  ]
  constructor: (@game, @node)->
    @node.on 'click', =>
      @game.flood(@color)

  reset: ->
    @controlled = false
    color = colors[Math.floor(Math.random() * colors.length)]
    @setColor(color)

  setColor: (color)->
    @node.removeClass(@color)
    @color = color
    @node.addClass(@color)

class Game
  DIMENSION = 14
  SIZE = DIMENSION * DIMENSION
  constructor: ($tbody)->
    @limit = 25
    @grid = []
    for i in [0...DIMENSION]
      $tr = $ ''
      $tbody.append $tr
      @grid.push []
      for j in [0...DIMENSION]
        $td = $('').html(' ')
        $tr.append $td
        @grid[i].push(new Square(@, $td))
    @top = @grid[0][0]
    @reset()

  reset: ->
    for i in [0...DIMENSION]
      for j in [0...DIMENSION]
        @grid[i][j].reset()
    @top = @grid[0][0]
    @top.controlled = true
    @flood(@top.color)
    @setTurnCounter(0)

  setTurnCounter: (counter)->
    $counter = $ '#count'
    @turn = counter
    $counter.toggleClass 'bad', @turn > @limit
    $('#counter-used').text(@turn)

  flood: (color)->
    if @top.color is color
      return
    @setTurnCounter(@turn + 1)
    @_flood(0, 0, color, [])
    if @hasWon()
      setTimeout(
        =>
          @decreaseLimit()
          @reset()
        2000
      )
  decreaseLimit: ()->
    @expected--

  _flood: (i, j, color, checked)->
    if i 
    for i in [0...DIMENSION]
      for j in [0...DIMENSION]
        if not @grid[i][j].controlled
          return false
    return true

(($, Game)->
  tbody = $('tbody')
  game = new Game(tbody)
  btnRestart = $('#btn-restart')
  btnRestart.on 'click', (e)->
    e.preventDefault()
    game.reset()

)(jQuery, Game)


I build assets with Grunt and use grunt-serve as a simple HTTP server.

P.S.: I use styles from another implementation

Solution

Overall, it's not bad. I only have some minor observations on the code itself:

-
You're setting, and re-setting @top in both the constructor and reset.

-
SIZE isn't used for anything.

-
Why does reset call flood? As far as I can tell, there's no need at all.

-
Doesn't seem like decreaseLimit has a point.

-
You could postfix a couple of if/unless statements and cut down on indentation.

-
in _flood the if i

-
When looping through the
@grid (in reset and hasWon) there's no need to use a [0...DIMENSION] range. You can just use regular CoffeeScript for...in loops:

for row in @grid
  for square in row
    # do something with square...


-
The IIFE at the end could be written more idiomatically using the
do keyword

do ($ = jQuery, Game) ->
  ...


Structurally, I have a few notes:

-
You inject both the
Game object and a td element into Square, so Square doesn't really have that much to do. In fact, the first thing it does is set an event listener on the element that the game object created, and set it to call back to the game object. It just seems a roundabout way to set things up.

I'd probably move the
td creation to Square.

-
You pass a
tbody element to the Game constructor, which is nice. But Game also directly accesses #count and #counter-user. So it's not really decoupled from the markup at all.

-
Somewhat similarly: You pass in
jQuery as $ in the IIFE that kicks things off. That's a perfectly good pattern. However, Game just uses $` "raw". So you're sort of half-way following the pattern.

Here's a (simplified) refactored version, just for fun.

Code Snippets

return unless 0 <= i < DIMENSION and 0 <= j < DIMENSION
square = @grid[i]?[j]
return unless square?
for row in @grid
  for square in row
    # do something with square...
do ($ = jQuery, Game) ->
  ...

Context

StackExchange Code Review Q#67287, answer score: 3

Revisions (0)

No revisions yet.