1 // Hyperbolic Rogue -- sumotron puzzle
2 // Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details
3 
4 /** \file sumotron.cpp
5  *  \brief dual geometry puzzle generator
6  */
7 
8 #include "../hyper.h"
9 
10 namespace hr {
11 
12 EX namespace sumotron {
13 
14 map<cell*, bignum> value;
15 vector<cell*> seq;
16 
17 bool dialog_shown = false;
18 
sumotron_puzzle()19 void sumotron_puzzle() {
20 
21   clearMessages();
22 
23   if(currentmap->gamestart()->wall == waSea) {
24     for(cell *c: currentmap->allcells()) {
25       c->wall = waNone;
26       c->landparam = 0xD0D0D0;
27       }
28     value.clear();
29     seq.clear();
30     }
31 
32   for(cell *c: currentmap->allcells()) {
33     bool mo = c == mouseover;
34     bool has = value.count(c);
35     if(mo && has && c == seq.back())
36       c->landparam = 0xC0FF80;
37     else if(mo && has)
38       c->landparam = 0xC0C080;
39     else if(mo)
40       c->landparam = 0xFFFF00;
41     else if(has && c == seq.back())
42       c->landparam = 0x80FF80;
43     else if(has)
44       c->landparam = 0xA0A0A0;
45     else
46       c->landparam = 0xF0F0F0;
47     }
48   getcstat = '-';
49   cmode = 0;
50   if(dialog_shown) cmode = sm::SIDE | sm::DIALOG_STRICT_X | sm::MAYDARK;
51   dynamicval<bool> dp(mapeditor::drawplayer, false);
52   gamescreen(0);
53 
54   initquickqueue();
55   for(auto p: value) {
56     cell *c = p.first;
57     bignum& b = value[p.first];
58     string s = short_form(b);
59     ld size = min<ld>(1, 1.5 / isize(s));
60     for(const shiftmatrix& V: current_display->all_drawn_copies[c])
61       queuestr(V, size, s, dialog_shown ? gradient(backcolor, 0x800000, 0, .5, 1) : 0xFF0000, 1);
62     }
63 
64   if(mouseover) queuecircleat(mouseover, .8, 0x800000FF);
65 
66   quickqueue();
67 
68   dialog::init("SUMOTRON", iinf[itPalace].color, 150, 100);
69   dialog::addInfo("based on Sumotron by Marcos Donnantuoni");
70 
71   bignum max = 0;
72   for(auto v: value) if(v.second > max) max = v.second;
73 
74   if(max > 0) {
75     dialog::addInfo("your result:");
76     dialog::addInfo(max.get_str(9999));
77     }
78   else {
79     dialog::addInfo("click to place number");
80     dialog::addInfo("arrows keys or middle button to scroll");
81     }
82 
83   dialog::addItem("undo", 'z');
84   dialog::add_action([] {
85     if(seq.empty()) return;
86     value.erase(seq.back());
87     seq.pop_back();
88     });
89   dialog::addItem("restart", 'r');
90   dialog::add_action([] {
91     value.clear();
92     seq.clear();
93     });
94   dialog::addItem("change geometry", 'g');
95   dialog::add_action(runGeometryExperiments);
96   dialog::addItem("change settings", 's');
97   dialog::add_action_push(showSettings);
98   dialog::addItem("hide menu", 'v');
99   dialog::add_action([] { dialog_shown = false; });
100 
101   if(dialog_shown) {
102     dialog::display();
103     }
104   else {
105     displayButton(8, vid.yres-vid.fsize, max.get_str(9999), 'v', 0);
106     displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(v) menu"), 'v', 16);
107     dialog::add_key_action('v', [] { dialog_shown = true; });
108     }
109 
110   keyhandler = [] (int sym, int uni) {
111     handlePanning(sym, uni);
112     dialog::handleNavigation(sym, uni);
113     if(sym == '-' && mouseover) {
114       cell *c = mouseover;
115       if(value.count(c)) return;
116       bignum total = 0;
117       for(cell *c1: adj_minefield_cells(c))
118         if(value.count(c1))
119           total = total + value[c1];
120       if(total.approx_int() == 0) total = 1;
121       value[c] = total;
122       seq.push_back(c);
123       }
124     };
125   }
126 
launch()127 void launch() {
128   /* setup */
129   stop_game();
130   specialland = firstland = laCanvas;
131   canvas_default_wall = waSea;
132   start_game();
133   pushScreen(sumotron_puzzle);
134   }
135 
136 #if CAP_COMMANDLINE
rugArgs()137 int rugArgs() {
138   using namespace arg;
139 
140   if(0) ;
141   else if(argis("-sumotron")) {
142     launch();
143     }
144 
145   else return 1;
146   return 0;
147   }
148 
149 auto rug_hook =
150   addHook(hooks_args, 100, rugArgs);
151 #endif
152 
153 EX }
154 
155 EX }
156 
157