From 0c2d81aa05a75b42fdc0f311cf378c5113cc9f8f Mon Sep 17 00:00:00 2001 From: Sam Fentress Date: Mon, 19 Jun 2017 16:50:18 -0400 Subject: [PATCH] Move fertilize and breed actions to drake reducer 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 (https://github.com/reactjs/redux/issues/601#issuecomment-174387073) 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. --- src/code/reducers/drakes.js | 47 ++++++++++++++++++++++++++++++++++-- src/code/reducers/index.js | 48 ++----------------------------------- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/code/reducers/drakes.js b/src/code/reducers/drakes.js index ad546fa5..3f65d473 100644 --- a/src/code/reducers/drakes.js +++ b/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) { @@ -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; } diff --git a/src/code/reducers/index.js b/src/code/reducers/index.js index 66f0223a..638c26c4 100644 --- a/src/code/reducers/index.js +++ b/src/code/reducers/index.js @@ -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'; @@ -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(); @@ -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) }); @@ -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);