Use mora instead of characters, e.g. しゅ

master
Elnu 1 year ago
parent 4076a4c556
commit 96b97ca820

@ -25,7 +25,7 @@ ws.onmessage = e => {
case "word":
let waiting = data.author === id;
displayWord(data.word, true);
input.placeholder = waiting ? "Waiting for other players..." : `${data.next_char}`;
input.placeholder = waiting ? "Waiting for other players..." : `${data.next_mora}`;
input.disabled = waiting;
if (!waiting) input.focus();
break;

@ -47,7 +47,6 @@ impl Database {
}
pub fn load_words_before(&self, before_id: i64) -> Result<Vec<Word>> {
println!("{}", before_id);
self.conn
.prepare("SELECT id, word, reading, timestamp FROM word WHERE id < ? ORDER BY id DESC LIMIT 10")?
.query_map(params![before_id], |row| {

@ -30,7 +30,7 @@ enum MessageResponseData {
Word {
author: u64,
word: Word,
next_char: char,
next_mora: String,
},
History {
words: Vec<Word>,
@ -70,7 +70,7 @@ pub struct Server {
event_hub: EventHub,
database: Database,
clients: HashMap<u64, Responder>,
next_char: Option<char>,
next_mora: Option<String>,
last_client_id: Option<u64>,
}
@ -85,13 +85,59 @@ pub enum ServerError {
DatabaseError(rusqlite::Error),
}
fn get_starting_mora(word: &str) -> String {
if word.is_empty() {
return String::from("");
}
let word = word.to_hiragana();
let mut iter = word.chars();
let starting_char = iter.next().unwrap();
let second_char = iter.next().unwrap();
match second_char {
'ゃ' | 'ゅ' | 'ょ' => format!("{starting_char}{second_char}"),
_ => starting_char.to_string(),
}
}
// Trim off lengtheners and non-kana that are irrelevant to shiritori
// TODO: Use slices
fn trim_irrelevant_chars(word: &str) -> String {
let mut iter = word.chars().rev().peekable();
while let Some(c) = iter.peek() {
if *c == 'ー' || !c.to_string().is_kana() {
iter.next();
} else {
break;
}
}
iter.rev().collect()
}
// Get final mora, which could be multiple chars e.g. しゃ
// TODO: Use slices
fn get_final_mora(word: &str) -> String {
let word = trim_irrelevant_chars(word).to_hiragana();
if word.is_empty() {
return String::from("");
}
let mut iter = word.chars().rev();
let final_char = iter.next().unwrap();
match final_char {
'ゃ' | 'ゅ' | 'ょ' => format!("{}{final_char}", match iter.next() {
Some(c) => c.to_string(),
None => String::from(""),
}),
_ => final_char.to_string(),
}
}
impl Server {
pub fn new(port: u16, testing: bool) -> Result<Self, ServerCreationError> {
Ok(Server {
event_hub: simple_websockets::launch(port)?,
database: Database::new(testing)?,
clients: HashMap::new(),
next_char: None,
next_mora: None,
last_client_id: None,
})
}
@ -153,32 +199,23 @@ impl Server {
} else {
match lookup(&message) {
Some(entry) => {
println!("{}, {:?}", get_starting_mora(&entry.reading), self.next_mora);
if entry.reading.chars().last().unwrap().to_string().to_hiragana() == "ん" {
MessageResponseData::Error {
message: String::from("Can't end with ん!"),
}
} else if self.next_char.is_none() || entry.reading.chars().next().unwrap().to_string().to_hiragana().chars().next().unwrap() == self.next_char.unwrap() {
self.next_char = {
// If final character is lengthener or not kana
// Use semifinal
let mut final_chars = entry.reading.chars().rev();
let final_char = final_chars.next().unwrap();
Some(if final_char == 'ー' || !final_char.to_string().is_kana() {
final_chars.next().unwrap()
} else {
final_char
}.to_string().to_hiragana().chars().next().unwrap())
};
} 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)?;
MessageResponseData::Word {
author: client_id,
word,
next_char: self.next_char.unwrap(),
next_mora: self.next_mora.as_deref().unwrap().to_owned(),
}
} else {
MessageResponseData::Error {
message: String::from("Wrong starting kana!"),
message: String::from("Wrong starting mora!"),
}
}
}

Loading…
Cancel
Save