Skip to content

Commit

Permalink
Move fertilize and breed actions to drake reducer
Browse files Browse the repository at this point in the history
Part of work to clean up the root reducer to make further refactoring
easier.

Both these actions only affect the `drakes` property, so can be handled
entirely by the drakes reducer.

The one issue is that `fertilize` needs additional information from
elsewhere in the state tree, namely the gametes. While we could maybe
completely restructure the state, or add an all-purpose way for all
reducers to get the entire state (reduxjs/redux#601 (comment))
it seemed more natural simply to let the drakes reducer know about the
gametes. This pattern can be applied elsewhere when a reducer is only
updating one property, but needs knowledge about other state props.
  • Loading branch information
sfentress committed Jun 20, 2017
1 parent c7b594e commit 0c2d81a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 48 deletions.
47 changes: 45 additions & 2 deletions src/code/reducers/drakes.js
@@ -1,12 +1,51 @@
import Immutable from 'seamless-immutable';
import actionTypes from '../action-types';
import GeneticsUtils from '../utilities/genetics-utils';
import { GAMETES_RESET } from '../modules/gametes';
import { GAMETES_RESET, motherCurrentGamete, fatherCurrentGamete } from '../modules/gametes';
import { assign } from 'lodash';

const initialState = Immutable([]);

export default function drakes(state = initialState, action) {

function fertilize(state, gametes) {
let chromosomes0 = new BioLogica.Organism(BioLogica.Species.Drake, state[0].alleleString, state[0].sex).getGenotype().chromosomes,
chromosomes1 = new BioLogica.Organism(BioLogica.Species.Drake, state[1].alleleString, state[1].sex).getGenotype().chromosomes,
alleleString = "",
sex = 1,
side, chromosome, name;
for (name in chromosomes0) {
side = motherCurrentGamete(gametes)[name];
chromosome = chromosomes0[name][side];
if (chromosome && chromosome.alleles) alleleString += "a:" + chromosome.alleles.join(",a:") + ",";
}
for (name in chromosomes1) {
side = fatherCurrentGamete(gametes)[name];
if (side === "y") sex = 0;
chromosome = chromosomes1[name][side];
if (chromosome && chromosome.alleles && chromosome.alleles.length) alleleString += "b:" + chromosome.alleles.join(",b:") + ",";
}

return state.setIn([2], {
alleleString,
sex
});
}

function breedClutch(state, clutchSize) {
let mother = new BioLogica.Organism(BioLogica.Species.Drake, state[0].alleleString, state[0].sex),
father = new BioLogica.Organism(BioLogica.Species.Drake, state[1].alleleString, state[1].sex);

for (let i = 0; i < clutchSize; i++) {
let clutchDrake = BioLogica.breed(mother, father, true);
state = state.concat({
alleleString: clutchDrake.getAlleleString(),
sex: clutchDrake.sex
});
}
return state;
}

export default function drakes(state = initialState, gametes = {}, action) {
switch (action.type) {
case actionTypes.ALLELE_CHANGED:
return state.update(action.index, function(drakeDef) {
Expand Down Expand Up @@ -71,6 +110,10 @@ export default function drakes(state = initialState, action) {
return state.setIn([action.eggDrakeIndex, "basket"], action.basketIndex);
case actionTypes.EGG_REJECTED:
return state.setIn([action.eggDrakeIndex, "basket"], -1);
case actionTypes.FERTILIZED:
return fertilize(state, gametes);
case actionTypes.CLUTCH_BRED:
return breedClutch(state, action.clutchSize);
default:
return state;
}
Expand Down
48 changes: 2 additions & 46 deletions src/code/reducers/index.js
Expand Up @@ -9,7 +9,7 @@ import routing from './routing';
import moves from './moves';
import modalDialog from './modal-dialog';
import userDrakeHidden from './user-drake-hidden';
import gametes, { motherCurrentGamete, fatherCurrentGamete } from '../modules/gametes';
import gametes from '../modules/gametes';
import drakes from './drakes';
import baskets from './baskets';
import notifications from '../modules/notifications';
Expand All @@ -31,45 +31,6 @@ function initialState() {
});
}

function fertilize(state) {
let chromosomes0 = new BioLogica.Organism(BioLogica.Species.Drake, state.drakes[0].alleleString, state.drakes[0].sex).getGenotype().chromosomes,
chromosomes1 = new BioLogica.Organism(BioLogica.Species.Drake, state.drakes[1].alleleString, state.drakes[1].sex).getGenotype().chromosomes,
alleleString = "",
sex = 1,
side, chromosome, name;
for (name in chromosomes0) {
side = motherCurrentGamete(state.gametes)[name];
chromosome = chromosomes0[name][side];
if (chromosome && chromosome.alleles) alleleString += "a:" + chromosome.alleles.join(",a:") + ",";
}
for (name in chromosomes1) {
side = fatherCurrentGamete(state.gametes)[name];
if (side === "y") sex = 0;
chromosome = chromosomes1[name][side];
if (chromosome && chromosome.alleles && chromosome.alleles.length) alleleString += "b:" + chromosome.alleles.join(",b:") + ",";
}

return state.setIn(["drakes", 2], {
alleleString,
sex
});
}

function breedClutch(state, clutchSize) {
let mother = new BioLogica.Organism(BioLogica.Species.Drake, state.drakes[0].alleleString, state.drakes[0].sex),
father = new BioLogica.Organism(BioLogica.Species.Drake, state.drakes[1].alleleString, state.drakes[1].sex),
newState = state;

for (let i = 0; i < clutchSize; i++) {
let clutchDrake = BioLogica.breed(mother, father, true);
newState = newState.setIn(["drakes", newState.drakes.length], {
alleleString: clutchDrake.getAlleleString(),
sex: clutchDrake.sex
});
}
return newState;
}

export default function reducer(state, action) {
if (!state) state = initialState();

Expand All @@ -79,7 +40,7 @@ export default function reducer(state, action) {
modalDialog: modalDialog(state.modalDialog, action),
userDrakeHidden: userDrakeHidden(state.userDrakeHidden, action),
gametes: gametes(state.gametes, action),
drakes: drakes(state.drakes, action),
drakes: drakes(state.drakes, state.gametes, action),
baskets: baskets(state.baskets, action),
notifications: notifications(state.notifications, action)
});
Expand All @@ -94,11 +55,6 @@ export default function reducer(state, action) {
challengeProgress: progress
});
}
case actionTypes.FERTILIZED:
return fertilize(state);

case actionTypes.CLUTCH_BRED:
return breedClutch(state, action.clutchSize);

case actionTypes.OFFSPRING_KEPT: {
let progress = updateProgress(state, action.success);
Expand Down

0 comments on commit 0c2d81a

Please sign in to comment.