Skip to content

Instantly share code, notes, and snippets.

@reedacartwright
Created June 10, 2021 21:22
Show Gist options
  • Save reedacartwright/ae9bb75421aa715e28666822367cdeb7 to your computer and use it in GitHub Desktop.
Save reedacartwright/ae9bb75421aa715e28666822367cdeb7 to your computer and use it in GitHub Desktop.
Source code for finding natural wither killers in bedrock edition.
#include <random>
#include <array>
#include <iostream>
using namespace std;
using mat_t = array<array<unsigned int, 32>, 32>;
uint32_t get_seed(int d, int x, int z) {
if(d == 0) {
return x * 0x14609048 + z * 0x7ebe2d5;
} else if(d == 1) {
return x * -0x66c60af8 + z * -0xea9a42b;
}
return 0;
}
/* Wither Killer Pattern
011*k*
2**kkk
2***k*
where:
k: 4+ high bedrock
0: 2-high bedrock
1: 2-high bedrock
2: 2-high bedrock
0 must be true and either 1 or 2 must be true.
You also need room to complete placing the skulls
sss 011 ss0
sss vs sss vs ss1 vs something with 4 openings
011 sss ss1
*/
void find_wither_killers(int dim, int chunk_x, int chunk_z, int extra) {
mat_t counts;
std::mt19937 gen;
auto f = [&](int a, int b) {
gen.seed(get_seed(dim, chunk_x+a, chunk_z+b));
for(int x = 0; x < 16; ++x) {
for(int z = 0; z < 16; ++z) {
unsigned int h = 1 + (gen() % 4);
counts[x+a*16][z+b*16] = h+1;
for(int i=0; i < extra; ++i) {
gen();
}
}
}
};
auto g = [&](int x, int z, const char *p, int h) {
if(dim == 1) {
cout << "nether,";
} else {
cout << "overworld,";
}
cout << (chunk_x*16+x) << ",2," << (chunk_z*16+z);
if(dim == 0) {
cout << (extra != 2 ? ",grassy," : ",sandy,");
} else {
cout << (extra != 3 ? ",regular," : ",delta/valley,");
}
cout << p << "," << h;
cout << endl;
};
// generate 4 chunks of bedrock height
f(0,0);
f(1,0);
f(0,1);
f(1,1);
// look for wither killers
for(int x=0; x < 18; ++x) {
for(int z=0; z < 18; ++z) {
// NW skull
bool b0 = counts[x][z] <= 2;
if(!b0) {
continue;
}
// Killer Cross
bool b4 = true;
b4 = b4 && counts[x+4][z+0] >= 4;
b4 = b4 && counts[x+3][z+1] >= 4 && counts[x+4][z+1] >= 4 && counts[x+5][z+1] >= 4;
b4 = b4 && counts[x+4][z+2] >= 4;
if(!b4) {
continue;
}
// NS skulls
bool b1 = counts[x][z+1] <= 2 && counts[x][z+2] <= 2;
// WE skulls
bool b2 = counts[x+1][z] <= 2 && counts[x+2][z] <= 2;
if(!(b1 || b2)) {
continue;
}
// Height of center
int center_height = counts[x+4][z+1];
// Check for south/east soul sand
if(b1 && b2 && x < 16 && z < 16) {
bool b5 = true;
b5 = b5 && counts[x+1][z+1] <= 2 && counts[x+2][z+1] <= 2;
b5 = b5 && counts[x+1][z+2] <= 2 && counts[x+2][z+2] <= 2;
if(b5) {
g(x,z,"S",center_height);
g(x,z,"E",center_height);
}
}
// Check for west soul sand
if(b1 && z < 16 && x >= 2 && x < 18) {
bool b5 = true;
b5 = b5 && counts[x-2][z+0] <= 2 && counts[x-1][z+0] <= 2;
b5 = b5 && counts[x-2][z+1] <= 2 && counts[x-1][z+1] <= 2;
b5 = b5 && counts[x-2][z+2] <= 2 && counts[x-1][z+2] <= 2;
if(b5) {
g(x,z,"W",center_height);
}
}
// Check for north soul sand
if(b2 && x < 16 && z >= 2 && z < 18) {
bool b5 = true;
b5 = b5 && counts[x+0][z-2] <= 2 && counts[x+1][z-2] <= 2 && counts[x+2][z-2] <= 2;
b5 = b5 && counts[x+0][z-1] <= 2 && counts[x+1][z-1] <= 2 && counts[x+2][z-1] <= 2;
if(b5) {
g(x,z,"N",center_height);
}
}
}
}
}
int main(int argv, char* argc[]) {
const int sz = 256;
cout << "dim,x,y,z,biome,direction,center_height" << endl;
for(int x=-sz; x < sz; ++x) {
for(int z=-sz; z < sz; ++z) {
// overworld normal
find_wither_killers(0, x, z, 1);
// overworld rare (desert and beach biomes, mostly)
find_wither_killers(0, x, z, 2);
// nether 1.16+ (hell, warped, crimson)
// nether 1.16-1.16.40 (soulsand_valey, basalt_deltas)
find_wither_killers(1, x, z, 2);
// nether 1.16.100+ (soulsand_valley, basalt_deltas)
find_wither_killers(1, x, z, 3);
}
}
}
#include <random>
#include <array>
#include <iostream>
#include <algorithm>
using namespace std;
using mat_t = array<array<unsigned int, 32>, 32>;
uint32_t get_seed(int d, int x, int z) {
if(d == 0) {
return x * 0x14609048 + z * 0x7ebe2d5;
} else if(d == 1) {
return x * -0x66c60af8 + z * -0xea9a42b;
}
return 0;
}
/* Wither Killer Pattern
011*k*
2**kkk
2***k*
where:
k: 4+ high bedrock
0: 2-high bedrock
1: 2-high bedrock
2: 2-high bedrock
0 must be true and either 1 or 2 must be true.
You also need room to complete placing the skulls
sss 011 ss0
sss vs sss vs ss1 vs something with 4 openings
011 sss ss1
*/
int offset_s[9][2] = {
{0,0}, {1,0}, {2,0},
{0,1}, {1,1}, {2,1},
{0,2}, {1,2}, {2,2}
};
int offset_k[5][2] = {
{4,0},{3,1},{4,1},{5,1},{4,2}
};
void find_wither_killers(int dim, int chunk_x, int chunk_z, int extra) {
mat_t counts;
std::mt19937 gen;
auto f = [&](int a, int b) {
gen.seed(get_seed(dim, chunk_x+a, chunk_z+b));
for(int x = 0; x < 16; ++x) {
for(int z = 0; z < 16; ++z) {
unsigned int h = 1 + (gen() % 4);
counts[x+a*16][z+b*16] = h+1;
for(int i=0; i < extra; ++i) {
gen();
}
}
}
};
auto g = [&](int x, int z, const char *p, unsigned int h[3]) {
if(dim == 1) {
cout << "nether,";
} else {
cout << "overworld,";
}
cout << (chunk_x*16+x) << ",2," << (chunk_z*16+z);
if(dim == 0) {
cout << (extra != 2 ? ",grassy," : ",sandy,");
} else {
cout << (extra != 3 ? ",regular," : ",delta/valley,");
}
cout << p << "," << h[0] << "," << h[1] << "," << h[2];
cout << endl;
};
// generate 4 chunks of bedrock height
f(0,0);
f(1,0);
f(0,1);
f(1,1);
// look for wither killers
for(int x=0; x < 16; ++x) {
for(int z=0; z < 16; ++z) {
// Look for 3x3 space
bool has_space = std::all_of(offset_s, offset_s+9, [&](int *p) {
return counts[x+p[0]][z+p[1]] <= 2;
});
if(!has_space) {
continue;
}
// Look for Killer 1
bool k1 = std::all_of(offset_k, offset_k+5, [&](int *p) {
return counts[x+p[0]][z+p[1]] >= 4;
});
if(!k1) {
continue;
}
// Look for Killer 2
bool k2 = std::all_of(offset_k, offset_k+5, [&](int *p) {
return counts[x+2+p[0]][z+p[1]] >= 4;
});
if(!k2) {
continue;
}
// Look for Killer 3
bool k3 = std::all_of(offset_k, offset_k+5, [&](int *p) {
return counts[x+p[0]][z+2+p[1]] >= 4;
});
if(!k3) {
continue;
}
unsigned int h[3] = {
counts[x+4][z+1],
counts[x+6][z+1],
counts[x+4][z+3]
};
g(x,z,"safe", h);
}
}
}
int main(int argv, char* argc[]) {
const int sz = 1024;
cout << "dim,x,y,z,biome,direction,center_height1,center_height2,center_height3" << endl;
for(int x=-sz; x < sz; ++x) {
for(int z=-sz; z < sz; ++z) {
// overworld normal
find_wither_killers(0, x, z, 1);
// overworld rare (desert and beach biomes, mostly)
find_wither_killers(0, x, z, 2);
// nether 1.16+ (hell, warped, crimson)
// nether 1.16-1.16.40 (soulsand_valey, basalt_deltas)
find_wither_killers(1, x, z, 2);
// nether 1.16.100+ (soulsand_valley, basalt_deltas)
find_wither_killers(1, x, z, 3);
}
}
}
#include <random>
#include <array>
#include <iostream>
#include <algorithm>
using namespace std;
using mat_t = array<array<unsigned int, 32>, 32>;
uint32_t get_seed(int d, int x, int z) {
if(d == 0) {
return x * 0x14609048 + z * 0x7ebe2d5;
} else if(d == 1) {
return x * -0x66c60af8 + z * -0xea9a42b;
}
return 0;
}
/* Wither Killer Pattern
011*k*
2**kkk
2***k*
where:
k: 4+ high bedrock
0: 2-high bedrock
1: 2-high bedrock
2: 2-high bedrock
0 must be true and either 1 or 2 must be true.
You also need room to complete placing the skulls
sss 011 ss0
sss vs sss vs ss1 vs something with 4 openings
011 sss ss1
*/
/* Wither Killer Pattern
22**44*
22*4554
22**44*
where:
4: 4+ high bedrock
5: 5-high bedrock
2: 2-high bedrock
*/
int offset_s[6][2] = {
{0,0}, {1,0},
{0,1}, {1,1},
{0,2}, {1,2},
};
int offset_k[8][2] = {
{4,0},
{3,1},{4,1},{5,1},
{4,2},
};
void find_wither_killers(int dim, int chunk_x, int chunk_z, int extra) {
mat_t counts;
std::mt19937 gen;
auto f = [&](int a, int b) {
gen.seed(get_seed(dim, chunk_x+a, chunk_z+b));
for(int x = 0; x < 16; ++x) {
for(int z = 0; z < 16; ++z) {
unsigned int h = 1 + (gen() % 4);
counts[x+a*16][z+b*16] = h+1;
for(int i=0; i < extra; ++i) {
gen();
}
}
}
};
auto g = [&](int x, int z, const char *p) {
if(dim == 1) {
cout << "nether,";
} else {
cout << "overworld,";
}
cout << (chunk_x*16+x) << ",2," << (chunk_z*16+z);
if(dim == 0) {
cout << (extra != 2 ? ",grassy," : ",sandy,");
} else {
cout << (extra != 3 ? ",regular," : ",delta/valley,");
}
cout << p << endl;
};
// generate 4 chunks of bedrock height
f(0,0);
f(1,0);
f(0,1);
f(1,1);
// look for wither killers
for(int x=0; x < 16; ++x) {
for(int z=0; z < 16; ++z) {
// Look for 2x3 space
bool has_space = std::all_of(offset_s, offset_s+6, [&](int *p) {
return counts[x+p[0]][z+p[1]] <= 2;
});
if(has_space) {
// Look for Killer 1
bool k1 = std::all_of(offset_k, offset_k+5, [&](int *p) {
return counts[x+p[0]][z+p[1]] >= 4;
});
k1 = k1 && counts[x+4][z+1] >= 5;
// Look for Killer 2
bool k2 = std::all_of(offset_k, offset_k+5, [&](int *p) {
return counts[x+p[0]+1][z+p[1]] >= 4;
});
k2 = k2 && counts[x+5][z+1] >= 5;
if(k1 && k2) {
g(x,z,"AS");
}
}
// Look for 3x2 space
has_space = std::all_of(offset_s, offset_s+6, [&](int *p) {
return counts[x+p[1]][z+p[0]] <= 2;
});
if(has_space) {
// Look for Killer 1
bool k1 = std::all_of(offset_k, offset_k+5, [&](int *p) {
return counts[x+p[0]][z+p[1]] >= 4;
});
k1 = k1 && counts[x+4][z+1] >= 5;
// Look for Killer 2
bool k2 = std::all_of(offset_k, offset_k+5, [&](int *p) {
return counts[x+p[0]][z+p[1]+1] >= 4;
});
k2 = k2 && counts[x+4][z+2] >= 5;
if(k1 && k2) {
g(x,z,"AE");
}
}
}
}
}
int main(int argv, char* argc[]) {
const int sz = 256;
cout << "dim,x,y,z,biome,direction" << endl;
for(int x=-sz; x < sz; ++x) {
for(int z=-sz; z < sz; ++z) {
// overworld normal
find_wither_killers(0, x, z, 1);
// overworld rare (desert and beach biomes, mostly)
find_wither_killers(0, x, z, 2);
// nether 1.16+ (hell, warped, crimson)
// nether 1.16-1.16.40 (soulsand_valey, basalt_deltas)
find_wither_killers(1, x, z, 2);
// nether 1.16.100+ (soulsand_valley, basalt_deltas)
find_wither_killers(1, x, z, 3);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment