Unlike cgol there isn't a global rule that determines cell behaviour, but rather a grid of rules is layed on top of the grid of cells. For every cell there is a corresponding rule-cell that contains the rule this cell follows.
The rules are enumerated from BS to B012345678S012345678 as 18 bit binary numbers (9 bits for B and 9 bits for S), counting all totalistic rules from 0 to 262143. For example, B0S1 would be 000000001000000010 (514 in base 10).
So this is how it works:
Two grids, a statespace and a rulespace.
To advance to the next generation, every rulecell checks a 3x3 area of rulecells around it. It's new value is determined by the bitwise XOR (^) of all the rulecells that correspond to living cells in the statespace, including the value of the rulecell itself.
Then every cell in the statespace evolves according to the rule in its corresponding rulecell.
If the statespace is filled with random dead and alive cells and the rulespace is filled with random rules, pretty much always chaos ensures and fills everything with noise. We assumed this had to do with B1 rules (B0 rules are irrelevant because rulecells with no living neighbors that are dead get assigned 0 as rule). So we started restricting the amount of randomness that was used to generate the rulespace of generation 0. We found some very interesting things.
The first discovery was when the ruleset B01S23 was disallowed a lot of still life (not surprising with S0 possible), spaceships, puffers, rakes and replicating patterns formed. We called it NAND 1548 for the time being because you can generate the rulespace by generating a random 18 bit number and taking it bitwise NAND (&~) with 1548.
Another interesting variant was disallowing B01S236, as well as some others. Both NAND B01S23 and NAND B01S236 seem to only contain spaceships that travel with light space, but no proof for that yet. NAND B136S167 contains at least one diagonal spaceship with 3c28 and NAND B013456S1678 contains at least one knightship with period 7 and speeds of c7 and 2c7 in the vertical and horizontal axis, but non-photon orthogonal spaceships exist as well in this rule.
When soup is subjected to this, many structures form. Single structures are often a lot more restricted than just the rules that are not allowed by the NAND.
It should be noted that a c1 spaceship formed in NAND B01S23 and a 3c28 diagonal glider formed in NAND B136S167 can fly side by side in the same grid and even hit each other and interact. The NAND merely restricts the initial conditions of the soup.
We believe this is a class 4 automaton.
In NAND B01S23 and NAND B01S236 we have found so far:
- oscillators of various periods
- 4p2 orthogonal spaceship guns of firing period 16, 32, but all powers of 2 are possible after that because colliding mechanics allow easily dividing the frequency by 2
- guns that shoot sometimes more than one spaceship with periods of 80, 180, 24 and 120, as well as different spaceships with p14
- NOT-gates, OR-gates, AND-gates, a set-reset latch
- spaceship doublers and quadruplers
- by carefully colliding smaller spaceships we have created factories for ships with periods 2, 4, 8, 10, 14, 16
- and spaceship-collision synthesis for some oscillators
- rakes and backrakes of various periods
- puffers producing oscillators
since there seems to be a limit on how many images I can attach in one post, I have uploaded most of the gifs here: https://imgur.com/a/HvTFv6X
Mod edit: files mirrored here: The data files for most of these can be found in the /sci/ thread.
Note that all of this was found mainly by hand, and the automaton itself is not older than about a week.
I'm using self-written spaghetti code at the moment, but at least it works. I'm also constantly modifying it as I go. The current source code can be found here, just keep in mind that it is bad: https://pastebin.com/bzy93FK0
Mod edit: code copied below:
Code: Select all
int[][] tab = new int[200][200];
int[][] tab2 = new int[200][200];
int[][] rtab = new int[200][200];
int[][] rtab2 = new int[200][200];
int[][] ptab = new int[200][200];
int[][] prtab = new int[200][200];
int[][] ctab = new int[200][200];
int[][] crtab = new int[200][200];
int[][][] ship = new int[80][20][20];
int[][][] rship = new int[80][20][20];
int n = 34;
int offset = -3;
int j = 0;
int r;
String temp, slog, onscreenconsole;
int stop = 0;
int px1, px2, py1, py2, selection, mark, record, frames, random, oneframe, delayon, periodb, period, movemode, copied, cx1, cx2, cy1, cy2, cmode, cf, cf2, cframes, tmp2, diff;
float sf = 1;
float sx = 0;
float sy = 0;
//String[] readinglist = {"37020_27290_p120gg.txt", "47834_60569_p60.txt", "28621_27721_p120gg_monodirectional.txt",
//"71195_16368_glidersideways.txt", "57758_85936_p128_gun.txt", "57758_76359_p180_gun.txt", "57758_66730_p32_gun.txt",
//"39469_318789_p16_gun_tiny.txt", "41605_70452_p32_gun_tiny_v2.txt", "41605_292692_latch_prototype3.txt", "29256_67675.txt"}; //importable files
String[] readinglist = {"53644_830_knightship.txt", "51943_1138_rake_p24_makes_4p2b.txt", "11932_3499_backrake_p4_makes_4p2b.txt", "95440_19926_p16_wide_factory.txt", "60553_35248_p16_shipfactory_with_p32.txt", "64335_28312_p4_shipfactory_v2_p32.txt", "4023_26238_coolshipfarm_prototype.txt", "44894_49376_p14_factory_with_p64.txt",
"41605_70452_p32_gun_tiny_v2.txt", "9170_14818_squidfarm.txt", "4023_2959_p32_squidfarm.txt", "47822_123223_shipfactory_almost.txt", "81030_49112_p8_shipfactory.txt"};
//String[] readinglist = {"73923_29625_squidcollisions.txt", "73923_46452_squidcollisions2.txt", "73923_50185_squidcollisions3.txt",
//"73923_52734_squidcollisions4.txt", "73923_58820_squidcollisions5.txt", "73923_62781_squidcollisions6.txt"};
String[] shippinglist = {"shiplist.txt"};
int imported = 0;
void setup() {
size(1000, 1000);
background(0);
noStroke();
selection = 0;
mark = 0;
record = 0;
frames = 0;
oneframe = 0;
random = int(random(0,100000));
delayon = 0;
periodb = 0;
period = 0;
movemode = 0;
copied = 0;
cmode = 0;
cf = 0;
cf2 = 0;
tmp2 = 0;
slog = "";
px1 = 0;
py1 = 0;
onscreenconsole = "";
cframes = 70;
cx1 = 0; cx2 = 0; cy1 = 0; cy2 = 0;
/*for (int j = 0; j < ship[0][0].length; j++) {
for (int i = 0; i < ship[0].length; i++) {
for (int k = 0; k < ship.length; k++) {
ship[k][i][j] = 0;
rship[k][i][j] = 0;
}
}
} */
//print(convertRules(148269) + " " + convertRules(92209) + " " + convertRules(207644));
//delay(10000);
scale(sf);
translate(sx, sy);
resetfield();
//r = replacerule();
//r = 91491;
r = 0;
}
void draw() {
background(0);
scale(sf);
translate(sx, sy);
noFill();
stroke(255);
rect(-1, -1, 1002, 1002);
noStroke();
if (delayon == 1) {delay(100);}
j++;
if (stop == 0) {
make();
frames++;
if (record == 1) {
save(random + "_" + frames + ".png");
}
if (periodb == 1) {
int diff = 0;
for (int i1 = 0; i1 < 200; i1++) {
for (int i2 = 0; i2 < 200; i2++) {
if (ptab[i1][i2] != tab[i1][i2] || prtab[i1][i2] != rtab[i1][i2]) {
diff = 1;
}
}
}
period++;
if (diff == 0) {
print("period found: " + period + "\n");
periodb = 0;
}
}
if (cmode == 1) {
cf++;
if (cf%cframes == 1) {
//Hier muss die neue Anordnung generiert werden
for (int i1 = 0; i1 < 200; i1++) {
for (int i2 = 0; i2 < 200; i2++) {
tab[i1][i2] = 0;
rtab[i1][i2] = 0;
}
}
slog += " " + str(tmp2) + " " + diff + "\n";
println(slog.split("\n")[slog.split("\n").length - 1]);
/*if (diff > 0) {
println(slog.split("\n")[slog.split("\n").length - 1]);
}*/
//int[][] tmp = {{0, 80+1, 80+0, 0, 0}, {1, 80+1+cf2%6, 80+4+cf2/6, 2, 0}};
//int[][] tmp = {{22, 80+cf2%10, 80-cf2/10%6, 0, 0}, {22+cf2/360%2, 80, 80+3, 2, 0}, {22+cf2/720%2, 80+4+cf2/60%6, 80, 1, 0}};
//int[][] tmp = {{24, 87, 76, 0, 0}, {24, 80, 83, 2, 0}};
//int[][] tmp = {{1, 80, 77, 0, 0}, {24, 78, 82, 3, 0}};
//int[][] tmp = {{0, 85+0, 85+0, 3, 0}, {0, 85+2+cf2%7, 85-2-cf2/7%7, 0, 0}, {0, 85+2+cf2/49, 85+2, 2, 0}};
int[][] tmp = {{24, 80+cf2%10, 80-cf2/10%6, 0, 0}, {24+cf2/60, 80-4, 80+4, 3, 0}};
//slist [zeile schiffnummer], dann [0] art/phase, [1] dx, [2] dy, [3] drehung, [4] gespiegelt
slog += "{{";
for (int i = 0; i < tmp.length; i++) {
for (int j = 0; j < tmp[0].length; j++) {
slog += tmp[i][j] + ", ";
}
slog = slog.substring(0, slog.length() - 2) + "}, {";
}
slog = slog.substring(0, slog.length() - 3) + "}";
gcol(tmp);
tmp2 = 1;
cf2++;
}
diff = 0;
for (int i1 = 0; i1 < 200; i1++) { //(int i1 = 0; i1 < 200; i1++)
for (int i2 = 0; i2 < 200; i2++) { //(int i2 = 0; i2 < 200; i2++)
diff += tab[i1][i2];
}
}
if (diff == 0) {
cf += cframes - cf%cframes;
tmp2 = 0;
}
}
} else {
//n = rtab[max(0, min(mouseX/5, 199))][max(0, min(mouseY/5, 199))];
for (int y = 0; y < 200; y++){
for (int x = 0; x < 200; x++){
noStroke();
fill(color(255*tab[x][y]));
rect(x*5, y*5, 5, 5);
if (rtab[x][y] == 0 && mark == 1) {
fill(255, 255, 0);
rect(x*5+1, y*5+1, 3, 3);
}
}
}
stroke(255, 0, 0);
strokeWeight(1/sf);
line(mouseX/sf-sx,-sy,mouseX/sf-sx, height/sf-sy);
line(-sx,mouseY/sf-sy,width/sf-sx,mouseY/sf-sy);
noStroke();
textAlign(LEFT);
textSize(20/sf);
fill(255);
fill(255);
text("(" + px1 + ", " + py1 + ") " + str(ceil(px2/5-px1/5)+1) + "x" + str(ceil(py2/5-py1/5)+1), (-sx+10/sf), (-sy+30/sf));
noStroke();
if (selection == 1) {
noFill();
stroke(255);
rect(5*(px1/5), 5*(py1/5), 5*(px2/5-px1/5)+5, 5*(py2/5-py1/5)+5);
noStroke();
}
}
if (oneframe == 1) {
stop = 1;
oneframe = 0;
}
//print(j + "\n");
//if(j%150==0){r = replacerule(); print(r + "\n"); resetfield();}//save("k2_" + str(j) + ".png");}
}
void make() {
for (int y = 0; y < 200; y++){
for (int x = 0; x < 200; x++){
rtab2[x][y] = r;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if(tab[(x+i+200)%200][(y+j+200)%200] == 1){
rtab2[x][y] = rtab2[x][y]^rtab[(x+i+200)%200][(y+j+200)%200];
}
}
}
//rtab2[x][y] = rtab2[x][y]&~unbinary("000000011000001100"); //the best xoxo
//rtab2[x][y] = rtab2[x][y]&~unbinary("000000011000001010");
//rtab2[x][y] = rtab2[x][y]&~unbinary("000000011000010101");
//rtab2[x][y] = rtab2[x][y]&~4108;
}
}
for (int y = 0; y < 200; y++){
for (int x = 0; x < 200; x++){
n = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
n += tab[(x+i+200)%200][(y+j+200)%200];
}
}
n -= tab[x][y];
rtab[x][y] = rtab2[x][y];
//rtab[x][y] = 4108;
if (tab[x][y] == 0) {
tab2[x][y] = rule(n, rtab[x][y]>>9);
} else {
tab2[x][y] = rule(n, rtab[x][y]&1023);
}
//print(r + "\n");
}
}
for (int y = 0; y < 200; y++){
for (int x = 0; x < 200; x++){
tab[x][y] = tab2[x][y];
fill(color(255*tab[x][y]));
//fill(255*((rtab[x][y]>>13)%2), 0, 0);
//fill(color(31*((rtab[x][y]>>9)%8), 31*((rtab[x][y]>>12)%8), 31*((rtab[x][y]>>15)%8)));
//fill(color(31*((rtab[x][y]>>0)%8), 31*((rtab[x][y]>>3)%8), 31*((rtab[x][y]>>15)%6)));
//if (rtab[x][y] != "00000000000000000000000000000000") {print(rtab[x][y] + "\n");}
rect(x*5, y*5, 5, 5);
//fill(color(31*((rtab[x][y]>>0)%8), 31*((rtab[x][y]>>3)%8), 31*((rtab[x][y]>>15)%6)));
//rect(x*5, y*5, 5, 5);
//fill(color(31*((rtab[x][y]>>9)%8), 31*((rtab[x][y]>>12)%8), 31*((rtab[x][y]>>15)%8)));
//rect(x*5+1, y*5+1, 3, 3);
//fill(color(255*tab[x][y]));
//rect(x*5+2, y*5+2, 1, 1);
}
}
}
int rule(int a, int rule) {
return(rule >> a)%2;
}
int replacerule() {
return int(random(0,262144))%262144;
}
void resetfield() {
//randomSeed(226);
print("Seed: " + j + "\n");
//n = replacerule();
for (int y = 0; y < 200; y++){
for (int x = 0; x < 200; x++){
tab[x][y] = 0;
rtab[x][y] = replacerule();
fill(color(255*tab[x][y]));
rect(x*5, y*5, 5, 5);
//print(tab[i][0]);
rtab[x][y] = rtab[x][y]&~unbinary("000000011001001100");
//rtab[x][y] = rtab[x][y]&~unbinary("000000011000001010");
//rtab[x][y] = rtab[x][y]&~unbinary("000000011000010101");
//rtab[x][y] = rtab[x][y]&~unbinary("000000011000010110");
//rtab[x][y] = rtab[x][y]&~unbinary("001011011111000010"); //B01346S1678
//rtab[x][y] = rtab[x][y]&~n;
//rtab[x][y] = rtab[x][y]&~38018;
}
}
for (int y = 70; y < 130; y++){
for (int x = 70; x < 130; x++){
tab[x][y] = int(random(0,2))%2;
fill(color(255*tab[x][y]));
rect(x*5, y*5, 5, 5);
//print(tab[i][0]);
}
}
}
void mousePressed() {
if (mouseButton == LEFT) {
px1 = int(mouseX/sf-sx);
py1 = int(mouseY/sf-sy);
selection = 0;
} else {
resetfield();
}
}
void keyPressed() {
if (movemode == 0) {
if (key == 'p') {
stop = (stop + 1)%2;
if (stop == 0) {
print("Unpaused\n");
} else {
print("Paused\n");
}
}
if (key == 'n') {
mark = (mark + 1)%2;
if (mark == 0) {
print("nullrules hidden\n");
} else {
print("nullrules shown\n");
}
}
if (key == 'd') {
delayon = (delayon + 1)%2;
if (delayon == 0) {
print("Delay off\n");
} else {
print("Delay on\n");
}
}
if (key == 'r') {
record = (record + 1)%2;
if (record == 0) {
print("recording stopped\n");
} else {
print("recording started\n");
}
}
if (key == 's') {
PrintWriter output;
output = createWriter(random + "_" + j + ".txt");
//output.print("Test");
int temp3 = 0;
String bb = " rulespace \n{";
for (int i = py1/5; i <= py2/5; i++) {
bb += "\n{";
for (int j = px1/5; j <= px2/5; j++) {
bb += " ".substring(0, 6-str(rtab[j][i]).length()) + rtab[j][i] + ", ";
temp3 = temp3|rtab[j][i];
}
bb = bb.substring(0, bb.length() - 2) + "},";
}
bb = bb.substring(0, bb.length() - 1) + "\n};\n\n statespace \n{";
for (int i = py1/5; i <= py2/5; i++) {
bb += "\n{";
for (int j = px1/5; j <= px2/5; j++) {
bb += tab[j][i] + ", ";
}
bb = bb.substring(0, bb.length() - 2) + "},";
}
bb = bb.substring(0, bb.length() - 1) + "\n};";
temp3 = 524287-temp3;
bb = "maximum restriction NAND " + convertRules(temp3) + "\n\n" + bb;
//print("NAND " + convertRules(temp3) + "\n");
output.print(bb);
//print(bb);
print("selection saved!\n");
output.flush();
output.close();
}
if (keyCode == BACKSPACE) {
for (int i = py1/5; i <= py2/5; i++) {
for (int j = px1/5; j <= px2/5; j++) {
//print(j + " " + i + "\n");
if (i < 200 && j < 200) {
tab[j][i] = 0;
rtab[j][i] = 0;
}
}
}
}
if (keyCode == ENTER) {
for (int i = 0; i < 200; i++) {
for (int j = 0; j < 200; j++) {
//print(j + " " + i + "\n");
if (i > py2/5 || i < py1/5 || j > px2/5 || j < px1/5) {
tab[j][i] = 0;
rtab[j][i] = 0;
}
}
}
}
if (keyCode == RIGHT) {
oneframe = 1;
stop = 0;
}
if (key == 'z') { //period
periodb = (periodb + 1)%2;
if (periodb == 0) {
print("period measurement stopped\n");
} else {
print("period measurement started\n");
period = 0;
for (int i = 0; i < 200; i++) {
for (int j = 0; j < 200; j++) {
ptab[i][j] = tab[i][j];
prtab[i][j] = rtab[i][j];
}
}
}
}
if (key == 'c') { //copy
copied = 1;
print("copied\n");
for (int i = py1/5; i <= py2/5; i++) {
for (int j = px1/5; j <= px2/5; j++) {
//print(j + " " + i + "\n");
if (j < 200 && i < 200) {
ctab[j][i] = tab[j][i];
crtab[j][i] = rtab[j][i];
}
}
}
cx1 = px1; cx2 = px2; cy1 = py1; cy2 = py2;
}
if (key == 'v') { //paste
if (copied == 1) {
print("pasted\n");
for (int i = cy1/5; i <= cy2/5; i++) {
for (int j = cx1/5; j <= cx2/5; j++) {
//print(j + " " + i + "\n");
if (j < 200 && i < 200 && j-cx1/5+px1/5 < 200 && i-cy1/5+py1/5 < 200 && j-cx1/5+px1/5 >= 0 && i-cy1/5+py1/5 >=0) {
tab[j-cx1/5+px1/5][i-cy1/5+py1/5] = ctab[j][i];
rtab[j-cx1/5+px1/5][i-cy1/5+py1/5] = crtab[j][i];
}
}
}
}
}
if (key == '5') {
int tmp4 = 0;
for (int i = 0; i < 200; i++) {
for (int j = 0; j < 200; j++) {
tmp4 += tab[i][j];
}
}
println("cell count: " + tmp4);
}
if (key == ' ') { //rotate 90 CW
println("Clipboard rotated");
ctab = rotatecw(ctab);
crtab = rotatecw(crtab);
int tmp = cx1;
cx1 = 1000 - cy1;
cy1 = tmp;
tmp = cx2;
cx2 = 1000 - cy2;
cy2 = tmp;
tmp = cx1;
cx1 = cx2;
cx2 = tmp;
}
if (key == 'm') { //mirror left/right
println("Clipboard mirrored");
ctab = mirrorlr(ctab);
crtab = mirrorlr(crtab);
int tmp = cx1;
cx1 = 1000 - cx2;
cx2 = 1000 - tmp;
}
if (key == 'i') {
String[] lines = loadStrings(readinglist[imported%readinglist.length]);
println("loaded file " + readinglist[imported%readinglist.length] + " (" + str(imported%readinglist.length+1) + "/" + readinglist.length + ")");
imported++;
boolean read = false;
String a = "";
String b = "";
int temp1, temp2;
for (int i = 0 ; i < lines.length; i++) {
if (read) {
a += lines[i];
}
if (lines[i].contains("rulespace")) {
read = true;
} else if (lines[i].contains(";")) {
read = false;
}
}
for (int i = 0 ; i < lines.length; i++) {
if (read) {
b += lines[i];
}
if (lines[i].contains("statespace")) {
read = true;
} else if (lines[i].contains(";")) {
read = false;
}
}
a = a.replace(";", "").replace(" ", "").replace("},{", "s").replace(",", "c").replace("}", "").replace("{", "");
b = b.replace(";", "").replace(" ", "").replace("},{", "s").replace(",", "c").replace("}", "").replace("{", "");
temp1 = 0;
temp2 = 0;
//int[][] tab1 = new int[20][20];
//int[][] tab2 = new int[20][20];
for (String i : a.split("s")) {
for (String j : i.split("c")) {
crtab[temp1][temp2] = int(j);
temp1++;
}
temp2++;
temp1 = 0;
}
temp2 = 0;
for (String i : b.split("s")) {
for (String j : i.split("c")) {
ctab[temp1][temp2] = int(j);
temp1++;
}
temp2++;
temp1 = 0;
}
cx1 = 0;
cx2 = 5*a.split("s")[0].split("c").length;
cy1 = 0;
cy2 = 5*a.split("s").length;
copied = 1;
}
if (key == 'q') { ///collision mode
cmode = (cmode+1)%2;
if (cmode == 1) {
cf = 0;
cf2 = 0;
print("collision mode started\n");
} else {
print("collision mode stopped\n");
//save slog
/*cmode = 0;
PrintWriter output;
output = createWriter("collision_log_" + random + "_" + j + ".txt");
output.print(slog.substring(3, slog.length()));
output.flush();
output.close();
print("collision log saved!\n");*/
}
}
if (key == 'w') { //save ship
print("saved ship\n");
for (int i = py1/5; i <= py2/5; i++) {
for (int j = px1/5; j <= px2/5; j++) {
//print(j + " " + i + "\n");
if (j < 200 && i < 200) {
ship[0][j-px1/5][i-py1/5] = tab[j][i];
rship[0][j-px1/5][i-py1/5] = rtab[j][i];
}
}
}
ship[0][int(mouseX/sf-sx)/5 - px1/5][int(mouseY/sf-sy)/5 - py1/5] += 2;
}
if (key == 'e') { //import ships
String[] lines = loadStrings(shippinglist[0]);
println("loaded shipping list " + shippinglist[0]);
boolean read;
String a;
String b;
int temp1, temp2;
int c = 0;
int d = 0;
while (c < lines.length) {
read = false;
a = "";
b = "";
for (int i = c ; i < lines.length; i++) {
if (read) {
a += lines[i];
}
if (lines[i].contains("rulespace")) {
read = true;
} else if (lines[i].contains(";") && read) {
read = false;
break;
}
}
for (int i = c ; i < lines.length; i++) {
if (read) {
b += lines[i];
}
if (lines[i].contains("statespace")) {
read = true;
} else if (lines[i].contains(";") && read) {
read = false;
c = i + 1;
break;
}
}
a = a.replace(";", "").replace(" ", "").replace("},{", "s").replace(",", "c").replace("}", "").replace("{", "");
b = b.replace(";", "").replace(" ", "").replace("},{", "s").replace(",", "c").replace("}", "").replace("{", "");
temp1 = 0;
temp2 = 0;
//int[][] tab1 = new int[20][20];
//int[][] tab2 = new int[20][20];
//println(d + " " + b);
for (String i : a.split("s")) {
for (String j : i.split("c")) {
rship[d][temp1][temp2] = int(j);
temp1++;
//rship[0][0][0] = 1;
}
temp2++;
temp1 = 0;
}
temp2 = 0;
for (String i : b.split("s")) {
for (String j : i.split("c")) {
ship[d][temp1][temp2] = int(j);
temp1++;
}
temp2++;
temp1 = 0;
}
d++;
}
for (int j = 0; j < ship[0][0].length; j++) {
for (int i = 0; i < ship[0].length; i++) {
for (int k = 0; k < 1; k++) {
//print(ship[k][i][j]);
//print(rship[k][i][j]);
}
}
}
}
} else { //movemode
if (keyCode == RIGHT) {
for (int i = py1/5; i <= py2/5; i++) {
for (int j = px2/5; j >= px1/5; j--) {
//print(j + " " + i + "\n");
tab[(j+1+200)%200][(i+200)%200] = tab[(j+200)%200][(i+200)%200];
rtab[(j+1+200)%200][(i+200)%200] = rtab[(j+200)%200][(i+200)%200];
}
}
px1 += 5;
px2 += 5;
if (px1 >= 1000 && px2 >= 1000) {
px1 = px1%1000;
px2 = px2%1000;
}
}
if (keyCode == LEFT) {
for (int i = py1/5; i <= py2/5; i++) {
for (int j = px1/5; j <= px2/5; j++) {
//print(j + " " + i + "\n");
tab[(j-1+200)%200][(i+200)%200] = tab[(j+200)%200][(i+200)%200];
rtab[(j-1+200)%200][(i+200)%200] = rtab[(j+200)%200][(i+200)%200];
}
}
px1 -= 5;
px2 -= 5;
if (px1 < 0 && px2 < 0) {
px1 += 1000;
px2 += 1000;
}
}
if (keyCode == DOWN) {
for (int i = py2/5; i >= py1/5; i--) {
for (int j = px1/5; j <= px2/5; j++) {
//print(j + " " + i + "\n");
tab[(j+200)%200][(i+1+200)%200] = tab[(j+200)%200][(i+200)%200];
rtab[(j+200)%200][(i+1+200)%200] = rtab[(j+200)%200][(i+200)%200];
}
}
py1 += 5;
py2 += 5;
if (py1 >= 1000 && py2 >= 1000) {
py1 = py1%1000;
py2 = py2%1000;
}
}
if (keyCode == UP) {
for (int i = py1/5; i <= py2/5; i++) {
for (int j = px1/5; j <= px2/5; j++) {
//print(j + " " + i + "\n");
tab[(j+200)%200][(i-1+200)%200] = tab[(j+200)%200][(i+200)%200];
rtab[(j+200)%200][(i-1+200)%200] = rtab[(j+200)%200][(i+200)%200];
}
}
py1 -= 5;
py2 -= 5;
if (py1 < 0 && py2 < 0) {
py1 += 1000;
py2 += 1000;
}
}
}
if (key == 'x' && selection == 1) {
movemode = (movemode + 1)%2;
if (movemode == 0) {
print("move mode deactivated\n");
} else {
print("move mode activated\n");
}
}
if (key == '+') {
sf *= 1.2;
sx = -px1 + mouseX/sf;
sy = -py1 + mouseY/sf;
}
if (key == '-') {
sf /= 1.2;
sx = -px1 + mouseX/sf;
sy = -py1 + mouseY/sf;
}
if (key == '*') {
sf = 1;
sx = 0;
sy = 0;
}
if (key == '0') {
sx = -px1 + mouseX/sf;
sy = -py1 + mouseY/sf;
}
}
void mouseReleased() {
if (mouseButton == LEFT) {
px2 = int(mouseX/sf-sx);
py2 = int(mouseY/sf-sy);
int tmp3;
tmp3 = px1;
px1 = min(px1, px2);
px2 = max(tmp3, px2);
tmp3 = py1;
py1 = min(py1, py2);
py2 = max(tmp3, py2);
selection = 1;
}
}
String convertRules(int a) {
String temp2;
temp2 = "B";
for (int i = 0; i < 9; i++) {
if(((a>>9)>>i)%2 == 1){
temp2 += i;
}
}
temp2 += "S";
for (int i = 0; i < 9; i++) {
if((a>>i)%2 == 1){
temp2 += i;
}
}
return temp2;
}
int[][] rotatecw(int[][] matrix) {
int n = matrix.length;
int res[][] = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
res[i][j] = matrix[j][n - i - 1];//matrix[n - j - 1][i];
}
}
return res;
}
int[][] mirrorlr(int[][] matrix) {
int n = matrix.length;
int res[][] = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
res[i][j] = matrix[n-i-1][j];//matrix[n - j - 1][i];
}
}
return res;
}
void gcol(int[][] slist) {
//slist [zeile schiffnummer], dann [0] art/phase, [1] dx, [2] dy, [3] drehung, [4] gespiegelt
int pcx, pcy;
int[][] tship;
int[][] trship;
for (int line = 0; line < slist.length; line++) {
//slist[line]
tship = ship[slist[line][0]];
trship = rship[slist[line][0]];
if (slist[line][4] == 1) {
tship = mirrorlr(tship);
trship = mirrorlr(trship);
}
for (int i = 0; i < slist[line][3]; i++) {
tship = rotatecw(tship);
trship = rotatecw(trship);
}
pcx = 0; pcy = 0;
for (int j = 0; j < tship[0].length; j++) {
for (int i = 0; i < tship.length; i++) {
if (tship[i][j]>>1 == 1) {
pcx = i; pcy = j;
}
}
}
for (int j = 0; j < tship[0].length; j++) {
for (int i = 0; i < tship.length; i++) {
if (tship[i][j]>>1 == 1) {
pcx = i; pcy = j;
}
}
}
int tx, ty;
for (int j = 0; j < tship[0].length; j++) {
for (int i = 0; i < tship.length; i++) {
tx = i-pcx+slist[line][1];
ty = j-pcy+slist[line][2];
if (tx >= 0 && tx < 200 && ty >= 0 && ty < 200 && (tship[i][j]%2 == 1 || trship[i][j] != 0)) {
tab[tx][ty] = tship[i][j]%2;
rtab[tx][ty] = trship[i][j];
}
}
}
}
return;
}