diff --git a/src/main.rs b/src/main.rs
index eb5de002219acb4469a36d728bbdc289bc7e5961..770b07b71b41375d28184f0e95f25332e80c1f4f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,6 +6,7 @@ pub mod slide;
 use crate::slide::s1_title::Title;
 use crate::slide::s2_introduction::Introduction;
 use crate::slide::s3_complexity::Complexity;
+use crate::slide::s4_conway::Conway;
 use crate::slide::Slide;
 use eframe::egui::style::{Margin, Widgets};
 use eframe::egui::{
@@ -56,6 +57,7 @@ fn create_slides() -> Vec<Box<dyn Slide>> {
         Box::new(Title::default()) as Box<dyn Slide>,
         Box::new(Introduction::default()),
         Box::new(Complexity::default()),
+        Box::new(Conway::default()),
     ]
 }
 
@@ -119,7 +121,9 @@ impl epi::App for Cartoon {
                 }
             } else {
                 ctx.request_repaint();
-                self.slide_index.saturating_sub(1)
+                self.slide_index
+                    .checked_sub(1)
+                    .unwrap_or(self.slides.len() - 1)
             };
         }
 
diff --git a/src/slide.rs b/src/slide.rs
index 123ae606f4f0538e4b98ecb17929f5352f386654..de7d7f2f8fc37cacce6cf76e3c2ae8916d03f815 100644
--- a/src/slide.rs
+++ b/src/slide.rs
@@ -4,6 +4,7 @@ use eframe::{egui, epi};
 pub mod s1_title;
 pub mod s2_introduction;
 pub mod s3_complexity;
+pub mod s4_conway;
 
 pub trait Slide {
     fn show(&mut self, ui: &mut Ui, ctx: &Context);
diff --git a/src/slide/s4_conway.rs b/src/slide/s4_conway.rs
new file mode 100644
index 0000000000000000000000000000000000000000..781e2d498351228018c7fa2f9d027fccd9f4c180
--- /dev/null
+++ b/src/slide/s4_conway.rs
@@ -0,0 +1,51 @@
+use crate::Slide;
+use eframe::egui::{
+    Align2, Color32, Context, Frame, Grid, Pos2, Rect, Shape, Stroke, Ui, Vec2, Window,
+};
+use eframe::emath;
+
+#[derive(Default)]
+pub struct Conway {}
+
+impl Slide for Conway {
+    fn show(&mut self, ui: &mut Ui, ctx: &Context) {
+        let PIXELS: f32 = 400.0;
+        let CELLS: usize = 32;
+
+        Window::new("conway")
+            .title_bar(false)
+            //.frame(Frame::none())
+            .anchor(Align2::CENTER_CENTER, Vec2::ZERO)
+            .fixed_size(Vec2::splat(PIXELS))
+            .show(ctx, |ui| {
+                let (_id, rect) = ui.allocate_space(Vec2::splat(PIXELS));
+                let to_screen = emath::RectTransform::from_to(
+                    Rect::from_x_y_ranges(0.0..=1.0, 0.0..=1.0),
+                    rect,
+                );
+
+                for c in 0..=CELLS {
+                    let coord = c as f32 / CELLS as f32;
+                    // Horizontal.
+                    ui.painter().add(Shape::LineSegment {
+                        points: [
+                            to_screen * Pos2::new(0.0, coord),
+                            to_screen * Pos2::new(1.0, coord),
+                        ],
+                        stroke: Stroke::new(1.0, Color32::BLACK),
+                    });
+                    // Vertical.
+                    ui.painter().add(Shape::LineSegment {
+                        points: [
+                            to_screen * Pos2::new(coord, 0.0),
+                            to_screen * Pos2::new(coord, 1.0),
+                        ],
+                        stroke: Stroke::new(1.0, Color32::GRAY),
+                    });
+                }
+                for x in 0..=CELLS {
+                    for y in 0..=CELLS {}
+                }
+            });
+    }
+}