From cfc41eb3ccc99b92220115b0710fb821525e1075 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 28 Oct 2023 16:38:07 -0400 Subject: generating a lot of puzzles --- app/controllers/wittle/puzzles_controller.rb | 1 + app/views/wittle/puzzles/index.html.haml | 3 +- ext/wittle_generator/Generate.cpp | 8 +- ext/wittle_generator/Generate.h | 4 +- ext/wittle_generator/Panel.cpp | 17 +- ext/wittle_generator/Panel.h | 2 + ext/wittle_generator/wittle_generator.cpp | 693 ++++++++++++++++++++++++++- lib/wittle/engine.rb | 1 + 8 files changed, 699 insertions(+), 30 deletions(-) diff --git a/app/controllers/wittle/puzzles_controller.rb b/app/controllers/wittle/puzzles_controller.rb index e23b435..09a2524 100644 --- a/app/controllers/wittle/puzzles_controller.rb +++ b/app/controllers/wittle/puzzles_controller.rb @@ -1,6 +1,7 @@ module Wittle class PuzzlesController < ApplicationController def index + @puzzle = WittleGenerator.new.generate_medium end end end diff --git a/app/views/wittle/puzzles/index.html.haml b/app/views/wittle/puzzles/index.html.haml index dfeac3c..9e12e8b 100644 --- a/app/views/wittle/puzzles/index.html.haml +++ b/app/views/wittle/puzzles/index.html.haml @@ -6,7 +6,8 @@ %svg#puzzle{ style: "pointer-events: auto"} :javascript window.onload = function() { - var puzzle = window.deserializePuzzle("_AAAAAA8PCQAAAEdlbmVyYXRlZAABAAAACAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAgAAQAAAAACAAAA/wABAAAAAAgAAQAAAAAIAAEAAAAACAABAAAAAAgAAQAAAAAIAAEAAQAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQABAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAAIAAEAAAAACAABAAAAAAgAAQAAAAAIAAEAAAAAAv////8AAQAAAAAIAAEAAAAAAv////8AAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAQEAAAAAAQAAAAABAAAAAAEAAQAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAIAAAD/AAEAAAAACAABAAAAAAgAAQAAAAAIAAEAAAAACAABAAAAAAgAAQAAAAAIAAEAAAAAAQAAAAEBAAAAAAEAAAAAAQAAAAABAAAAAQEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAAIAAEAAQAAAv////8AAQAAAAAIAAEAAAAAAv////8AAQAAAAACAAAA/wABAAAAAAIAAAD/AAEAAAAAAgAAAP8AAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAL/////AAEAAAAAAv////8AAQAAAAAIAAEAAAAACAABAAAAAAgAAQAAAAACAAAA/wABAAAAAAgAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAQAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAABAQAAAAABAAEAAAEAAAAAAQAAAAABAAAAAAL/////AAEAAAAAAgAAAP8AAQAAAAAIAAEAAAAAAv////8AAQAAAAACAAAA/wABAAAAAAIAAAD/AAEAAAAACAABAAEAAAEAAAAAAQABAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAgAAAP8AAQAAAAAIAAEAAAAAAv////8AAQAAAAAIAAEAAAAAAv////8AAQAAAAAIAAEAAAAACAABAAAAAAEAAAAIAQAAAAABAAAAAAEAAAAAAQABAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAQAAAQAAAAABAAAAEAAAAAAN") + //var puzzle = window.deserializePuzzle("_AAAAAA8PCQAAAEdlbmVyYXRlZAABAAAACAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAgAAQAAAAACAAAA/wABAAAAAAgAAQAAAAAIAAEAAAAACAABAAAAAAgAAQAAAAAIAAEAAQAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQABAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAAIAAEAAAAACAABAAAAAAgAAQAAAAAIAAEAAAAAAv////8AAQAAAAAIAAEAAAAAAv////8AAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAQEAAAAAAQAAAAABAAAAAAEAAQAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAIAAAD/AAEAAAAACAABAAAAAAgAAQAAAAAIAAEAAAAACAABAAAAAAgAAQAAAAAIAAEAAAAAAQAAAAEBAAAAAAEAAAAAAQAAAAABAAAAAQEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAAIAAEAAQAAAv////8AAQAAAAAIAAEAAAAAAv////8AAQAAAAACAAAA/wABAAAAAAIAAAD/AAEAAAAAAgAAAP8AAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAL/////AAEAAAAAAv////8AAQAAAAAIAAEAAAAACAABAAAAAAgAAQAAAAACAAAA/wABAAAAAAgAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAQAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAABAQAAAAABAAEAAAEAAAAAAQAAAAABAAAAAAL/////AAEAAAAAAgAAAP8AAQAAAAAIAAEAAAAAAv////8AAQAAAAACAAAA/wABAAAAAAIAAAD/AAEAAAAACAABAAEAAAEAAAAAAQABAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAgAAAP8AAQAAAAAIAAEAAAAAAv////8AAQAAAAAIAAEAAAAAAv////8AAQAAAAAIAAEAAAAACAABAAAAAAEAAAAIAQAAAAABAAAAAAEAAAAAAQABAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAAAAAQAAAAABAAAAAAEAAQAAAQAAAAABAAAAEAAAAAAN") + var puzzle = window.deserializePuzzle("#{@puzzle}") draw(puzzle) } diff --git a/ext/wittle_generator/Generate.cpp b/ext/wittle_generator/Generate.cpp index 5e38ba8..2a92269 100644 --- a/ext/wittle_generator/Generate.cpp +++ b/ext/wittle_generator/Generate.cpp @@ -491,8 +491,8 @@ void Generate::generate(int width, int height, PuzzleSymbols symbols) { // point the generator fails to add a symbol while still making the solution // correct, the function returns false and must be called again. bool Generate::generateInternal(int width, int height, PuzzleSymbols symbols) { - _width = width; - _height = height; + _width = width * 2 + 1; + _height = height * 2 + 1; initPanel(); @@ -966,7 +966,7 @@ std::vector Generate::get_symbols_in_region( // Place a start point in a random location bool Generate::place_start(int amount) { _starts.clear(); - //_panel->_startpoints.clear(); + _panel->ClearStartpoints(); while (amount > 0) { Point pos = Point(Random::rand() % (_panel->width() / 2 + 1) * 2, Random::rand() % (_panel->height() / 2 + 1) * 2); @@ -1014,7 +1014,7 @@ bool Generate::place_start(int amount) { // Place an exit point in a random location on the edge of the grid bool Generate::place_exit(int amount) { _exits.clear(); - //_panel->_endpoints.clear(); + _panel->ClearExits(); while (amount > 0) { Point pos = Point(Random::rand() % (_panel->width() / 2 + 1) * 2, Random::rand() % (_panel->height() / 2 + 1) * 2); diff --git a/ext/wittle_generator/Generate.h b/ext/wittle_generator/Generate.h index cbb870d..9969998 100644 --- a/ext/wittle_generator/Generate.h +++ b/ext/wittle_generator/Generate.h @@ -114,6 +114,8 @@ class Generate { std::set customPath; Color arrowColor, backgroundColor, successColor; // For the arrow puzzles + bool place_gaps(int amount); + private: int get_symbol_type(int flags) { return flags & 0x700; } void set_path(Point pos); @@ -174,7 +176,7 @@ class Generate { bool place_start(int amount); bool place_exit(int amount); bool can_place_gap(Point pos); - bool place_gaps(int amount); + bool can_place_dot(Point pos, bool intersectionOnly); bool place_dots(int amount, int color, bool intersectionOnly); bool can_place_stone(const std::set& region, int color); diff --git a/ext/wittle_generator/Panel.cpp b/ext/wittle_generator/Panel.cpp index 4bf4be7..892d4cc 100644 --- a/ext/wittle_generator/Panel.cpp +++ b/ext/wittle_generator/Panel.cpp @@ -157,16 +157,11 @@ std::string Panel::Write() { serializer.writeByte(Serializer::Nega); serializer.writeColor(val & 0xF); } else if (symbol == Decoration::Poly) { - serializer.writeByte(Serializer::Poly); - serializer.writeColor(val & 0xF); - - long polyshape = (val & 0xFFFF0000) >> 16; - if (val & Decoration::Can_Rotate) { - polyshape |= (1 << 20); + if (val & Decoration::Negative) { + serializer.writeByte(Serializer::Ylop); + } else { + serializer.writeByte(Serializer::Poly); } - serializer.writeLong(polyshape); - } else if (symbol == Decoration::Negative) { - serializer.writeByte(Serializer::Ylop); serializer.writeColor(val & 0xF); long polyshape = (val & 0xFFFF0000) >> 16; @@ -194,7 +189,9 @@ std::string Panel::Write() { } else { serializer.writeByte(Serializer::DotNone); } - if (val & Decoration::Gap) { + if (val == OPEN) { + serializer.writeByte(Serializer::GapFull); + } else if (val & Decoration::Gap) { serializer.writeByte(Serializer::GapBreak); } else { serializer.writeByte(Serializer::GapNone); diff --git a/ext/wittle_generator/Panel.h b/ext/wittle_generator/Panel.h index 7f1588d..b8dec2f 100644 --- a/ext/wittle_generator/Panel.h +++ b/ext/wittle_generator/Panel.h @@ -160,6 +160,8 @@ class Panel { Decoration::Color color = Decoration::Color::None); void ClearGridSymbol(int x, int y); void Resize(int width, int height); + void ClearStartpoints() { _startpoints.clear(); } + void ClearExits() { _endpoints.clear(); } int width() const { return _width; } int height() const { return _height; } diff --git a/ext/wittle_generator/wittle_generator.cpp b/ext/wittle_generator/wittle_generator.cpp index e8f2dba..e1b5323 100644 --- a/ext/wittle_generator/wittle_generator.cpp +++ b/ext/wittle_generator/wittle_generator.cpp @@ -1,21 +1,685 @@ +#include #include #include "Generate.h" +#include "Random.h" -Rice::Object wittle_generator_generate(Rice::Object /* self */) { +Rice::Object wittle_generator_generate_easy(Rice::Object /* self */) { Generate generator; - // generator.setFlag(Generate::RegularStartEnd); - /*generator.generate(4 * 2 + 1, 4 * 2 + 1, - {{{Decoration::Triangle | Decoration::Orange, 6}}});*/ - // generator.setSymmetry(Panel::Vertical); - generator.setSymbol(Decoration::Exit, 0, 0); - generator.setSymbol(Decoration::Exit, 7 * 2, 0); - generator.setSymbol(Decoration::Exit, 7 * 2, 7 * 2); - generator.generate(7 * 2 + 1, 7 * 2 + 1, - {{{Decoration::Stone | Decoration::Color::White, 10}, - {Decoration::Stone | Decoration::Color::Black, 10}, - {Decoration::Dot, 10}, - {Decoration::Start, 2}}}); + + int choice = Random::rand() % 46; + std::cout << "Generate EASY: choice " << std::dec << choice << std::endl; + + switch (choice) { + case 0: { + generator.setSymbol(Decoration::Start, 2 * 2, 2 * 2); + generator.setSymbol(Decoration::Exit, 4 * 2, 0); + generator.generate( + 4, 4, {{{Decoration::Dot_Intersection, 25}, {Decoration::Gap, 2}}}); + break; + } + case 1: { + generator.setSymbol(Decoration::Start, 0, 4 * 2); + generator.generate(4, 4, + {{{Decoration::Stone | Decoration::Color::Black, 7}, + {Decoration::Stone | Decoration::Color::White, 5}, + {Decoration::Exit, 1}}}); + break; + } + case 2: { + generator.setFlag(Generate::RegularStartEnd); + generator.setSymmetry(Panel::Rotational); + generator.generate(6, 6, {{{Decoration::Gap, 15}}}); + break; + } + case 3: { + generator.setFlag(Generate::RegularStartEnd); + generator.setSymmetry(Panel::Vertical); + generator.generate(5, 8, {{{Decoration::Gap, 15}}}); + break; + } + case 4: { + generator.setFlag(Generate::RegularStartEnd); + generator.setSymmetry(Panel::Horizontal); + generator.generate(5, 5, {{{Decoration::Dot, 7}}}); + break; + } + case 5: { + generator.setFlag(Generate::RegularStartEnd); + generator.setSymmetry(Panel::Rotational); + generator.generate(5, 5, {{{Decoration::Dot, 6}}}); + break; + } + case 6: { + generator.setFlag(Generate::RegularStartEnd); + generator.setSymmetry(Panel::Rotational); + generator.generate(5, 5, + {{{Decoration::Dot | Decoration::Color::Blue, 1}, + {Decoration::Dot | Decoration::Color::Yellow, 2}, + {Decoration::Dot, 4}}}); + break; + } + case 7: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 2}}}); + break; + } + case 8: { + generator.setFlag(Generate::FullGaps); + generator.setFlag(Generate::StartEdgeOnly); + generator.generate(5, 5, + {{{Decoration::Gap, 16}, + {Decoration::Dot, 10}, + {Decoration::Exit, 1}, + {Decoration::Start, 1}}}); + break; + } + case 9: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(3, 3, + {{{Decoration::Eraser | Decoration::Color::Green, 1}, + {Decoration::Dot, 8}}}); + break; + } + case 10: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate( + 4, 4, + {{{Decoration::Stone | Decoration::Color::White, 8}, + {Decoration::Stone | Decoration::Color::Black, 4}, + {Decoration::Eraser | Decoration::Color::Green, 1}}}); + break; + } + case 11: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate( + 4, 4, + {{{Decoration::Stone | Decoration::Color::Red, 4}, + {Decoration::Stone | Decoration::Color::White, 4}, + {Decoration::Stone | Decoration::Color::Black, 3}, + {Decoration::Eraser | Decoration::Color::Green, 1}}}); + break; + } + case 12: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::RequireCombineShapes); + generator.generate(4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 1}, + {Decoration::Poly | Decoration::Color::Yellow | + Decoration::Can_Rotate, + 1}, + {Decoration::Gap, 5}}}); + break; + } + case 13: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate( + 3, 3, + {{{Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Eraser | Decoration::Color::White, 1}}}); + break; + } + case 14: { + generator.setFlag(Generate::FullGaps); + generator.generate(4, 4, + {{{Decoration::Gap, 8}, + {Decoration::Dot_Intersection, 10}, + {Decoration::Exit, 1}, + {Decoration::Start, 3}}}); + break; + } + case 15: { + generator.generate(5, 5, + {{{Decoration::Exit, 1}, + {Decoration::Stone | Decoration::Color::Black, 11}, + {Decoration::Stone | Decoration::Color::White, 8}, + {Decoration::Start, 3}}}); + break; + } + case 16: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Green, 6}, + {Decoration::Star | Decoration::Color::Orange, 5}, + {Decoration::Eraser | Decoration::Orange, 1}}}); + break; + } + case 17: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Orange, 6}, + {Decoration::Star | Decoration::Color::Magenta, 5}, + {Decoration::Star | Decoration::Color::Green, 4}, + {Decoration::Eraser | Decoration::Magenta, 1}}}); + break; + } + case 18: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Magenta, 6}, + {Decoration::Poly | Decoration::Color::Yellow, 2}, + {Decoration::Eraser | Decoration::White, 1}}}); + break; + } + case 19: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Magenta, 5}, + {Decoration::Poly | Decoration::Color::Yellow, 2}, + {Decoration::Eraser | Decoration::White, 1}}}); + break; + } + case 20: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Orange, 4}, + {Decoration::Gap, 10}}}); + break; + } + case 21: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(5, 5, + {{{Decoration::Star | Decoration::Color::Orange, 10}, + {Decoration::Gap, 3}}}); + break; + } + case 22: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Orange, 4}, + {Decoration::Star | Decoration::Color::Magenta, 4}, + {Decoration::Gap, 8}}}); + break; + } + case 23: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Orange, 4}, + {Decoration::Star | Decoration::Color::Magenta, 2}, + {Decoration::Star | Decoration::Color::Green, 2}, + {Decoration::Gap, 8}}}); + break; + } + case 24: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(4, 3, + {{{Decoration::Star | Decoration::Color::Orange, 6}, + {Decoration::Star | Decoration::Color::Magenta, 4}, + {Decoration::Star | Decoration::Color::Green, 2}}}); + break; + } + case 25: { + generator.setFlag(Generate::TreehouseLayout); + generator.setFlag(Generate::FullGaps); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Magenta, 6}, + {Decoration::Dot_Intersection, 6}, + {Decoration::Gap, 3}}}); + break; + } + case 26: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Magenta, 4}, + {Decoration::Stone | Decoration::Color::Black, 4}, + {Decoration::Stone | Decoration::Color::White, 4}}}); + break; + } + case 27: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(3, 3, + {{{Decoration::Star | Decoration::Color::Black, 1}, + {Decoration::Stone | Decoration::Color::Black, 2}, + {Decoration::Stone | Decoration::Color::White, 2}}}); + break; + } + case 28: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate( + 4, 4, + {{{Decoration::Star | Decoration::Color::White, 2}, + {Decoration::Stone | Decoration::Color::Black, 2}, + {Decoration::Stone | Decoration::Color::White, 2}, + {Decoration::Stone | Decoration::Color::Purple, 2}}}); + break; + } + case 29: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate( + 4, 4, + {{{Decoration::Poly | Decoration::Color::Orange, 2}, + {Decoration::Star | Decoration::Color::Magenta, 4}}}); + break; + } + case 30: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate( + 4, 5, + {{{Decoration::Stone | Decoration::Color::White, 8}, + {Decoration::Stone | Decoration::Color::Black, 8}, + {Decoration::Eraser | Decoration::Color::White, 2}}}); + break; + } + case 31: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(4, 5, + {{{Decoration::Poly | Decoration::Color::Orange, 2}, + {Decoration::Stone | Decoration::Color::White, 4}, + {Decoration::Stone | Decoration::Color::Black, 4}, + {Decoration::Gap, 4}}}); + break; + } + case 32: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(4, 4, + {{{Decoration::Dot_Intersection, 25}, + {Decoration::Poly | Decoration::Color::Yellow, 2}}}); + break; + } + case 33: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate( + 4, 4, + {{{Decoration::Dot_Intersection, 25}, + {Decoration::Poly | Decoration::Color::Yellow | + Decoration::Can_Rotate, + 2}, + {Decoration::Eraser | Decoration::Color::White, 1}}}); + break; + } + case 34: { + generator.setFlag(Generate::RegularStartEnd); + generator.setSymmetry(Panel::Rotational); + generator.generate(5, 5, + {{{Decoration::Stone | Decoration::Color::Black, 6}, + {Decoration::Stone | Decoration::Color::White, 6}}}); + break; + } + case 35: { + generator.setFlag(Generate::RegularStartEnd); + generator.setSymmetry(Panel::Rotational); + generator.generate(5, 5, + {{{Decoration::Stone | Decoration::Color::Black, 5}, + {Decoration::Stone | Decoration::Color::White, 5}, + {Decoration::Dot, 3}}}); + break; + } + case 36: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::SplitShapes); + generator.generate(4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Gap, 8}}}); + break; + } + case 37: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::BigShapes); + generator.generate(5, 5, + {{{Decoration::Poly | Decoration::Color::Yellow, 2}, + {Decoration::Gap, 12}}}); + break; + } + case 38: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::DisconnectShapes); + generator.generate(3, 3, + {{{Decoration::Poly | Decoration::Color::Yellow, 2}}}); + break; + } + case 39: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::DisconnectShapes); + generator.setFlag(Generate::BigShapes); + generator.generate(4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 2}}}); + break; + } + case 40: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::RequireCombineShapes); + generator.setFlag(Generate::DisableCancelShapes); + generator.generate( + 3, 3, + {{{Decoration::Poly | Decoration::Color::Yellow, 2}, + {Decoration::Poly | Decoration::Negative | Decoration::Color::Blue, + 1}}}); + break; + } + case 41: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::RequireCombineShapes); + generator.setFlag(Generate::DisableCancelShapes); + generator.generate( + 4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 2}, + {Decoration::Poly | Decoration::Negative | Decoration::Color::Blue, + 1}}}); + break; + } + case 42: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::BigShapes); + generator.setFlag(Generate::DisableCancelShapes); + generator.generate( + 4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 2}, + {Decoration::Poly | Decoration::Negative | Decoration::Color::Blue, + 1}}}); + break; + } + case 43: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::RequireCancelShapes); + generator.generate( + 4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Poly | Decoration::Negative | Decoration::Color::Blue, + 2}}}); + break; + } + case 44: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate( + 4, 4, {{{Decoration::Triangle | Decoration::Color::Orange, 6}}}); + break; + } + case 45: { + generator.setFlag(Generate::TreehouseLayout); + generator.setFlag(Generate::LongPath); + generator.generate(5, 4, + {{{Decoration::Star | Decoration::Color::Magenta, 6}, + {Decoration::Stone | Decoration::Color::Orange, 4}, + {Decoration::Stone | Decoration::Color::Green, 4}}}); + generator.place_gaps(8); + break; + } + } + + Rice::String str(generator.AsCode()); + return str; +} + +Rice::Object wittle_generator_generate_medium(Rice::Object /* self */) { + Generate generator; + + int choice = Random::rand() % 30; + std::cout << "Generate MEDIUM: choice " << std::dec << choice << std::endl; + + switch (choice) { + case 0: { + generator.setSymbol(Decoration::Start, 2 * 2, 2 * 2); + generator.setSymbol(Decoration::Exit, 4 * 2, 0); + generator.generate( + 4, 4, + {{{Decoration::Stone | Decoration::Color::White, 5}, + {Decoration::Stone | Decoration::Color::Black, 5}, + {Decoration::Dot, 4}, + {Decoration::Eraser | Decoration::Color::Green, 1}}}); + break; + } + case 1: { + generator.setSymbol(Decoration::Exit, 0, 0); + generator.setSymbol(Decoration::Exit, 7 * 2, 0); + generator.setSymbol(Decoration::Exit, 7 * 2, 7 * 2); + generator.generate(7, 7, + {{{Decoration::Stone | Decoration::Color::White, 10}, + {Decoration::Stone | Decoration::Color::Black, 10}, + {Decoration::Dot, 10}, + {Decoration::Start, 4}}}); + break; + } + case 2: { + generator.setSymbol(Decoration::Exit, 0, 0); + generator.setSymbol(Decoration::Exit, 7 * 2, 0); + generator.setSymbol(Decoration::Exit, 7 * 2, 7 * 2); + generator.generate(7, 7, + {{{Decoration::Stone | Decoration::Color::White, 10}, + {Decoration::Stone | Decoration::Color::Black, 10}, + {Decoration::Dot, 10}, + {Decoration::Eraser | Decoration::Color::Purple, 1}, + {Decoration::Start, 3}}}); + break; + } + case 3: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(5, 5, + {{{Decoration::Star | Decoration::White, 8}, + {Decoration::Star | Decoration::Black, 6}}}); + break; + } + case 4: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::DisconnectShapes); + generator.generate( + 4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Eraser | Decoration::Color::White, 1}}}); + break; + } + case 5: { + generator.setSymbol(Decoration::Start, 2 * 2, 2 * 2); + generator.setSymbol(Decoration::Exit, 4 * 2, 0); + generator.generate(4, 4, + {{{Decoration::Dot_Intersection, 25}, + {Decoration::Stone | Decoration::Color::Black, 2}, + {Decoration::Stone | Decoration::Color::White, 2}}}); + break; + } + case 6: { + generator.setSymmetry(Panel::Rotational); + generator.generate(5, 5, + {{{Decoration::Dot | Decoration::Color::Blue, 2}, + {Decoration::Dot | Decoration::Color::Yellow, 2}, + {Decoration::Dot, 4}, + {Decoration::Start, 2}, + {Decoration::Exit, 1}}}); + break; + } + case 7: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::RequireCancelShapes); + generator.generate( + 6, 6, + {{{Decoration::Dot_Intersection, 49}, + {Decoration::Poly | Decoration::Color::Yellow, 1}, + {Decoration::Poly | Decoration::Color::Yellow | + Decoration::Can_Rotate, + 2}, + {Decoration::Poly | Decoration::Color::Blue | Decoration::Negative, + 3}}}); + break; + } + case 8: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate( + 4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Eraser | Decoration::Color::White, 1}}}); + break; + } + case 9: { + generator.setSymbol(Decoration::Start, 0, 3 * 2); + generator.setSymbol(Decoration::Exit, 6 * 2, 3 * 2); + generator.generate(6, 3, + {{{Decoration::Star | Decoration::Color::Magenta, 3}, + {Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Eraser | Decoration::White, 1}}}); + break; + } + case 10: { + generator.setSymbol(Decoration::Start, 0, 3 * 2); + generator.setSymbol(Decoration::Exit, 6 * 2, 3 * 2); + generator.generate(6, 3, + {{{Decoration::Star | Decoration::Color::Magenta, 5}, + {Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Eraser | Decoration::White, 1}}}); + break; + } + case 11: { + generator.setSymbol(Decoration::Start, 0, 3 * 2); + generator.setSymbol(Decoration::Exit, 6 * 2, 3 * 2); + generator.generate(6, 3, + {{{Decoration::Star | Decoration::Color::Magenta, 6}, + {Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Eraser | Decoration::White, 1}}}); + break; + } + case 12: { + generator.setSymbol(Decoration::Start, 0, 3 * 2); + generator.setSymbol(Decoration::Exit, 7 * 2, 3 * 2); + generator.generate(7, 3, + {{{Decoration::Star | Decoration::Color::Magenta, 5}, + {Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Eraser | Decoration::White, 1}}}); + break; + } + case 13: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Orange, 6}, + {Decoration::Star | Decoration::Color::Magenta, 6}, + {Decoration::Star | Decoration::Color::Green, 4}}}); + break; + } + case 14: { + generator.setFlag(Generate::TreehouseLayout); + generator.setFlag(Generate::FullGaps); + generator.generate(5, 5, + {{{Decoration::Star | Decoration::Color::Magenta, 8}, + {Decoration::Dot_Intersection, 9}, + {Decoration::Gap, 5}}}); + break; + } + case 15: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate(4, 4, + {{{Decoration::Star | Decoration::Color::Black, 4}, + {Decoration::Star | Decoration::Color::White, 4}, + {Decoration::Stone | Decoration::Color::Black, 2}, + {Decoration::Stone | Decoration::Color::White, 2}}}); + break; + } + case 16: { + generator.setFlag(Generate::TreehouseLayout); + generator.generate( + 5, 5, + {{{Decoration::Poly | Decoration::Color::Orange, 2}, + {Decoration::Poly | Decoration::Color::Magenta, 1}, + {Decoration::Star | Decoration::Color::Magenta, 3}}}); + break; + } + case 17: { + generator.setFlag(Generate::TreehouseLayout); + generator.setFlag(Generate::RequireCombineShapes); + generator.generate(5, 5, + {{{Decoration::Poly | Decoration::Color::Orange, 1}, + {Decoration::Poly | Decoration::Can_Rotate | + Decoration::Color::Orange, + 1}, + {Decoration::Star | Decoration::Color::Magenta, 4}, + {Decoration::Star | Decoration::Color::Green, 4}}}); + break; + } + case 18: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(4, 4, + {{{Decoration::Poly | Decoration::Color::Orange, 3}, + {Decoration::Stone | Decoration::Color::White, 2}, + {Decoration::Stone | Decoration::Color::Black, 2}}}); + break; + } + case 19: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(4, 4, + {{{Decoration::Dot_Intersection, 25}, + {Decoration::Poly | Decoration::Can_Rotate | + Decoration::Color::Yellow, + 2}}}); + break; + } + case 20: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::SmallShapes); + generator.generate(5, 5, + {{{Decoration::Poly | Decoration::Can_Rotate | + Decoration::Color::Yellow, + 4}, + {Decoration::Star | Decoration::Color::Orange, 6}}}); + break; + } + case 21: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(5, 5, + {{{Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Gap, 5}}}); + break; + } + case 22: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(5, 5, + {{{Decoration::Poly | Decoration::Color::Yellow, 4}}}); + break; + } + case 23: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::DisconnectShapes); + generator.generate(4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 3}}}); + break; + } + case 24: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(5, 5, + {{{Decoration::Poly | Decoration::Can_Rotate | + Decoration::Color::Yellow, + 2}, + {Decoration::Poly | Decoration::Color::Yellow, 1}, + {Decoration::Gap, 2}}}); + break; + } + case 25: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::BigShapes); + generator.generate(5, 5, + {{{Decoration::Poly | Decoration::Can_Rotate | + Decoration::Color::Yellow, + 3}}}); + break; + } + case 26: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate(5, 6, + {{{Decoration::Poly | Decoration::Color::Yellow, 5}}}); + break; + } + case 27: { + generator.setFlag(Generate::RegularStartEnd); + generator.setFlag(Generate::BigShapes); + generator.generate( + 4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 2}, + {Decoration::Poly | Decoration::Negative | Decoration::Color::Blue, + 2}}}); + break; + } + case 28: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate( + 4, 4, + {{{Decoration::Poly | Decoration::Color::Yellow, 3}, + {Decoration::Poly | Decoration::Negative | Decoration::Color::Blue, + 2}}}); + break; + } + case 29: { + generator.setFlag(Generate::RegularStartEnd); + generator.generate( + 4, 4, {{{Decoration::Triangle | Decoration::Color::Orange, 8}}}); + break; + } + } Rice::String str(generator.AsCode()); return str; @@ -24,5 +688,6 @@ Rice::Object wittle_generator_generate(Rice::Object /* self */) { extern "C" void Init_wittle_generator() { Rice::Class rb_cWittleGenerator = Rice::define_class("WittleGenerator") - .define_method("generate", &wittle_generator_generate); + .define_method("generate_easy", &wittle_generator_generate_easy) + .define_method("generate_medium", &wittle_generator_generate_medium); } diff --git a/lib/wittle/engine.rb b/lib/wittle/engine.rb index fd1ec4c..f0ec682 100644 --- a/lib/wittle/engine.rb +++ b/lib/wittle/engine.rb @@ -1,4 +1,5 @@ require "haml" +require "wittle_generator/wittle_generator" module Wittle class Engine < ::Rails::Engine -- cgit 1.4.1