# Octagon border algorithm

I'm working on an open source game for 2 years but I'm very bad at math. The game permits moving a character on an octagonal basis. When the character reaches the border coordinate (colored in yellow), I permit him to travel to another octagon: The map is a simple 2d array of x, y coordinates. The goal is to know if an x, y tile coordinate is on a "yellow" tile, and which direction it represents (north, northeast, east etc.) depending on map width and height.

I wrote this algorithm many times and in two different language, example with Rust:

pub fn get_corner(width: i16, height: i16, new_row_i: i16, new_col_i: i16) -> Option<CornerEnum> {
let left_col_i_end = width / 3;
let right_col_i_start = (width / 3) * 2;
let top_row_i_end = height / 3;
let bottom_row_i_start = (height / 3) * 2;
let mut more = if new_row_i >= 0 { new_row_i } else { 0 };
#[allow(unused_assignments)]
let mut right_col_i = 0;
#[allow(unused_assignments)]
let mut left_col_i = 0;

if new_row_i < top_row_i_end {
right_col_i = right_col_i_start + more;
left_col_i = left_col_i_end - more;
} else {
if new_row_i >= bottom_row_i_start {
more = (height / 3) - (new_row_i - bottom_row_i_start + 1);
more = if more >= 0 { more } else { 0 };
right_col_i = right_col_i_start + more;
left_col_i = left_col_i_end - more;
} else {
left_col_i = left_col_i_end;
right_col_i = right_col_i_start;
}
}

if new_col_i < left_col_i && new_row_i < top_row_i_end {
return Some(CornerEnum::TopLeft);
}
if new_row_i < 0 && left_col_i <= new_col_i {
return Some(CornerEnum::Top);
}
if new_col_i >= right_col_i && new_row_i < top_row_i_end {
return Some(CornerEnum::TopRight);
}
if new_col_i > width - 1 && top_row_i_end <= new_row_i {
return Some(CornerEnum::Right);
}
if new_col_i >= right_col_i && new_row_i >= bottom_row_i_start {
return Some(CornerEnum::BottomRight);
}
if new_row_i > height - 1 && left_col_i_end <= new_col_i {
return Some(CornerEnum::Bottom);
}
if new_col_i < left_col_i && new_row_i >= bottom_row_i_start {
return Some(CornerEnum::BottomLeft);
}
if new_col_i < 0 && top_row_i_end <= new_row_i {
return Some(CornerEnum::Left);
}

None
}


But it is not working too well: it works only for some borders, but not for others, apparently depending on width/height odd/even... I curse my math. I'm sure it's not that complicated but I've failed for two years. So, I'm here to ask for a solution... which would be greatly appreciated!

• Remember, we have never seen your game before. Be more explicit about how it is not working... telling us that "it's not working well" is not very helpful to us, and thus not helpful to you, if you want answers. – Engineer May 22 at 15:10
• Hello Enginneer. I just add some detail in question. Thanks for you remark. – bux May 23 at 11:30
• Hello @bux. You're welcome. I have also edited your grammar to make it easier to read. Please check using a translator that I have not changed your meaning! – Engineer May 23 at 15:15