diff --git a/rogueviz/rogueviz-all.cpp b/rogueviz/rogueviz-all.cpp index 16d19f68..1a35e2fd 100644 --- a/rogueviz/rogueviz-all.cpp +++ b/rogueviz/rogueviz-all.cpp @@ -23,3 +23,4 @@ #include "snow.cpp" #include "impossible-ring.cpp" #include "triangle.cpp" +#include "sumotron.cpp" diff --git a/rogueviz/sumotron.cpp b/rogueviz/sumotron.cpp new file mode 100644 index 00000000..53247493 --- /dev/null +++ b/rogueviz/sumotron.cpp @@ -0,0 +1,156 @@ +// Hyperbolic Rogue -- sumotron puzzle +// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details + +/** \file sumotron.cpp + * \brief dual geometry puzzle generator + */ + +#include "../hyper.h" + +namespace hr { + +EX namespace sumotron { + +map value; +vector seq; + +bool dialog_shown = false; + +void sumotron_puzzle() { + + clearMessages(); + + if(currentmap->gamestart()->wall == waSea) { + for(cell *c: currentmap->allcells()) { + c->wall = waNone; + c->landparam = 0xD0D0D0; + } + value.clear(); + seq.clear(); + } + + for(cell *c: currentmap->allcells()) { + bool mo = c == mouseover; + bool has = value.count(c); + if(mo && has && c == seq.back()) + c->landparam = 0xC0FF80; + else if(mo && has) + c->landparam = 0xC0C080; + else if(mo) + c->landparam = 0xFFFF00; + else if(has && c == seq.back()) + c->landparam = 0x80FF80; + else if(has) + c->landparam = 0xA0A0A0; + else + c->landparam = 0xF0F0F0; + } + getcstat = '-'; + cmode = 0; + if(dialog_shown) cmode = sm::SIDE | sm::DIALOG_STRICT_X | sm::MAYDARK; + dynamicval dp(mapeditor::drawplayer, false); + gamescreen(0); + + initquickqueue(); + for(auto p: value) { + cell *c = p.first; + bignum& b = value[p.first]; + string s = short_form(b); + ld size = min(1, 1.5 / isize(s)); + for(const shiftmatrix& V: current_display->all_drawn_copies[c]) + queuestr(V, size, s, dialog_shown ? gradient(backcolor, 0x800000, 0, .5, 1) : 0xFF0000, 1); + } + + if(mouseover) queuecircleat(mouseover, .8, 0x800000FF); + + quickqueue(); + + dialog::init("SUMOTRON", iinf[itPalace].color, 150, 100); + dialog::addInfo("based on Sumotron by Marcos Donnantuoni"); + + bignum max = 0; + for(auto v: value) if(v.second > max) max = v.second; + + if(max > 0) { + dialog::addInfo("your result:"); + dialog::addInfo(max.get_str(9999)); + } + else { + dialog::addInfo("click to place number"); + dialog::addInfo("arrows keys or middle button to scroll"); + } + + dialog::addItem("undo", 'z'); + dialog::add_action([] { + if(seq.empty()) return; + value.erase(seq.back()); + seq.pop_back(); + }); + dialog::addItem("restart", 'r'); + dialog::add_action([] { + value.clear(); + seq.clear(); + }); + dialog::addItem("change geometry", 'g'); + dialog::add_action(runGeometryExperiments); + dialog::addItem("change settings", 's'); + dialog::add_action_push(showSettings); + dialog::addItem("hide menu", 'v'); + dialog::add_action([] { dialog_shown = false; }); + + if(dialog_shown) { + dialog::display(); + } + else { + displayButton(8, vid.yres-vid.fsize, max.get_str(9999), 'v', 0); + displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(v) menu"), 'v', 16); + dialog::add_key_action('v', [] { dialog_shown = true; }); + } + + keyhandler = [] (int sym, int uni) { + handlePanning(sym, uni); + dialog::handleNavigation(sym, uni); + if(sym == '-' && mouseover) { + cell *c = mouseover; + if(value.count(c)) return; + bignum total = 0; + for(cell *c1: adj_minefield_cells(c)) + if(value.count(c1)) + total = total + value[c1]; + if(total.approx_int() == 0) total = 1; + value[c] = total; + seq.push_back(c); + } + }; + } + +void launch() { + /* setup */ + stop_game(); + specialland = firstland = laCanvas; + canvas_default_wall = waSea; + start_game(); + pushScreen(sumotron_puzzle); + } + +#if CAP_COMMANDLINE +int rugArgs() { + using namespace arg; + + if(0) ; + else if(argis("-sumotron")) { + launch(); + } + + else return 1; + return 0; + } + +auto rug_hook = + addHook(hooks_args, 100, rugArgs); +#endif + +EX } + +EX } +