From cfc41eb3ccc99b92220115b0710fb821525e1075 Mon Sep 17 00:00:00 2001
From: Star Rauchenberger <fefferburbia@gmail.com>
Date: Sat, 28 Oct 2023 16:38:07 -0400
Subject: generating a lot of puzzles

---
 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 +++++++++++++++++++++++++++++-
 5 files changed, 695 insertions(+), 29 deletions(-)

(limited to 'ext/wittle_generator')

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<int> 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<Point> 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<Point>& 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 <iostream>
 #include <rice/rice.hpp>
 
 #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);
 }
-- 
cgit 1.4.1