Restructuring, prepare for room, Discord support
This commit is contained in:
parent
1fbb0ede50
commit
ed11799bf5
8 changed files with 492 additions and 239 deletions
92
src/room.rs
Normal file
92
src/room.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
// ---------------
|
||||
// Module overview
|
||||
// ---------------
|
||||
//
|
||||
// RoomSettings: Stores database settings for room.
|
||||
// In future, could store passphrase, etc.
|
||||
//
|
||||
// Room: Game state abstracted away from any networking.
|
||||
// Any events that aren't game-related are handled by Server.
|
||||
|
||||
use crate::database::{Database, DatabaseCreationError, DatabaseSettings};
|
||||
use crate::dictionary::lookup;
|
||||
use crate::response::MessageResponseData;
|
||||
use crate::utils::{get_starting_mora, get_final_mora};
|
||||
use crate::word::Word;
|
||||
|
||||
use wana_kana::{IsJapaneseStr, ConvertJapanese};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RoomSettings {
|
||||
pub database_settings: DatabaseSettings,
|
||||
}
|
||||
|
||||
pub struct Room {
|
||||
database: Database,
|
||||
next_mora: Option<String>,
|
||||
last_client_id: Option<u64>,
|
||||
}
|
||||
|
||||
impl Room {
|
||||
pub fn new(settings: RoomSettings) -> Result<Self, DatabaseCreationError> {
|
||||
Ok(Self {
|
||||
database: Database::new(settings.database_settings)?,
|
||||
next_mora: None,
|
||||
last_client_id: None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn next_mora(&self) -> &Option<String> {
|
||||
&self.next_mora
|
||||
}
|
||||
|
||||
pub fn get_history(&self) -> rusqlite::Result<Vec<Word>> {
|
||||
self.database.load_words_before(self.database.last_word_id + 1)
|
||||
}
|
||||
|
||||
// Err(&str) will be converted to MessageResponseData::Error
|
||||
pub fn handle_query(&mut self, query: &str, client_id: u64) -> Result<MessageResponseData, &str> {
|
||||
// Ensure query isn't from last player
|
||||
if Some(client_id) == self.last_client_id {
|
||||
return Err("It's not your turn!");
|
||||
};
|
||||
|
||||
// Ensure query is in Japanese
|
||||
let query = query.to_string();
|
||||
let query = if query.is_japanese() {
|
||||
query
|
||||
} else {
|
||||
let kana = query.to_kana();
|
||||
if kana.is_japanese() {
|
||||
kana
|
||||
} else {
|
||||
return Err("Not Japanese!");
|
||||
}
|
||||
};
|
||||
|
||||
// Look up word in dictionary
|
||||
let dictionary_result = lookup(&query);
|
||||
|
||||
// Send result
|
||||
match dictionary_result {
|
||||
Some(entry) => {
|
||||
if entry.reading.chars().last().unwrap().to_string().to_hiragana() == "ん" {
|
||||
Err("Can't end with ん!")
|
||||
} else if self.next_mora.is_none() || get_starting_mora(&entry.reading).eq(self.next_mora.as_deref().unwrap()) {
|
||||
let word: Word = entry.clone().into();
|
||||
self.next_mora = Some(get_final_mora(&word.reading));
|
||||
self.database.add_word(&word).unwrap(); // TODO: replace .unwrap() with ?
|
||||
self.last_client_id = Some(client_id);
|
||||
Ok(MessageResponseData::Word {
|
||||
author: client_id,
|
||||
word,
|
||||
next_mora: self.next_mora.as_deref().unwrap().to_owned(),
|
||||
})
|
||||
} else {
|
||||
Err("Wrong starting mora!")
|
||||
}
|
||||
}
|
||||
None => Err("Not in dictionary!"),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue