Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

We created an implementation of Flood game with React.js(GitHub). We tried to use Flux-architecture. The implementation consists of parts: the storage

class Storage extends EventEmitter {
  refresh() {
    this.cells = _(_.range(15 * 15)).map(
      _.partial(getRandomInt, 0, colors.length-1)
    );
    this.turns = 0;
  }
  getState() {
    return {
      cells: this.cells,
      currentColor: this.getCurrentColor(),
      turns: this.turns
    };
  }
  constructor() {
    super();
    this.refresh();

    this.handleClick = this.handleClick.bind(this)
    this.handleRefresh = this.handleRefresh.bind(this)
    this.isValidIndex = this.isValidIndex.bind(this)
    this.getItemColor = this.getItemColor.bind(this)
  }
  getCurrentColor() {
    return this.cells[0];
  }

  handleRefresh() {
    this.refresh()
    this.emitChange();
  }

  handleClick(i) {
    var desiredColor = this.cells[i];
    if(desiredColor === this.getCurrentColor()) {
      return;
    }
    this.updateCells(desiredColor)
    this.turns++;
    this.emitChange();
  }
  emitChange() {
    this.emit('change');
  }

  isValidIndex(i) {
    return i >=0 && i < 15*15;
  }

  getSiblings(index) {
    var siblings = [
      // left
      (index % 15 == 0) ? -1 : (index - 1),
      // top
      index - 15,
      // right
      ((index + 1) % 15 == 0) ? -1 : (index + 1),
      // bottom
      index + 15
    ]
    return siblings.filter(this.isValidIndex)
  }

  getItemColor(index) {
    return this.cells[index];
  }

  updateItem(index, newColor) {
    this.cells[index] = newColor
  }

  updateCells(newColor) {
    var itemsToUpdate = []
    this.determineItemsToUpdate(0, newColor, itemsToUpdate);
    itemsToUpdate.forEach((index)=> this.updateItem(index, newColor))
    // TODO update background here
  }

  determineItemsToUpdate(index, newColor, itemsToUpdate) {
    itemsToUpdate.push(index)
    var currentColor = this.getItemColor(index)
    var siblings = this.getSiblings(index);
    var siblingsColors = siblings.map(this.getItemColor);
    siblingsColors.forEach(function(color, i) {
      if(color == currentColor && itemsToUpdate.indexOf(siblings[i]) == -1) {
        this.determineItemsToUpdate(siblings[i], newColor, itemsToUpdate)
      }
    }, this)
  }
}

and components:

class FieldComponent extends React.Component {
    handleClick(e) {
      debugger
    }

    render() {
        var {cells, handleClick} = this.props;
        cells = _(cells).map(function(k, i) {
            return <div key={i} className={`item ${colors[k]}`} onClick={handleClick.bind(undefined, i)}></div>
        })
        return (
            <div className="game-container clearfix">
                {cells}
            </div>
        )
    }
};
class ControlsComponent extends React.Component {
    render() {
      var {turns, handleRefresh} = this.props
      return (
        <div className="controls clearfix">
          <span className="counter">{turns}</span>
          <button className="btn btn-default pull-right" onClick={handleRefresh}>
            <i className="glyphicon glyphicon-repeat"></i>
          </button>
        </div>
      )
    }
};

class AppComponent extends React.Component {
  constructor(props) {
    super(props)
    this.state = props.store.getState()
  }
  componentDidMount() {
    this.props.store.addListener('change', this._onChange.bind(this));
  }
  componentWillUnmount() {
    this.props.store.removeListener('change', this._onChange.bind(this));
  }
  _onChange() {
    var {store} = this.props;
    this.setState(store.getState());
  }
  render() {
      var {state, props} = this;
      var {handleClick, handleRefresh, turns} = props.store;
      return (
          <div className={`main-container ${colors[state.currentColor]}`}>
              <div className={"wrapper"}>
                  <FieldComponent cells={state.cells} handleClick={handleClick}/>
                  <ControlsComponent handleRefresh={handleRefresh} turns={turns}  />
              </div>
          </div>
      )
  }
}

React.render(
    <AppComponent store={new Storage()}/>,
    document.body
);
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.