-
Notifications
You must be signed in to change notification settings - Fork 2
/
2d_rock_paper_scissor.rs
113 lines (104 loc) · 3.53 KB
/
2d_rock_paper_scissor.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use bevy::{color::palettes::css::*, prelude::*};
use bevy_life::{CellState, CellularAutomatonPlugin, MooreCell2d, SimulationBatch};
use rand::Rng;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Component)]
pub enum RockPaperScissor {
Rock,
Paper,
Scissor,
}
impl RockPaperScissor {
pub const fn beaten_by(&self) -> Self {
match self {
Self::Rock => Self::Paper,
Self::Paper => Self::Scissor,
Self::Scissor => Self::Rock,
}
}
}
impl CellState for RockPaperScissor {
fn new_cell_state<'a>(&self, neighbor_cells: impl Iterator<Item = &'a Self>) -> Self {
let beaten_by = self.beaten_by();
let count = neighbor_cells.filter(|state| *state == &beaten_by).count();
if count > 2 {
beaten_by
} else {
*self
}
}
}
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
title: "Rock Paper Scissor".to_string(),
resolution: [1200.0, 800.0].into(),
..default()
}),
..default()
}))
.add_plugins(CellularAutomatonPlugin::<MooreCell2d, RockPaperScissor>::default())
.insert_resource(SimulationBatch)
.add_systems(Startup, (setup_camera, setup_map))
.add_systems(Update, color_sprites)
.run();
}
fn setup_camera(mut commands: Commands) {
// Camera
commands.spawn(Camera2dBundle::default());
}
fn setup_map(mut commands: Commands) {
spawn_map(&mut commands);
}
fn spawn_map(commands: &mut Commands) {
let mut rng = rand::thread_rng();
let (size_x, size_y) = (300, 200);
let sprite_size = 4.;
let color = Color::srgba(0., 0., 0., 0.);
commands
.spawn(SpatialBundle::from_transform(Transform::from_xyz(
-(size_x as f32 * sprite_size) / 2.,
-(size_y as f32 * sprite_size) / 2.,
0.,
)))
.with_children(|builder| {
for y in 0..=size_y {
for x in 0..=size_x {
let state = match rng.gen_range(0.0..=1.0) {
x if x < 0.33 => RockPaperScissor::Rock,
x if x < 0.66 => RockPaperScissor::Paper,
_ => RockPaperScissor::Scissor,
};
builder.spawn((
SpriteBundle {
sprite: Sprite {
custom_size: Some(Vec2::splat(sprite_size)),
color,
..default()
},
transform: Transform::from_xyz(
sprite_size * x as f32,
sprite_size * y as f32,
0.,
),
..default()
},
MooreCell2d::new(IVec2::new(x, y)),
state,
));
}
}
});
println!("map generated");
}
pub fn color_sprites(
mut query: Query<(&RockPaperScissor, &mut Sprite), Changed<RockPaperScissor>>,
) {
query
.par_iter_mut()
.for_each(|(state, mut sprite)| match state {
RockPaperScissor::Rock => sprite.color = Color::Srgba(BLUE),
RockPaperScissor::Paper => sprite.color = Color::Srgba(BEIGE),
RockPaperScissor::Scissor => sprite.color = Color::Srgba(RED),
});
}