diff --git a/actions/board/board.actions.js b/actions/board/board.actions.js
new file mode 100644
index 0000000..c8a4f4f
--- /dev/null
+++ b/actions/board/board.actions.js
@@ -0,0 +1,35 @@
+export const BOARD_ACTION = 'BOARD_ACTION';
+export const GENERATE = 'GENERATE';
+export const UPDATE = 'UPDATE';
+export const HIDE = 'HIDE';
+export const SHOW = 'SHOW';
+export const NEXT_LEVEL = 'NEXT_LEVEL';
+
+export const generateValues = () => ({
+ type: BOARD_ACTION,
+ action: GENERATE
+});
+
+export const updateValue = (index, value) => ({
+ type: BOARD_ACTION,
+ action: UPDATE,
+ index: index,
+ value: value
+});
+
+export const showValue = (index) => ({
+ type: BOARD_ACTION,
+ action: SHOW,
+ index: index
+});
+
+export const hideValue = (index) => ({
+ type: BOARD_ACTION,
+ action: HIDE,
+ index: index
+});
+
+export const nextLevel = () => ({
+ type: BOARD_ACTION,
+ action: NEXT_LEVEL
+});
diff --git a/actions/board/grid.actions.js b/actions/board/grid.actions.js
deleted file mode 100644
index 98f9a3f..0000000
--- a/actions/board/grid.actions.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Grid component actions and action creators.
-export const GRID_ACTION = 'GRID_ACTION';
-export const GENERATE = 'GENERATE';
-export const UPDATE = 'UPDATE';
-
-export const generateValues = (count, level) => ({
- type: GRID_ACTION,
- action: GENERATE,
- count: count,
- level: level
-});
-
-export const updateValues = (index, value) => ({
- type: GRID_ACTION,
- action: UPDATE,
- index: index,
- value: value
-});
diff --git a/actions/board/message.actions.js b/actions/board/message.actions.js
index 8c5c90a..243b076 100644
--- a/actions/board/message.actions.js
+++ b/actions/board/message.actions.js
@@ -1,13 +1,12 @@
-// Message component actions and action creators.
export const MESSAGE_ACTION = 'MESSAGE_ACTION';
export const DISPLAY = 'DISPLAY';
export const HIDE = 'HIDE';
-export const display = (msg1, msg2, hidden) => ({
+export const display = (line1, line2, hidden) => ({
type: MESSAGE_ACTION,
action: DISPLAY,
- message1: msg1,
- message2: msg2,
+ line1: line1,
+ line2: line2,
hidden: hidden
});
diff --git a/actions/board/muncher.actions.js b/actions/board/muncher.actions.js
index 575b23b..35d7af5 100644
--- a/actions/board/muncher.actions.js
+++ b/actions/board/muncher.actions.js
@@ -1,4 +1,3 @@
-// Muncher component actions and action creators.
export const MUNCHER_ACTION = 'MUNCHER_ACTION';
export const LEFT = 'LEFT';
export const RIGHT = 'RIGHT';
diff --git a/actions/board/scorebar.actions.js b/actions/board/scorebar.actions.js
index 434ea50..766d646 100644
--- a/actions/board/scorebar.actions.js
+++ b/actions/board/scorebar.actions.js
@@ -1,4 +1,3 @@
-// Scorebar component actions and action creators.
export const SCOREBAR_ACTION = 'SCOREBAR_ACTION';
export const MUNCH_SUCCEEDED = 'MUNCH_SUCCEEDED';
export const MUNCH_FAILED = 'MUNCH_FAILED';
diff --git a/components/board/board.component.js b/components/board/board.component.js
index 3cd41e4..c76977b 100644
--- a/components/board/board.component.js
+++ b/components/board/board.component.js
@@ -8,15 +8,16 @@ import Titlebar from './titlebar.component';
import Grid from './grid.component';
import Message from './message.component';
import Muncher from './muncher.component';
+
import Values from '../../reducers/Values';
import { SETTINGS } from '../../App';
-import * as GridActions from '../../actions/board/grid.actions';
+import * as BoardActions from '../../actions/board/board.actions';
import * as MuncherActions from '../../actions/board/muncher.actions';
import * as ScorebarActions from '../../actions/board/scorebar.actions';
import * as MessageActions from '../../actions/board/message.actions';
-var exclamations = [
+const exclamations = [
'Congratulations!',
'Yippee!',
'Woohoo!',
@@ -27,35 +28,106 @@ var exclamations = [
'Shazam!'
];
+let muncherListener = null;
+let messageListener = null;
+
export default class Board extends Component {
- munch(x, y) {
- this.props.dispatch(MuncherActions.munch());
+ componentDidMount(n) {
+ muncherListener = this.muncherKeydown.bind(this);
+ messageListener = this.messageKeydown.bind(this);
- const index = y * SETTINGS.GRID_HEIGHT + x
- const valid = Values.validate(this.props.grid[index], 0);
+ window.addEventListener('keydown', muncherListener);
+ // window.addEventListener('keydown', messageListener);
- if (valid) {
- const msg = exclamations[Math.floor(Math.random() * exclamations.length)];
+ this.props.dispatch(BoardActions.nextLevel());
+ };
+
+ muncherKeydown(e) {
+ switch (e.keyCode) {
+ case 32:
+ this.munch();
+ break;
+
+ case 37:
+ this.props.dispatch(MuncherActions.moveLeft());
+ break;
+
+ case 38:
+ this.props.dispatch(MuncherActions.moveUp());
+ break;
- this.props.dispatch(GridActions.updateValues(index, ''));
- this.props.dispatch(ScorebarActions.munchSucceeded());
- this.props.dispatch(MessageActions.display(msg, 'Press Spacebar to Continue'));
+ case 39:
+ this.props.dispatch(MuncherActions.moveRight());
+ break;
+
+ case 40:
+ this.props.dispatch(MuncherActions.moveDown());
+ break;
+ }
+ };
+
+ messageKeydown(e) {
+ if (e.keyCode === 32) {
+ window.removeEventListener('keydown', messageListener);
+ window.addEventListener('keydown', muncherListener);
+
+ this.props.dispatch(MessageActions.hide());
+ }
+ };
+
+ componentWillUnmount() {
+ window.removeEventListener('keydown', muncherListener);
+ window.removeEventListener('keydown', messageListener);
+ };
+
+ munch() {
+ const { board, muncher, dispatch } = this.props;
+ const index = muncher.y * SETTINGS.GRID_HEIGHT + muncher.x;
+
+ dispatch(MuncherActions.munch());
+
+ if (board.values[index].valid) {
+ dispatch(BoardActions.hideValue(index));
+ dispatch(ScorebarActions.munchSucceeded());
}
else {
- this.props.dispatch(ScorebarActions.munchFailed());
+ window.removeEventListener('keydown', muncherListener);
+ window.addEventListener('keydown', messageListener);
+
+ const msg = Values.getError(board.values[index].value, board.level);
+ dispatch(MessageActions.display(msg, 'Press Spacebar to Continue'));
+ dispatch(ScorebarActions.munchFailed());
+ }
+
+ if (Values.checkComplete(this.props.board.values, board.level)) {
+ window.removeEventListener('keydown', muncherListener);
+ window.addEventListener('keydown', messageListener);
+
+ const msg = exclamations[Math.floor(Math.random() * exclamations.length)];
+ dispatch(MessageActions.display(msg, 'Press Spacebar to Continue'));
+ dispatch(BoardActions.nextLevel());
}
};
render() {
+ const { board, muncher, message } = this.props;
+
return (
-
-
-
-
+
+
+
+
);
};
};
-// Connect state for inspection to determine dispatching flow.
-export default connect((s) => s)(Board);
+const select = (state) => {
+ return {
+ board: state.board,
+ muncher: state.muncher,
+ message: state.message
+ };
+}
+
+export default connect(select)(Board);
diff --git a/components/board/grid-cell.component.js b/components/board/grid-cell.component.js
index 749d770..c680a31 100644
--- a/components/board/grid-cell.component.js
+++ b/components/board/grid-cell.component.js
@@ -4,6 +4,8 @@ export default class GridCell extends Component {
render() {
const classname = ['cell', 'x' + this.props.x, 'y' + this.props.y];
- return ({this.props.value}
);
+ const value = (this.props.show ? this.props.value : '');
+
+ return ({value}
);
}
};
diff --git a/components/board/grid.component.js b/components/board/grid.component.js
index 2a62608..dba8402 100644
--- a/components/board/grid.component.js
+++ b/components/board/grid.component.js
@@ -1,36 +1,20 @@
require('../../sass/board/grid.scss');
import { Component } from 'react';
-import { connect } from 'react-redux';
import GridCell from './grid-cell.component';
-import * as Actions from '../../actions/board/grid.actions';
import { SETTINGS } from '../../App';
export default class Grid extends Component {
- componentDidMount(n) {
- this.props.dispatch(Actions.generateValues(SETTINGS.GRID_WIDTH * SETTINGS.GRID_HEIGHT, 1));
- };
-
render() {
- const { values } = this.props;
+ const { values } = this.props.values;
const cells = [];
- let i;
- for (let x = 0; x < SETTINGS.GRID_WIDTH; x++) {
- for (let y = 0; y < SETTINGS.GRID_HEIGHT; y++) {
- i = y * SETTINGS.GRID_WIDTH + x;
- cells.push();
- }
- }
+ this.props.values.map((v, i) => {
+ const x = i % SETTINGS.GRID_WIDTH;
+ const y = Math.floor(i / SETTINGS.GRID_HEIGHT);
+ cells.push();
+ });
return ({cells}
);
};
};
-
-const select = (state) => {
- return {
- values: state.grid
- }
-};
-
-export default connect(select)(Grid);
diff --git a/components/board/message.component.js b/components/board/message.component.js
index 46b4a6d..b6ce4c6 100644
--- a/components/board/message.component.js
+++ b/components/board/message.component.js
@@ -1,58 +1,8 @@
require('../../sass/board/message.scss');
import { Component } from 'react';
-import { connect } from 'react-redux';
-import * as MessageActions from '../../actions/board/message.actions';
-
-const exclamations = [
- 'Congratulations!',
- 'Yippee!',
- 'Woohoo!',
- 'Nice work!',
- 'Great job!',
- 'Boom!',
- 'All finished!',
- 'Shazam!'
-];
-
-let listener = null;
-
-export class Message extends Component {
- keydown(e) {
- if (e.keyCode === 32) {
- this.props.dispatch(MessageActions.hide());
- }
- };
-
- componentDidMount() {
- listener = this.keydown.bind(this);
- window.addEventListener('keydown', listener);
- };
-
- componentWillUnmount() {
- window.removeEventListener('keydown', listener);
- };
-
- // munchFailed(value) {
- // var self = this;
- //
- // // var msg = Values.getError(value, State.level);
- // // this.setState({ hidden: false, message1: msg });
- // };
- //
- // levelComplete() {
- // function keydown(e) {
- // if (e.keyCode === 32) {
- // window.removeEventListener('keydown', keydown);
- // // State.publish('level/next');
- // }
- // };
- //
- // var msg = exclamations[Math.floor(Math.random() * exclamations.length)];
- // // this.setState({ hidden: false, message1: msg });
- // window.addEventListener('keydown', keydown);
- // };
+export default class Message extends Component {
render() {
var classname = ['message'];
@@ -62,16 +12,10 @@ export class Message extends Component {
return (
- {this.props.message1}
+ {this.props.line1}
- {this.props.message2}
+ {this.props.line2}
);
};
};
-
-const select = (state) => {
- return state.message;
-};
-
-export default connect(select)(Message);
diff --git a/components/board/muncher.component.js b/components/board/muncher.component.js
index f015f79..f903cc4 100644
--- a/components/board/muncher.component.js
+++ b/components/board/muncher.component.js
@@ -1,48 +1,8 @@
require('../../sass/board/muncher.scss');
import { Component } from 'react';
-import { connect } from 'react-redux';
-import * as Actions from '../../actions/board/muncher.actions';
-
-let listener = null;
-
-export class Muncher extends Component {
- keydown(e) {
- const x = this.props.x;
- const y = this.props.y;
-
- switch (e.keyCode) {
- case 32:
- this.props.munch(x, y);
- break;
-
- case 37:
- this.props.dispatch(Actions.moveLeft());
- break;
-
- case 38:
- this.props.dispatch(Actions.moveUp());
- break;
-
- case 39:
- this.props.dispatch(Actions.moveRight());
- break;
-
- case 40:
- this.props.dispatch(Actions.moveDown());
- break;
- }
- };
-
- componentDidMount() {
- listener = this.keydown.bind(this);
- window.addEventListener('keydown', listener);
- };
-
- componentWillUnmount() {
- window.removeEventListener('keydown', listener);
- };
+export default class Muncher extends Component {
render() {
const classname = ['muncher', 'x' + this.props.x, 'y' + this.props.y];
@@ -51,9 +11,3 @@ export class Muncher extends Component {
);
};
};
-
-const select = (state) => {
- return state.muncher;
-};
-
-export default connect(select)(Muncher);
diff --git a/components/board/titlebar.component.js b/components/board/titlebar.component.js
index 26ee142..a279c10 100644
--- a/components/board/titlebar.component.js
+++ b/components/board/titlebar.component.js
@@ -3,15 +3,7 @@ require('../../sass/board/titlebar.scss');
import { Component } from 'react';
export default class Titlebar extends Component {
- componentDidMount() {
- // State.subscribe('level/next', this.levelNext);
- };
-
- levelNext() {
- // this.setState({ title: Values.getDescription(State.level) });
- };
-
render() {
- return (DYNAMIC TITLE
);
+ return ({this.props.title}
);
};
};
diff --git a/index.js b/index.js
index a5a42ed..da09496 100644
--- a/index.js
+++ b/index.js
@@ -7,7 +7,7 @@ import { Provider } from 'react-redux';
import App from './App';
import modeReducer from './reducers/mode.reducer';
import newgameReducer from './reducers/welcome/new-game.reducer';
-import gridReducer from './reducers/board/grid.reducer';
+import boardReducer from './reducers/board/board.reducer';
import muncherReducer from './reducers/board/muncher.reducer';
import scorebarReducer from './reducers/board/scorebar.reducer';
import messageReducer from './reducers/board/message.reducer';
@@ -17,7 +17,7 @@ const reducers = combineReducers({
newgame: newgameReducer,
muncher: muncherReducer,
scorebar: scorebarReducer,
- grid: gridReducer,
+ board: boardReducer,
message: messageReducer
});
diff --git a/reducers/Values.js b/reducers/Values.js
index 79eb58e..cab023e 100644
--- a/reducers/Values.js
+++ b/reducers/Values.js
@@ -1,11 +1,21 @@
+const validate = function(value, level) {
+ return ((value || -1) % (level + 2) === 0);
+};
+
const Values = {
// Anagrams, multiples, equality
- generate(n) {
- var values = [];
-
- for (var i = 0; i < n; i++) {
- values.push(Math.ceil(Math.random() * 1000));
- }
+ generate(n, level) {
+ const values = [];
+ let v;
+
+ for (let i = 0; i < n; i++) {
+ v = Math.ceil(Math.random() * 1000);
+ values.push({
+ value: v,
+ show: true,
+ valid: validate(v, level)
+ });
+ };
return values;
},
@@ -18,21 +28,14 @@ const Values = {
return `Oops! ${value} is not a multiple of ${level + 2}.`;
},
- validate(value, level) {
- return ((value || -1) % (level + 2) === 0);
- },
-
checkComplete(values, level) {
- var len = values.length;
- var remaining = 0;
-
- for (var i = 0; i < len; i++) {
- if (module.exports.validate(values[i], level) === true) {
- remaining++;
+ for (let i = 0; i < values.length; i++) {
+ if (values[i].valid === true && values[i].show === true) {
+ return false;
}
}
- return (remaining === 0);
+ return true;
}
};
diff --git a/reducers/board/board.reducer.js b/reducers/board/board.reducer.js
new file mode 100644
index 0000000..4ab6159
--- /dev/null
+++ b/reducers/board/board.reducer.js
@@ -0,0 +1,42 @@
+const Immutable = require('immutable');
+
+import * as BoardActions from '../../actions/board/board.actions';
+import Values from '../Values';
+import { SETTINGS } from '../../App';
+
+const initial = {
+ level: -1,
+ values: [],
+ title: 'Setting up...'
+};
+
+const count = SETTINGS.GRID_WIDTH * SETTINGS.GRID_HEIGHT;
+
+const reducer = (state = initial, action) => {
+ if (action.type !== BoardActions.BOARD_ACTION) {
+ return state;
+ }
+
+ switch (action.action) {
+ case BoardActions.UPDATE:
+ return Immutable.fromJS(state).setIn(['values', action.index, 'value'], action.value).toJS();
+
+ case BoardActions.SHOW:
+ return Immutable.fromJS(state).setIn(['values', action.index, 'show'], true).toJS();
+
+ case BoardActions.HIDE:
+ return Immutable.fromJS(state).setIn(['values', action.index, 'show'], false).toJS();
+
+ case BoardActions.NEXT_LEVEL:
+ const lvl = state.level + 1;
+ return Immutable.Map(state)
+ .set('level', lvl)
+ .set('title', Values.getDescription(lvl))
+ .set('values', Values.generate(count, lvl))
+ .toObject();
+ }
+
+ return state;
+};
+
+export default reducer;
diff --git a/reducers/board/grid.reducer.js b/reducers/board/grid.reducer.js
deleted file mode 100644
index 167fbce..0000000
--- a/reducers/board/grid.reducer.js
+++ /dev/null
@@ -1,24 +0,0 @@
-const Immutable = require('immutable');
-
-import * as GridActions from '../../actions/board/grid.actions';
-import Values from '../Values';
-
-const initial = [];
-
-const reducer = (state = initial, action) => {
- if (action.type !== GridActions.GRID_ACTION) {
- return state;
- }
-
- switch (action.action) {
- case GridActions.GENERATE:
- return Values.generate(action.count, action.level);
-
- case GridActions.UPDATE:
- return Immutable.List(state).set(action.index, action.value).toArray();
- }
-
- return state;
-};
-
-export default reducer;
diff --git a/reducers/board/message.reducer.js b/reducers/board/message.reducer.js
index 437fc8d..eac90e6 100644
--- a/reducers/board/message.reducer.js
+++ b/reducers/board/message.reducer.js
@@ -2,7 +2,7 @@ const Immutable = require('immutable');
import * as MessageActions from '../../actions/board/message.actions';
-const initial = { message1: '', message2: '', hidden: true };
+const initial = { line1: '', line2: '', hidden: true };
const reducer = (state = initial, action) => {
if (action.type !== MessageActions.MESSAGE_ACTION) {
@@ -12,8 +12,8 @@ const reducer = (state = initial, action) => {
switch (action.action) {
case MessageActions.DISPLAY:
return Immutable.Map(state)
- .set('message1', action.message1)
- .set('message2', action.message2)
+ .set('line1', action.line1)
+ .set('line2', action.line2)
.set('hidden', false)
.toObject();
diff --git a/reducers/board/scorebar.reducer.js b/reducers/board/scorebar.reducer.js
index 7eee9d5..c8156ba 100644
--- a/reducers/board/scorebar.reducer.js
+++ b/reducers/board/scorebar.reducer.js
@@ -11,16 +11,12 @@ const reducer = (state = initial, action) => {
return state;
}
- const result = Immutable.Map(state);
-
switch (action.action) {
- case ScorebarActions.MUNCH:
- if (action.success) {
- return result.set('current', state.current + 10).toObject();
- }
- else {
- return result.set('lives', state.lives - 1).toObject();
- }
+ case ScorebarActions.MUNCH_SUCCEEDED:
+ return Immutable.Map(state).set('current', state.current + 10).toObject();
+
+ case ScorebarActions.MUNCH_FAILED:
+ return Immutable.Map(state).set('lives', state.lives - 1).toObject();
}
return state;