fix some clippy issues

This commit is contained in:
Michael Zhang 2019-08-10 00:50:12 -05:00
parent 0fdab97044
commit eb3c12fc58
No known key found for this signature in database
GPG key ID: 5BAEFE5D04F0CE6C
9 changed files with 63 additions and 196 deletions

View file

@ -34,6 +34,7 @@ impl AnimationState {
}
pub fn begin_move_transition(&mut self, result: MoveResult) {
println!("result: {:?}", result);
self.last_move_result = Some(result);
self.is_animating = true;
self.progress = 0.0;
@ -45,12 +46,10 @@ impl AnimationState {
for (entity, direction) in change_set {
// TODO: implement ease-out?
let pair = direction.as_pair();
// cap progress at 1.0, we don't want blocks going past where they're supposed to
let progress = progress.min(1.0);
let offset = (pair.0 as f32 * progress, pair.1 as f32 * progress);
println!(
"|| entity: {:?}, direction: {:?} => {:?}",
entity, direction, offset
);
offsets.insert(entity.clone(), offset);
offsets.insert(entity, offset);
}
}
// vibrate all blocking pieces
@ -66,12 +65,6 @@ impl AnimationState {
self.progress_function = Some(Box::new(func));
}
pub fn begin_transition(&mut self, f: AnimationFn) {
self.is_animating = true;
self.progress = 0.0;
self.progress_function = Some(f);
}
pub fn make_progress(&mut self, delta: Duration) {
let progress = self.progress + (delta.as_millis() as f32 / ANIMATION_DURATION) / 1000.0;
@ -97,10 +90,6 @@ impl AnimationState {
}
}
pub fn is_done(&self) -> bool {
self.progress > 1.0
}
pub fn get_block_offset(&self, index: usize) -> (f32, f32) {
self.block_offsets
.get(&Entity::Block(index))

View file

@ -44,7 +44,7 @@ pub enum PushDir {
}
impl PushDir {
pub fn as_pair(&self) -> (i32, i32) {
pub fn as_pair(self) -> (i32, i32) {
match self {
PushDir::Up => (0, -1),
PushDir::Down => (0, 1),
@ -90,25 +90,20 @@ impl From<i32> for Shape {
}
impl Shape {
pub fn opposite(&self) -> Shape {
pub fn get_opposite(self) -> Option<Shape> {
use Shape::*;
match self {
TopRight => BottomLeft,
BottomLeft => TopRight,
TopLeft => BottomRight,
BottomRight => TopLeft,
Full => Full,
TopRight => Some(BottomLeft),
BottomLeft => Some(TopRight),
TopLeft => Some(BottomRight),
BottomRight => Some(TopLeft),
Full => None,
}
}
pub fn is_opposite(&self, other: &Shape) -> bool {
use Shape::*;
match (self, other) {
(TopRight, BottomLeft)
| (BottomLeft, TopRight)
| (TopLeft, BottomRight)
| (BottomRight, TopLeft) => true,
_ => false,
}
pub fn is_opposite(self, other: Shape) -> bool {
self.get_opposite()
.map(|shape| shape == other)
.unwrap_or_else(|| false)
}
}

View file

@ -19,8 +19,6 @@ const SEGMENT_IMAGE: &[u8] = include_bytes!("../textures/segment.png");
const LEVEL_TUTORIAL: &str = include_str!("../levels/tutorial.json");
const ANIMATION_SPEED: f32 = 6.0;
pub struct Game<'a> {
pub resources: Resources,
pub display: &'a Display,
@ -55,8 +53,8 @@ impl<'a> Game<'a> {
}
pub fn handle_event(&mut self, event: Event) {
match event {
Event::WindowEvent { event, .. } => match event {
if let Event::WindowEvent { event, .. } = event {
match event {
WindowEvent::Resized(size) => self.resources.window_dimensions = size.into(),
WindowEvent::KeyboardInput { input, .. } => {
if let Some(code) = &input.virtual_keycode {
@ -68,8 +66,7 @@ impl<'a> Game<'a> {
}
}
_ => (),
},
_ => (),
}
}
}
@ -78,15 +75,15 @@ impl<'a> Game<'a> {
}
pub fn get_current_level(&self) -> &Level {
self.levels.iter().nth(self.current_level).unwrap()
self.levels.get(self.current_level).unwrap()
}
pub fn get_current_level_mut(&mut self) -> &mut Level {
self.levels.iter_mut().nth(self.current_level).unwrap()
self.levels.get_mut(self.current_level).unwrap()
}
pub fn is_pressed(&self, code: &VirtualKeyCode) -> bool {
if let Some(true) = self.keymap.get(code) {
pub fn is_pressed(&self, code: VirtualKeyCode) -> bool {
if let Some(true) = self.keymap.get(&code) {
true
} else {
false
@ -96,7 +93,7 @@ impl<'a> Game<'a> {
pub fn update(&mut self, delta: Duration) {
macro_rules! shit {
($key:expr, $board:expr, $direction:expr) => {
if self.is_pressed(&$key) {
if self.is_pressed($key) {
println!("pushed: {:?}", $key);
let level = self.get_current_level_mut();
let result = level.try_move($board, $direction);
@ -107,7 +104,7 @@ impl<'a> Game<'a> {
}
if self.animations.is_animating {
println!("animating. {:?}", self.animations.progress);
// println!("animating. {:?}", self.animations.progress);
self.animations.make_progress(delta);
// we just finished!
@ -134,9 +131,6 @@ impl<'a> Game<'a> {
shit!(VirtualKeyCode::J, Board::Right, PushDir::Left);
shit!(VirtualKeyCode::K, Board::Right, PushDir::Down);
shit!(VirtualKeyCode::L, Board::Right, PushDir::Right);
// failed a move
if let Some(Err(fail_set)) = &self.animations.last_move_result {}
}
}

View file

@ -26,13 +26,10 @@ impl Block {
let segments = data
.segments
.iter()
.map(|segment| {
let seg = Segment {
position: (segment[0], segment[1]),
shape: segment[2].into(),
board: segment[3].into(),
};
seg
.map(|segment| Segment {
position: (segment[0], segment[1]),
shape: segment[2].into(),
board: segment[3].into(),
})
.collect();
let orientation = data.orientation.into();

View file

@ -1,72 +0,0 @@
use std::collections::HashMap;
use crate::enums::Board;
use crate::level::Segment;
#[derive(Debug)]
pub struct CellMap(HashMap<(i32, i32, Board), CellContents>);
#[derive(Copy, Clone, Debug)]
pub enum CellContents {
Empty,
Player,
Single((usize, Segment)),
// invariant: .0 < .1
Double((usize, Segment), (usize, Segment)),
}
impl CellMap {
pub fn new() -> Self {
CellMap(HashMap::new())
}
pub fn get(&self, loc: (i32, i32, Board)) -> CellContents {
self.0
.get(&loc)
.cloned()
.unwrap_or_else(|| CellContents::Empty)
}
pub fn clear(&mut self, loc: (i32, i32, Board)) {
self.0.remove(&loc);
}
pub fn add_player(&mut self, loc: (i32, i32, Board)) -> bool {
let contents = self.get(loc).clone();
match contents {
CellContents::Empty => {
self.0.insert(loc, CellContents::Player);
true
}
_ => false,
}
}
pub fn add(&mut self, loc: (i32, i32, Board), index: usize, segment: &Segment) -> bool {
let contents = self.get(loc).clone();
match contents {
CellContents::Empty => {
// just add it like normal
self.0.insert(loc, CellContents::Single((index, *segment)));
true
}
CellContents::Single((index0, existing)) => {
if existing.shape.is_opposite(&segment.shape) {
self.0.insert(
loc,
if *segment < existing {
CellContents::Double((index, *segment), (index0, existing))
} else {
CellContents::Double((index0, existing), (index, *segment))
},
);
true
} else {
false
}
}
CellContents::Player | CellContents::Double(_, _) => false,
}
}
}

View file

@ -8,16 +8,6 @@ macro_rules! set {
}
}
macro_rules! merge {
($(item:expr)*) => {
{
let mut set = std::collections::HashSet::new();
$(set.extend($item);)*
set
}
}
}
macro_rules! fail_set {
($change_set:expr) => {
$change_set
@ -34,7 +24,7 @@ macro_rules! entity_fail {
($item:expr) => {
match $item {
Some(index) => set!(index),
None => set!(),
None => std::collections::HashSet::new(),
}
};
}

View file

@ -2,25 +2,21 @@
mod macros;
mod block;
mod cell_map;
mod player;
use std::collections::{HashMap, HashSet, VecDeque};
use crate::animations::AnimationState;
use crate::color::Color;
use crate::data::LevelData;
use crate::enums::{Board, Orientation, PushDir, Shape};
use crate::renderer::Renderer;
use self::block::{Block, Blockish};
use self::cell_map::{CellContents, CellMap};
use self::player::Player;
pub struct Level {
dimensions: (u32, u32),
move_stack: VecDeque<()>,
cell_map: CellMap,
blocks: Vec<Block>,
player1: Player,
player2: Player,
@ -46,25 +42,13 @@ pub type FailSet = HashSet<usize>;
impl Level {
pub fn from_json(data: impl AsRef<str>) -> Level {
let data: LevelData = json5::from_str(data.as_ref()).unwrap();
println!("{:?}", data);
let mut cell_map = CellMap::new();
println!("level data: {:?}", data);
let blocks = data
.blocks
.iter()
.enumerate()
.map(|(i, block)| {
let block = Block::from_data(i, block);
for segment in block.get_segments() {
cell_map.add(
(segment.position.0, segment.position.1, segment.board),
i,
&segment,
);
}
block
})
.map(|(i, block)| Block::from_data(i, block))
.collect();
let player1 = Player {
@ -75,21 +59,10 @@ impl Level {
position: data.player2.position,
color: data.player2.color.into(),
};
cell_map.add_player((
data.player1.position.0,
data.player1.position.1,
Board::Left,
));
cell_map.add_player((
data.player2.position.0,
data.player2.position.1,
Board::Right,
));
Level {
dimensions: (data.dimensions[0], data.dimensions[1]),
move_stack: VecDeque::new(),
cell_map,
blocks,
player1,
player2,
@ -152,7 +125,7 @@ impl Level {
println!("block_can_move({:?}, {:?})", index, direction);
let block = match self.blocks.get(index) {
Some(block) => block,
None => return Err(set!()),
None => return Err(HashSet::new()),
};
// is the block even movable?
@ -247,8 +220,7 @@ impl Level {
);
// handle special pushes
// if-statement disguised as a loop
while let Some((other_block, other_shape)) = current_occupant {
if let Some((other_block, other_shape)) = current_occupant {
// are both shapes triangles?
let both_triangles = match (segment.shape, other_shape) {
(Shape::Full, Shape::Full) => false,
@ -256,28 +228,28 @@ impl Level {
// TODO: enumerate them to get rid of invalid states
};
// what directions could we be pushing the other block into?
let possible_directions = match segment.shape {
Shape::TopRight => [PushDir::Up, PushDir::Right],
Shape::TopLeft => [PushDir::Left, PushDir::Up],
Shape::BottomLeft => [PushDir::Down, PushDir::Left],
Shape::BottomRight => [PushDir::Right, PushDir::Down],
Shape::Full => unreachable!("already eliminated this possibility"),
};
if both_triangles {
// what directions could we be pushing the other block into?
let possible_directions = match segment.shape {
Shape::TopRight => [PushDir::Up, PushDir::Right],
Shape::TopLeft => [PushDir::Left, PushDir::Up],
Shape::BottomLeft => [PushDir::Down, PushDir::Left],
Shape::BottomRight => [PushDir::Right, PushDir::Down],
Shape::Full => unreachable!("already eliminated this possibility"),
};
// does the direction we're pushing appear in this list?
if !possible_directions.contains(&direction) {
break;
// does the direction we're pushing appear in this list?
if possible_directions.contains(&direction) {
// the other shape goes in the other direction
let other_direction = {
let mut set = possible_directions.iter().collect::<HashSet<_>>();
set.remove(&direction);
*set.into_iter().next().unwrap()
};
return self.block_can_move(other_block, other_direction, change_set);
}
}
// the other shape goes in the other direction
let other_direction = {
let mut set = possible_directions.iter().collect::<HashSet<_>>();
set.remove(&direction);
*set.into_iter().next().unwrap()
};
return self.block_can_move(other_block, other_direction, change_set);
}
// handle normal pushes
@ -288,18 +260,20 @@ impl Level {
Err(fail_set!(change_set))
}
Entity::Block(index) => {
if
// if it's part of the same block it's ok to push
if block_index.is_some() && block_index.unwrap() == index {
Ok(change_set)
}
block_index.is_some() && block_index.unwrap() == index ||
// if the shapes are opposite, we can actually both fit into the same spot
else if segment.shape.is_opposite(&shape) {
segment.shape.is_opposite(shape)
{
Ok(change_set)
}
// if the block is already in the change set, it can't move
else if change_set.contains_key(&Entity::Block(index)) {
Err(fail_set!(change_set))
} else {
}
// if the next block can move then so can this one
else {
self.block_can_move(index, direction, change_set)
}
}
@ -414,7 +388,7 @@ impl Level {
location.1 += (animation_offset.1 * scale as f32) as i32;
renderer.render_segment(
location,
(scale - 8),
scale - 8,
player.color,
Orientation::Both,
Shape::Full,

View file

@ -17,7 +17,7 @@ use std::time::Instant;
use glium::glutin::dpi::PhysicalSize;
use glium::glutin::{ContextBuilder, Event, EventsLoop, WindowBuilder, WindowEvent};
use glium::{Display, Rect, Surface};
use glium::{Display, Surface};
use crate::game::Game;

View file

@ -2,7 +2,7 @@ use std::collections::HashMap;
use glium::texture::RawImage2d;
use glium::{Display, Program, ProgramCreationError, Texture2d};
use image::{DynamicImage, GenericImageView, ImageBuffer, ImageError, Rgba};
use image::{DynamicImage, GenericImageView, ImageError};
#[derive(Default)]
pub struct Resources {