let sim; var mutationrate = 0.001; var cell_diffusion = 0; function cacatoo() { let config = { title: "Jackpot mutations", description: "", maxtime: 10000000, ncol: 250, nrow: 250, // dimensions of the grid to build wrap: [false, false], // Wrap boundary [COLS, ROWS] scale: 1, // scale of the grid (nxn pixels per grid cell) graph_interval: 10, graph_update: 10, seed: 14, bgcolour: 'white', statecolours: { alive: 'default' }, // The background state '0' is never drawn num_colours: 4 } sim = new Simulation(config) sim.makeGridmodel("cells") delete sim.cells.statecolours.alive[0] // Remove colour so it doesn't show in legend sim.cells.statecolours.alive[1] = [79, 31, 154] // Change WT 1 to white sim.cells.statecolours.alive[2] = [228, 178, 36] // Change mutant 1 to gold sim.cells.statecolours.alive[3] = [32, 100, 100] // Change mutant 2 to dark-turquoise sim.cells.statecolours.alive[3] = [100, 100, 255] // Change mutant 3 to light blue sim.createDisplay("cells", "alive", "Colony growth (colours = #mutations)") sim.createDisplay_continuous({model:"cells",label:"Number of generations",property:"generation",fill:"viridis", minval:0,maxval:200,nticks:3}) sim.makeGridmodel("cells_wellmixed"); sim.cells_wellmixed.statecolours = sim.cells.statecolours sim.createDisplay("cells_wellmixed", "alive", "Well-mixed population (colours = #mutations)") sim.createDisplay_continuous({model:"cells_wellmixed",label:"Number of generations",property:"generation",fill:"viridis", minval:0,maxval:200,nticks:3}) sim.cells.birth_rate=0.85 sim.cells_wellmixed.birth_rate=0.05 sim.cells.nextState = function (i, j) // Define the next-state function. This example is stochastic growth in a petri dish { if (this.grid[i][j].alive == undefined) { let neighbour = this.randomMoore8(this, i, j) // In the Moore8 neighbourhood of this grid count # of 1's for the 'alive' property if (neighbour.alive > 0 && sim.rng.genrand_real1() < this.birth_rate) { this.grid[i][j].alive = neighbour.alive this.grid[i][j].generation = neighbour.generation ? neighbour.generation + 1 : 1 if (sim.rng.genrand_real1() < mutationrate) this.grid[i][j].alive = (this.grid[i][j].alive + 1) % 19 } } else{ if(!this.grid[i][j].generation) this.grid[i][j].generation = 1 } } sim.cells_wellmixed.nextState = sim.cells.nextState sim.cells.update = function () { this.synchronous() // Applied as many times as it can in 1/60th of a second this.plotPopsizes('alive', [1, 2, 3, 4],{width:""}) } sim.cells.canvases["Colony growth (colours = #mutations)"].elem.className = "canvas-cacatoo-round" sim.cells_wellmixed.update = function () { this.synchronous() // Applied as many times as it can in 1/60th of a second this.plotPopsizes('alive', [1, 2, 3, 4],{width:""}) sim.cells_wellmixed.perfectMix() } sim.cells_wellmixed.canvases["Well-mixed population (colours = #mutations)"].elem.className = "canvas-cacatoo-round" sim.cells.reset = function () { sim.initialSpot(sim.cells, 'alive', 1, 2, sim.cells.nr / 2, sim.cells.nc / 2) sim.initialSpot(sim.cells_wellmixed, 'alive', 1, 2, sim.cells_wellmixed.nr / 2, sim.cells_wellmixed.nc / 2) sim.initialGrid(sim.cells, 'age', 0, 1.0) sim.initialGrid(sim.cells, 'generation', 0, 1.0) sim.initialGrid(sim.cells_wellmixed, 'generation', 0, 1.0) sim.initialGrid(sim.cells_wellmixed, 'age', 0, 1.0) sim.time = 0 } sim.cells.reset() sim.addButton("pause/continue", function () { sim.toggle_play() }) // Add a button that calls function "display" in "model" sim.addButton("mix once", function () { sim.cells.perfectMix() }) // Add a button that calls function "perfectMix" in "model.cheater" sim.addButton("reset", function () { sim.cells.reset() }) // Add a button that calls function "perfectMix" in "model.cheater" sim.start() }