Starting Troggle AI.

master
Ben Burlingham 9 years ago
parent 4c671ec007
commit 568af65c07
  1. 4
      App.js
  2. 6
      actions/board/message.actions.js
  3. 12
      actions/board/muncher.actions.js
  4. 16
      actions/board/troggle.actions.js
  5. 139
      components/board/board.component.js
  6. 2
      components/board/grid.component.js
  7. 4
      components/board/message.component.js
  8. 57
      components/board/muncher.component.js
  9. 13
      components/board/troggle.component.js
  10. 1
      components/welcome/welcome.component.js
  11. 4
      index.js
  12. 5
      reducers/board/message.reducer.js
  13. 30
      reducers/board/muncher.reducer.js
  14. 71
      reducers/board/troggle.reducer.js
  15. 10
      sass/board/troggle.scss

@ -7,8 +7,8 @@ import Board from './components/board/board.component';
import Welcome from './components/welcome/welcome.component';
export const SETTINGS = {
GRID_WIDTH: 3,
GRID_HEIGHT: 3,
GRID_WIDTH: 6,
GRID_HEIGHT: 5,
LIVES: 3
};

@ -2,12 +2,10 @@ export const MESSAGE_ACTION = 'MESSAGE_ACTION';
export const DISPLAY = 'DISPLAY';
export const HIDE = 'HIDE';
export const display = (line1, line2, hidden) => ({
export const display = (message) => ({
type: MESSAGE_ACTION,
action: DISPLAY,
line1: line1,
line2: line2,
hidden: hidden
message: message
});
export const hide = () => ({

@ -4,6 +4,8 @@ export const RIGHT = 'RIGHT';
export const UP = 'UP';
export const DOWN = 'DOWN';
export const MUNCH = 'MUNCH';
export const FREEZE = 'FREEZE';
export const UNFREEZE = 'UNFREEZE';
export const moveLeft = () => ({
type: MUNCHER_ACTION,
@ -29,3 +31,13 @@ export const munch = (x, y) => ({
type: MUNCHER_ACTION,
action: MUNCH
});
export const freeze = () => ({
type: MUNCHER_ACTION,
action: FREEZE
});
export const unfreeze = () => ({
type: MUNCHER_ACTION,
action:UNFREEZE
});

@ -0,0 +1,16 @@
export const TROGGLE_ACTION = 'TROGGLE_ACTION';
export const CREATE = 'CREATE';
export const MOVE = 'MOVE';
export const create = () => ({
type: TROGGLE_ACTION,
action: CREATE
});
export const move = (index, muncherX, muncherY) => ({
type: TROGGLE_ACTION,
action: MOVE,
index: index,
muncherX: muncherX,
muncherY: muncherY
});

@ -8,14 +8,16 @@ import Titlebar from './titlebar.component';
import Grid from './grid.component';
import Message from './message.component';
import Muncher from './muncher.component';
import Troggle from './troggle.component';
import Values from '../../reducers/Values';
import { SETTINGS } from '../../App';
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';
import * as MuncherActions from '../../actions/board/muncher.actions';
import * as TroggleActions from '../../actions/board/troggle.actions';
const exclamations = [
'Congratulations!',
@ -28,95 +30,101 @@ const exclamations = [
'Shazam!'
];
let muncherListener = null;
let messageListener = null;
export default class Board extends Component {
componentDidMount(n) {
muncherListener = this.muncherKeydown.bind(this);
messageListener = this.messageKeydown.bind(this);
const troggleMoveTimers = [];
const troggleCreateTimers = [];
window.addEventListener('keydown', muncherListener);
// window.addEventListener('keydown', messageListener);
// const toggleMoveTimeout = function() {
// this.props.dispatch(TroggleActions.move());
// };
this.props.dispatch(BoardActions.nextLevel());
};
const continuations = {
muncher: null,
message: null
};
muncherKeydown(e) {
switch (e.keyCode) {
case 32:
this.munch();
break;
let listener = null;
case 37:
this.props.dispatch(MuncherActions.moveLeft());
break;
export default class Board extends Component {
nextLevel() {
this.props.dispatch(BoardActions.nextLevel());
case 38:
this.props.dispatch(MuncherActions.moveUp());
break;
const troggleCount = 1; //Math.min(Math.ceil(this.props.board.level / 2), 5);
for (let i = 0; i < troggleCount; i++) {
this.props.dispatch(TroggleActions.create());
troggleMoveTimers.push(setTimeout(this.moveTroggle.bind(this, i), 1000));
}
case 39:
this.props.dispatch(MuncherActions.moveRight());
break;
// toggleTimeout.call(this);
};
case 40:
this.props.dispatch(MuncherActions.moveDown());
break;
}
componentDidMount() {
listener = this.keydown.bind(this);
window.addEventListener('keydown', listener);
this.nextLevel();
};
messageKeydown(e) {
if (e.keyCode === 32) {
window.removeEventListener('keydown', messageListener);
window.addEventListener('keydown', muncherListener);
componentWillUnmount() {
window.removeEventListener('keydown', listener);
this.props.dispatch(MessageActions.hide());
}
// destroy all troggle timers
};
componentWillUnmount() {
window.removeEventListener('keydown', muncherListener);
window.removeEventListener('keydown', messageListener);
moveTroggle(index) {
this.props.dispatch(TroggleActions.move(index));
clearTimeout(troggleMoveTimers[index]);
troggleMoveTimers[index] = setTimeout(this.moveTroggle.bind(this, index), 1000);
};
munch() {
const { board, muncher, dispatch } = this.props;
const index = muncher.y * SETTINGS.GRID_HEIGHT + muncher.x;
// Keydown listener for spacebar, since it is bound to munch event and
// message hide event. Couldn't find a more modular way to do this.
keydown(e) {
if (e.keyCode !== 32) {
return;
}
dispatch(MuncherActions.munch());
if (this.props.message.hidden === false) {
this.props.dispatch(MessageActions.hide());
this.props.dispatch(MuncherActions.unfreeze());
if (board.values[index].valid) {
dispatch(BoardActions.hideValue(index));
dispatch(ScorebarActions.munchSucceeded());
if (Values.checkComplete(this.props.board.values, this.props.board.level)) {
console.warn("NEXT LEVEL")
}
}
else {
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());
const index = this.props.muncher.y * SETTINGS.GRID_HEIGHT + this.props.muncher.x
const { board, dispatch } = this.props;
if (board.values[index].valid) {
dispatch(BoardActions.hideValue(index));
dispatch(ScorebarActions.munchSucceeded());
}
else {
const msg = Values.getError(board.values[index].value, board.level);
dispatch(MessageActions.display(msg));
dispatch(ScorebarActions.munchFailed());
dispatch(MuncherActions.freeze());
}
if (Values.checkComplete(this.props.board.values, board.level)) {
const msg = exclamations[Math.floor(Math.random() * exclamations.length)];
dispatch(MessageActions.display(msg));
}
}
};
render() {
const { board, muncher, message } = this.props;
const { board, message, troggles } = this.props;
const troggleElements = [];
for (let i = 0; i < troggles.length; i++) {
troggleElements.push(<Troggle x={troggles[i].x} y={troggles[i].y} key={i} />);
}
return (<div className='board'>
<Scorebar />
<Titlebar title={board.title} />
<Message hidden={message.hidden} line1={message.line1} line2={message.line2} />
<Muncher x={muncher.x} y={muncher.y} />
<Message hidden={message.hidden} message={message.message} />
<Muncher />
{troggleElements}
<Grid values={board.values} />
</div>);
};
@ -126,7 +134,8 @@ const select = (state) => {
return {
board: state.board,
muncher: state.muncher,
message: state.message
message: state.message,
troggles: state.troggles
};
}

@ -11,7 +11,7 @@ export default class Grid extends Component {
this.props.values.map((v, i) => {
const x = i % SETTINGS.GRID_WIDTH;
const y = Math.floor(i / SETTINGS.GRID_HEIGHT);
const y = Math.floor(i / SETTINGS.GRID_WIDTH);
cells.push(<GridCell value={v.value} show={v.show} x={x} y={y} key={i} />);
});

@ -12,9 +12,9 @@ export default class Message extends Component {
return (
<div className={classname.join(' ')}>
{this.props.line1}
{this.props.message}
<br />
{this.props.line2}
Press Spacebar to continue.
</div>
);
};

@ -1,8 +1,57 @@
require('../../sass/board/muncher.scss');
import { Component } from 'react';
import { connect } from 'react-redux';
import * as MuncherActions from '../../actions/board/muncher.actions';
import { SETTINGS } from '../../App';
let listener = null;
export class Muncher extends Component {
componentDidMount() {
listener = this.keydown.bind(this);
window.addEventListener('keydown', listener);
};
componentWillUnmount() {
window.removeEventListener('keydown', listener);
};
keydown(e) {
if (this.props.frozen === true) {
return;
}
const x = this.props.x;
const y = this.props.y;
switch (e.keyCode) {
case 37:
if (x !== 0) {
this.props.dispatch(MuncherActions.moveLeft());
}
break;
case 38:
if (y !== 0) {
this.props.dispatch(MuncherActions.moveUp());
}
break;
case 39:
if (x !== SETTINGS.GRID_WIDTH - 1) {
this.props.dispatch(MuncherActions.moveRight());
}
break;
case 40:
if (y !== SETTINGS.GRID_HEIGHT - 1) {
this.props.dispatch(MuncherActions.moveDown());
}
break;
}
};
export default class Muncher extends Component {
render() {
const classname = ['muncher', 'x' + this.props.x, 'y' + this.props.y];
@ -11,3 +60,9 @@ export default class Muncher extends Component {
);
};
};
const select = (state) => {
return state.muncher;
}
export default connect(select)(Muncher);

@ -0,0 +1,13 @@
require('../../sass/board/troggle.scss');
import { Component } from 'react';
export default class Muncher extends Component {
render() {
const classname = ['troggle', 'x' + this.props.x, 'y' + this.props.y];
return (
<div className={classname.join(' ')}></div>
);
};
};

@ -6,7 +6,6 @@ import NewGame from './new-game.component';
import HighScores from './high-scores.component';
export default class Welcome extends Component {
render() {
return (
<div className='welcome'>

@ -11,6 +11,7 @@ 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';
import troggleReducer from './reducers/board/troggle.reducer';
const reducers = combineReducers({
mode: modeReducer,
@ -18,7 +19,8 @@ const reducers = combineReducers({
muncher: muncherReducer,
scorebar: scorebarReducer,
board: boardReducer,
message: messageReducer
message: messageReducer,
troggles: troggleReducer
});
const store = createStore(reducers);

@ -2,7 +2,7 @@ const Immutable = require('immutable');
import * as MessageActions from '../../actions/board/message.actions';
const initial = { line1: '', line2: '', hidden: true };
const initial = { message: '', hidden: true };
const reducer = (state = initial, action) => {
if (action.type !== MessageActions.MESSAGE_ACTION) {
@ -12,9 +12,8 @@ const reducer = (state = initial, action) => {
switch (action.action) {
case MessageActions.DISPLAY:
return Immutable.Map(state)
.set('line1', action.line1)
.set('line2', action.line2)
.set('hidden', false)
.set('message', action.message)
.toObject();
case MessageActions.HIDE:

@ -1,7 +1,8 @@
const Immutable = require('immutable');
import * as MuncherActions from '../../actions/board/muncher.actions';
import { SETTINGS } from '../../App';
const initial = { x: 0, y: 0 };
const initial = { x: 0, y: 0, frozen: false };
const reducer = (state = initial, action) => {
if (action.type !== MuncherActions.MUNCHER_ACTION) {
@ -10,31 +11,22 @@ const reducer = (state = initial, action) => {
switch (action.action) {
case MuncherActions.LEFT:
if (state.x === 0) {
return state;
}
return { x: state.x - 1, y: state.y };
return Immutable.Map(state).set('x', state.x - 1).toObject();
case MuncherActions.RIGHT:
if (state.x === SETTINGS.GRID_WIDTH - 1) {
return state;
}
return { x: state.x + 1, y: state.y };
return Immutable.Map(state).set('x', state.x + 1).toObject();
case MuncherActions.UP:
if (state.y === 0) {
return state;
}
return { x: state.x, y: state.y - 1 };
return Immutable.Map(state).set('y', state.y - 1).toObject();
case MuncherActions.DOWN:
if (state.y === SETTINGS.GRID_HEIGHT - 1) {
return state;
}
return { x: state.x, y: state.y + 1 };
return Immutable.Map(state).set('y', state.y + 1).toObject();
case MuncherActions.MUNCH:
return state;
case MuncherActions.FREEZE:
return Immutable.Map(state).set('frozen', true).toObject();
case MuncherActions.UNFREEZE:
return Immutable.Map(state).set('frozen', false).toObject();
}
return state;

@ -0,0 +1,71 @@
const Immutable = require('immutable');
import * as TroggleActions from '../../actions/board/troggle.actions';
import { SETTINGS } from '../../App';
const initial = [];
const reducer = (state = initial, action) => {
if (action.type !== TroggleActions.TROGGLE_ACTION) {
return state;
}
switch (action.action) {
case TroggleActions.MOVE:
// 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()));
const x = state[action.index].x;
const y = state[action.index].y;
let newX = x;
let newY = y;
// DO NOT CONSOLIDATE. Attack first, ask questions later.
if (moveAlongXAxis === true) {
if (x === SETTINGS.GRID_WIDTH - 1 ||
(moveToAttack && x >= action.muncherX)) {
newX = x - 1;
}
else if (x === 0 ||
(moveToAttack && x < action.muncherX)) {
newX = x + 1;
}
else if (moveInPositiveDirection) {
newX = x + 1;
}
else if (!moveInPositiveDirection) {
newX = x - 1;
}
}
else {
if (y === SETTINGS.GRID_HEIGHT - 1 ||
(moveToAttack && y >= action.muncherY)) {
newY = y - 1;
}
else if (y === 0 ||
(moveToAttack && y < action.muncherY)) {
newY = y + 1;
}
else if (moveInPositiveDirection) {
newY = y + 1;
}
else if (!moveInPositiveDirection) {
newY = y - 1;
}
}
return Immutable.fromJS(state)
.setIn([action.index, 'x'], newX)
.setIn([action.index, 'y'], newY)
.toJS();
case TroggleActions.CREATE:
return Immutable.List(state).push({ x: 0, y: 0 }).toArray();
break;
}
return state;
};
export default reducer;

@ -0,0 +1,10 @@
.troggle {
$bg: crimson;
background: $bg;
height:100px;
margin-top:110px;
opacity: 0.5;
position:absolute;
width:100px;
}
Loading…
Cancel
Save