C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
Classes | Functions
exprtk_game_of_life.cpp File Reference
#include <algorithm>
#include <array>
#include <chrono>
#include <cstdio>
#include <random>
#include <string>
#include <thread>
#include "exprtk.hpp"
Include dependency graph for exprtk_game_of_life.cpp:

Go to the source code of this file.

Classes

struct  rnd_01< T >
 

Functions

template<typename T >
void game_of_life ()
 
int main ()
 

Function Documentation

◆ game_of_life()

template<typename T >
void game_of_life ( )

Definition at line 56 of file exprtk_game_of_life.cpp.

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;
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}

◆ main()

int main ( )

Definition at line 232 of file exprtk_game_of_life.cpp.

233{
234 game_of_life<double>();
235 return 0;
236}