From a0c406ca212ed4f2a3bc41bbdacc789ee57da42e Mon Sep 17 00:00:00 2001
From: Tom Barrett <tom@tombarrett.xyz>
Date: Sun, 14 Mar 2021 21:03:53 +0100
Subject: split up into multiple files

---
 src/cell.rs      | 143 ++++++++++++++++++++++++++++
 src/constants.rs |   8 ++
 src/cosmonaut.rs | 110 +++++++++++++++++++++
 src/lib.rs       |   3 +
 src/main.rs      | 284 ++++---------------------------------------------------
 5 files changed, 283 insertions(+), 265 deletions(-)
 create mode 100644 src/cell.rs
 create mode 100644 src/constants.rs
 create mode 100644 src/cosmonaut.rs
 create mode 100644 src/lib.rs

diff --git a/src/cell.rs b/src/cell.rs
new file mode 100644
index 0000000..b085c5e
--- /dev/null
+++ b/src/cell.rs
@@ -0,0 +1,143 @@
+use crate::constants;
+use ggez::graphics::{
+    self, spritebatch::SpriteBatch, Color, DrawMode, DrawParam, Mesh, Rect, StrokeOptions,
+};
+use ggez::mint::{Point2, Vector2};
+use ggez::{Context, GameResult};
+use rand::{
+    distributions::{Distribution, Standard},
+    Rng,
+};
+
+use std::time::Instant;
+#[derive(Clone, Copy, PartialEq)]
+pub enum Occupant {
+    None,
+    Green,
+    Yellow,
+    Diamond,
+    Red,
+    Explosion { frame: usize, timer: Instant },
+}
+
+impl Distribution<Occupant> for Standard {
+    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Occupant {
+        match rng.gen_range(0..=3) {
+            0 => Occupant::Green,
+            1 => Occupant::Yellow,
+            2 => Occupant::Diamond,
+            3 => Occupant::Red,
+            _ => Occupant::None,
+        }
+    }
+}
+
+#[derive(Clone, Copy)]
+pub struct Cell {
+    pub occupant: Occupant,
+    position: Point2<f32>,
+    hover: bool,
+    clicked: bool,
+}
+
+impl Cell {
+    pub fn new(position: Point2<f32>) -> Cell {
+        Cell {
+            occupant: rand::random(),
+            position,
+            hover: false,
+            clicked: false,
+        }
+    }
+
+    pub fn contains(&self, position: Point2<f32>) -> bool {
+        position.x > self.position.x
+            && position.y > self.position.y
+            && position.x < self.position.x + constants::TILE_WIDTH * constants::TILE_SCALE
+            && position.y < self.position.y + constants::TILE_WIDTH * constants::TILE_SCALE
+    }
+
+    pub fn moveable(&self) -> bool {
+        //!matches!(self.occupant, Occupant::Explosion{ ..} | Occupant::None)
+        match self.occupant {
+            Occupant::Explosion { .. } => false,
+            Occupant::None => false,
+            _ => true,
+        }
+    }
+
+    pub fn clicked_on(&mut self) {
+        self.clicked = true;
+    }
+
+    pub fn clicked_off(&mut self) {
+        self.clicked = false;
+    }
+
+    pub fn hover_on(&mut self) {
+        self.hover = true;
+    }
+
+    pub fn hover_off(&mut self) {
+        self.hover = false;
+    }
+
+    pub fn draw(&self, context: &mut Context, spritebatch: &mut SpriteBatch) -> GameResult {
+        let source = match self.occupant {
+            Occupant::None => None,
+            Occupant::Explosion { frame, .. } => match frame {
+                0 => Some(Rect::new(0.0, 0.5, 0.25, 0.5)),
+                1 => Some(Rect::new(0.25, 0.5, 0.25, 0.5)),
+                2 => Some(Rect::new(0.50, 0.5, 0.25, 0.5)),
+                3 => Some(Rect::new(0.75, 0.5, 0.25, 0.5)),
+                _ => None,
+            },
+            Occupant::Green => Some(Rect::new(0.0, 0.0, 0.25, 0.5)),
+            Occupant::Yellow => Some(Rect::new(0.25, 0.0, 0.25, 0.5)),
+            Occupant::Diamond => Some(Rect::new(0.50, 0.0, 0.25, 0.5)),
+            Occupant::Red => Some(Rect::new(0.75, 0.0, 0.25, 0.5)),
+        };
+
+        if let Some(source) = source {
+            spritebatch.add(
+                DrawParam::default()
+                    .src(source)
+                    .dest(self.position)
+                    .scale(Vector2 {
+                        x: constants::TILE_SCALE,
+                        y: constants::TILE_SCALE,
+                    }),
+            );
+        }
+
+        if self.hover {
+            let mesh = Mesh::new_rectangle(
+                context,
+                DrawMode::Stroke(StrokeOptions::default()),
+                Rect::new(
+                    self.position.x,
+                    self.position.y,
+                    constants::TILE_WIDTH * constants::TILE_SCALE,
+                    constants::TILE_HEIGHT * constants::TILE_SCALE,
+                ),
+                Color::from_rgb(255, 100, 100),
+            )?;
+            graphics::draw(context, &mesh, DrawParam::default())?;
+        }
+        if self.clicked {
+            let mesh = Mesh::new_rectangle(
+                context,
+                DrawMode::Stroke(StrokeOptions::default()),
+                Rect::new(
+                    self.position.x,
+                    self.position.y,
+                    constants::TILE_WIDTH * constants::TILE_SCALE,
+                    constants::TILE_HEIGHT * constants::TILE_SCALE,
+                ),
+                Color::from_rgb(100, 255, 100),
+            )?;
+            graphics::draw(context, &mesh, DrawParam::default())?;
+        }
+        Ok(())
+    }
+}
diff --git a/src/constants.rs b/src/constants.rs
new file mode 100644
index 0000000..f9a5003
--- /dev/null
+++ b/src/constants.rs
@@ -0,0 +1,8 @@
+pub const TILE_SCALE: f32 = 3.0;
+pub const TILE_HEIGHT: f32 = 16.0;
+pub const TILE_WIDTH: f32 = 16.0;
+pub const BORDER_SIZE: f32 = 3.0;
+pub const SHIFT_X: f32 = 50.0;
+pub const SHIFT_Y: f32 = 50.0;
+pub const COLUMNS: usize = 8;
+pub const ROWS: usize = 8;
diff --git a/src/cosmonaut.rs b/src/cosmonaut.rs
new file mode 100644
index 0000000..235861e
--- /dev/null
+++ b/src/cosmonaut.rs
@@ -0,0 +1,110 @@
+use crate::constants;
+use ggez::graphics::{self, DrawParam, FilterMode, Image, Rect};
+use ggez::mint::{Point2, Vector2};
+use ggez::{Context, GameResult};
+use std::time::Instant;
+
+#[derive(Clone, Copy)]
+enum CosmonautFrames {
+    None,
+    One,
+    Two,
+    Three,
+    Four,
+}
+
+impl CosmonautFrames {
+    pub fn next(&mut self) {
+        *self = match self {
+            CosmonautFrames::None => CosmonautFrames::One,
+            CosmonautFrames::One => CosmonautFrames::Two,
+            CosmonautFrames::Two => CosmonautFrames::Three,
+            CosmonautFrames::Three => CosmonautFrames::Four,
+            CosmonautFrames::Four => CosmonautFrames::None,
+        };
+    }
+}
+
+pub struct Cosmonaut {
+    destination: Point2<f32>,
+    image: Image,
+    frame: CosmonautFrames,
+    timer: Instant,
+    scale: Vector2<f32>,
+}
+
+impl Cosmonaut {
+    pub fn new(context: &mut Context) -> GameResult<Cosmonaut> {
+        let mut image = Image::new(context, "/cosmonaut.png")?;
+        image.set_filter(FilterMode::Nearest);
+
+        Ok(Cosmonaut {
+            image,
+            destination: Point2 { x: 600.0, y: 200.0 },
+            frame: CosmonautFrames::None,
+            timer: Instant::now(),
+            scale: Vector2 {
+                x: constants::TILE_SCALE * 2.0,
+                y: constants::TILE_SCALE * 2.0,
+            },
+        })
+    }
+
+    pub fn draw(&self, context: &mut Context) -> GameResult {
+        graphics::draw(
+            context,
+            &self.image,
+            DrawParam::default()
+                .dest(self.destination)
+                .scale(self.scale)
+                .src(Rect::new(0.0, 0.0, 1.0 / 3.0, 1.0)),
+        )?;
+        let source = match self.frame {
+            CosmonautFrames::None => None,
+            CosmonautFrames::One => Some(Rect::new(1.0 / 3.0, 0.0, 1.0 / 3.0, 1.0 / 2.0)),
+            CosmonautFrames::Two => Some(Rect::new(2.0 / 3.0, 0.0, 1.0, 1.0 / 2.0)),
+            CosmonautFrames::Three => Some(Rect::new(1.0 / 3.0, 1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0)),
+            CosmonautFrames::Four => Some(Rect::new(2.0 / 3.0, 1.0 / 2.0, 1.0, 1.0)),
+        };
+        if let Some(source) = source {
+            graphics::draw(
+                context,
+                &self.image,
+                DrawParam::default()
+                    .dest(self.destination)
+                    .src(source)
+                    .scale(self.scale),
+            )?;
+        }
+
+        Ok(())
+    }
+
+    pub fn update(&mut self) {
+        match self.frame {
+            CosmonautFrames::None => (),
+            _ => {
+                if self.timer.elapsed().as_millis() > 50 {
+                    self.frame.next();
+                    self.timer = Instant::now();
+                }
+            }
+        }
+    }
+
+    pub fn start(&mut self) {
+        if let CosmonautFrames::None = self.frame {
+            if self.timer.elapsed().as_secs() > 5 {
+                self.timer = Instant::now();
+                self.frame.next()
+            }
+        }
+    }
+
+    pub fn contains(&self, position: Point2<f32>) -> bool {
+        position.x > self.destination.x
+            && position.y > self.destination.y
+            && position.x < self.destination.x + constants::TILE_WIDTH * constants::TILE_SCALE * 2.0
+            && position.y < self.destination.y + constants::TILE_WIDTH * constants::TILE_SCALE * 2.0
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..9b47535
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,3 @@
+pub mod cell;
+pub mod constants;
+pub mod cosmonaut;
diff --git a/src/main.rs b/src/main.rs
index 13c5c6c..bff0079 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,261 +1,13 @@
 use ggez::event::{self, EventHandler};
-use ggez::graphics::{
-    self, spritebatch::SpriteBatch, Color, DrawMode, DrawParam, FilterMode, Image, Mesh, Rect,
-    StrokeOptions, WrapMode,
-};
+use ggez::graphics::{self, spritebatch::SpriteBatch, DrawParam, FilterMode, Image, WrapMode};
 use ggez::input::mouse;
-use ggez::mint::{Point2, Vector2};
+use ggez::mint::Point2;
 use ggez::{Context, ContextBuilder, GameResult};
-use rand::{
-    distributions::{Distribution, Standard},
-    Rng,
-};
 use std::time::Instant;
 
-pub const TILE_SCALE: f32 = 3.0;
-pub const TILE_HEIGHT: f32 = 16.0;
-pub const TILE_WIDTH: f32 = 16.0;
-pub const BORDER_SIZE: f32 = 3.0;
-pub const SHIFT_X: f32 = 50.0;
-pub const SHIFT_Y: f32 = 50.0;
-pub const COLUMNS: usize = 8;
-pub const ROWS: usize = 8;
-
-#[derive(Clone, Copy, PartialEq)]
-enum Occupant {
-    None,
-    Green,
-    Yellow,
-    Diamond,
-    Red,
-    Explosion { frame: usize, timer: Instant },
-}
-
-impl Distribution<Occupant> for Standard {
-    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Occupant {
-        match rng.gen_range(0..=3) {
-            0 => Occupant::Green,
-            1 => Occupant::Yellow,
-            2 => Occupant::Diamond,
-            3 => Occupant::Red,
-            _ => Occupant::None,
-        }
-    }
-}
-
-#[derive(Clone, Copy)]
-enum CosmonautFrames {
-    None,
-    One,
-    Two,
-    Three,
-    Four,
-}
-
-impl CosmonautFrames {
-    pub fn next(&mut self) {
-        *self = match self {
-            CosmonautFrames::None => CosmonautFrames::One,
-            CosmonautFrames::One => CosmonautFrames::Two,
-            CosmonautFrames::Two => CosmonautFrames::Three,
-            CosmonautFrames::Three => CosmonautFrames::Four,
-            CosmonautFrames::Four => CosmonautFrames::None,
-        };
-    }
-}
-
-struct Cosmonaut {
-    destination: Point2<f32>,
-    image: Image,
-    frame: CosmonautFrames,
-    timer: Instant,
-    scale: Vector2<f32>,
-}
-
-impl Cosmonaut {
-    pub fn new(context: &mut Context) -> GameResult<Cosmonaut> {
-        let mut image = Image::new(context, "/cosmonaut.png")?;
-        image.set_filter(FilterMode::Nearest);
-
-        Ok(Cosmonaut {
-            image,
-            destination: Point2 { x: 600.0, y: 200.0 },
-            frame: CosmonautFrames::None,
-            timer: Instant::now(),
-            scale: Vector2 {
-                x: TILE_SCALE * 2.0,
-                y: TILE_SCALE * 2.0,
-            },
-        })
-    }
-
-    pub fn draw(&self, context: &mut Context) -> GameResult {
-        graphics::draw(
-            context,
-            &self.image,
-            DrawParam::default()
-                .dest(self.destination)
-                .scale(self.scale)
-                .src(Rect::new(0.0, 0.0, 1.0 / 3.0, 1.0)),
-        )?;
-        let source = match self.frame {
-            CosmonautFrames::None => None,
-            CosmonautFrames::One => Some(Rect::new(1.0 / 3.0, 0.0, 1.0 / 3.0, 1.0 / 2.0)),
-            CosmonautFrames::Two => Some(Rect::new(2.0 / 3.0, 0.0, 1.0, 1.0 / 2.0)),
-            CosmonautFrames::Three => Some(Rect::new(1.0 / 3.0, 1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0)),
-            CosmonautFrames::Four => Some(Rect::new(2.0 / 3.0, 1.0 / 2.0, 1.0, 1.0)),
-        };
-        if let Some(source) = source {
-            graphics::draw(
-                context,
-                &self.image,
-                DrawParam::default()
-                    .dest(self.destination)
-                    .src(source)
-                    .scale(self.scale),
-            )?;
-        }
-
-        Ok(())
-    }
-
-    pub fn update(&mut self) {
-        match self.frame {
-            CosmonautFrames::None => (),
-            _ => {
-                if self.timer.elapsed().as_millis() > 50 {
-                    self.frame.next();
-                    self.timer = Instant::now();
-                }
-            }
-        }
-    }
-
-    pub fn start(&mut self) {
-        if let CosmonautFrames::None = self.frame {
-            if self.timer.elapsed().as_secs() > 5 {
-                self.timer = Instant::now();
-                self.frame.next()
-            }
-        }
-    }
-
-    pub fn contains(&self, position: Point2<f32>) -> bool {
-        position.x > self.destination.x
-            && position.y > self.destination.y
-            && position.x < self.destination.x + TILE_WIDTH * TILE_SCALE * 2.0
-            && position.y < self.destination.y + TILE_WIDTH * TILE_SCALE * 2.0
-    }
-}
-
-#[derive(Clone, Copy)]
-struct Cell {
-    occupant: Occupant,
-    position: Point2<f32>,
-    hover: bool,
-    clicked: bool,
-}
-
-impl Cell {
-    pub fn new(position: Point2<f32>) -> Cell {
-        Cell {
-            occupant: rand::random(),
-            position,
-            hover: false,
-            clicked: false,
-        }
-    }
-
-    pub fn contains(&self, position: Point2<f32>) -> bool {
-        position.x > self.position.x
-            && position.y > self.position.y
-            && position.x < self.position.x + TILE_WIDTH * TILE_SCALE
-            && position.y < self.position.y + TILE_WIDTH * TILE_SCALE
-    }
-
-    pub fn moveable(&self) -> bool {
-        match self.occupant {
-            Occupant::Explosion { .. } => false,
-            Occupant::None => false,
-            _ => true,
-        }
-    }
-
-    pub fn clicked_on(&mut self) {
-        self.clicked = true;
-    }
-
-    pub fn clicked_off(&mut self) {
-        self.clicked = false;
-    }
-
-    pub fn hover_on(&mut self) {
-        self.hover = true;
-    }
-
-    pub fn hover_off(&mut self) {
-        self.hover = false;
-    }
-
-    pub fn draw(&self, context: &mut Context, spritebatch: &mut SpriteBatch) -> GameResult {
-        let source = match self.occupant {
-            Occupant::None => None,
-            Occupant::Explosion { frame, .. } => match frame {
-                0 => Some(Rect::new(0.0, 0.5, 0.25, 0.5)),
-                1 => Some(Rect::new(0.25, 0.5, 0.25, 0.5)),
-                2 => Some(Rect::new(0.50, 0.5, 0.25, 0.5)),
-                3 => Some(Rect::new(0.75, 0.5, 0.25, 0.5)),
-                _ => None,
-            },
-            Occupant::Green => Some(Rect::new(0.0, 0.0, 0.25, 0.5)),
-            Occupant::Yellow => Some(Rect::new(0.25, 0.0, 0.25, 0.5)),
-            Occupant::Diamond => Some(Rect::new(0.50, 0.0, 0.25, 0.5)),
-            Occupant::Red => Some(Rect::new(0.75, 0.0, 0.25, 0.5)),
-        };
-
-        if let Some(source) = source {
-            spritebatch.add(
-                DrawParam::default()
-                    .src(source)
-                    .dest(self.position)
-                    .scale(Vector2 {
-                        x: TILE_SCALE,
-                        y: TILE_SCALE,
-                    }),
-            );
-        }
-
-        if self.hover {
-            let mesh = Mesh::new_rectangle(
-                context,
-                DrawMode::Stroke(StrokeOptions::default()),
-                Rect::new(
-                    self.position.x,
-                    self.position.y,
-                    TILE_WIDTH * TILE_SCALE,
-                    TILE_HEIGHT * TILE_SCALE,
-                ),
-                Color::from_rgb(255, 100, 100),
-            )?;
-            graphics::draw(context, &mesh, DrawParam::default())?;
-        }
-        if self.clicked {
-            let mesh = Mesh::new_rectangle(
-                context,
-                DrawMode::Stroke(StrokeOptions::default()),
-                Rect::new(
-                    self.position.x,
-                    self.position.y,
-                    TILE_WIDTH * TILE_SCALE,
-                    TILE_HEIGHT * TILE_SCALE,
-                ),
-                Color::from_rgb(100, 255, 100),
-            )?;
-            graphics::draw(context, &mesh, DrawParam::default())?;
-        }
-        Ok(())
-    }
-}
+use gems::cell::{Cell, Occupant};
+use gems::constants;
+use gems::cosmonaut::Cosmonaut;
 
 struct Game {
     selected: Option<(usize, usize)>,
@@ -277,15 +29,17 @@ impl Game {
         let mut grid = Vec::new();
         let mut y = 0.0;
 
-        for _ in 0..COLUMNS {
+        for _ in 0..constants::COLUMNS {
             let mut column = Vec::new();
-            for j in 0..ROWS {
+            for j in 0..constants::ROWS {
                 column.push(Cell::new(Point2 {
-                    x: (j as f32) * (TILE_WIDTH * TILE_SCALE + BORDER_SIZE) + SHIFT_X,
-                    y: y + SHIFT_Y,
+                    x: (j as f32)
+                        * (constants::TILE_WIDTH * constants::TILE_SCALE + constants::BORDER_SIZE)
+                        + constants::SHIFT_X,
+                    y: y + constants::SHIFT_Y,
                 }));
             }
-            y += TILE_HEIGHT * TILE_SCALE + BORDER_SIZE;
+            y += constants::TILE_HEIGHT * constants::TILE_SCALE + constants::BORDER_SIZE;
             grid.push(column);
         }
 
@@ -301,9 +55,9 @@ impl Game {
     fn update_explosions(&mut self) {
         let mut last = Occupant::None;
         let mut connected = Vec::new();
-        for i in 0..COLUMNS {
+        for i in 0..constants::COLUMNS {
             let mut c = Vec::new();
-            for j in 0..ROWS {
+            for j in 0..constants::ROWS {
                 if self.grid[i][j].occupant == last && last != Occupant::None {
                     c.push((i, j));
                     c.push((i, j - 1));
@@ -329,9 +83,9 @@ impl Game {
         }
 
         connected.clear();
-        for i in 0..COLUMNS {
+        for i in 0..constants::COLUMNS {
             let mut c = Vec::new();
-            for j in 0..ROWS {
+            for j in 0..constants::ROWS {
                 if self.grid[j][i].occupant == last && last != Occupant::None {
                     c.push((j, i));
                     c.push((j - 1, i));
@@ -358,8 +112,8 @@ impl Game {
     }
 
     fn update_dropping(&mut self) {
-        for i in 1..COLUMNS {
-            for j in 0..ROWS {
+        for i in 1..constants::COLUMNS {
+            for j in 0..constants::ROWS {
                 if self.grid[i][j].occupant == Occupant::None
                     && self.grid[i - 1][j].occupant != Occupant::None
                 {
@@ -371,7 +125,7 @@ impl Game {
     }
 
     fn update_feeding(&mut self) {
-        for i in 0..COLUMNS {
+        for i in 0..constants::COLUMNS {
             if self.grid[0][i].occupant == Occupant::None {
                 self.grid[0][i].occupant = rand::random();
             }
-- 
cgit v1.2.3