From efe0aeed5f1854628df8bace645a072d569fe7b9 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Sat, 10 Dec 2016 15:39:39 +0100 Subject: Introduce `BoxIndicator` and `BoxTraverser` helper classes `BoxIndicator` implements an indicator function for the world area. Together with `BoxTraverser` it is used to simplifiy action validation and area traversion. --- src/world.h | 68 ++++++++++++++++++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 37 deletions(-) (limited to 'src/world.h') diff --git a/src/world.h b/src/world.h index 72cc32f..b60c658 100644 --- a/src/world.h +++ b/src/world.h @@ -6,6 +6,8 @@ #include #include +#include "box_traverser.h" + namespace life { template< @@ -14,19 +16,18 @@ template< > class World { public: - World() { - for ( std::size_t j = 0; j < HEIGHT; j++ ) { - for ( std::size_t i = 0; i < WIDTH; i++ ) { - this->matrix_[j][i] = false; - } - } + static const std::size_t width = WIDTH; + static const std::size_t height = HEIGHT; + + World(): + area_(width, height) { + this->area_.for_each([&](std::size_t i, std::size_t j) { + this->matrix_[j][i] = false; + }); } bool isLifeAt(std::ptrdiff_t x, std::ptrdiff_t y) const { - if ( x >= 0 && - x < WIDTH && - y >= 0 && - y < HEIGHT ) { + if ( this->area_(x, y) ) { return this->matrix_[y][x]; } else { return false; // end of world is dead @@ -69,19 +70,13 @@ class World { } void summonLifeAt(std::size_t x, std::size_t y) { - if ( x >= 0 && - x < WIDTH && - y >= 0 && - y < HEIGHT ) { + if ( this->area_(x, y) ) { this->matrix_[y][x] = true; } } void extinguishLifeAt(std::size_t x, std::size_t y) { - if ( x >= 0 && - x < WIDTH && - y >= 0 && - y < HEIGHT ) { + if ( this->area_(x, y) ) { this->matrix_[y][x] = false; } } @@ -91,25 +86,23 @@ class World { std::stack> updates; - for ( std::size_t j = 0; j < HEIGHT; j++ ) { - for ( std::size_t i = 0; i < WIDTH; i++ ) { - const std::uint8_t d = this->lifeDensityAt(i, j); - - if ( this->matrix_[j][i] ) { - if ( d < 2 ) { - updates.push(std::make_tuple(i, j, false)); - } else if ( d == 2 || d == 3 ) { - updates.push(std::make_tuple(i, j, true)); - } else if ( d > 3 ) { - updates.push(std::make_tuple(i, j, false)); - } - } else { - if ( d == 3 ) { - updates.push(std::make_tuple(i, j, true)); - } + this->area_.for_each([&](std::size_t i, std::size_t j) { + const std::uint8_t d = this->lifeDensityAt(i, j); + + if ( this->matrix_[j][i] ) { + if ( d < 2 ) { + updates.push(std::make_tuple(i, j, false)); + } else if ( d == 2 || d == 3 ) { + updates.push(std::make_tuple(i, j, true)); + } else if ( d > 3 ) { + updates.push(std::make_tuple(i, j, false)); + } + } else { + if ( d == 3 ) { + updates.push(std::make_tuple(i, j, true)); } } - } + }); while ( !updates.empty() ) { const auto& update = updates.top(); @@ -125,14 +118,15 @@ class World { std::get<1>(update) ); } - + updates.pop(); } } private: - std::size_t age_ = 0; + const util::BoxTraverser area_; + std::size_t age_ = 0; std::array, HEIGHT> matrix_; }; -- cgit v1.2.3