¡Bienvenidos al

Rust Day

CDMX 2017!

Construyendo una aventura textual con Rust y mutando a ChatBot

Agenda

  • Modelado del Juego
  • Implementación con UI en línea de comandos
  • Implementación de un API REST para el juego

¿Qué es un

Text Adventure?

Modelando nuestra aventura

1) Estados

2) Transiciones

3) Diálogos

Construiremos una casa con Rust

Conceptos que aprenderemos

  • Gestión de módulos y estructura de proyectos
  • Estructuras y tipos de datos
  • Tiempos de vida (Lifetimes)
  • Iteradores
  • Patrones (Pattern Matching)
  • Mecanismos para compartir memoria de manera segura

Arrancando...

$ cargo new --bin text-adventure
     Created binary (application) `text-adventure` project
$ cd text-adventure

Para correr en cualquier momento

$ cargo run

Módulo house

Usamos módulos para agrupar funcionalidad

  • Estructuras de Datos
    • Structs
    • Traits
  • Funciones
src/house.rs

¿Qué es una casa?

pub struct Room<'a> {
    pub title: &'a str,
    pub description: &'a str,
    pub transitions: Vec<i32>
}
pub type House<'a> = HashMap<i32, Room<'a>>;

Construyendo la casa

pub fn build_house<'a>() -> House<'a> {
    let mut house = House::new();

    house.insert(-1, Room {
        title: "Entrada",
        description: "Estás frente a la puerta de la casa",
        transitions: vec![0],
    });
    // ...

    house
}

¿Quién habitará

la casa?

Módulo player

src/player.rs

¿Qué es el jugador?

pub struct Detective<'a, 'b> {
    pub name: &'a str,
    pub current_room: i32,
    pub house: &'b House<'b>
}

¿Qué hace el jugador?

impl<'a, 'b> Detective<'a, 'b> {
    pub fn change_room(&mut self,
                       room_id: i32)
                       -> Result<&mut Self, &str> {
        ...
    }
}

Conectando módulos

En main.rs

mod house;
mod player;

Controlando la visibilidad

pub struct ...
pub type ...
pub fn ...

pub struct Room {
    pub title ...
}

Usando funcionalidad de módulos

use house::{House, build_house};
use player::Detective;

Instanciando datos


fn main() {
    let house: House = build_house();

    let mut detective: Detective = Detective {
        name: "test",
        current_room: -1,
        house: &house
    };
}

... con inferencia


fn main() {
    let house = build_house();

    let mut detective = Detective {
        name: "test",
        current_room: -1,
        house: &house
    };
}

El bucle principal del juego

fn main() {
    ...
    loop {
    }
}

El bucle principal del juego

fn main() {
    ...
    loop {
    }
}

Ubicación actual

match house.get(&detective.current_room) {
    Some(room) => {
        ...
    },
    None => panic!("Habitación inválida..."),
}

Ubicación actual

println!("Estás en: {} ({})", room.title, room.description);
println!("Te puedes mover a:");
for t in &room.transitions {
    match house.get(&t) {
        Some(t_room) => {
            println!("\t- {}: {}", &t, t_room.title);
        },
        None => panic!("Transición inválida..."),
    }
}
println!("Puedes indicar ....");

Leyendo la siguiente ubicación

// en el tope de main.rs
use std::io::{self};

// dentro del loop

let mut next_room_buf = String::new();

match io::stdin().read_line(&mut next_room_buf) {
    Ok(_) => {
        ....
    },
    Err(_) => panic!("Error al leer entrada..."),
}

Parseando la entrada

let command = next_room_buf.trim();

if command == "x" {
    println!("Adiós!");
    break;
} else {
    match command.parse::<i32>() {
        Ok(room_number) => {
            match detective.change_room(room_number) {
                Ok(_) => {},
                Err(e) => panic!("err: {}", e),
            }
        },
        Err(err) => {
            println!("Error: {:?}", err);
        }
    }
}

Ahora como lo convierto en un ChatBot?

Construyendo un Text Adventure con Rust

By sebasmagri

Construyendo un Text Adventure con Rust

  • 419