sys/sysmod/openai/basicfuncs/
game.rs

1//! ゲーム。
2
3use crate::sysmod::openai::ParameterType;
4use crate::sysmod::openai::function::{
5    FuncArgs, Function, FunctionTable, ParameterElement, Parameters, get_arg_i64, get_arg_str,
6};
7use utils::game::mine_sweeper::{self, MineSweeper};
8
9use anyhow::{Result, bail};
10use std::collections::HashMap;
11
12/// このモジュールの関数をすべて登録する。
13pub fn register_all<T: 'static>(func_table: &mut FunctionTable<T>) {
14    register_mine_sweeper(func_table);
15}
16
17/// マインスイーパ。
18async fn mine_sweeper(args: &FuncArgs) -> Result<String> {
19    static GAME: std::sync::Mutex<Option<MineSweeper>> = std::sync::Mutex::new(None);
20
21    let action = get_arg_str(args, "action")?;
22
23    let mut game = GAME.lock().unwrap();
24    if game.is_none() {
25        *game = Some(MineSweeper::new(mine_sweeper::Level::Easy.to_config()).unwrap());
26    }
27
28    let result = match action {
29        "start" => {
30            *game = Some(MineSweeper::new(mine_sweeper::Level::Easy.to_config()).unwrap());
31
32            game.as_ref().unwrap().to_json_pretty()
33        }
34        "status" => {
35            let game = game.as_ref().unwrap();
36
37            game.to_json_pretty()
38        }
39        "open" => {
40            let game = game.as_mut().unwrap();
41
42            let x = get_arg_i64(args, "x", 1..=game.width as i64)? as i32 - 1;
43            let y = get_arg_i64(args, "y", 1..=game.height as i64)? as i32 - 1;
44
45            game.reveal(x, y)?;
46
47            game.to_json_pretty()
48        }
49        _ => {
50            bail!("Invalid action: {}", action);
51        }
52    };
53
54    Ok(result)
55}
56
57fn register_mine_sweeper<T: 'static>(func_table: &mut FunctionTable<T>) {
58    let mut properties = HashMap::new();
59    properties.insert(
60        "action".to_string(),
61        ParameterElement {
62            type_: vec![ParameterType::String],
63            description: None,
64            enum_: Some(vec![
65                "start".to_string(),
66                "status".to_string(),
67                "open".to_string(),
68            ]),
69        },
70    );
71    properties.insert(
72        "x".to_string(),
73        ParameterElement {
74            type_: vec![ParameterType::Integer, ParameterType::Null],
75            description: Some("x to be opened (1 <= x <= width)".to_string()),
76            ..Default::default()
77        },
78    );
79    properties.insert(
80        "y".to_string(),
81        ParameterElement {
82            type_: vec![ParameterType::Integer, ParameterType::Null],
83            description: Some("y to be opened (1 <= y <= height)".to_string()),
84            ..Default::default()
85        },
86    );
87
88    func_table.register_function(
89        Function {
90            name: "mine_sweeper".to_string(),
91            description: Some("Play Mine Sweeper".to_string()),
92            parameters: Parameters {
93                properties,
94                required: vec!["action".to_string(), "x".to_string(), "y".to_string()],
95                ..Default::default()
96            },
97            ..Default::default()
98        },
99        |_, _, args| Box::pin(mine_sweeper(args)),
100    );
101}