From 6a5b143c0fd0a90979d9315b50be2387facb752f Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 20:27:05 +0200 Subject: Refile for merging repos --- 2020/src/bin/day_3.rs | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 2020/src/bin/day_3.rs (limited to '2020/src/bin/day_3.rs') diff --git a/2020/src/bin/day_3.rs b/2020/src/bin/day_3.rs new file mode 100644 index 0000000..5e6f0bd --- /dev/null +++ b/2020/src/bin/day_3.rs @@ -0,0 +1,205 @@ +use bevy::app::AppExit; +use bevy::prelude::*; +use bevy::render::camera::Camera; +use std::fs::File; +use std::io::{BufRead, BufReader}; + +fn main() { + App::build() + .add_resource(WindowDescriptor { + title: "Advent of Code".to_string(), + width: 1920, + height: 1080, + ..Default::default() + }) + .add_resource(ClearColor(Color::rgb(0., 0., 0.))) + .add_startup_system(setup_camera.system()) + .add_startup_stage("game_entities") + .add_startup_system_to_stage("game_entities", read_input_file.system()) + .add_system(move_tobogganist.system()) + .add_system(collide_with_trees.system()) + .add_system(clear_finished_tobogganists.system()) + .add_system(end_of_slope.system()) + .add_system(translate_positions.system()) + .add_system(tobogganist_cam.system()) + .add_plugins(DefaultPlugins) + .run(); +} + +fn setup_camera(mut commands: Commands, mut materials: ResMut>) { + commands.spawn(Camera2dComponents::default()); + + commands.insert_resource(Materials { + tobogganist_material: materials.add(Color::rgb(0., 0., 255.).into()), + tree_material: materials.add(Color::rgb(0., 255., 0.).into()), + }); +} + +struct Materials { + tobogganist_material: Handle, + tree_material: Handle, +} + +struct Tobogganist; + +struct Tree; +#[derive(PartialEq, Eq)] +struct Position { + x: usize, + y: usize, +} +struct Velocity { + x: usize, + y: usize, +} +struct MapSize { + width: usize, + height: usize, +} +struct TreeHitCount(usize); +struct Score(usize); + +fn read_input_file(mut commands: Commands, materials: Res) { + commands + .spawn(SpriteComponents { + sprite: Sprite::new(Vec2::new(10., 10.)), + material: materials.tobogganist_material.clone(), + ..Default::default() + }) + .with(Tobogganist) + .with(Position { x: 0, y: 0 }) + .with(Velocity { x: 1, y: 1 }) + .with(TreeHitCount(0)); + + commands + .spawn(SpriteComponents { + sprite: Sprite::new(Vec2::new(10., 10.)), + material: materials.tobogganist_material.clone(), + ..Default::default() + }) + .with(Tobogganist) + .with(Position { x: 0, y: 0 }) + .with(Velocity { x: 3, y: 1 }) + .with(TreeHitCount(0)); + + commands + .spawn(SpriteComponents { + sprite: Sprite::new(Vec2::new(10., 10.)), + material: materials.tobogganist_material.clone(), + ..Default::default() + }) + .with(Tobogganist) + .with(Position { x: 0, y: 0 }) + .with(Velocity { x: 5, y: 1 }) + .with(TreeHitCount(0)); + + commands + .spawn(SpriteComponents { + sprite: Sprite::new(Vec2::new(10., 10.)), + material: materials.tobogganist_material.clone(), + ..Default::default() + }) + .with(Tobogganist) + .with(Position { x: 0, y: 0 }) + .with(Velocity { x: 7, y: 1 }) + .with(TreeHitCount(0)); + + commands + .spawn(SpriteComponents { + sprite: Sprite::new(Vec2::new(10., 10.)), + material: materials.tobogganist_material.clone(), + ..Default::default() + }) + .with(Tobogganist) + .with(Position { x: 0, y: 0 }) + .with(Velocity { x: 1, y: 2 }) + .with(TreeHitCount(0)); + + let f = File::open("./inputs/day_3.txt").expect("Failed to read file"); // TODO: Use the asset loading system to load this rather? + let mut width = 0; + let mut height = 0; + for (y, line) in BufReader::new(f).lines().enumerate() { + let line = line.expect("Error reading file"); + let line = line.trim(); + width = width.max(line.len()); + for (x, c) in line.chars().enumerate() { + if c == '#' { + commands + .spawn(SpriteComponents { + sprite: Sprite::new(Vec2::new(10., 10.)), + material: materials.tree_material.clone(), + ..Default::default() + }) + .with(Tree) + .with(Position { x, y }) + .with(TreeHitCount(0)); + } + } + height = y + 1; + } + commands.insert_resource(MapSize { width, height }); + commands.insert_resource(Score(1)); +} + +fn translate_positions(mut transform: Mut, position: &Position) { + transform.translation = Vec3::new(position.x as f32 * 10., position.y as f32 * -10., 0.); +} + +fn tobogganist_cam( + tobogganist: Query>, + mut camera: Query>, +) { + for mut camera_transform in camera.iter_mut() { + if let Some(tobogganist_transform) = tobogganist.iter().next() { + camera_transform.translation = Vec3::new(0., tobogganist_transform.translation.y(), 0.); + } + } +} + +fn move_tobogganist(map_size: Res, mut position: Mut, velocity: &Velocity) { + position.x += velocity.x; + position.x %= map_size.width; + position.y += velocity.y; +} + +fn collide_with_trees( + mut tobogganists: Query>, + trees: Query>, +) { + for (tobogganist_position, mut tree_hit_count) in tobogganists.iter_mut() { + for tree_position in trees.iter() { + if *tree_position == *tobogganist_position { + tree_hit_count.0 += 1; + } + } + } +} + +fn clear_finished_tobogganists( + mut commands: Commands, + map_size: Res, + mut score: ResMut, + tobogganists: Query>, +) { + for (entity, position, velocity, tree_hit_count) in tobogganists.iter() { + if position.y >= map_size.height { + println!( + "A tobogganist finished heading at incline {} x {}, after hitting {} trees", + velocity.x, velocity.y, tree_hit_count.0 + ); + score.0 *= tree_hit_count.0; + commands.despawn(entity); + } + } +} + +fn end_of_slope( + score: Res, + mut exit_events: ResMut>, + tobogganists: Query<&Tobogganist>, +) { + if tobogganists.iter().count() == 0 { + println!("All tobogganists finished. Total score: {}", score.0); + exit_events.send(AppExit); + } +} -- cgit v1.2.3