diff --git a/actions/board/message.actions.js b/actions/board/message.actions.js
index 59048e5..5ee2331 100644
--- a/actions/board/message.actions.js
+++ b/actions/board/message.actions.js
@@ -1,7 +1,6 @@
export const MESSAGE_ACTION = 'MESSAGE_ACTION';
-export const SHOW = 'SHOW';
-export const HIDE = 'HIDE';
-export const EXCLAIM = 'EXCLAIM';
+export const SHOW = 'MESSAGE_SHOW';
+export const HIDE = 'MESSAGE_HIDE';
export const show = (message) => ({
type: MESSAGE_ACTION,
@@ -9,11 +8,6 @@ export const show = (message) => ({
message: message
});
-export const exclaim = () => ({
- type: MESSAGE_ACTION,
- action: EXCLAIM
-});
-
export const hide = () => ({
type: MESSAGE_ACTION,
action: HIDE
diff --git a/actions/board/scorebar.actions.js b/actions/board/scorebar.actions.js
index bd442ce..c78d4b0 100644
--- a/actions/board/scorebar.actions.js
+++ b/actions/board/scorebar.actions.js
@@ -1,13 +1,7 @@
export const SCOREBAR_ACTION = 'SCOREBAR_ACTION';
-export const MUNCH_SUCCEEDED = 'SCOREBAR_MUNCH_SUCCEEDED';
-export const MUNCH_FAILED = 'SCOREBAR_MUNCH_FAILED';
+export const UPDATE = 'SCOREBAR_UPDATE';
-export const munchSucceeded = () => ({
+export const update = () => ({
type: SCOREBAR_ACTION,
- action: MUNCH_SUCCEEDED,
-});
-
-export const munchFailed = () => ({
- type: SCOREBAR_ACTION,
- action: MUNCH_FAILED
+ action: UPDATE
});
diff --git a/actions/board/troggle.actions.js b/actions/board/troggle.actions.js
index b31247b..4738155 100644
--- a/actions/board/troggle.actions.js
+++ b/actions/board/troggle.actions.js
@@ -1,18 +1,22 @@
export const TROGGLE_ACTION = 'TROGGLE_ACTION';
export const CREATE = 'TROGGLE_CREATE';
-export const MOVE = 'TROGGLE_MOVE';
+export const UPDATE = 'TROGGLE_UPDATE';
export const CLEAR_ALL = 'TROGGLE_CLEAR_ALL';
-export const create = (index) => ({
+export const create = (index, x, y) => ({
type: TROGGLE_ACTION,
action: CREATE,
- index: index
+ index: index,
+ x: x,
+ y: y
});
-export const move = (index) => ({
+export const update = (index, x, y) => ({
type: TROGGLE_ACTION,
- action: MOVE,
- index: index
+ action: UPDATE,
+ index: index,
+ x: x,
+ y: y
});
export const clearAll = () => ({
diff --git a/components/board/troggles.component.js b/components/board/troggles.component.js
index 184c32a..50dfeb0 100644
--- a/components/board/troggles.component.js
+++ b/components/board/troggles.component.js
@@ -15,7 +15,7 @@ export class Troggles extends Component {
const { troggles, muncher } = this.props;
const troggleElements = Array.from(Array(troggles.length), (v, i) => {
- return ;
+ return ;
});
return
{troggleElements}
@@ -24,8 +24,7 @@ export class Troggles extends Component {
const select = (state) => {
return {
- troggles: state.troggles,
- muncher: state.muncher
+ troggles: state.troggles
};
}
diff --git a/controllers/board.controller.js b/controllers/board.controller.js
index 3b5cfd1..5499537 100644
--- a/controllers/board.controller.js
+++ b/controllers/board.controller.js
@@ -1,15 +1,14 @@
import { SETTINGS } from '../App.js';
-import * as ScorebarActions from '../actions/board/scorebar.actions';
-import * as MessageActions from '../actions/board/message.actions';
-
import TroggleCtrl from './troggle.controller';
import MessageCtrl from './message.controller';
import MuncherCtrl from './muncher.controller';
import GridCtrl from './grid.controller';
import TitlebarCtrl from './titlebar.controller';
+import ScorebarCtrl from './scorebar.controller';
let level = -1;
+let collision = false;
let dispatch;
const BoardCtrl = {
@@ -18,30 +17,51 @@ const BoardCtrl = {
GridCtrl.setDispatch(d);
MuncherCtrl.setDispatch(d);
TitlebarCtrl.setDispatch(d);
+ ScorebarCtrl.setDispatch(d);
+ MessageCtrl.setDispatch(d);
+ TroggleCtrl.setDispatch(d);
},
+ isCollision: () => collision,
+
munch() {
const index = MuncherCtrl.getY() * SETTINGS.GRID_WIDTH + MuncherCtrl.getX();
if (GridCtrl.getValues()[index].valid) {
GridCtrl.hideValue(index);
+ ScorebarCtrl.munchSucceeded();
if (GridCtrl.isCompleted() === true) {
- dispatch(MessageActions.exclaim());
+ MessageCtrl.goodNews('Level complete!');
}
}
else {
- dispatch(MessageActions.show(`Uh oh - ${GridCtrl.getValues()[index].value} is not a match.`));
+ TroggleCtrl.freeze();
+ MessageCtrl.badNews(`${GridCtrl.getValues()[index].value} is not a match.`);
+ ScorebarCtrl.munchFailed();
}
},
keyListener(e) {
- if (e.keyCode === 32 && GridCtrl.isCompleted() === true) {
+ if (e.keyCode === 32 && ScorebarCtrl.getLives() === 0) {
+ MessageCtrl.show("Game over!");
+ }
+ else if (e.keyCode === 32 && GridCtrl.isCompleted() === true) {
this.nextLevel();
- dispatch(MessageActions.hide());
+ ScorebarCtrl.levelUp(level);
+ MessageCtrl.hide();
+ }
+ else if (e.keyCode === 32 && BoardCtrl.isCollision() === true) {
+ collision = false;
+ TroggleCtrl.clearTroggles();
+ TroggleCtrl.createTroggles(level);
+ TroggleCtrl.unfreeze();
+ ScorebarCtrl.eatenByTroggle();
+ MessageCtrl.hide();
}
else if (e.keyCode === 32 && MessageCtrl.isShowing() === true) {
- dispatch(MessageActions.hide());
+ TroggleCtrl.unfreeze();
+ MessageCtrl.hide();
}
else if (e.keyCode === 32 && MessageCtrl.isShowing() === false) {
this.munch();
@@ -55,16 +75,24 @@ const BoardCtrl = {
level++;
GridCtrl.generateValues(level);
TitlebarCtrl.setTitle(level);
- // TroggleCtrl.clearAll(this.props.dispatch);
- // TroggleCtrl.createTroggles(this.props.dispatch);
+ TroggleCtrl.clearTroggles();
+ TroggleCtrl.createTroggles(level);
},
- // if (troggles[i].x === muncher.x && troggles[i].y === muncher.y) {
- // this.props.dispatch(MessageActions.show("You've been eaten by a troggle!"));
- // this.props.dispatch(ScorebarActions.munchFailed());
- // TroggleCtrl.frozen = true;
- // ReactDOM.findDOMNode(this.refs.message).focus();
- // }
+ checkCollision() {
+ const x = MuncherCtrl.getX();
+ const y = MuncherCtrl.getY();
+
+ const troggles = TroggleCtrl.getTroggles();
+ for (let i = 0; i < troggles.length; i++) {
+ if (troggles[i].x === x && troggles[i].y === y) {
+ collision = true;
+ TroggleCtrl.freeze();
+ MessageCtrl.badNews("You've been eaten by a troggle!");
+ break;
+ }
+ }
+ }
};
export default BoardCtrl;
diff --git a/controllers/message.controller.js b/controllers/message.controller.js
index 35d7db5..6c4046d 100644
--- a/controllers/message.controller.js
+++ b/controllers/message.controller.js
@@ -1,8 +1,69 @@
+import * as MessageActions from '../actions/board/message.actions';
+
+const positives = [
+ 'All finished!',
+ 'Boom!',
+ 'Capital!',
+ 'Congratulations!',
+ 'Great job!',
+ 'Huzzah!',
+ 'Hooray!',
+ 'Hot dog!',
+ 'Marvelous!',
+ 'Nice work!',
+ 'Shazam!',
+ 'Spot on!',
+ 'Whee!',
+ 'Wonderful!',
+ 'Woohoo!',
+ 'Yippee!'
+];
+
+const negatives = [
+ 'Cripes!',
+ 'Darn it!',
+ 'Doggone it!',
+ 'Drat!',
+ 'Fiddlesticks!',
+ 'Good grief!',
+ 'Oh dear!',
+ 'Oh no!',
+ 'Rats!',
+ 'Shazbot!',
+ 'Shoot!',
+ 'Shucks!',
+ 'Too bad!',
+ 'Uh oh!'
+];
+
+let dispatch;
let show = false;
const MessageCtrl = {
- hide: () => show = false,
- show: () => show = true,
+ setDispatch: (d) => dispatch = d,
+
+ hide: () => {
+ show = false;
+ dispatch(MessageActions.hide());
+ },
+
+ show: (msg) => {
+ show = true;
+ dispatch(MessageActions.show(`${msg}`));
+ },
+
+ goodNews: (msg) => {
+ show = true;
+ const exclaim = positives[Math.floor(positives.length * Math.random())];
+ dispatch(MessageActions.show(`${exclaim} ${msg}`));
+ },
+
+ badNews: (msg) => {
+ show = true;
+ const exclaim = negatives[Math.floor(negatives.length * Math.random())];
+ dispatch(MessageActions.show(`${exclaim} ${msg}`));
+ },
+
isShowing: () => show
};
diff --git a/controllers/muncher.controller.js b/controllers/muncher.controller.js
index dde9342..e73e838 100644
--- a/controllers/muncher.controller.js
+++ b/controllers/muncher.controller.js
@@ -1,4 +1,5 @@
import * as MuncherActions from '../actions/board/muncher.actions';
+import BoardCtrl from './board.controller';
import { SETTINGS } from '../App';
let x = 0;
@@ -15,31 +16,32 @@ const MuncherCtrl = {
case 37:
if (x !== 0) {
x -= 1;
- dispatch(MuncherActions.update());
}
break;
case 38:
if (y !== 0) {
y -= 1;
- dispatch(MuncherActions.update());
}
break;
case 39:
if (x !== SETTINGS.GRID_WIDTH - 1) {
x += 1;
- dispatch(MuncherActions.update());
}
break;
case 40:
if (y !== SETTINGS.GRID_HEIGHT - 1) {
y += 1;
- dispatch(MuncherActions.update());
}
break;
}
+
+ if (e.keyCode >= 37 || e.keyCode <= 40) {
+ dispatch(MuncherActions.update());
+ BoardCtrl.checkCollision();
+ }
}
};
diff --git a/controllers/scorebar.controller.js b/controllers/scorebar.controller.js
new file mode 100644
index 0000000..273478e
--- /dev/null
+++ b/controllers/scorebar.controller.js
@@ -0,0 +1,43 @@
+import * as ScorebarActions from '../actions/board/scorebar.actions';
+import { SETTINGS } from '../App';
+
+let dispatch;
+let lives = 3;
+let currentScore = 0;
+let highScore = 7;
+
+const ScorebarCtrl = {
+ setDispatch: d => dispatch = d,
+
+ getCurrentScore: () => currentScore,
+ getHighScore: () => highScore,
+ getLives: () => lives,
+
+ munchSucceeded: () => {
+ currentScore += 10;
+ dispatch(ScorebarActions.update());
+ },
+
+ munchFailed: () => {
+ lives--;
+ currentScore -= 5;
+ dispatch(ScorebarActions.update());
+ },
+
+ eatenByTroggle: () => {
+ lives--;
+ dispatch(ScorebarActions.update());
+ },
+
+ levelUp: (level) => {
+ currentScore += 25;
+ dispatch(ScorebarActions.update());
+ },
+
+ reset: () => {
+ lives = SETTINGS.LIVES;
+ currentScore = 0;
+ }
+};
+
+export default ScorebarCtrl;
diff --git a/controllers/troggle.controller.js b/controllers/troggle.controller.js
index 57221de..3643798 100644
--- a/controllers/troggle.controller.js
+++ b/controllers/troggle.controller.js
@@ -1,16 +1,30 @@
import { SETTINGS } from '../App';
import * as TroggleActions from '../actions/board/troggle.actions';
+import MuncherCtrl from './muncher.controller';
+import BoardCtrl from './board.controller';
+const troggles = [];
const troggleMoveTimers = [];
const troggleCreateTimers = [];
+let frozen = false;
+let dispatch;
+
const TroggleCtrl = {
- frozen: false,
+ setDispatch: (d) => dispatch = d,
+
+ getTroggles: () => troggles,
+
+ freeze: () => frozen = true,
+ unfreeze: () => frozen = false,
+ isFrozen: () => frozen,
- clearAll(dispatch) {
+ clearTroggles() {
dispatch(TroggleActions.clearAll());
+ troggles.length = 0;
+
troggleMoveTimers.forEach((timer) => {
clearTimeout(timer);
});
@@ -20,41 +34,50 @@ const TroggleCtrl = {
});
},
- createTroggle(index, dispatch) {
- dispatch(TroggleActions.create(index));
+ createTroggle(index) {
+ const coords = this.getStartingCoords();
+ troggles[index] = { x: coords.x, y: coords.y };
+ dispatch(TroggleActions.create(index, coords.x, coords.y));
- const ref = this.moveTroggle.bind(this, index, dispatch);
+ const ref = this.moveTroggle.bind(this, index);
troggleMoveTimers[index] = setTimeout(ref, 1000);
},
- createTroggles(dispatch, level) {
+ createTroggles(level) {
// const count = Math.min(Math.ceil((level + 1) / 2), 5);
const count = 3;
for (let index = 0; index < count; index++) {
- const ref = this.createTroggle.bind(this, index, dispatch);
+ const ref = this.createTroggle.bind(this, index);
troggleCreateTimers[index] = setTimeout(ref, (index) * 1000);
// troggleCreateTimers[index] = setTimeout(ref, (index + 1) * 5000);
}
},
- moveTroggle(index, dispatch) {
- if (this.frozen === false) {
- dispatch(TroggleActions.move(index));
+ moveTroggle(index) {
+ if (frozen === false) {
+ const coords = this.getMoveCoords(troggles[index].x, troggles[index].y);
+ troggles[index].x = coords.x;
+ troggles[index].y = coords.y;
+
+ BoardCtrl.checkCollision();
+ dispatch(TroggleActions.update(index, coords.x, coords.y));
}
- const ref = this.moveTroggle.bind(this, index, dispatch);
+ const ref = this.moveTroggle.bind(this, index);
troggleMoveTimers[index] = setTimeout(ref, 1000);
},
- getMoveCoords(currX, currY, muncherX, muncherY) {
- // Randomize movement with boolean flags.
- const moveToAttack = Boolean(Math.round(Math.random()));
- const moveAlongXAxis = Boolean(Math.round(Math.random()));
- const moveInPositiveDirection = Boolean(Math.round(Math.random()));
+ getMoveCoords(currX, currY) {
+ // Randomize movement with boolean flags. Aggression can be controlled here.
+ const moveToAttack = Boolean(Math.random() > 0.35);
+ const moveAlongXAxis = Boolean(Math.random() > 0.5);
+ const moveInPositiveDirection = Boolean(Math.random() > 0.5);
let newX = currX;
let newY = currY;
+ let muncherX = MuncherCtrl.getX();
+ let muncherY = MuncherCtrl.getY();
// DO NOT CONSOLIDATE. Attack first, ask questions later.
if (moveAlongXAxis === true) {
diff --git a/reducers/board/message.reducer.js b/reducers/board/message.reducer.js
index fc9328c..0db98dc 100644
--- a/reducers/board/message.reducer.js
+++ b/reducers/board/message.reducer.js
@@ -1,18 +1,6 @@
const Immutable = require('immutable');
import * as MessageActions from '../../actions/board/message.actions';
-import MessageCtrl from '../../controllers/message.controller';
-
-const exclamations = [
- 'Congratulations!',
- 'Yippee!',
- 'Woohoo!',
- 'Nice work!',
- 'Great job!',
- 'Boom!',
- 'All finished!',
- 'Shazam!'
-];
const initial = { message: '', hidden: true };
@@ -22,23 +10,13 @@ const reducer = (state = initial, action) => {
}
switch (action.action) {
- case MessageActions.EXCLAIM:
- MessageCtrl.show();
- const msg = exclamations[Math.floor(Math.random() * exclamations.length)];
- return Immutable.Map(state)
- .set('hidden', false)
- .set('message', msg)
- .toObject();
-
case MessageActions.SHOW:
- MessageCtrl.show();
return Immutable.Map(state)
.set('hidden', false)
.set('message', action.message)
.toObject();
case MessageActions.HIDE:
- MessageCtrl.hide();
return Immutable.Map(state)
.set('hidden', true)
.toObject();
diff --git a/reducers/board/scorebar.reducer.js b/reducers/board/scorebar.reducer.js
index 17ca7c6..9f4108b 100644
--- a/reducers/board/scorebar.reducer.js
+++ b/reducers/board/scorebar.reducer.js
@@ -1,24 +1,24 @@
const Immutable = require('immutable');
import * as ScorebarActions from '../../actions/board/scorebar.actions';
-import { SETTINGS } from '../../App';
+import ScorebarCtrl from '../../controllers/scorebar.controller.js';
-const initial = { current: 0, high: 999, lives: SETTINGS.LIVES };
+const initial = {
+ current: ScorebarCtrl.getCurrentScore(),
+ high: ScorebarCtrl.getHighScore(),
+ lives: ScorebarCtrl.getLives()
+};
const reducer = (state = initial, action) => {
if (action.type !== ScorebarActions.SCOREBAR_ACTION) {
return state;
}
- switch (action.action) {
- 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;
+ return Immutable.Map(state)
+ .set('current', ScorebarCtrl.getCurrentScore())
+ .set('high', ScorebarCtrl.getHighScore())
+ .set('lives', ScorebarCtrl.getLives())
+ .toObject();
};
export default reducer;
diff --git a/reducers/board/troggle.reducer.js b/reducers/board/troggle.reducer.js
index cc1ec85..1493d61 100644
--- a/reducers/board/troggle.reducer.js
+++ b/reducers/board/troggle.reducer.js
@@ -1,7 +1,6 @@
const Immutable = require('immutable');
import * as TroggleActions from '../../actions/board/troggle.actions';
-import TroggleCtrl from '../../controllers/troggle.controller';
const initial = [];
@@ -11,21 +10,20 @@ const reducer = (state = initial, action) => {
}
switch (action.action) {
- case TroggleActions.MOVE:
- const t = state[action.index];
- const coords1 = TroggleCtrl.getMoveCoords(t.x, t.y, t.mx, t.my);
-
+ case TroggleActions.UPDATE:
return Immutable.fromJS(state)
- .setIn([action.index, 'x'], coords1.x)
- .setIn([action.index, 'y'], coords1.y)
+ .setIn([action.index, 'x'], action.x)
+ .setIn([action.index, 'y'], action.y)
.toJS();
case TroggleActions.CREATE:
- const coords2 = TroggleCtrl.getStartingCoords();
- return Immutable.List(state).set(action.index, { x: coords2.x, y: coords2.y }).toArray();
+ return Immutable.List(state)
+ .set(action.index, { x: action.x, y: action.y })
+ .toArray();
case TroggleActions.CLEAR_ALL:
- return Immutable.List().toArray();
+ return Immutable.List()
+ .toArray();
};
return state;