1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-25 01:20:37 +00:00
hyperrogue/rogueviz/sumotron.cpp
2020-08-02 12:56:43 +02:00

157 lines
3.7 KiB
C++

// 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<cell*, bignum> value;
vector<cell*> 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<bool> 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<ld>(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 }