use anyhow::anyhow;
use crate::img::CodeImg;
pub struct Cursor<'a> {
pub x: u32,
pub y: u32,
next_move: Move,
prev_move: Move,
code: &'a mut CodeImg,
}
#[derive(Clone, Copy)]
enum Move {
Left,
UpRight,
DownRight,
}
impl<'a> Cursor<'a> {
pub fn new(code: &'a mut CodeImg, side_len: u32) -> Self {
Self {
x: side_len - 1,
y: side_len - 1,
next_move: Move::Left,
prev_move: Move::UpRight,
code,
}
}
pub fn next(&mut self) -> anyhow::Result<bool> {
match self.next_move {
Move::Left => {
if self.x != 0 && !self.code.is_open(self.x - 1, self.y) {
self.code.save()?;
return Err(anyhow!("No valid moves! at ({},{})", self.x, self.y));
}
self.x -= 1;
match &self.prev_move {
Move::Left => {
if self.y != 0 && self.code.is_open(self.x + 1, self.y - 1) {
self.next_move = Move::UpRight;
} else {
self.next_move = Move::DownRight;
}
self.prev_move = Move::Left;
}
other_move => {
self.next_move = *other_move;
self.prev_move = Move::Left;
}
}
}
Move::UpRight => {
if self.y != 0 && self.code.is_open(self.x + 1, self.y - 1) {
self.x += 1;
self.y -= 1;
self.next_move = Move::Left;
self.prev_move = Move::UpRight;
} else if self.y >= 1 && self.code.is_open(self.x, self.y - 1) {
self.y -= 1;
self.next_move = Move::UpRight;
self.prev_move = Move::UpRight;
} else if self.y >= 2 && self.code.is_open(self.x + 1, self.y - 2) {
self.x += 1;
self.y -= 2;
self.next_move = Move::Left;
self.prev_move = Move::UpRight;
} else if self.y >= 2 && self.code.is_open(self.x, self.y - 2) {
self.y -= 2;
self.next_move = Move::UpRight;
self.prev_move = Move::UpRight;
} else if self.y >= 6 && self.code.is_open(self.x + 1, self.y - 6) {
self.x += 1;
self.y -= 6;
self.next_move = Move::Left;
self.prev_move = Move::UpRight;
} else if self.y >= 7 && self.x >= 2 && self.code.is_open(self.x - 2, self.y - 7) {
self.x -= 2;
self.y -= 7;
self.next_move = Move::DownRight;
self.prev_move = Move::DownRight;
} else if self.x >= 1 && self.code.is_open(self.x - 1, self.y) {
self.x -= 1;
self.next_move = Move::Left;
self.prev_move = Move::Left;
} else if self.x >= 2 && self.code.is_open(self.x - 2, self.y) {
self.x -= 2;
self.next_move = Move::Left;
self.prev_move = Move::Left;
} else {
self.code.save()?;
return Err(anyhow!("No valid moves! at ({},{})", self.x, self.y));
}
}
Move::DownRight => {
if self.code.is_open(self.x + 1, self.y + 1) {
self.x += 1;
self.y += 1;
self.next_move = Move::Left;
self.prev_move = Move::DownRight;
} else if self.code.is_open(self.x, self.y + 1) {
self.y += 1;
self.prev_move = Move::DownRight;
self.next_move = Move::DownRight;
} else if self.code.is_open(self.x + 1, self.y + 2) {
self.x += 1;
self.y += 2;
self.next_move = Move::Left;
self.prev_move = Move::DownRight;
} else if self.code.is_open(self.x, self.y + 2) {
self.y += 2;
self.prev_move = Move::DownRight;
self.next_move = Move::DownRight;
} else if self.code.is_open(self.x + 1, self.y + 6) {
self.x += 1;
self.y += 6;
self.next_move = Move::Left;
self.prev_move = Move::DownRight;
} else if self.x >= 1 && self.code.is_open(self.x - 1, self.y) {
self.x -= 1;
self.next_move = Move::Left;
self.prev_move = Move::Left;
} else if self.x >= 1 && self.y >= 8 && self.code.is_open(self.x - 1, self.y - 8) {
self.x -= 1;
self.y -= 8;
self.next_move = Move::Left;
self.prev_move = Move::Left;
} else {
return Ok(false);
}
}
};
return Ok(true);
}
pub fn place(&mut self, color: bool) {
self.code.fill_module(self.x, self.y, color)
}
pub fn place_debug(&mut self, color: image::Rgba<u8>) {
self.code.debug(self.x, self.y, color)
}
}