/tic-tac-toe-js

#⃣ Tic-tac-toe.js: redux pattern implemented in vanilla javascript

Primary LanguageJavaScript

Tic-Tac-Toe.js

Tic-Tac-Toe game written in vanilla javascript using redux-like approach.

Mobile and desktop Tic-Tac-Toe.js screenshots

How the game applies Redux pattern?

It uses the unidirectional data flow:

Mobile and desktop Tic-Tac-Toe.js screenshots

The key principles

1. Single source of truth

One single store.js:

function Store() {
  this.state = {};
  this.state = this.update(this.state, {});
  // `this.update()` will return the initial state:
  // ----------------------------------------------
  // {
  //   grid: ['', '', '', '', '', '', '', '', ''],
  //   turn: 'x',
  //   score: { x: 0, o: 0 },
  //   winnerSequence: [],
  //   turnCounter: 0,
  //   player: ''
  // }
}

2. State is read-only

Game.js dispatches actions whenever needed:

this.$table.addEventListener('click', function(event) {
  var state = store.getState();
  // [Prevent dispatch under certain conditions]
  // Otherwise, trigger `SET_X` or `SET_O`
  store.dispatch({
    type: state.turn === 'x' ? 'SET_X' : 'SET_O',
    index: parseInt(index, 10)
  });
});

3. Changes are made with pure functions

Store.js: reducers receive actions and return new state.

// Reducer (pure function)
function updatePlayer(player, action) {
  switch (action.type) {
    case 'PICK_SIDE':
      return action.side;
    default:
      return player || '';
  }
}

// Call reducer on Store.update()
Store.prototype.update = function(state, action) {
  return {
    player: updatePlayer(state.player, action)
    // [...other cool stuff here]
  };
};

4. After update, UI can render latest state

Game.js handles UI changes:

var store = require('./store');
var gridView = require('./grid-view');

TicTacToe.prototype.eventListeners = function() {
  store.subscribe(this.render.bind(this));
};

TicTacToe.prototype.render = function(prevState, state) {
  // You can even check whether new state is different
  if (prevState.grid !== state.grid) {
    this.gridView.render('grid', state.grid);
  }
};

Further details about implementation you can find on this page.

Browser support

The game has been tested in the following platforms:

Latest Latest 10+ Latest
Chrome Firefox IE Safari

Development stack

  • Server: NodeJS / Express / Socket.io
  • Client: VanillaJS / Redux
  • Tools: Gulp / Webpack / Sass / Heroku

Did you find a bug?

Please report on the issues tab.