Implemented choices successfully

This commit is contained in:
2026-05-10 23:19:42 +01:00
parent 7e5874ffbb
commit fbd315ed7b
5 changed files with 85 additions and 79 deletions
+5 -2
View File
@@ -1,4 +1,5 @@
import requests import requests
import os
# Loop and get new api # Loop and get new api
def main(): def main():
@@ -6,14 +7,17 @@ def main():
while True: while True:
try: try:
response = api_get() response = api_get()
print(response)
match response["action_type"]: match response["action_type"]:
case "output": case "output":
character = get_character(response["character"]) character = get_character(response["character"])
output(character, response["content"]) output(character, response["content"])
case "choice": case "choice":
user_choice = choice(response["choices"]) user_choice = choice(response["choices"])
continue
case "end": case "end":
exit() print("Exitting successfully")
os._exit(0)
except: except:
print("Server not up or cannot be reached") print("Server not up or cannot be reached")
input() # Enter to go to next loop (testing) input() # Enter to go to next loop (testing)
@@ -44,7 +48,6 @@ def get_character(character):
def api_get(): def api_get():
api_url = "http://localhost:20264/happening/" api_url = "http://localhost:20264/happening/"
response = requests.get(api_url).json() response = requests.get(api_url).json()
print(response)
return response return response
main() main()
+1 -28
View File
@@ -29,40 +29,13 @@ pub struct Character
bottom_clothing: String, bottom_clothing: String,
shoes: String, shoes: String,
} }
impl Character
{
pub fn new(new_name: String) -> Character
{
Character
{
name: new_name,
gender: "".to_string(),
eye_color: "".to_string(),
pronoun_subject: "".to_string(),
pronoun_object: "".to_string(),
pronoun_deppos: "".to_string(),
pronoun_indpos: "".to_string(),
pronoun_reflex: "".to_string(),
animation: "".to_string(),
head: "".to_string(),
hair: "".to_string(),
torso: "".to_string(),
arm: "".to_string(),
leg: "".to_string(),
hair_color: "".to_string(),
top_clothing: "".to_string(),
bottom_clothing: "".to_string(),
shoes: "".to_string(),
}
}
}
pub async fn character_parse() pub async fn character_parse()
-> Result<Arc<Mutex<HashMap<String, Character>>>,String> -> Result<Arc<Mutex<HashMap<String, Character>>>,String>
{ {
// Get the JSON file to a string // Get the JSON file to a string
let file_contents: String = fs::read_to_string("stories/characters.json") let file_contents: String = fs::read_to_string("stories/characters.json")
.unwrap_or_else(|err| { return err.to_string() }); .unwrap_or_else(|err| { err.to_string() });
// Serialise this to a HashMap // Serialise this to a HashMap
let characters: HashMap<String, Character> = let characters: HashMap<String, Character> =
+16 -9
View File
@@ -9,9 +9,13 @@ use log::
info, info,
warn, warn,
debug, debug,
error,
};
use serde::
{
Deserialize,
Serialize
}; };
use serde_json::from_str;
use serde::{Deserialize, Serialize};
mod parsing; mod parsing;
mod character; mod character;
@@ -34,13 +38,16 @@ async fn main()
choices: vec![], choices: vec![],
})); }));
// Setup the characters hashmap which will store each character in it as a Character struct // Setup the characters hashmap which will store each character in it as a Character struct
let mut characters: Arc<Mutex<HashMap::<String, character::Character>>> = Default::default(); let characters = match character::character_parse().await
match character::character_parse().await
{ {
Ok(result) => characters = result, //let mut characters = character, Ok(result) =>
Err(error) =>
{ {
eprintln!("{}",error); info!("{:?}", result);
result
},
Err(error) =>
{
error!("{}",error);
std::process::exit(3); std::process::exit(3);
}, },
}; };
@@ -64,7 +71,7 @@ async fn main()
let file_contents: String = fs::read_to_string("stories/story.ha") // TODO make this a command line argument let file_contents: String = fs::read_to_string("stories/story.ha") // TODO make this a command line argument
.unwrap_or_else(|err| .unwrap_or_else(|err|
{ {
eprintln!("Failed to read file: {}", err); error!("Failed to read file: {}", err);
std::process::exit(2); std::process::exit(2);
}); });
let tokens: Vec<&str> = file_contents let tokens: Vec<&str> = file_contents
@@ -96,7 +103,7 @@ async fn main()
}, },
Err(error) => Err(error) =>
{ {
eprintln!("{}", error); error!("{}", error);
std::process::exit(1); std::process::exit(1);
}, },
} }
+54 -36
View File
@@ -26,67 +26,83 @@ pub async fn token_parse(
) -> Result<(),String> ) -> Result<(),String>
{ {
let mut index: usize = 0; let mut index: usize = 0;
if rx.recv().is_err()
{
warn!("Some issue with api");
// TOD eh?
};
// Run an infinite loop // Run an infinite loop
loop 'parse_loop: loop
{ {
// If the client hasn't responded then continue (after a short pause)
if rx.recv().is_err()
{
continue
}
// Get the next token // Get the next token
let token = tokens let token = tokens
.get(index) .get(index)
.ok_or_else(|| "File reached termination point".to_string())?; .ok_or_else(|| "File unexpectedly reached termination point".to_string())?;
debug!("{}: {}",index, token);
// The instructions are related to characters // The instructions are related to characters
if token.starts_with('@') if token.starts_with('@')
{ {
let character_name: String = token.chars().skip(1).collect(); let character_name: String = token.chars().skip(1).collect();
info!("Doing something with a character: {}", character_name); info!("Doing something with a character: {}", character_name);
// The index is incremented to after the character's instructions // The index is incremented to after the character's instructions
index += match character_parse(index+1, &tokens, character_name, &characters, &data_to_send).await index = match character_parse(index+1, tokens, character_name, &characters, &data_to_send).await
{ {
Ok(increment) => increment, Ok(increment) => increment,
Err(error) => return Err(error), Err(error) => return Err(error),
}; };
continue
} }
// Miscelleneous instructions // Miscelleneous instructions
match token.to_lowercase().as_str() else
{ {
"end" => match token.to_lowercase().as_str()
{ {
info!("END command, exiting"); "end" =>
return Ok(()) // quit
},
"choice" =>
{
let (_,jump_points) = match choice_parse(index+1, &tokens, &data_to_send).await
{ {
Ok((increment,jump_point)) => (increment,jump_point), info!("END command, exiting");
Err(error) => return Err(error), return Ok(()) // quit
}; },
if rx.recv().is_err() { warn!("Error sending choices to client"); }; "choice" =>
let (_, choice) = rx.recv().unwrap(); // TODO eh {
index = jump_points[choice]; let (_,jump_points) = match choice_parse(index+1, tokens, &data_to_send).await
debug!("{:?} {} {}",jump_points, choice, index); {
continue Ok((increment,jump_point)) => (increment,jump_point),
} Err(error) => return Err(error),
_ => };
{ if rx.recv().is_err() { warn!("Error sending choices to client"); };
warn!("Invalid command: {}", token); let (_, choice) = rx.recv().unwrap(); // TODO eh
} index = jump_points[choice];
debug!("{:?} {} {}",jump_points, choice, index);
continue 'parse_loop
},
"or" =>
{
index += strings::closing_char(&tokens[index..], '{','}').unwrap(); // TODO eh
continue
},
"}" =>
{
index += 1;
continue
},
_ =>
{
warn!("Invalid command: {}", token);
}
};
}
if rx.recv().is_err()
{
warn!("Some issue with api");
continue
} }
index += 1;
} }
} }
// TODO underdev // Parse the options in a choice clause and returns the idexes of the code blocks
async fn choice_parse async fn choice_parse
( (
index: usize, index: usize,
tokens: &Vec<&str>, tokens: &[&str],
data_to_send: &Arc<Mutex<api::DataToSend>>, data_to_send: &Arc<Mutex<api::DataToSend>>,
) -> Result<(usize, Vec<usize>), String> ) -> Result<(usize, Vec<usize>), String>
{ {
@@ -119,7 +135,8 @@ async fn choice_parse
} }
// Parsing character related instructions // Parsing character related instructions
async fn character_parse // TODO only send relevant tokens
#[allow(unused_variables)] async fn character_parse
( (
index: usize, index: usize,
tokens: &Vec<&str>, tokens: &Vec<&str>,
@@ -146,6 +163,7 @@ async fn character_parse
{ {
debug!("{}", output_string); debug!("{}", output_string);
sum_index += counter; sum_index += counter;
debug!("{}",sum_index);
let mut data = data_to_send.lock().unwrap(); let mut data = data_to_send.lock().unwrap();
data.action_type = String::from("output"); data.action_type = String::from("output");
data.content = output_string; data.content = output_string;
@@ -157,7 +175,7 @@ async fn character_parse
}, },
// Catch all condition, if the instruction is unrecognised as a // Catch all condition, if the instruction is unrecognised as a
// character command // character command
_ => return Err(String::from(format!("Invalid command: {}", token))), _ => return Err(format!("Invalid command: {}", token)),
} }
sum_index += 1; sum_index += 1;
Ok(sum_index) Ok(sum_index)
+9 -4
View File
@@ -2,11 +2,16 @@ pub fn closing_char(parts: &[&str], open: char, close: char)
-> Result<usize,()> -> Result<usize,()>
{ {
let mut indentation: usize = 0; let mut indentation: usize = 0;
for (index, part) in parts.into_iter().enumerate() let mut flag = false; // flag to mark you've passed open
for (index, part) in parts.iter().enumerate()
{ {
if part.contains(open) { indentation += 1; } if part.contains(open)
{
indentation += 1;
flag = true;
}
if part.contains(close) { indentation -= 1; } if part.contains(close) { indentation -= 1; }
if indentation == 0 { return Ok(index); } if indentation == 0 && flag == true { return Ok(index); }
} }
Err(()) Err(())
} }
@@ -19,7 +24,7 @@ pub fn extract_quoted(parts: &[&str])
{ {
counter += 1; counter += 1;
// End of the string // End of the string
if part.chars().next_back().unwrap() == '"' // TODO allow for backslashes and ' if part.ends_with('\"') // TODO allow for backslashes and '
{ {
vec_string.push(*part); vec_string.push(*part);
let final_string: String = vec_string.join(" "); let final_string: String = vec_string.join(" ");