Проектная работа - MVP

Создание нового проекта
This commit is contained in:
28 changed files with 6505 additions and 3 deletions
+127
View File
@@ -0,0 +1,127 @@
/// Инициализация логирования
pub fn define_log_layer() -> Option<bevy::log::BoxedFmtLayer> {
use std::fs::File;
use tracing::Level;
use tracing_subscriber::{Layer, filter::Targets, fmt::layer};
let targets = Targets::new().with_default(Level::TRACE);
let stdout = layer()
.compact()
.with_thread_names(true)
.with_file(false)
.with_line_number(false)
.with_filter(targets.clone())
.boxed();
let file = match File::options().create(true).append(true).open("snake-game.log") {
Ok(file) => file,
Err(e) => {
eprintln!("No access to log file: {:?}", e);
return Some(stdout);
}
};
let log_file = layer()
.compact()
.with_ansi(false)
.with_thread_names(true)
.with_file(false)
.with_line_number(false)
.with_writer(file)
.with_filter(targets.clone())
.boxed();
Some(Box::new(vec![stdout, log_file]))
}
/// Разбиение изменения координаты по границам сетки
/// Элементы выходного вектора представляют пары значений, где первое обозначает промежуточное значение координаты,
/// а второе - изменение координаты относительно предыдущего значения (дельта).
/// Если движение начинается на границе сетки и оно не нулевое (начальное и конечное значение координвты отличаются),
/// то размер выходного вектора всегда больше 1 и второе значение первой пары (дельта) равно 0.
/// На основе этой логики происходит в дальнейшем распознавание момента прохождения узла сетки и генерируется соответствующее событие.
pub fn split_by_grid(src: f32, dst: f32, grid: f32) -> Vec<(f32, f32)> {
if dst == src {
return vec![(dst, 0.0)];
}
if grid <= 0.0 {
return vec![(dst, dst - src)];
};
let mut output = Vec::with_capacity(2);
if src < dst {
let src_grid = src / grid;
let dst_grid = dst / grid;
let src_grid_right = src_grid.ceil();
let dst_grid_left = dst_grid.floor();
let mut src: f32 = src;
for step in src_grid_right as i32..=dst_grid_left as i32 {
let step = step as f32 * grid;
output.push((step, step - src));
src = step;
}
if src != dst {
output.push((dst, dst - src));
}
} else {
let src_grid = src / grid;
let dst_grid = dst / grid;
let dst_grid_right = dst_grid.ceil();
let dst_grid_right = if dst_grid_right == dst { dst_grid_right + 1.0 } else { dst_grid_right };
let src_grid_left = src_grid.floor();
let mut dst: f32 = dst;
for step in dst_grid_right as i32..=src_grid_left as i32 {
let step = step as f32 * grid;
output.push((dst, dst - step));
dst = step;
}
output.push((dst, dst - src));
output.reverse();
}
output
}
#[cfg(test)]
mod test {
use crate::tools::*;
#[test]
fn test_split_by_grid() {
// движение вправо
assert_eq!(split_by_grid(1.0, 4.0, 5.0), vec![(4.0, 3.0)]);
assert_eq!(split_by_grid(3.0, 5.0, 5.0), vec![(5.0, 2.0)]);
assert_eq!(split_by_grid(3.0, 6.0, 5.0), vec![(5.0, 2.0), (6.0, 1.0)]);
assert_eq!(split_by_grid(3.0, 10.0, 5.0), vec![(5.0, 2.0), (10.0, 5.0)]);
assert_eq!(split_by_grid(3.0, 11.0, 5.0), vec![(5.0, 2.0), (10.0, 5.0), (11.0, 1.0)]);
assert_eq!(split_by_grid(-2.0, 3.0, 5.0), vec![(0.0, 2.0), (3.0, 3.0)]);
assert_eq!(split_by_grid(-6.0, 7.0, 5.0), vec![(-5.0, 1.0), (0.0, 5.0), (5.0, 5.0), (7.0, 2.0)]);
assert_eq!(split_by_grid(-6.0, -2.0, 5.0), vec![(-5.0, 1.0), (-2.0, 3.0)]);
// движение влево
assert_eq!(split_by_grid(4.0, 1.0, 5.0), vec![(1.0, -3.0)]);
assert_eq!(split_by_grid(5.0, 3.0, 5.0), vec![(5.0, 0.0), (3.0, -2.0)]);
assert_eq!(split_by_grid(6.0, 3.0, 5.0), vec![(5.0, -1.0), (3.0, -2.0)]);
assert_eq!(split_by_grid(10.0, 3.0, 5.0), vec![(10.0, 0.0), (5.0, -5.0), (3.0, -2.0)]);
assert_eq!(split_by_grid(11.0, 3.0, 5.0), vec![(10.0, -1.0), (5.0, -5.0), (3.0, -2.0)]);
assert_eq!(split_by_grid(3.0, -2.0, 5.0), vec![(0.0, -3.0), (-2.0, -2.0)]);
assert_eq!(split_by_grid(7.0, -6.0, 5.0), vec![(5.0, -2.0), (0.0, -5.0), (-5.0, -5.0), (-6.0, -1.0)]);
assert_eq!(split_by_grid(-2.0, -6.0, 5.0), vec![(-5.0, -3.0), (-6.0, -1.0)]);
// сценарии с нулевой сеткой
assert_eq!(split_by_grid(1.0, 4.0, 0.0), vec![(4.0, 3.0)]);
assert_eq!(split_by_grid(4.0, 1.0, 0.0), vec![(1.0, -3.0)]);
// сценарии со стартом в узле сетки
assert_eq!(split_by_grid(0.0, 1.5, 5.0), vec![(0.0, 0.0), (1.5, 1.5)]);
assert_eq!(split_by_grid(5.0, 7.0, 5.0), vec![(5.0, 0.0), (7.0, 2.0)]);
assert_eq!(split_by_grid(0.0, -1.5, 5.0), vec![(0.0, 0.0), (-1.5, -1.5)]);
assert_eq!(split_by_grid(5.0, 3.0, 5.0), vec![(5.0, 0.0), (3.0, -2.0)]);
// сценарии с нулевым движением
assert_eq!(split_by_grid(5.0, 5.0, 5.0), vec![(5.0, 0.0)]);
assert_eq!(split_by_grid(0.0, 0.0, 5.0), vec![(0.0, 0.0)]);
assert_eq!(split_by_grid(0.0, 0.0, 0.0), vec![(0.0, 0.0)]);
}
}