diff options
author | Brian Cully <bjc@kublai.com> | 2021-02-19 15:27:22 -0500 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2021-02-19 15:27:22 -0500 |
commit | a5e378e2b4c075f09d3293ccc301f0e504cb20d7 (patch) | |
tree | 5cadc502f422e180ac82030fd98e01692e4268d0 | |
parent | ed2b76634a6fb1a9fb45abdd7afc7342f5b6f12c (diff) | |
download | molsim2-a5e378e2b4c075f09d3293ccc301f0e504cb20d7.tar.gz molsim2-a5e378e2b4c075f09d3293ccc301f0e504cb20d7.zip |
Alter rule flow
It’s simpler to put kill/clone buttons on the final step, so kill the
initial clone step.
This is probably more sensible overall. The old, clone first method
was done to simplify the state machine at the time, at the cost of
expected instruction order.
-rw-r--r-- | index.html | 35 | ||||
-rw-r--r-- | lethality-selector.mjs | 35 | ||||
-rw-r--r-- | main.mjs | 4 | ||||
-rw-r--r-- | rules.mjs | 122 |
4 files changed, 54 insertions, 142 deletions
@@ -29,26 +29,22 @@ <span id='remaining-iterations'>--</span> more times: <ol> - <li id='clone-nucleotide' class='step'> - <button id='clone' disabled=''>Clone</button> the genome to - start mutating it. - </li> - <li id='roll-for-nucleotide' class='step'> Roll to find the nucleotide to mutate. + </li> + + <li id='nucleotide-select' class='step'> + Depending on the roll: + <ul> <li>If the roll is between 1 through 18, inclusive, select that nucleotide.</li> - <li>Otherwise, skip mutation and clone the genome - again.</li> + <li>Otherwise, skip mutation and + <button class='clone' disabled=''>clone</button> the + genome again.</li> </ul> </li> - <li id='nucleotide-select' class='step'> - Select the <span id='select-number'>rolled</span> - nucleotide in the sequence. - </li> - <li id='roll-for-mutation' class='step'> Roll to see what kind of mutation to perform. </li> @@ -76,12 +72,12 @@ <li id='mark-as-lethal'> Depending on the change to the codon: <ul> - <li>If the mutation caused a change in the amino acid being - coded, mark this mutation as <em>lethal</em>, and start - over with the genome from the previous iteration.</li> + <li>If the mutation caused a change in the amino acid + being coded, then <button id='kill' disabled=''>kill</button> it and + start again with the previous generation.</li> - <li>Otherwise, mark the mutation as <em>non-lethal</em>, - and continue with this new genome.</li> + <li>Otherwise, <button id='clone' disabled=''>clone</button> this + genome for the next generation.</li> </ul> </li> </ol> @@ -130,11 +126,6 @@ </ul> </div> - <div id='lethality-selector' class='hidden'> - <button id='lethal'>Lethal</button> - <button id='non-lethal'>Non-lethal</button> - </div> - <script src='main.mjs' type='module'></script> </body> </html> diff --git a/lethality-selector.mjs b/lethality-selector.mjs deleted file mode 100644 index 80c3e71..0000000 --- a/lethality-selector.mjs +++ /dev/null @@ -1,35 +0,0 @@ -class LethalitySelector { - constructor(elt) { - this.elt = elt - - for (const elt of this.elt.querySelectorAll('button')) { - elt.addEventListener('click', this.select.bind(this)) - } - } - - attach() { - this.elt.classList.remove('hidden') - } - - detach() { - this.elt.classList.add('hidden') - } - - get onItemSelected() { - if (this._onItemSelected !== undefined) { - return this._onItemSelected - } - return () => {} - } - - set onItemSelected(fn) { - this._onItemSelected = fn - } - - select(evt) { - window.evt = evt - this.onItemSelected(evt.target.id == 'lethal') - } -} - -export default LethalitySelector @@ -5,14 +5,12 @@ function init() { const die = document.querySelector('#die') const aminoAcidSelector = document.querySelector('#amino-acid-selector') const nucleotideSelector = document.querySelector('#nucleotide-selector') - const lethalitySelector = document.querySelector('#lethality-selector') const instructions = document.querySelector('#instructions') - const cloneButton = document.querySelector('#clone') const remainingIterations = document.querySelector('#remaining-iterations') const printButton = document.querySelector('#print') const errors = document.querySelector('#errors') - const rules = new Rules(die, instructions, genomeList, aminoAcidSelector, nucleotideSelector, lethalitySelector, cloneButton, remainingIterations, printButton, errors) + const rules = new Rules(die, instructions, genomeList, aminoAcidSelector, nucleotideSelector, remainingIterations, printButton, errors) } init() @@ -5,37 +5,9 @@ import Die from './die.mjs' import Error from './error.mjs' import Genome from './genome.mjs' import GenomeList from './genome-list.mjs' -import LethalitySelector from './lethality-selector.mjs' import Nucleotide from './nucleotide.mjs' import NucleotideSelector from './nucleotide-selector.mjs' -class CloneNucleotide { - constructor(rules) { - this.rules = rules - - this.id = 'clone-nucleotide' - this._boundClickHandler = this.clickHandler.bind(this) - } - - enter() { - this.rules.cloneButton.addEventListener('click', - this._boundClickHandler) - this.rules.cloneButton.disabled = false - } - - exit() { - this.rules.cloneButton.removeEventListener('click', - this._boundClickHandler) - this.rules.cloneButton.disabled = true - } - - clickHandler(evt) { - const genome = this.rules.currentGenome.clone() - this.rules.genomeList.push(genome) - this.rules.next(new RollForNucleotide(this.rules)) - } -} - class RollForNucleotide { constructor(rules) { this.rules = rules @@ -55,16 +27,7 @@ class RollForNucleotide { } handleDieRoll() { - if (this.rules.die.value > Rules.initialGenomeBases.length) { - this.rules.iterations-- - if (this.rules.isLastIteration) { - this.rules.next(new DoNothing(this.rules)) - } else { - this.rules.next(new CloneNucleotide(this.rules)) - } - } else { - this.rules.next(new NucleotideSelect(this.rules)) - } + this.rules.next(new NucleotideSelect(this.rules)) } } @@ -73,26 +36,56 @@ class NucleotideSelect { this.rules = rules this.id = 'nucleotide-select' + this._boundCloneHandler = this.handleClone.bind(this) } enter() { - this.want = this.rules.die.value - this.rules.instructions.querySelector('#select-number').innerHTML = - `${this.want}<sup>${ordinalSuffix(this.want)}</sup>` + this.cloneButtons = document.querySelectorAll(`#${this.id} .clone`) + this.cloneButtons.forEach(button => { + button.addEventListener('click', this._boundCloneHandler) + button.disabled = false + }) + this.want = this.rules.die.value this.rules.currentGenome.onNucleotideSelectionChanged = this.handleSelectionChanged.bind(this) + this.rules.currentGenome.unlock() } exit() { this.rules.currentGenome.lock() + + this.cloneButtons.forEach(button => { + button.removeEventListener('click', this._boundCloneHandler) + button.disabled = true + }) + this.rules.currentGenome.onNucleotideSelectionChanged = undefined; } + handleClone(evt) { + window.r = this.rules + console.debug('clone', this.rules.die.value, this.rules.currentGenome.length) + if (this.rules.die.value < this.rules.currentGenome.length) { + this.rules.error.innerHTML = + `TODO: this should have been a selection operation` + this.rules.next(new ShowError(this.rules, this)) + return + } + + this.rules.genomeList.push(this.rules.currentGenome.clone()) + this.rules.next(new RollForNucleotide(this.rules)) + } + handleSelectionChanged(nucleotide, i) { i++; - if (i != this.rules.die.value) { + if (this.rules.die.value > this.rules.currentGenome.length) { + this.rules.error.innerHTML = + `TODO: this should have been a clone operation` + this.rules.next(new ShowError(this.rules, this)) + return + } else if (i != this.rules.die.value) { this.rules.error.innerHTML = `You selected the ${i}<sup>${ordinalSuffix(i)}</sup> nucleotide. Please select the ${this.want}<sup>${ordinalSuffix(this.want)}</sup> one.` this.rules.next(new ShowError(this.rules, this)) @@ -245,12 +238,9 @@ class MarkAsLethal { } enter() { - this.rules.lethalitySelector.onItemSelected = this.handleItemSelected.bind(this) - this.rules.lethalitySelector.attach() } exit() { - this.rules.lethalitySelector.detach() } get lethalHTML() { @@ -260,25 +250,6 @@ class MarkAsLethal { get nonLethalHTML() { return 'A change in amino acid is a <em>lethal</em> change.' } - - handleItemSelected(isLethal) { - if (isLethal !== this.isLethal) { - if (this.isLethal) { - this.rules.error.innerHTML = this.lethalHTML - } else { - this.rules.error.innerHTML = this.nonLethalHTML - } - this.rules.next(new ShowError(this.rules, this)) - return - } - - this.rules.iterations-- - if (this.rules.isLastIteration) { - this.rules.next(new DoNothing(this.rules)) - } else { - this.rules.next(new CloneNucleotide(this.rules)) - } - } } class DoNothing { @@ -328,21 +299,19 @@ class ShowError { } class Rules { - constructor(die, instructions, genomeList, aminoAcidSelector, nucleotideSelector, lethalitySelector, cloneButton, remainingIterations, printButton, errors) { + constructor(die, instructions, genomeList, aminoAcidSelector, nucleotideSelector, remainingIterations, printButton, errors) { this.die = new Die(die) this.instructions = instructions this.genomeList = new GenomeList(genomeList) this.aminoAcidSelector = new AminoAcidSelector(aminoAcidSelector) this.nucleotideSelector = new NucleotideSelector(nucleotideSelector) - this.lethalitySelector = new LethalitySelector(lethalitySelector) - this.cloneButton = cloneButton this.remainingIterations = remainingIterations this.printButton = printButton this.error = new Error(errors) this.iterations = Rules.maxIterations - this.cloneButton.disabled = true this.genomeList.push(new Genome(Rules.initialGenomeBases)) + this.genomeList.push(this.currentGenome.clone()) if (false) { this._debugStartAtRollForMutation() @@ -350,12 +319,12 @@ class Rules { this._debugStartAtPerformMutation(3) } else if (false) { this._debugStartAtSelectAminoAcid() - } else if (true) { + } else if (false) { this._debugStartAtSelectLethality() } else if (false) { this._debugStartWithError() } else { - this.currentState = new CloneNucleotide(this) + this.currentState = new RollForNucleotide(this) } this.enterState() } @@ -373,19 +342,12 @@ class Rules { } _debugStartAtRollForMutation() { - this.genomeList.push(this.currentGenome.clone()) - this.currentState = new RollForMutation(this) const nucleotide = this.currentGenome.nucleotides[2] this.currentGenome.selectedNucleotide = nucleotide } _debugStartAtPerformMutation(n) { - // The semicolon below is necessary to prevent the array - // expansion below it from being understood as an index - // operation. - this.genomeList.push(this.currentGenome.clone()); - [...Array(n)].forEach(i => { const n = randomItem(this.currentGenome.nucleotides) n.value = randomItem(Nucleotide.bases) @@ -401,8 +363,6 @@ class Rules { } _debugStartAtSelectAminoAcid() { - this.genomeList.push(this.currentGenome.clone()) - this.currentState = new SelectAminoAcid(this) this.die.value = 15 const nucleotide = this.currentGenome.nucleotides[15] @@ -411,8 +371,6 @@ class Rules { } _debugStartAtSelectLethality() { - this.genomeList.push(this.currentGenome.clone()) - this.currentState = new MarkAsLethal(this, true) this.die.value = 15 const nucleotide = this.currentGenome.nucleotides[15] @@ -422,7 +380,7 @@ class Rules { } _debugStartWithError() { - this.currentState = new ShowError(this, new CloneNucleotide(this)) + this.currentState = new ShowError(this, new RollForNucleotide(this)) this.error.innerHTML = 'test an error' } |