C++ Mathematical Expression Toolkit (ExprTk)
release
Toggle main menu visibility
Loading...
Searching...
No Matches
exprtk
exprtk_game_of_life.cpp
Go to the documentation of this file.
1
/*
2
**************************************************************
3
* C++ Mathematical Expression Toolkit Library *
4
* *
5
* ExprTk Conway's Game Of Life *
6
* Author: Arash Partow (1999-2025) *
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 <chrono>
23
#include <cstdio>
24
#include <random>
25
#include <string>
26
#include <thread>
27
28
#include "
exprtk.hpp
"
29
30
31
template
<
typename
T>
32
struct
rnd_01
final :
public
exprtk::ifunction
<T>
33
{
34
using
exprtk::ifunction
<T>::operator();
35
36
rnd_01
()
37
:
exprtk
::
ifunction
<T>(0)
38
{
39
std::random_device device;
40
std::array<unsigned int,std::mt19937::state_size> seed;
41
std::generate_n(seed.data(), seed.size(), std::ref(device));
42
std::seed_seq seq(std::begin(seed), std::end(seed));
43
generator
.seed(seq);
44
}
45
46
inline
T
operator()
()
override
47
{
48
return
distribution
(
generator
);
49
}
50
51
std::mt19937
generator
;
52
std::uniform_real_distribution<T>
distribution
{T(0),T(1)};
53
};
54
55
template
<
typename
T>
56
void
game_of_life
()
57
{
58
typedef
exprtk::symbol_table<T>
symbol_table_t;
59
typedef
exprtk::expression<T>
expression_t;
60
typedef
exprtk::parser<T>
parser_t;
61
typedef
exprtk::function_compositor<T>
compositor_t;
62
typedef
typename
compositor_t::function function_t;
63
64
const
std::size_t width = 80;
65
const
std::size_t height = 40;
66
67
std::vector<T> world(width * height, T(0));
68
rnd_01<T>
rnd01;
69
exprtk::rtl::io::package<T>
io_package;
70
71
symbol_table_t symbol_table;
72
symbol_table.add_constant(
"width"
,
static_cast<
T
>
(width ));
73
symbol_table.add_constant(
"height"
,
static_cast<
T
>
(height));
74
symbol_table.add_vector (
"world"
, world);
75
symbol_table.add_package (io_package);
76
symbol_table.add_function(
"random"
, rnd01);
77
78
symbol_table.
79
add_function(
"sleep"
,
80
[](T time_ms) -> T
81
{
82
std::this_thread::sleep_for(
83
std::chrono::milliseconds(
static_cast<
std::size_t
>
(time_ms)));
84
return
T(1);
85
});
86
87
symbol_table.
88
add_function(
"clear"
,
89
[](T full) -> T
90
{
91
printf(
"%s\033[H"
, full == T(1) ?
""
:
"\033[2J"
);
92
std::fflush(stdout);
93
return
T(1);
94
});
95
96
compositor_t compositor(symbol_table);
97
98
compositor.load_variables(
true
);
99
compositor.load_vectors (
true
);
100
101
compositor.add(
102
function_t(
"point"
)
103
.vars(
"x"
,
"y"
)
104
.expression
105
(
106
" world[y * width + x]; "
107
));
108
109
compositor.add(
110
function_t(
"set_point"
)
111
.vars(
"x"
,
"y"
,
"value"
)
112
.expression
113
(
114
" if ( "
115
" (x >= 0) and (y >= 0) and "
116
" (x < width) and (y < height) "
117
" ) "
118
" { "
119
" world[y * width + x] := value; "
120
" } "
121
));
122
123
compositor.add(
124
function_t(
"set_glider"
)
125
.vars(
"x"
,
"y"
)
126
.expression
127
(
128
" set_point(x + 1, y, 1); "
129
" set_point(x + 2, y + 1, 1); "
130
" set_point(x, y + 2, 1); "
131
" set_point(x + 1, y + 2, 1); "
132
" set_point(x + 2, y + 2, 1); "
133
));
134
135
compositor.add(
136
function_t(
"render"
)
137
.expression
138
(
139
" print('+'); "
140
" for (var x := 0; x < width; x += 1) { print('-'); } "
141
" println('+'); "
142
" "
143
" for (var y := 0; y < height; y += 1) "
144
" { "
145
" print('|'); "
146
" for (var x := 0; x < width; x += 1) "
147
" { "
148
" print( point(x,y) ? '*' : ' ' ); "
149
" }; "
150
" println('|'); "
151
" }; "
152
" "
153
" print('+'); "
154
" for (var x := 0; x < width; x += 1) { print('-'); } "
155
" println('+'); "
156
));
157
158
compositor.add(
159
function_t(
"evolve"
)
160
.expression
161
(
162
" var next_world[world[]] := [0]; "
163
" "
164
" for (var y := 0; y < height; y += 1) "
165
" { "
166
" for (var x := 0; x < width; x += 1) "
167
" { "
168
" var alive_count := point(x,y) ? -1 : 0; "
169
" "
170
" for (var y1 := y - 1; y1 <= y + 1; y1 += 1) "
171
" { "
172
" var curr_y := (y1 + height) % height; "
173
" "
174
" for (var x1 := x - 1; x1 <= x + 1; x1 += 1) "
175
" { "
176
" var curr_x := (x1 + width) % width; "
177
" "
178
" if (point(curr_x,curr_y)) "
179
" { "
180
" alive_count += 1; "
181
" } "
182
" } "
183
" }; "
184
" "
185
" next_world[y * width + x] := "
186
" switch "
187
" { "
188
" case alive_count == 2 and point(x,y) : 1; "
189
" case alive_count == 3 : 1; "
190
" default : 0; "
191
" }; "
192
" } "
193
" }; "
194
" "
195
" world := next_world; "
196
));
197
198
const
std::string game_of_life_driver =
199
" /* Setup the initial state of the world */ "
200
" for (var x := 0; x < width; x += 1) "
201
" { "
202
" for (var y := 0; y < height; y += 1) "
203
" { "
204
" switch "
205
" { "
206
" case (random() < 0.10) : set_glider(x,y); "
207
" case (random() < 0.10) : set_point (x,y,1); "
208
" }; "
209
" } "
210
" }; "
211
" "
212
" var num_generations := 1000; "
213
" "
214
" for (var i := 0; i < num_generations; i += 1) "
215
" { "
216
" clear(i % 50 == 0); "
217
" println('Generation: ', i); "
218
" render(); "
219
" evolve(); "
220
" sleep(10); "
221
" } "
;
222
223
expression_t expression;
224
expression.register_symbol_table(symbol_table);
225
226
parser_t parser;
227
parser.compile(game_of_life_driver,expression);
228
229
expression.value();
230
}
231
232
int
main
()
233
{
234
game_of_life<double>
();
235
return
0;
236
}
exprtk::expression
Definition
exprtk.hpp:21832
exprtk::function_compositor
Definition
exprtk.hpp:43057
exprtk::ifunction
Definition
exprtk.hpp:19861
exprtk::ifunction::ifunction
ifunction(const std::size_t &pc)
Definition
exprtk.hpp:19864
exprtk::parser
Definition
exprtk.hpp:22525
exprtk::symbol_table
Definition
exprtk.hpp:20090
exprtk.hpp
main
int main()
Definition
exprtk_game_of_life.cpp:232
game_of_life
void game_of_life()
Definition
exprtk_game_of_life.cpp:56
exprtk
Definition
exprtk.hpp:60
exprtk::rtl::io::package
Definition
exprtk.hpp:44296
rnd_01
Definition
exprtk_game_of_life.cpp:33
rnd_01::rnd_01
rnd_01()
Definition
exprtk_game_of_life.cpp:36
rnd_01::distribution
std::uniform_real_distribution< T > distribution
Definition
exprtk_game_of_life.cpp:52
rnd_01::generator
std::mt19937 generator
Definition
exprtk_game_of_life.cpp:51
rnd_01::operator()
T operator()() override
Definition
exprtk_game_of_life.cpp:46
Generated by
1.17.0