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