Skip to content

Instantly share code, notes, and snippets.

@jbzdarkid
Created February 25, 2021 05:40
Show Gist options
  • Save jbzdarkid/89a108fbd7f2bfa32626d78b7d0b70e7 to your computer and use it in GitHub Desktop.
Save jbzdarkid/89a108fbd7f2bfa32626d78b7d0b70e7 to your computer and use it in GitHub Desktop.
The Witness logic for handling for 3-color triple
Entity_Machine_Panel* panel;
bool shouldSolve = false;
Entity_Record_Player* recordPlayer = get_record_player(panel->entity_manager)
if (recordPlayer != NULL) {
if (strings_match(panel->pattern_name, recordPlayer->lotus_onlyone_tricolor_solvable_name)) {
shouldSolve = true;
}
}
do {
clear_dots(panel);
make_n_by_n(panel, 5 /* n */, true /* connect_dots */, true /* should_add_finisher */);
init_decorations(panel, 0x10 /* count */, 0 /* default_value */);
panel->dot_flags[0] |= 0x02; // is_startpoint
for (int i=5; i != 0; i--) {
int slot = get_empty_decoration_slot(panel);
panel->decorations[slot] = 0x102; // White stone
}
for (int i=2; i != 0; i--) {
int slot = get_empty_decoration_slot(panel);
panel->decorations[slot] = 0x104; // Purple stone
}
for (int i=2; i != 0; i--) {
int slot = get_empty_decoration_slot(panel);
panel->decorations[slot] = 0x105; // Green stone
}
panel->style_flags |= 0x100; // Has Stones
if (test_stones_early_fail(panel)) continue;
bool canSolve = is_solvable(panel);
} while (canSolve != shouldSolve);
bool test_stones_early_fail(Entity_Machine_Panel* panel) {
int num_columns = panel->grid_size_x - 1
int num_rows = panel->grid_size_y - 1
if (panel->style_flags != 0x4000) { // Is Pillar
num_columns++
}
if (num_columns <= 1 || num_rows <= 1) return false;
for (int x = 0; x < num_columns; x++) {
int idx = x;
for (int y = 0; y < num_rows-1; y++ && idx += num_columns) {
// Load 4 cells in a 2x2 pattern
int cellA = panel->decorations[idx]
if (cellA & 0x00000F00 != 0x100) { // Any Stone
cellA = 0;
}
int cellB = panel->decorations[idx + 1];
if (cellB & 0x00000F00 != 0x100) { // Any Stone
cellB = 0;
}
int cellC = panel->decorations[idx + num_columns]
if (cellC & 0x00000F00 != 0x100) { // Any Stone
cellC = 0
}
int cellD = panel->decorations[idx + num_columns + 1]
if (cellD & 0x00000F00 != 0x100) { // Any Stone
cellD = 0
}
// First, check that a given pair of cells is non-empty.
// Then, check if either of the two remaining cells is distinct from the two non-empty cells.
// If both conditions pass, then there is an impossible L shape.
if (cellA != 0 && cellB != 0 && cellA != cellB) {
if (cellC != 0 && cellC != cellA && cellC != cellB) return true;
if (cellD != 0 && cellD != cellA && cellD != cellB) return true;
}
if (cellB != 0 && cellC != 0 && cellB != cellC) {
if (cellD != 0 && cellD != cellB && cellD != cellC) return true;
if (cellA != 0 && cellA != cellB && cellA != cellC) return true;
}
if (cellC != 0 && cellD != 0 && cellC != cellD) {
if (cellA != 0 && cellA != cellC && cellA != cellD) return true;
if (cellB != 0 && cellB != cellC && cellB != cellD) return true;
}
if (cellD != 0 && cellA != 0 && cellD != cellA) {
if (cellB != 0 && cellB != cellD && cellB != cellA) return true;
if (cellC != 0 && cellC != cellD && cellC != cellA) return true;
}
}
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment