mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-16 12:12:35 -06:00
refactor: simplify/improve is_adjacent, add tests & docs
This commit is contained in:
113
src/helper.rs
113
src/helper.rs
@@ -1,15 +1,110 @@
|
||||
/// Checks if two grid positions are adjacent to each other
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `a` - First position as (x, y) coordinates
|
||||
/// * `b` - Second position as (x, y) coordinates
|
||||
/// * `diagonal` - Whether to consider diagonal adjacency (true) or only orthogonal (false)
|
||||
///
|
||||
/// # Returns
|
||||
/// * `true` if positions are adjacent according to the diagonal parameter
|
||||
/// * `false` otherwise
|
||||
pub fn is_adjacent(a: (u32, u32), b: (u32, u32), diagonal: bool) -> bool {
|
||||
let (ax, ay) = a;
|
||||
let (bx, by) = b;
|
||||
|
||||
// Calculate absolute differences between coordinates
|
||||
let dx = if ax > bx { ax - bx } else { bx - ax };
|
||||
let dy = if ay > by { ay - by } else { by - ay };
|
||||
|
||||
if diagonal {
|
||||
(ax == bx && (ay == by + 1 || ay == by - 1))
|
||||
|| (ay == by && (ax == bx + 1 || ax == bx - 1))
|
||||
|| (ax == bx + 1 && ay == by + 1)
|
||||
|| (ax == bx + 1 && ay == by - 1)
|
||||
|| (ax == bx - 1 && ay == by + 1)
|
||||
|| (ax == bx - 1 && ay == by - 1)
|
||||
// For diagonal adjacency: both differences must be ≤ 1 and at least one > 0
|
||||
dx <= 1 && dy <= 1 && (dx + dy) > 0
|
||||
} else {
|
||||
(ax == bx && (ay == by + 1 || ay == by - 1))
|
||||
|| (ay == by && (ax == bx + 1 || ax == bx - 1))
|
||||
// For orthogonal adjacency: exactly one difference must be 1, the other 0
|
||||
(dx == 1 && dy == 0) || (dx == 0 && dy == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_orthogonal_adjacency() {
|
||||
// Test orthogonal adjacency (diagonal = false)
|
||||
|
||||
// Same position should not be adjacent
|
||||
assert!(!is_adjacent((0, 0), (0, 0), false));
|
||||
|
||||
// Adjacent positions should be true
|
||||
assert!(is_adjacent((0, 0), (1, 0), false)); // Right
|
||||
assert!(is_adjacent((0, 0), (0, 1), false)); // Down
|
||||
assert!(is_adjacent((1, 1), (0, 1), false)); // Left
|
||||
assert!(is_adjacent((1, 1), (1, 0), false)); // Up
|
||||
|
||||
// Diagonal positions should be false
|
||||
assert!(!is_adjacent((0, 0), (1, 1), false));
|
||||
assert!(!is_adjacent((0, 1), (1, 0), false));
|
||||
|
||||
// Positions more than 1 step away should be false
|
||||
assert!(!is_adjacent((0, 0), (2, 0), false));
|
||||
assert!(!is_adjacent((0, 0), (0, 2), false));
|
||||
assert!(!is_adjacent((0, 0), (2, 2), false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_diagonal_adjacency() {
|
||||
// Test diagonal adjacency (diagonal = true)
|
||||
|
||||
// Same position should not be adjacent
|
||||
assert!(!is_adjacent((0, 0), (0, 0), true));
|
||||
|
||||
// Orthogonal adjacent positions should be true
|
||||
assert!(is_adjacent((0, 0), (1, 0), true)); // Right
|
||||
assert!(is_adjacent((0, 0), (0, 1), true)); // Down
|
||||
assert!(is_adjacent((1, 1), (0, 1), true)); // Left
|
||||
assert!(is_adjacent((1, 1), (1, 0), true)); // Up
|
||||
|
||||
// Diagonal adjacent positions should be true
|
||||
assert!(is_adjacent((0, 0), (1, 1), true)); // Down-right
|
||||
assert!(is_adjacent((1, 0), (0, 1), true)); // Down-left
|
||||
assert!(is_adjacent((0, 1), (1, 0), true)); // Up-right
|
||||
assert!(is_adjacent((1, 1), (0, 0), true)); // Up-left
|
||||
|
||||
// Positions more than 1 step away should be false
|
||||
assert!(!is_adjacent((0, 0), (2, 0), true));
|
||||
assert!(!is_adjacent((0, 0), (0, 2), true));
|
||||
assert!(!is_adjacent((0, 0), (2, 2), true));
|
||||
assert!(!is_adjacent((0, 0), (1, 2), true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edge_cases() {
|
||||
// Test with larger coordinates
|
||||
assert!(is_adjacent((100, 100), (101, 100), false));
|
||||
assert!(is_adjacent((100, 100), (100, 101), false));
|
||||
assert!(!is_adjacent((100, 100), (102, 100), false));
|
||||
|
||||
assert!(is_adjacent((100, 100), (101, 101), true));
|
||||
assert!(!is_adjacent((100, 100), (102, 102), true));
|
||||
|
||||
// Test with zero coordinates
|
||||
assert!(is_adjacent((0, 0), (1, 0), false));
|
||||
assert!(is_adjacent((0, 0), (0, 1), false));
|
||||
assert!(is_adjacent((0, 0), (1, 1), true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commutative_property() {
|
||||
// The function should work the same regardless of parameter order
|
||||
assert_eq!(
|
||||
is_adjacent((1, 2), (2, 2), false),
|
||||
is_adjacent((2, 2), (1, 2), false)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
is_adjacent((1, 2), (2, 3), true),
|
||||
is_adjacent((2, 3), (1, 2), true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ mod constants;
|
||||
mod direction;
|
||||
mod entity;
|
||||
mod game;
|
||||
mod helper;
|
||||
mod map;
|
||||
mod modulation;
|
||||
mod pacman;
|
||||
|
||||
Reference in New Issue
Block a user