C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
exprtk_maze_generator.cpp
Go to the documentation of this file.
1/*
2 **************************************************************
3 * C++ Mathematical Expression Toolkit Library *
4 * *
5 * ExprTk Maze Generator *
6 * Author: Arash Partow (1999-2024) *
7 * URL: https://www.partow.net/programming/exprtk/index.html *
8 * *
9 * Copyright notice: *
10 * Free use of the Mathematical Expression Toolkit Library is *
11 * permitted under the guidelines and in accordance with the *
12 * most current version of the MIT License. *
13 * https://www.opensource.org/licenses/MIT *
14 * SPDX-License-Identifier: MIT *
15 * *
16 **************************************************************
17*/
18
19
20#include <algorithm>
21#include <array>
22#include <cstdio>
23#include <random>
24#include <string>
25
26#include "exprtk.hpp"
27
28
29template <typename T>
30struct shuffle final : public exprtk::igeneric_function<T>
31{
36
37 using igfun_t::operator();
38
40 : exprtk::igeneric_function<T>("V")
41 {
42 std::random_device device;
43 std::array<unsigned int,std::mt19937::state_size> seed;
44 std::generate_n(seed.data(), seed.size(), std::ref(device));
45 std::seed_seq seq(std::begin(seed), std::end(seed));
46 generator.seed(seq);
47 }
48
49 inline T operator() (parameter_list_t parameters) override
50 {
51 vector_t vec(parameters[0]);
52 std::shuffle(std::begin(vec), std::end(vec), generator);
53 return T(1);
54 }
55
56 std::mt19937 generator;
57 std::uniform_real_distribution<T> distribution{T(0),T(1)};
58};
59
60template <typename T>
62{
63 typedef exprtk::symbol_table<T> symbol_table_t;
64 typedef exprtk::expression<T> expression_t;
65 typedef exprtk::parser<T> parser_t;
66 typedef exprtk::function_compositor<T> compositor_t;
67 typedef typename compositor_t::function function_t;
68
69 const T width = T(40);
70 const T height = T(30);
71
72 const T N = T(1);
73 const T E = T(2);
74 const T S = T(3);
75 const T W = T(4);
76
77 std::vector<T> board (static_cast<std::size_t>(width * height), T(0));
78 std::vector<T> north_wall_board(static_cast<std::size_t>(width * height), T(0));
79 std::vector<T> west_wall_board (static_cast<std::size_t>(width * height), T(0));
80
82
84
85 symbol_table_t symbol_table;
86
87 symbol_table.add_constant( "width" , width );
88 symbol_table.add_constant( "height" , height );
89 symbol_table.add_constant( "N" , N );
90 symbol_table.add_constant( "E" , E );
91 symbol_table.add_constant( "S" , S );
92 symbol_table.add_constant( "W" , W );
93
94 symbol_table.add_vector ( "board" , board );
95 symbol_table.add_vector ( "north_wall_board" , north_wall_board);
96 symbol_table.add_vector ( "west_wall_board" , west_wall_board );
97
98 symbol_table.add_function( "shuffle" , shuffle );
99 symbol_table.add_function( "print_digit" ,
100 [](T v) ->T
101 { printf(" %d ",static_cast<int>(v)); return 0; });
102
103 symbol_table.add_package (io_package);
104
105 compositor_t compositor(symbol_table);
106
107 compositor.load_variables(true);
108 compositor.load_vectors (true);
109
110 compositor.add(
111 function_t("get_board")
112 .vars("x", "y")
113 .expression
114 ( " board[y * width + x]; " ));
115
116 compositor.add(
117 function_t("set_board")
118 .vars("x", "y", "value")
119 .expression
120 ( " board[y * width + x] := value; " ));
121
122 compositor.add(
123 function_t("get_nwall_board")
124 .vars("x", "y")
125 .expression
126 ( " north_wall_board[y * width + x]; " ));
127
128 compositor.add(
129 function_t("get_wwall_board")
130 .vars("x", "y")
131 .expression
132 ( " west_wall_board[y * width + x]; " ));
133
134 compositor.add(
135 function_t("set_nwall_board")
136 .vars("x", "y", "value")
137 .expression
138 ( " north_wall_board[y * width + x] := value; " ));
139
140 compositor.add(
141 function_t("set_wwall_board")
142 .vars("x", "y", "value")
143 .expression
144 ( " west_wall_board[y * width + x] := value; " ));
145
146 compositor.add(
147 function_t("display_maze")
148 .expression
149 (
150 " for (var x := 0; x < width; x += 1) "
151 " { "
152 " print('+---'); "
153 " }; "
154 " "
155 " println('+'); "
156 " "
157 " for (var y := 0; y < height; y += 1) "
158 " { "
159 " for (var x := 0; x < width; x += 1) "
160 " { "
161 " var segment := get_wwall_board(x,y) == W ? ' ' : '| '; "
162 " print(segment); "
163 " }; "
164 " "
165 " println('|'); "
166 " "
167 " for (var x := 0; x < width; x += 1) "
168 " { "
169 " var segment := get_nwall_board(x,y) == N ? '+ ' : '+---'; "
170 " print(segment); "
171 " }; "
172 " "
173 " println('+'); "
174 " }; "
175 " "
176 " println(); "
177 ));
178
179 compositor.add(
180 function_t("generate_maze")
181 .vars("x","y")
182 .expression
183 (
184 " set_board(x, y, 1); "
185 " "
186 " var x_move [4] := { -1, 0, +1, 0 }; "
187 " var y_move [4] := { 0, +1, 0, -1 }; "
188 " var heading[4] := { W, N, E, S }; "
189 " var moves [4] := { 0, 1, 2, 3 }; "
190 " "
191 " shuffle(moves); "
192 " "
193 " for (var i := 0; i < moves[]; i += 1) "
194 " { "
195 " var move := moves[i]; "
196 " var new_x := x + x_move[move]; "
197 " var new_y := y + y_move[move]; "
198 " "
199 " if ((new_x < 0 ) or (new_y < 0 )) continue; "
200 " if ((new_x >= width) or (new_y >= height)) continue; "
201 " "
202 " if (get_board(new_x, new_y) == 0) "
203 " { "
204 " if (heading[move] == N) { set_nwall_board(x, y, N); }; "
205 " if (heading[move] == W) { set_wwall_board(x, y, W); }; "
206 " "
207 " if (heading[move] == S) { set_nwall_board(new_x, new_y, N); }; "
208 " if (heading[move] == E) { set_wwall_board(new_x, new_y, W); }; "
209 " "
210 " generate_maze(new_x,new_y); "
211 " } "
212 " }; "
213 ));
214
215 const std::string maze_generator_program =
216 " generate_maze(0, 0); "
217 " display_maze(); ";
218
219 expression_t expression;
220 expression.register_symbol_table(symbol_table);
221
222 parser_t parser;
223 parser.compile(maze_generator_program,expression);
224
225 expression.value();
226}
227
228int main()
229{
230 maze_generator<double>();
231 return 0;
232}
igeneric_function(const std::string &param_seq="", const return_type rtr_type=e_rtrn_scalar)
Definition exprtk.hpp:19667
void maze_generator()
std::uniform_real_distribution< T > distribution
igfun_t::parameter_list_t parameter_list_t
exprtk::igeneric_function< T > igfun_t
std::mt19937 generator
T operator()(parameter_list_t parameters) override
generic_type::vector_view vector_t
igfun_t::generic_type generic_type