Troggle AI work continues.

master
Ben Burlingham 9 years ago
parent 568af65c07
commit 43a0a09314
  1. 12
      actions/board/message.actions.js
  2. 30
      actions/board/troggle.actions.js
  3. 88
      components/board/board.component.js
  4. 74
      reducers/TroggleAI.js
  5. 20
      reducers/board/message.reducer.js
  6. 61
      reducers/board/troggle.reducer.js
  7. 2
      sass/board/board.scss

@ -1,13 +1,19 @@
export const MESSAGE_ACTION = 'MESSAGE_ACTION';
export const DISPLAY = 'DISPLAY';
export const SHOW = 'SHOW';
export const HIDE = 'HIDE';
export const EXCLAIM = 'EXCLAIM';
export const display = (message) => ({
export const show = (message) => ({
type: MESSAGE_ACTION,
action: DISPLAY,
action: SHOW,
message: message
});
export const exclaim = () => ({
type: MESSAGE_ACTION,
action: EXCLAIM
});
export const hide = () => ({
type: MESSAGE_ACTION,
action: HIDE

@ -1,16 +1,36 @@
export const TROGGLE_ACTION = 'TROGGLE_ACTION';
export const CREATE = 'CREATE';
export const MOVE = 'MOVE';
export const FREEZE_ALL = 'FREEZE_ALL';
export const UNFREEZE_ALL = 'UNFREEZE_ALL';
export const CLEAR_ALL = 'CLEAR_ALL';
export const create = () => ({
export const create = (x, y) => ({
type: TROGGLE_ACTION,
action: CREATE
action: CREATE,
x: x,
y: y
});
export const move = (index, muncherX, muncherY) => ({
export const move = (index, x, y) => ({
type: TROGGLE_ACTION,
action: MOVE,
index: index,
muncherX: muncherX,
muncherY: muncherY
x: x,
y: y
});
export const freezeAll = () => ({
type: TROGGLE_ACTION,
action: FREEZE_ALL
});
export const unfreezeAll = () => ({
type: TROGGLE_ACTION,
action: UNFREEZE_ALL
});
export const clearAll = () => ({
type: TROGGLE_ACTION,
action: CLEAR_ALL
});

@ -11,6 +11,7 @@ import Muncher from './muncher.component';
import Troggle from './troggle.component';
import Values from '../../reducers/Values';
import TroggleAI from '../../reducers/TroggleAI';
import { SETTINGS } from '../../App';
import * as BoardActions from '../../actions/board/board.actions';
@ -19,44 +20,12 @@ 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!',
'Yippee!',
'Woohoo!',
'Nice work!',
'Great job!',
'Boom!',
'All finished!',
'Shazam!'
];
const troggleMoveTimers = [];
const troggleCreateTimers = [];
// const toggleMoveTimeout = function() {
// this.props.dispatch(TroggleActions.move());
// };
const continuations = {
muncher: null,
message: null
};
let listener = null;
export default class Board extends Component {
nextLevel() {
this.props.dispatch(BoardActions.nextLevel());
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));
}
// toggleTimeout.call(this);
};
componentDidMount() {
listener = this.keydown.bind(this);
window.addEventListener('keydown', listener);
@ -64,15 +33,57 @@ export default class Board extends Component {
};
componentWillUnmount() {
this.clearTroggleTimers();
window.removeEventListener('keydown', listener);
};
// destroy all troggle timers
nextLevel() {
this.props.dispatch(BoardActions.nextLevel());
this.props.dispatch(TroggleActions.clearAll());
this.clearTroggleTimers();
this.createTroggles();
};
clearTroggleTimers() {
troggleMoveTimers.forEach((timer) => {
clearTimeout(timer);
});
troggleCreateTimers.forEach((timer) => {
clearTimeout(timer);
});
};
createTroggle(index) {
const newCoords = TroggleAI.create();
this.props.dispatch(TroggleActions.create(newCoords.x, newCoords.y));
troggleMoveTimers.push(setTimeout(this.moveTroggle.bind(this, index), 1000));
};
createTroggles() {
const troggleCount = 3; //Math.min(Math.ceil(this.props.board.level / 2), 5);
for (let i = 0; i < troggleCount; i++) {
setTimeout(this.createTroggle.bind(this, i), (i + 1) * 5000);
}
};
moveTroggle(index) {
this.props.dispatch(TroggleActions.move(index));
clearTimeout(troggleMoveTimers[index]);
troggleMoveTimers[index] = setTimeout(this.moveTroggle.bind(this, index), 1000);
const newCoords = TroggleAI.move(
this.props.troggles[index].x,
this.props.troggles[index].y,
this.props.muncher.x,
this.props.muncher.y
);
if (newCoords.x === this.props.muncher.x && newCoords.y === this.props.muncher.y) {
this.props.dispatch(MessageActions.show('Eaten by a troggle!'));
this.props.dispatch(TroggleActions.clearAll());
}
else {
this.props.dispatch(TroggleActions.move(index, newCoords.x, newCoords.y));
clearTimeout(troggleMoveTimers[index]);
troggleMoveTimers[index] = setTimeout(this.moveTroggle.bind(this, index), 1000);
}
};
// Keydown listener for spacebar, since it is bound to munch event and
@ -100,14 +111,13 @@ export default class Board extends Component {
}
else {
const msg = Values.getError(board.values[index].value, board.level);
dispatch(MessageActions.display(msg));
dispatch(MessageActions.show(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));
dispatch(MessageActions.exclaim());
}
}
};

@ -0,0 +1,74 @@
import { SETTINGS } from '../App';
const TroggleAI = {
move: function(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()));
let newX = currX;
let newY = currY;
// DO NOT CONSOLIDATE. Attack first, ask questions later.
if (moveAlongXAxis === true) {
if (currX >= SETTINGS.GRID_WIDTH - 1 ||
(moveToAttack && currX > muncherX)) {
newX = currX - 1;
}
else if (currX <= 0 ||
(moveToAttack && currX < muncherX)) {
newX = currX + 1;
}
else if (moveInPositiveDirection) {
newX = currX + 1;
}
else if (!moveInPositiveDirection) {
newX = currX - 1;
}
}
else {
if (currY >= SETTINGS.GRID_HEIGHT - 1 ||
(moveToAttack && currY > muncherY)) {
newY = currY - 1;
}
else if (currY <= 0 ||
(moveToAttack && currY < muncherY)) {
newY = currY + 1;
}
else if (moveInPositiveDirection) {
newY = currY + 1;
}
else if (!moveInPositiveDirection) {
newY = currY - 1;
}
}
return { x: newX, y: newY };
},
create: function() {
// Start outside grid at a randomized location.
const enterOnXAxis = Boolean(Math.round(Math.random()));
const enterFromPositive = Boolean(Math.round(Math.random()));
let x = -1;
let y = -1;
if (enterFromPositive === true) {
x = SETTINGS.GRID_WIDTH;
y = SETTINGS.GRID_HEIGHT;
}
if (enterOnXAxis === true) {
y = Math.round(Math.random() * (SETTINGS.GRID_HEIGHT - 1));
}
else {
x = Math.round(Math.random() * (SETTINGS.GRID_WIDTH - 1));
}
return { x: x, y: y }
}
};
export default TroggleAI;

@ -1,5 +1,16 @@
const Immutable = require('immutable');
const exclamations = [
'Congratulations!',
'Yippee!',
'Woohoo!',
'Nice work!',
'Great job!',
'Boom!',
'All finished!',
'Shazam!'
];
import * as MessageActions from '../../actions/board/message.actions';
const initial = { message: '', hidden: true };
@ -10,7 +21,14 @@ const reducer = (state = initial, action) => {
}
switch (action.action) {
case MessageActions.DISPLAY:
case MessageActions.EXCLAIM:
const msg = exclamations[Math.floor(Math.random() * exclamations.length)];
return Immutable.Map(state)
.set('hidden', false)
.set('message', msg)
.toObject();
case MessageActions.SHOW:
return Immutable.Map(state)
.set('hidden', false)
.set('message', action.message)

@ -1,7 +1,6 @@
const Immutable = require('immutable');
import * as TroggleActions from '../../actions/board/troggle.actions';
import { SETTINGS } from '../../App';
const initial = [];
const reducer = (state = initial, action) => {
@ -11,59 +10,21 @@ const reducer = (state = initial, action) => {
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)
.setIn([action.index, 'x'], action.x)
.setIn([action.index, 'y'], action.y)
.toJS();
case TroggleActions.CREATE:
return Immutable.List(state).push({ x: 0, y: 0 }).toArray();
break;
}
return Immutable.List(state).push({ x: action.x, y: action.y }).toArray();
case TroggleActions.FREEZE_ALL:
case TroggleActions.UNFREEZE_ALL:
case TroggleActions.CLEAR_ALL:
return Immutable.List().toArray();
};
return state;
};

@ -3,7 +3,7 @@
position:relative;
width:600px;
@for $i from 0 through 6 {
@for $i from -1 through 7 {
.x#{$i} {
left: #{$i * 100}px;
}

Loading…
Cancel
Save