feat: Completed commands list

- Added MapError::CannotReach variant
- Updated Map::unlock_room_for_account to check reachableness
- Added /info command
- Added /unlock command
- Added /move command
- Added /reset command
This commit is contained in:
Alexey 2025-12-15 15:19:07 +03:00
commit b6ea2d8958
11 changed files with 170 additions and 12 deletions

View file

@ -69,8 +69,10 @@ pub enum MapError {
RoomNotFound(u16),
/// Room (self.0) is already unlocked on account (self.1)
RoomAlreadyUnlocked(u16, String),
/// Account (self.1) does not have much money (self.0)
InsufficientFunds(u16, String),
/// Account (self.1) does not have much money (self.0), expected (self.2)
InsufficientFunds(u16, String, u32),
/// Account (self.1) can't reach room (self.0)
CannotReach(u16, String),
}
impl fmt::Display for MapError {
@ -78,7 +80,8 @@ impl fmt::Display for MapError {
match self {
Self::RoomNotFound(id) => write!(f, "could not find room #{id}"),
Self::RoomAlreadyUnlocked(room_id, account_id) => write!(f, "room #{room_id} is already unlocked on account \"{account_id}\""),
Self::InsufficientFunds(room_id, account_id) => write!(f, "account \"{account_id}\" does not have enough money to unlock room #{room_id}"),
Self::InsufficientFunds(room_id, account_id, amount) => write!(f, "account \"{account_id}\" does not have enough money to unlock room #{room_id}, expected {amount}"),
Self::CannotReach(room, account) => write!(f, "account \"{account}\" cannot reach room #{room}"),
}
}
}

View file

@ -99,8 +99,15 @@ impl Map {
return Err(MapError::RoomAlreadyUnlocked(room_id, account.id.clone()));
}
// Room 0 will always be reachable
let reachable = room.reachable_for(&account) || room.id == 0;
if !reachable {
return Err(MapError::CannotReach(room_id, account.id.clone()));
}
if account.balance < room.value {
return Err(MapError::InsufficientFunds(room_id, account.id.clone()));
return Err(MapError::InsufficientFunds(room_id, account.id.clone(), room.value));
}
account.balance -= room.value;
@ -141,3 +148,14 @@ impl Default for Room {
}
}
}
impl Room {
fn reachable_for(&self, account: &Account) -> bool {
for rid in account.rooms_unlocked.iter() {
if self.children.contains(&rid) {
return true;
}
}
false
}
}