-
Notifications
You must be signed in to change notification settings - Fork 45
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
(Improvement) Add additional calculation methods to RoomXY #521
Conversation
These functions give RoomXY approximate parity with Position for doing math and being convenient to use.
@@ -229,6 +246,19 @@ impl RoomXY { | |||
} | |||
} | |||
|
|||
impl PartialOrd for RoomXY { |
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.
Strongly disagree with these impls existing, considering even in-game objects disagree on being row or column major (which this implicitly enforces).
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.
This was copied over from Position
, purely because it allows for usage as a key in things like BTreeMap
and that seems like a reasonable thing to keep parity with. If we want to tear it out here, we should tear it out there as well.
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.
Honestly, yes. Position is even worse, since on top of picking row/column major, you also have to decide if you're doing a lex order on the (room name, room xy) pair or treating the whole position as a single world xy.
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 position, there's really 6 different ways you could arrange the components into a 4-tuple and use the lex ordering to come up with a sensible Position ordering:
(room_name.x, room_xy.x, room_name.y, room_xy.y)
(room_name.y, room_xy.y, room_name.x, room_xy.x)
<- the one Position implements(room_name.x, room_name.y, room_xy.x, room_xy.y)
(room_name.x, room_name.y, room_xy.y, room_xy.x)
(room_name.y, room_name.x, room_xy.x, room_xy.y)
(room_name.y, room_name.x, room_xy.y, room_xy.x)
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.
I can tear this out if we really want to, and you can open up a PR for tearing out the Position
implementation, but I'm not comfortable doing the latter in this PR. It feels out of scope for the intended goal of bringing RoomXY
into approximate API parity with Position
.
/// RoomXY::checked_new(9, 10).unwrap() | ||
/// ); | ||
/// ``` | ||
pub fn towards(self, target: RoomXY, distance_towards_target: i8) -> RoomXY { |
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.
This is a bit of a weird one; wouldn't you want a float in [0,1]
for self*x + target*(1-x)
?
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.
I'm not entirely sure what you're asking here. Can you clarify a bit more?
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.
It seems like this is supposed to be some sort of interpolation method, where you get a point on the line segment between self and target.
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.
Ah, yes, this is a directional interpolation method. I'm not sure that returning the interpolation multiplier (or even vector) is all that helpful, though, since the user would still need to determine what RoomXY
corresponds to that interpolation multiplier.
As with PartialOrd
, this was copied from Position
for API parity.
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.
Left replies in discussions
Back from a trip and catching up on this - the changes look good to me, though it sounds like whether to implement |
That's pretty much where I'm sitting for the |
If we're going for consistency, then sure (although I'd also check that we used the same of column or row major here as we do for EDIT: I do think you can have a default impl PartialOrd for RoomXY {
fn partial_cmp(&self, other: &Self) -> Optional<Ordering> {
match (self.x.cmp(&other.x), self.y.cmp(&other.y)) {
(ord, Equal) | (Equal, ord) => Some(ord),
(a, b) if a == b => Some(a),
_ => None
}
// To make the point clearer, and actually be more efficient
// according to godbolt:
let row_major = RowMajor(*self).cmp(&RowMajor(*other));
let col_major = ColMajor(*self).cmp(&ColMajor(*other));
(row_major == col_major).then_some(row_major)
}
} This partial ordering would be extendible into either row or column major ordering, i.e. if |
It's the same ordering. https://github.com/rustyscreeps/screeps-game-api/blob/main/src/local/position.rs#L376 |
Got #523 opened for switching over to a struct-wrapped implementation for all of these ordered types when someone has a chance to implement that. |
This PR adds calculation methods to
RoomXY
that give it approximate parity toPosition
.