Skip to content

Commit 5ef6e8d

Browse files
committed
add puzzle four blinkers + glider collision (draft)
1 parent 389d621 commit 5ef6e8d

File tree

1 file changed

+121
-2
lines changed

1 file changed

+121
-2
lines changed

backend/src/bin/gol.rs

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,15 @@ fn get_all_puzzles(draft: bool) -> Vec<(&'static str, fn() -> (Puzzle, Board))>
107107
"20_glider_migration",
108108
create_glider_migration_puzzle_and_solution,
109109
),
110+
("21_four_blinkers", create_four_blinkers_puzzle_and_solution),
110111
];
111112

112113
if draft {
113-
puzzles.push(("21_robot_face", create_robot_face_puzzle_and_solution));
114+
puzzles.push((
115+
"21_glider_collision",
116+
create_glider_collision_puzzle_and_solution,
117+
));
118+
puzzles.push(("22_robot_face", create_robot_face_puzzle_and_solution));
114119
}
115120
puzzles
116121
}
@@ -576,6 +581,63 @@ fn create_clock_puzzle_and_solution() -> (Puzzle, Board) {
576581
(puzzle, initial_board)
577582
}
578583

584+
fn create_four_blinkers_puzzle_and_solution() -> (Puzzle, Board) {
585+
let size = 16;
586+
let offset = size / 2 - 1;
587+
// Define the initial board.
588+
let initial_board = Board::with_live_cells(
589+
size,
590+
vec![
591+
Position {
592+
x: offset,
593+
y: offset - 1,
594+
},
595+
Position {
596+
x: offset - 2,
597+
y: offset,
598+
},
599+
Position {
600+
x: offset - 1,
601+
y: offset,
602+
},
603+
Position {
604+
x: offset + 1,
605+
y: offset,
606+
},
607+
Position {
608+
x: offset + 2,
609+
y: offset,
610+
},
611+
Position {
612+
x: offset,
613+
y: offset + 1,
614+
},
615+
],
616+
);
617+
let mut initial_conditions = initial_board.to_exactly_matching_conditions();
618+
// Drop a point to force a lucky guess.
619+
initial_conditions.remove(3);
620+
initial_conditions.remove(0);
621+
622+
// Define the final board.
623+
let final_board = initial_board.advance(10);
624+
let final_conditions = final_board.to_exactly_matching_conditions();
625+
626+
let puzzle = Puzzle {
627+
title: "Four blinkers".to_string(),
628+
summary: "Create four blinkers from very few cells".to_string(),
629+
difficulty: Difficulty::Easy,
630+
size,
631+
minimal_steps: 10,
632+
maximal_steps: 10,
633+
is_strict: false,
634+
initial_conditions,
635+
final_conditions,
636+
};
637+
638+
(puzzle, initial_board)
639+
}
640+
579641
#[allow(clippy::identity_op)]
580642
fn create_robot_face_puzzle_and_solution() -> (Puzzle, Board) {
581643
let size = 60;
@@ -625,7 +687,7 @@ fn create_robot_face_puzzle_and_solution() -> (Puzzle, Board) {
625687
let puzzle = Puzzle {
626688
title: "Robot face".to_string(),
627689
summary: "Create a robot-like face from very few cells".to_string(),
628-
difficulty: Difficulty::Medium,
690+
difficulty: Difficulty::Easy,
629691
size,
630692
minimal_steps: 170,
631693
maximal_steps: 200,
@@ -637,6 +699,63 @@ fn create_robot_face_puzzle_and_solution() -> (Puzzle, Board) {
637699
(puzzle, initial_board)
638700
}
639701

702+
fn create_glider_collision_puzzle_and_solution() -> (Puzzle, Board) {
703+
// Create two gliders on a collision course that will cancel each other out
704+
// First glider (moving down-right) starting at top-left
705+
// Second glider (moving up-left) starting at bottom-right
706+
let initial_board = Board::with_live_cells(
707+
12,
708+
vec![
709+
// First glider (top-left, moving down-right)
710+
Position { x: 2, y: 1 },
711+
Position { x: 3, y: 2 },
712+
Position { x: 1, y: 3 },
713+
Position { x: 2, y: 3 },
714+
Position { x: 3, y: 3 },
715+
// Second glider (bottom-right, moving up-left)
716+
// Glider pattern rotated 180 degrees
717+
Position { x: 8, y: 9 },
718+
Position { x: 7, y: 8 },
719+
Position { x: 9, y: 7 },
720+
Position { x: 8, y: 7 },
721+
Position { x: 7, y: 7 },
722+
],
723+
);
724+
725+
// After collision, the board should be empty or nearly empty
726+
let final_board = initial_board.advance(16);
727+
let final_conditions = final_board.to_exactly_matching_conditions();
728+
729+
let puzzle = Puzzle {
730+
title: "Glider Collision".to_string(),
731+
summary: "Make two gliders collide and cancel each other out".to_string(),
732+
difficulty: Difficulty::Medium,
733+
size: 12,
734+
minimal_steps: 16,
735+
maximal_steps: 16,
736+
is_strict: true,
737+
initial_conditions: vec![
738+
// First glider should be in top-left area
739+
Condition::TestRectangle {
740+
x_range: 0..5,
741+
y_range: 0..5,
742+
min_live_count: 5,
743+
max_live_count: 5,
744+
},
745+
// Second glider should be in bottom-right area
746+
Condition::TestRectangle {
747+
x_range: 7..12,
748+
y_range: 7..12,
749+
min_live_count: 5,
750+
max_live_count: 5,
751+
},
752+
],
753+
final_conditions,
754+
};
755+
756+
(puzzle, initial_board)
757+
}
758+
640759
fn create_glider_migration_puzzle_and_solution() -> (Puzzle, Board) {
641760
// Place a glider pattern in the top-left square.
642761
let initial_board = Board::with_live_cells(

0 commit comments

Comments
 (0)