From 0277e5ddc7c6461df7e734195bd2db8c0265257c Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Thu, 5 Jul 2018 17:59:11 +0200 Subject: [PATCH] Initial Commit --- CHANGELOG.md | 3 ++ README.md | 7 ++++- analysis_options.yaml | 15 +++++++++ lib/App.dart | 70 ++++++++++++++++++++++++++++++++++++++++++ lib/Cell.dart | 23 ++++++++++++++ lib/Grid.dart | 63 +++++++++++++++++++++++++++++++++++++ lib/Rule.dart | 5 +++ pubspec.yaml | 16 ++++++++++ test/dart_test.dart | 12 ++++++++ web/favicon.ico | Bin 0 -> 3559 bytes web/index.html | 22 +++++++++++++ web/main.dart | 19 ++++++++++++ web/styles.css | 14 +++++++++ 13 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.md create mode 100644 analysis_options.yaml create mode 100644 lib/App.dart create mode 100644 lib/Cell.dart create mode 100644 lib/Grid.dart create mode 100644 lib/Rule.dart create mode 100644 pubspec.yaml create mode 100644 test/dart_test.dart create mode 100644 web/favicon.ico create mode 100644 web/index.html create mode 100644 web/main.dart create mode 100644 web/styles.css diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..687440b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version, created by Stagehand diff --git a/README.md b/README.md index 396bf9b..2c1b8d2 100644 --- a/README.md +++ b/README.md @@ -1 +1,6 @@ -rules-of-living +# rules_of_living + +An absolute bare-bones web app. + +Created from templates made available by Stagehand under a BSD-style +[license](https://github.com/dart-lang/stagehand/blob/master/LICENSE). diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..97f0908 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,15 @@ +analyzer: + strong-mode: true +# exclude: +# - path/to/excluded/files/** + +# Lint rules and documentation, see http://dart-lang.github.io/linter/lints +linter: + rules: + - cancel_subscriptions + - hash_and_equals + - iterable_contains_unrelated_type + - list_remove_unrelated_type + - test_types_in_equals + - unrelated_type_equality_checks + - valid_regexps diff --git a/lib/App.dart b/lib/App.dart new file mode 100644 index 0000000..1705823 --- /dev/null +++ b/lib/App.dart @@ -0,0 +1,70 @@ +import 'dart:html' as html; + +import 'package:rules_of_living/Cell.dart'; +import 'package:rules_of_living/Grid.dart'; + +class App { + // Elapsed Time Counter - useful for Safety Timeout + Stopwatch _elapsed = new Stopwatch(); + + // Game Tick Rate - *does* impact game speed + final int _MS_PER_STEP = 1000 ~/ 1; + + // Max Frame (i.e. Rendering) rate - does *not* impact game speed + final int _MS_PER_FRAME = 1000 ~/ 1; + + // ms stuck in updateloop after which game will declare itself unresponsive + final int SAFETY_TIMEOUT = 1000; + + num _updateLag = 0.0; + num _drawLag = 0.0; + + + final html.CanvasElement canvas; + final Grid grid = new Grid(20,20); + final List> map = new Grid(20, 20).map; + + App(this.canvas); + + void process(num now) { + _drawLag = now; + _updateLag += _drawLag; + _elapsed.reset(); + + while (_updateLag >= _MS_PER_STEP) { + if (_elapsed.elapsedMilliseconds > SAFETY_TIMEOUT) { + // TODO stub - give warning etc when this occurs + break; + } + update(); + _updateLag -= _MS_PER_STEP; + } + + if (_drawLag >= _MS_PER_FRAME) { + render(_updateLag / _MS_PER_STEP); + _drawLag = 0; + } + } + + void update() { + grid.update(); + } + + + void render([num interp]) { + html.CanvasRenderingContext2D ctx = canvas.getContext('2d'); + int brickW = (canvas.width ~/ map[0].length); + int brickH = (canvas.height ~/ map.length); + 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++) { + 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); + } + } + } +} \ No newline at end of file diff --git a/lib/Cell.dart b/lib/Cell.dart new file mode 100644 index 0000000..2509733 --- /dev/null +++ b/lib/Cell.dart @@ -0,0 +1,23 @@ +import 'package:rules_of_living/Rule.dart'; + +class Cell { + bool state; + List surviveRules = new List(); + List birthRules = new List(); + + Cell([bool state = false]) : this.state = state; + + void update(int neighbors) { + bool newState = false; + if (state == true) { + surviveRules.forEach((Rule rule) { + if (rule.evaluate(neighbors) == true) newState = true; + }); + } else { + birthRules.forEach((Rule rule) { + if (rule.evaluate(neighbors) == true) newState = true; + }); + } + state = newState; + } +} diff --git a/lib/Grid.dart b/lib/Grid.dart new file mode 100644 index 0000000..cd47a83 --- /dev/null +++ b/lib/Grid.dart @@ -0,0 +1,63 @@ +import 'package:rules_of_living/Cell.dart'; +import 'package:rules_of_living/Rule.dart'; + +class Grid { + final int w; + final int h; + final List> map; + + Grid(int w, int h) + : this.w = w, + this.h = h, + this.map = new List() { + map.addAll(_buildGrid(w, h)); + + map[5][5].state = true; + } + + List> _buildGrid(int w, int h) { + List> grid = new List(h); + Rule threeTrue = new Rule((int n) { + if(n==3) return true; + else return false; + }); + Rule twoTrue = new Rule((int n) { + if(n==2) return true; + else 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.birthRules.add(twoTrue); + + grid[y][x] = new Cell(); + } + } + return grid; + } + + void update() { + 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( getNeighbors(x, y, 1) ); + } + } + } + + int getNeighbors(int x, int y, int range) { + int count = 0; + for (int iy = y - range ~/ 2; iy < iy + range / 2; iy++) { + for (int ix = x - range ~/ 2; ix < ix + range / 2; ix++) { + if (iy > 0 && iy < map.length && ix > 0 && ix < map[iy].length && + map[iy][ix].state == true) count++; + } + } + return count; + } +} diff --git a/lib/Rule.dart b/lib/Rule.dart new file mode 100644 index 0000000..3a5eb1a --- /dev/null +++ b/lib/Rule.dart @@ -0,0 +1,5 @@ +class Rule { + final Function evaluate; + + Rule(this.evaluate); +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..0bffd9e --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,16 @@ +name: rules_of_living +description: An absolute bare-bones web app. +# version: 1.0.0 +#homepage: https://www.example.com +#author: marty + +environment: + sdk: '>=2.0.0-dev.66.0 <2.0.0' + +#dependencies: +# path: ^1.4.1 + +dev_dependencies: + build_runner: ^0.9.0 + build_web_compilers: ^0.4.0 + test: ^1.2.0 diff --git a/test/dart_test.dart b/test/dart_test.dart new file mode 100644 index 0000000..c4ff6af --- /dev/null +++ b/test/dart_test.dart @@ -0,0 +1,12 @@ +import 'package:test/test.dart'; +import 'dart:html' as html; + +void main() { + test("dart_test works", () { + expect(4+4, equals(8)); + }); + + test("dart_test works with the browser", () { + expect(html.Document, equals(isNotNull)); + }); +} \ No newline at end of file diff --git a/web/favicon.ico b/web/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7ba349b3e628d2423d4a2ed217422a4722f73739 GIT binary patch literal 3559 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 + + + + + + + + rules_of_living + + + + + + + +
+ +
+ + + diff --git a/web/main.dart b/web/main.dart new file mode 100644 index 0000000..8d236aa --- /dev/null +++ b/web/main.dart @@ -0,0 +1,19 @@ +import 'dart:html' as html; + +import 'package:rules_of_living/App.dart'; + + +html.CanvasElement el; +App engine; + +void main() { + el = new html.CanvasElement(width: 500, height: 500); + html.querySelector('#output').append(el); + engine = new App(el); + html.window.animationFrame.then(animFrame); +} + +void animFrame(num now) { + engine.process(now); + html.window.animationFrame.then(animFrame); +} diff --git a/web/styles.css b/web/styles.css new file mode 100644 index 0000000..cc035c9 --- /dev/null +++ b/web/styles.css @@ -0,0 +1,14 @@ +@import url(https://fonts.googleapis.com/css?family=Roboto); + +html, body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + font-family: 'Roboto', sans-serif; +} + +#output { + padding: 20px; + text-align: center; +}