diff --git a/lib/src/Simulation.dart b/lib/src/Simulation.dart index 3b2c559..8261071 100644 --- a/lib/src/Simulation.dart +++ b/lib/src/Simulation.dart @@ -2,14 +2,13 @@ import 'dart:html' as html; import 'dart:math' as math; import 'package:rules_of_living/src/Cell.dart'; +import 'package:rules_of_living/src/Grid.dart'; import 'package:rules_of_living/src/Rule.dart'; enum CellPattern { SpaceShip, Blinker } class Simulation { - final int w; - final int h; - final List> map; + final Grid map; bool _dirty = true; bool _renderEdges = true; @@ -21,17 +20,27 @@ class Simulation { int _dispersal; CellPattern _pattern; - Simulation(int w, int h) - : this.w = w, - this.h = h, - this.map = new List() { - map.addAll(_buildGrid(w, h)); - + Simulation(int w, int h) : this.map = new Grid.fill(w, h, _getGOLCell()) { print("Grid creation finished"); } + static Cell _getGOLCell([bool defaultState = false]) { + Cell cell = Cell(defaultState); + Rule threeTrue = new Rule((int n) { + if (n == 3) return true; + return false; + }); + Rule twoTrue = new Rule((int n) { + if (n == 2) return true; + return false; + }); + cell.surviveRules..add(twoTrue)..add(threeTrue); + cell.birthRules.add(twoTrue); + return cell; + } + void reset() { - map.setAll(0, _buildGrid(w, h)); + map.setAll(0, List.filled(map.length, _getGOLCell())); if (_startingSeed != null) addPattern( pattern: _pattern, @@ -57,8 +66,8 @@ class Simulation { _amount = amount ?? rng.nextInt(20); _dispersal = dispersal ?? 10; _pattern = pattern; - int cx = x ?? rng.nextInt(w ~/ 3) + (w ~/ 3); - int cy = y ?? rng.nextInt(h ~/ 3) + (h ~/ 3); + int cx = x ?? rng.nextInt(map.width ~/ 3) + (map.width ~/ 3); + int cy = y ?? rng.nextInt(map.height ~/ 3) + (map.height ~/ 3); switch (pattern) { // Two blocks, offset // ## @@ -101,70 +110,26 @@ class Simulation { } void setCellState(int x, int y, bool state) { - if (y < map.length && x < map[y].length) map[y][x].state = state; + if (y < map.height && x < map.width) map.get(x, y).state = state; } bool getCellState(int x, int y) { - if (y < map.length && x < map[y].length) return map[y][x].state; + if (y < map.height && x < map.width) return map.get(x, y).state; return null; } - List> _buildGrid(int w, int h) { - print("grid being created"); - List> grid = new List(h); - // GENERAL RULE LAYOUT - Rule threeTrue = new Rule((int n) { - if (n == 3) return true; - return false; - }); - Rule twoTrue = new Rule((int n) { - if (n == 2) return true; - return false; - }); - - // DEBUG RULE TESTING FOR PATTERNS - Rule coagSurvive = new Rule((int n) { - if (n == 1) return true; - return false; - }); - Rule coagBirth = new Rule((int n) { - if (n == 1) return true; - return false; - }); - - for (int y = 0; y < h; y++) { - grid[y] = new List(w); - for (int x = 0; x < w; x++) { - // GIVES RULES FOR CONWAY GAME OF LIFE BY DEFAULT S23/B3 - Cell cell = new Cell(); -// cell.surviveRules.add(twoTrue); - cell.surviveRules.add(threeTrue); - cell.surviveRules.add(twoTrue); - cell.birthRules.add(threeTrue); - - grid[y][x] = cell; - } - } - return grid; - } - bool update() { bool stateChanges = false; - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - // DEFAULTS TO CONWAY GAME OF LIFE RANGE OF ONE - map[y][x].update(getSurroundingNeighbors(x, y, 1)); - } - } - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - Cell c = map[y][x]; - if (c.state != c.nextState) stateChanges = true; - c.advanceState(); - if (!_dirty && map[y][x].dirty) _dirty = true; - } + for (int i = 0; i < map.length; i++) { + math.Point p = map.toCoordinates(i); + map[i].update(getSurroundingNeighbors(p.x, p.y, 1)); } + // TODO when implementing changeSet we can remove this second loop and add to changeSet in the first + map.forEach((Cell el) { + if (el.state != el.nextState) stateChanges = true; + el.advanceState(); + }); return stateChanges; } @@ -174,9 +139,9 @@ class Simulation { for (int ix = x - range; ix <= x + range; ix++) { if (ix > 0 && iy > 0 && - iy < map.length && - ix < map[iy].length && - map[iy][ix].state == true && + iy < map.height && + ix < map.width && + map.get(x, y).state == true && !(x == ix && y == iy)) { count++; } @@ -190,24 +155,22 @@ class Simulation { if (!_dirty) return; html.CanvasRenderingContext2D ctx = canvas.getContext('2d'); - int brickW = (canvas.width ~/ map[0].length); - int brickH = (canvas.height ~/ map.length); + int brickW = (canvas.width ~/ map.width); + int brickH = (canvas.height ~/ map.height); ctx.clearRect(0, 0, canvas.width, canvas.height); - for (int y = 0; y < map.length; y++) { - for (int x = 0; x < map[y].length; x++) { - if (_renderEdges) { - ctx.setStrokeColorRgb(100, 100, 100); - ctx.strokeRect(x * brickW, y * brickH, brickW, brickH); - } - - Cell c = map[y][x]; - if (c.state == true) - ctx.setFillColorRgb(155, 155, 255); - else - ctx.setFillColorRgb(0, 0, 0); - ctx.fillRect(x * brickW, y * brickH, brickW, brickH); + for (int i; i < map.length; i++) { + math.Point p = map.toCoordinates(i); + if (_renderEdges) { + ctx.setStrokeColorRgb(100, 100, 100); + ctx.strokeRect(p.x * brickW, p.y * brickH, brickW, brickH); } + + if (map[i].state == true) + ctx.setFillColorRgb(155, 155, 255); + else + ctx.setFillColorRgb(0, 0, 0); + ctx.fillRect(p.x * brickW, p.y * brickH, brickW, brickH); } _dirty = false;