Moving state of grid, message, muncher into board reducer.

master
Ben Burlingham 9 years ago
parent a660ff6b78
commit 4c671ec007
  1. 35
      actions/board/board.actions.js
  2. 18
      actions/board/grid.actions.js
  3. 7
      actions/board/message.actions.js
  4. 1
      actions/board/muncher.actions.js
  5. 1
      actions/board/scorebar.actions.js
  6. 108
      components/board/board.component.js
  7. 4
      components/board/grid-cell.component.js
  8. 28
      components/board/grid.component.js
  9. 62
      components/board/message.component.js
  10. 48
      components/board/muncher.component.js
  11. 10
      components/board/titlebar.component.js
  12. 4
      index.js
  13. 37
      reducers/Values.js
  14. 42
      reducers/board/board.reducer.js
  15. 24
      reducers/board/grid.reducer.js
  16. 6
      reducers/board/message.reducer.js
  17. 14
      reducers/board/scorebar.reducer.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
});

@ -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
});

@ -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
});

@ -1,4 +1,3 @@
// Muncher component actions and action creators.
export const MUNCHER_ACTION = 'MUNCHER_ACTION';
export const LEFT = 'LEFT';
export const RIGHT = 'RIGHT';

@ -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';

@ -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 (<div className='board'>
<Scorebar />
<Titlebar />
<Message />
<Grid />
<Muncher munch={this.munch.bind(this)} />
<Titlebar title={board.title} />
<Message hidden={message.hidden} line1={message.line1} line2={message.line2} />
<Muncher x={muncher.x} y={muncher.y} />
<Grid values={board.values} />
</div>);
};
};
// 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);

@ -4,6 +4,8 @@ export default class GridCell extends Component {
render() {
const classname = ['cell', 'x' + this.props.x, 'y' + this.props.y];
return (<div className={classname.join(' ')}>{this.props.value}</div>);
const value = (this.props.show ? this.props.value : '');
return (<div className={classname.join(' ')}>{value}</div>);
}
};

@ -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(<GridCell value={values[i]} x={x} y={y} key={i} />);
}
}
this.props.values.map((v, i) => {
const x = i % SETTINGS.GRID_WIDTH;
const y = Math.floor(i / SETTINGS.GRID_HEIGHT);
cells.push(<GridCell value={v.value} show={v.show} x={x} y={y} key={i} />);
});
return (<div className='grid'>{cells}</div>);
};
};
const select = (state) => {
return {
values: state.grid
}
};
export default connect(select)(Grid);

@ -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 (
<div className={classname.join(' ')}>
{this.props.message1}
{this.props.line1}
<br />
{this.props.message2}
{this.props.line2}
</div>
);
};
};
const select = (state) => {
return state.message;
};
export default connect(select)(Message);

@ -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);

@ -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 (<div className='titlebar'>DYNAMIC TITLE</div>);
return (<div className='titlebar'>{this.props.title}</div>);
};
};

@ -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
});

@ -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;
}
};

@ -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;

@ -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;

@ -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();

@ -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;

Loading…
Cancel
Save