-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwolfram.cpp
More file actions
167 lines (148 loc) · 4.68 KB
/
wolfram.cpp
File metadata and controls
167 lines (148 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <iostream>
#include <limits.h>
#include <stdio.h>
#include <ncurses.h>
#include "wolfram.h"
#include "main.h"
// Binary conversion of decimal user input in future
int ruleset[8]; //= { 0, 1, 0, 1, 1, 0, 1, 0};
int wolframBoard[BOARD_Y][BOARD_X] = { };
int gen;
void automaton() {
//1 in the middle for the traditional initial state
wolframBoard[0][BOARD_X/2] = 1;
//Get user's input, convert to binary and initialize the rule set array
handle_user_input();
//Run the ruleset on the initial state
while(gen < BOARD_Y - 1) {
find_next_generation();
}
print_generations();
mvprintw((BOARD_Y), 0, "Press any key to continue or ESC to quit.");
refresh();
switch(getch()) {
case 27:
clear();
menu();
return;
}
gen = 0;
clear();
automaton();
}
void print_generations() {
clear();
for (int i = 0; i < BOARD_Y; i++) {
for (int j = 0; j < BOARD_X; j++) {
if (wolframBoard[i][j] == 0) {
mvprintw(i, j, " ");
}
else {
mvprintw(i, j, "X");
}
}
cout << endl;
}
refresh();
}
void find_next_generation() {
int left, center, right;
//Gets environment's values while ignoring edge cases. (0's instead)
for (int i = 0; i < BOARD_X; i++) {
left = wolframBoard[gen % BOARD_Y][(i + BOARD_X - 1) % BOARD_X];
center = wolframBoard[gen % BOARD_Y][i];
right = wolframBoard[gen % BOARD_Y][(i + 1) % BOARD_X];
wolframBoard[(gen + 1) % BOARD_Y][i] = rule(left, center, right);
}
gen++;
}
//The next generation of a cell is dependent on the current generation's environment.
//The environment of each cell is that of itself and its two adjacent neighbors.
//That's three cells to account for that could be one of two states.
//That's 3 bits in binary that together can produce 8 different values.
//Every cell's environment can influence the future generation in 8 different ways.
//This function points to the ruleset array for the predetermined future state determined by the current environment's binary representation.
int rule (int a, int b, int c) {
if (a == 1 && b == 1 && c == 1) {
return ruleset[7];
}
if (a == 1 && b == 1 && c == 0) {
return ruleset[6];
}
if (a == 1 && b == 0 && c == 1) {
return ruleset[5];
}
if (a == 1 && b == 0 && c == 0) {
return ruleset[4];
}
if (a == 0 && b == 1 && c == 1) {
return ruleset[3];
}
if (a == 0 && b == 1 && c == 0) {
return ruleset[2];
}
if (a == 0 && b == 0 && c == 1) {
return ruleset[1];
}
//else (a == 0 && b == 0 && c == 0) {
return ruleset[0];
//}
}
void handle_user_input()
{
clear();
mvprintw(3, 21, "-------------------------------------");
mvprintw(4, 21, "WOLFRAM ELEMENTARY CELLULAR AUTOMATON");
mvprintw(5, 21, "-------------------------------------");
mvprintw(7, 10, "Rule 30, 60, 90, 105, 182, 147 are interesting generations.");
mvprintw(9, 24, "Type in the integer of the rule");
mvprintw(10, 29, "to see the evolution.");
mvprintw(11, 17, "(Numbers 0 - 255 are all possible rule sets)");
mvprintw(13, 29, "Then press press ENTER.");
mvprintw(14, 34, "('Q' to QUIT)");
mvprintw(16, 15, "These generations would continue to evolve infinitely");
mvprintw(17, 21, "But ... our terminal is only so big!");
refresh();
//Trick to get string of input from user rather than the typical ncurses single char ASCII value
string input;
//Terminal does the editing
nocbreak();
echo();
//Reads from buffer after ENTER
int ch = getch();
while (ch != '\n') {
input.push_back(ch);
ch = getch();
}
//Fix ncurses settings
raw();
noecho();
if (input == "Q") {
clear();
menu();
return;
}
//Error handling the user's input string
bool only_numbers = (input.find_first_not_of("0123456789") == string::npos);
if (!only_numbers) {
mvprintw(20, 12, "!!!!!!Make sure to type a number between 0 and 255!!!!!!");
handle_user_input();
return;
}
//Converts the user's string to int
int x = stoi(input);
if (x < 0 || x > 255) {
mvprintw(20, 12, "!!!!!!Make sure to type a number between 0 and 255!!!!!!");
handle_user_input();
return;
}
//Grabs the binary value from the int and inserts into array
for (int i = sizeof(x) * CHAR_BIT; i--; )
{
if (i < 8) {
char temp = ('0' + ((x >> i) & 1));
int x = temp - '0';
ruleset[i] = x;
}
}
}