-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add distance transform algorithm #17
Conversation
src/algorithms/distance_transform.rs
Outdated
for x in 0..ROOM_SIZE { | ||
for y in 0..ROOM_SIZE { | ||
let position = unsafe { RoomXY::unchecked_new(x as u8, y as u8) }; | ||
let val = match &room_data.terrain.get_xy(position) { | ||
screeps::constants::Terrain::Wall => 0, | ||
_ => 255, | ||
}; | ||
|
||
initial_cm.set(position, val); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for x in 0..ROOM_SIZE { | |
for y in 0..ROOM_SIZE { | |
let position = unsafe { RoomXY::unchecked_new(x as u8, y as u8) }; | |
let val = match &room_data.terrain.get_xy(position) { | |
screeps::constants::Terrain::Wall => 0, | |
_ => 255, | |
}; | |
initial_cm.set(position, val); | |
} | |
for (xy, cm_val) in initial_cm.iter_mut() { | |
*cm_val = match room_data.terrain.get_xy(xy) { | |
screeps::constants::Terrain::Wall => 0, | |
_ => 255 | |
}; | |
} |
src/algorithms/distance_transform.rs
Outdated
let current_position = unsafe { RoomXY::unchecked_new(x as u8, y as u8) }; | ||
|
||
// The distance to the closest wall is the minimum of the current position value and | ||
// all of its neighbors. However, since we're going RTL:TTB, we can ignore tiles we |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// all of its neighbors. However, since we're going RTL:TTB, we can ignore tiles we | |
// all of its neighbors. However, since we're going LTR:TTB, we can ignore tiles we |
src/algorithms/distance_transform.rs
Outdated
|
||
// The distance to the closest wall is the minimum of the current position value and | ||
// all of its neighbors. However, since we're going RTL:TTB, we can ignore tiles we | ||
// know we haven't visited yet: Right, BottomRight, and Bottom. We could include them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also ignore TopRight.
src/algorithms/distance_transform.rs
Outdated
let mut neighbor_values: [u8; 5] = [255; 5]; | ||
|
||
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::Top) { | ||
let value = cm.get(neighbor_position); | ||
neighbor_values[0] = value; | ||
} | ||
|
||
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::Left) { | ||
let value = cm.get(neighbor_position); | ||
neighbor_values[1] = value; | ||
} | ||
|
||
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::TopLeft) { | ||
let value = cm.get(neighbor_position); | ||
neighbor_values[2] = value; | ||
} | ||
|
||
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::TopRight) { | ||
let value = cm.get(neighbor_position); | ||
neighbor_values[3] = value; | ||
} | ||
|
||
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::BottomLeft) { | ||
let value = cm.get(neighbor_position); | ||
neighbor_values[4] = value; | ||
} | ||
|
||
let current_value = cm.get(current_position); | ||
|
||
let neighbors_minimum = match neighbor_values.iter().min() { | ||
Some(value) => match value { | ||
255 => 255, | ||
_ => value + 1 | ||
}, | ||
None => 255, | ||
}; | ||
|
||
let min_value = cmp::min(current_value, neighbors_minimum); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let mut neighbor_values: [u8; 5] = [255; 5]; | |
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::Top) { | |
let value = cm.get(neighbor_position); | |
neighbor_values[0] = value; | |
} | |
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::Left) { | |
let value = cm.get(neighbor_position); | |
neighbor_values[1] = value; | |
} | |
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::TopLeft) { | |
let value = cm.get(neighbor_position); | |
neighbor_values[2] = value; | |
} | |
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::TopRight) { | |
let value = cm.get(neighbor_position); | |
neighbor_values[3] = value; | |
} | |
if let Some(neighbor_position) = current_position.checked_add_direction(Direction::BottomLeft) { | |
let value = cm.get(neighbor_position); | |
neighbor_values[4] = value; | |
} | |
let current_value = cm.get(current_position); | |
let neighbors_minimum = match neighbor_values.iter().min() { | |
Some(value) => match value { | |
255 => 255, | |
_ => value + 1 | |
}, | |
None => 255, | |
}; | |
let min_value = cmp::min(current_value, neighbors_minimum); | |
let min_value = [Direction::Top, Direction::TopLeft, Direction::Left, Direction::BottomLeft].into_iter() | |
.filter_map(|dir| current_position.checked_add_direction(dir)) | |
.map(|position| cm.get(position)) | |
.min() | |
.map(|x| x.saturating_add(1)) | |
.map(|x| x.min(cm.get(current_position))) | |
.unwrap_or_else(|| cm.get(current_position)); |
Can do basically the same thing for the reverse direction too.
Adds a basic implementation of the distance transform algorithm.