<commit_before>extern crate piston_window;
#[macro_use]
extern crate clap;
extern crate rand;
extern crate find_folder;

mod game;
mod field;
mod ui;
mod common;

use piston_window::*;
use clap::{Arg, App};

fn main() {
    let matches = App::new("Minesweeper")
        .author("Alexander Kuvaev <alexander@kuvaev.me>")
        .version(&*format!("v{}", crate_version!()))
        .about("Simple minesweeper in Rust ")
        .arg(Arg::from_usage("-s, --size [size] 'window size \"width\"x\"height\"'")
            .validator(|val| {
                let mut s = val.split("x");
                match s.next() {
                    Some(w) => {
                        match w.parse::<u32>() {
                            Ok(r) => {
                                if (r < 100) || (r > 4096) {
                                    return Err(format!("window width must be between 100 and 4096"))
                                }
                            },
                            Err(e) => return Err(format!("window width arg error: {}", e))
                        }
                    }
                    None => return Err(format!("window size expected \"width\"x\"height\", got {}", val))
                }
                match s.next() {
                    Some(h) => {
                        match h.parse::<u32>() {
                            Ok(r) => {
                                if (r < 100) || (r > 3072) {
                                    return Err(format!("window height must be between 100 and 3072"))
                                }
                            },
                            Err(e) => return Err(format!("window height arg error: {}", e))
                        }
                    }
                    None => return Err(format!("window size expected \"width\"x\"height\", got {}", val))
                }
                match s.next() {
                    Some(_r) => Err(format!("window size arg expected \"width\"x\"height\", got {}", val)),
                    None => Ok(())
                }
            }))
        .arg(Arg::from_usage("-f, --field [field] 'field size \"width\"x\"height\"'")
            .validator(|val| {
                let mut s = val.split("x");
                match s.next() {
                    Some(w) => {
                        match w.parse::<u32>() {
                            Ok(r) => {
                                if (r < 5) || (r > 100) {
                                    return Err(format!("field width must be between 5 and 100"))
                                }
                            },
                            Err(e) => return Err(format!("field width arg error: {}", e))
                        }
                    }
                    None => return Err(format!("field size expected \"width\"x\"height\", got {}", val))
                }
                match s.next() {
                    Some(h) => {
                        match h.parse::<u32>() {
                            Ok(r) => {
                                if (r < 5) || (r > 100) {
                                    return Err(format!("field height must be between 5 and 100"))
                                }
                            },
                            Err(e) => return Err(format!("field height arg error: {}", e))
                        }
                    }
                    None => return Err(format!("field size expected \"width\"x\"height\", got {}", val))
                }
                match s.next() {
                    Some(_r) => Err(format!("field size arg expected \"width\"x\"height\", got {}", val)),
                    None => Ok(())
                }
            }))
        .arg(Arg::from_usage("-m, --mines [mines] 'max mines'")
            .min_values(1))
        .get_matches();

    let mut width = 1024;
    let mut height = 768;
    let mut f_width = 20;
    let mut f_height = 20;
    let mut mines = 50;
    if let Some(size) = matches.value_of("size") {
        let mut s = size.split("x");
        width = s.next().unwrap().parse().unwrap_or(width);
        height = s.next().unwrap().parse().unwrap_or(height);
    }
    if let Some(field) = matches.value_of("field") {
        let mut s = field.split("x");
        f_width = s.next().unwrap().parse().unwrap_or(f_width);
        f_height = s.next().unwrap().parse().unwrap_or(f_height);
    }
    if let Some(m) = matches.value_of("mines") {
        mines = m.parse().unwrap_or(mines);
    }

    let window: PistonWindow =
        WindowSettings::new("Minesweeper", [width, height])
        .opengl(OpenGL::V2_1)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let assets = find_folder::Search::ParentsThenKids(3, 3)
        .for_folder("assets").unwrap();
    let ref font = assets.join("FiraSans-Regular.ttf");
    let factory = window.factory.borrow().clone();
    let glyphs = Glyphs::new(font, factory).unwrap();

    let mut game = game::Game::new(glyphs, f_width, f_height, mines);

    for e in window {
        game.render(&e);

        if let Some(mouse_rel) = e.mouse_cursor_args() {
            game.mouse_move(mouse_rel);
        }

        if let Some(button) = e.press_args() {
            game.proc_key(button, &e);
        }
    }
}<commit_msg>fix: fixed problems with OpenGL version<commit_after>extern crate piston_window;
#[macro_use]
extern crate clap;
extern crate rand;
extern crate find_folder;

mod game;
mod field;
mod ui;
mod common;

use piston_window::*;
use clap::{Arg, App};

fn main() {
    let matches = App::new("Minesweeper")
        .author("Alexander Kuvaev <alexander@kuvaev.me>")
        .version(&*format!("v{}", crate_version!()))
        .about("Simple minesweeper in Rust ")
        .arg(Arg::from_usage("-s, --size [size] 'window size \"width\"x\"height\"'")
            .validator(|val| {
                let mut s = val.split("x");
                match s.next() {
                    Some(w) => {
                        match w.parse::<u32>() {
                            Ok(r) => {
                                if (r < 100) || (r > 4096) {
                                    return Err(format!("window width must be between 100 and 4096"))
                                }
                            },
                            Err(e) => return Err(format!("window width arg error: {}", e))
                        }
                    }
                    None => return Err(format!("window size expected \"width\"x\"height\", got {}", val))
                }
                match s.next() {
                    Some(h) => {
                        match h.parse::<u32>() {
                            Ok(r) => {
                                if (r < 100) || (r > 3072) {
                                    return Err(format!("window height must be between 100 and 3072"))
                                }
                            },
                            Err(e) => return Err(format!("window height arg error: {}", e))
                        }
                    }
                    None => return Err(format!("window size expected \"width\"x\"height\", got {}", val))
                }
                match s.next() {
                    Some(_r) => Err(format!("window size arg expected \"width\"x\"height\", got {}", val)),
                    None => Ok(())
                }
            }))
        .arg(Arg::from_usage("-f, --field [field] 'field size \"width\"x\"height\"'")
            .validator(|val| {
                let mut s = val.split("x");
                match s.next() {
                    Some(w) => {
                        match w.parse::<u32>() {
                            Ok(r) => {
                                if (r < 5) || (r > 100) {
                                    return Err(format!("field width must be between 5 and 100"))
                                }
                            },
                            Err(e) => return Err(format!("field width arg error: {}", e))
                        }
                    }
                    None => return Err(format!("field size expected \"width\"x\"height\", got {}", val))
                }
                match s.next() {
                    Some(h) => {
                        match h.parse::<u32>() {
                            Ok(r) => {
                                if (r < 5) || (r > 100) {
                                    return Err(format!("field height must be between 5 and 100"))
                                }
                            },
                            Err(e) => return Err(format!("field height arg error: {}", e))
                        }
                    }
                    None => return Err(format!("field size expected \"width\"x\"height\", got {}", val))
                }
                match s.next() {
                    Some(_r) => Err(format!("field size arg expected \"width\"x\"height\", got {}", val)),
                    None => Ok(())
                }
            }))
        .arg(Arg::from_usage("-m, --mines [mines] 'max mines'"))
        .arg(Arg::from_usage("--oldOGL 'set OpenGL version to 2.1'"))
        .get_matches();

    let mut width = 1024;
    let mut height = 768;
    let mut f_width = 20;
    let mut f_height = 20;
    let mut mines = 50;
    let mut opengl = OpenGL::V3_2;
    if let Some(size) = matches.value_of("size") {
        let mut s = size.split("x");
        width = s.next().unwrap().parse().unwrap_or(width);
        height = s.next().unwrap().parse().unwrap_or(height);
    }
    if let Some(field) = matches.value_of("field") {
        let mut s = field.split("x");
        f_width = s.next().unwrap().parse().unwrap_or(f_width);
        f_height = s.next().unwrap().parse().unwrap_or(f_height);
    }
    if let Some(m) = matches.value_of("mines") {
        mines = m.parse().unwrap_or(mines);
    }
    if letmatches.is_present("oldOGL") {
        opengl = OpenGL::V2_1;
    }

    let window: PistonWindow =
        WindowSettings::new("Minesweeper", [width, height])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let assets = find_folder::Search::ParentsThenKids(3, 3)
        .for_folder("assets").unwrap();
    let ref font = assets.join("FiraSans-Regular.ttf");
    let factory = window.factory.borrow().clone();
    let glyphs = Glyphs::new(font, factory).unwrap();

    let mut game = game::Game::new(glyphs, f_width, f_height, mines);

    for e in window {
        game.render(&e);

        if let Some(mouse_rel) = e.mouse_cursor_args() {
            game.mouse_move(mouse_rel);
        }

        if let Some(button) = e.press_args() {
            game.proc_key(button, &e);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

mod action;
mod opts;
mod session;

use std::fs::File;
use std::io::Result;

use log::error;
use opts::{Opts};

fn main() -> Result<()> {
    let opts = opts::from_args();
    init(&opts);

    fleetspeak::startup(env!("CARGO_PKG_VERSION"))?;

    use session::Error::*;
    match action::startup::handle(&mut session::startup(), ()) {
        Err(Action(error)) => {
            error!("failed to collect startup metadata: {}", error);
        }
        Err(Dispatch(_)) => panic!(),
        Err(Encode(error)) => {
            error!("failed to encode startup metadata: {}", error);
        }
        Err(Parse(error)) => {
            error!("malformed action input: {}", error);
        }
        Ok(()) => (),
    }

    loop {
        use fleetspeak::ReadError::*;
        let packet = match fleetspeak::collect(opts.heartbeat_rate) {
            Ok(packet) => packet,
            Err(Malformed(error)) => {
                error!("received a malformed message: {}", error);
                continue;
            }
            Err(Decode(error)) => {
                error!("failed to decode the message: {}", error);
                continue;
            }
            Err(error) => return Err(error.into()),
        };

        handle(packet.data);
    }
}

fn init(opts: &Opts) {
    init_log(opts);
}

fn init_log(opts: &Opts) {
    let level = opts.log_verbosity.level();

    let mut loggers = Vec::<Box<dyn simplelog::SharedLogger>>::new();

    if let Some(std) = &opts.log_std {
        let config = Default::default();
        let logger = simplelog::TermLogger::new(level, config, std.mode())
            .expect("failed to create a terminal logger");

        loggers.push(logger);
    }

    if let Some(path) = &opts.log_file {
        let file = File::create(path)
            .expect("failed to create the log file");

        let config = Default::default();
        let logger = simplelog::WriteLogger::new(level, config, file);

        loggers.push(logger);
    }

    simplelog::CombinedLogger::init(loggers)
        .expect("failed to init logging");
}

fn handle(message: rrg_proto::GrrMessage) {
    use session::Error;
    match action::dispatch(message) {
        Ok(()) => (),
        Err(Error::Action(error)) => {
            error!("failed to execute the action: {}", error);
        }
        Err(Error::Dispatch(Some(name))) => {
            error!("unknown action to call: {}", name);
        }
        Err(Error::Dispatch(None)) => {
            error!("missing action to call");
        }
        Err(Error::Encode(error)) => {
            error!("failed to encode action response: {}", error);
        }
        Err(Error::Parse(error)) => {
            error!("malformed action input: {}", error);
        }
    }
}
<commit_msg>Remove useless branches.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

mod action;
mod opts;
mod session;

use std::fs::File;
use std::io::Result;

use log::error;
use opts::{Opts};

fn main() -> Result<()> {
    let opts = opts::from_args();
    init(&opts);

    fleetspeak::startup(env!("CARGO_PKG_VERSION"))?;

    match action::startup::handle(&mut session::startup(), ()) {
        Err(error) => {
            error!("failed to collect startup information: {}", error);
        }
        Ok(()) => (),
    }

    loop {
        use fleetspeak::ReadError::*;
        let packet = match fleetspeak::collect(opts.heartbeat_rate) {
            Ok(packet) => packet,
            Err(Malformed(error)) => {
                error!("received a malformed message: {}", error);
                continue;
            }
            Err(Decode(error)) => {
                error!("failed to decode the message: {}", error);
                continue;
            }
            Err(error) => return Err(error.into()),
        };

        handle(packet.data);
    }
}

fn init(opts: &Opts) {
    init_log(opts);
}

fn init_log(opts: &Opts) {
    let level = opts.log_verbosity.level();

    let mut loggers = Vec::<Box<dyn simplelog::SharedLogger>>::new();

    if let Some(std) = &opts.log_std {
        let config = Default::default();
        let logger = simplelog::TermLogger::new(level, config, std.mode())
            .expect("failed to create a terminal logger");

        loggers.push(logger);
    }

    if let Some(path) = &opts.log_file {
        let file = File::create(path)
            .expect("failed to create the log file");

        let config = Default::default();
        let logger = simplelog::WriteLogger::new(level, config, file);

        loggers.push(logger);
    }

    simplelog::CombinedLogger::init(loggers)
        .expect("failed to init logging");
}

fn handle(message: rrg_proto::GrrMessage) {
    match action::dispatch(message) {
        Ok(()) => (),
        Err(error) => {
            error!("failed to execute the action: {}", error);
        }
    }
}
<|endoftext|>


<commit_before>extern crate curl;
extern crate serde;
extern crate serde_json;
extern crate getopts;
extern crate define;
use define::dictionaries::{Dictionary, wordnik};
use define::thesaureses::Thesaurus;
use std::collections::HashMap;
use std::env;
use getopts::{Matches, Options};

static KEY: &'static str = "a2a73e7b926c924fad7001ca3111acd55af2ffabf50eb4ae5";
static UKEY: &'static str = "ub2JDDg9Iumsh1HfdO3a3HQbZi0up1qe8LkjsnWQvyVvQLFn1q";

struct Config {
    max_definitions: i16,
}

fn parse_args() -> (Options, Matches) {
    let argv: Vec<String> = env::args().collect();
    let mut parser = Options::new();
    parser.optflag("t", "thesaurus", "Finds synonyms for word");
    parser.optflag("u", "urban", "Urban Dictionary");
    parser.optopt("", "source", "Set dictionary source", "SOURCE");
    parser.optopt("",
                  "thesaurus-source",
                  "Set thesaurus source (not functional yet)",
                  "SOURCE");
    let parsed = parser.parse(&argv[1..]).unwrap();
    (parser, parsed)
}

fn get_sources()
    -> (HashMap<String, Box<Dictionary>>,
        HashMap<String, Box<Thesaurus>>)
{
    // insert your dictionaries here
    let mut dictionaries: HashMap<String, Box<Dictionary>> = HashMap::new();
    let wordnik = wordnik::Wordnik::new(KEY);
    dictionaries.insert(String::from("wordnik"), Box::new(wordnik.clone()));
    dictionaries.insert(String::from("example"),
                        Box::new(define::dictionaries::example::ExampleDictionary));
    dictionaries.insert(String::from("urban"),
                        Box::new(define::dictionaries::urban::Urban::new(UKEY)));
    let mut thesaureses: HashMap<String, Box<Thesaurus>> = HashMap::new();
    thesaureses.insert(String::from("wordnik"), Box::new(wordnik.clone()));
    (dictionaries, thesaureses)
}

fn print_definition<'a, T: Dictionary + ?Sized>(dict: &'a mut Box<T>,
                                                word: &str,
                                                max_definitions: Option<usize>)
                                                -> Result<(), &'a str> {
    let definitions = try!(dict.get_definitions(word));
    let max_definitions = max_definitions.unwrap_or(1);
    if max_definitions > 1 {
        for (wordnumber, word) in definitions.iter().take(max_definitions).enumerate() {
            println!("{}. {}", wordnumber + 1, word.text);
        }
    } else {
        println!("{}", definitions[0].text);
    }
    Ok(())
}

fn print_synonyms<'a, T: Thesaurus + ?Sized>(thes: &'a mut Box<T>,
                                             word: &str)
                                             -> Result<(), &'a str> {
    let synonyms = try!(thes.get_synonyms(word));
    println!("{}", synonyms.join(", "));
    Ok(())
}

fn get_source<'a, T: Dictionary + ?Sized, K: Thesaurus + ?Sized>
    (dictionaries: &'a mut HashMap<String, Box<T>>,
     thesaureses: &'a mut HashMap<String, Box<K>>,
     args: &Matches)
     -> (&'a mut Box<T>, &'a mut Box<K>) {

    let mut source: String = "wordnik".to_string();
    let tsource: String;
    tsource = args.opt_str("thesaurus-source").unwrap_or("wordnik".to_owned()).to_owned();
    if !args.opt_present("source") {
        for dictionary_source in dictionaries.keys() {
            if args.opt_present(&dictionary_source) {
                source = dictionary_source.clone();
            }
        }
    }
    else if args.opt_present("source") {
        source = args.opt_str("source").unwrap_or("wordnik".to_owned()).to_owned();
    }
    println!("{}", &source);
    let dict: Option<&mut Box<T>> = dictionaries.get_mut(&source);
    let thes: Option<&mut Box<K>> = thesaureses.get_mut(&tsource);
    (dict.unwrap(), thes.unwrap())
}

fn main() {
    let (mut dictionaries, mut thesaureses) = get_sources();
    let (opts, args) = parse_args(); //we needs opts too for printing brief description
    let (dictionary, thesaurus) = get_source(&mut dictionaries, &mut thesaureses, &args);
    if args.free.is_empty() {
        println!("{}", opts.usage("USAGE: define WORD"));
    }
    for word in &args.free {
        println!("{}:", word.to_uppercase());
        print_definition(dictionary, word, Some(3)).unwrap_or_else(|err| println!("{}", err));
        if args.opt_present("t") {
            println!("SYNONYMS:");
            print_synonyms(thesaurus, word).unwrap_or_else(|err| println!("{}", err));
        }
    }
}
<commit_msg>Removed printing source<commit_after>extern crate curl;
extern crate serde;
extern crate serde_json;
extern crate getopts;
extern crate define;
use define::dictionaries::{Dictionary, wordnik};
use define::thesaureses::Thesaurus;
use std::collections::HashMap;
use std::env;
use getopts::{Matches, Options};

static KEY: &'static str = "a2a73e7b926c924fad7001ca3111acd55af2ffabf50eb4ae5";
static UKEY: &'static str = "ub2JDDg9Iumsh1HfdO3a3HQbZi0up1qe8LkjsnWQvyVvQLFn1q";

struct Config {
    max_definitions: i16,
}

fn parse_args() -> (Options, Matches) {
    let argv: Vec<String> = env::args().collect();
    let mut parser = Options::new();
    parser.optflag("t", "thesaurus", "Finds synonyms for word");
    parser.optflag("u", "urban", "Urban Dictionary");
    parser.optopt("", "source", "Set dictionary source", "SOURCE");
    parser.optopt("",
                  "thesaurus-source",
                  "Set thesaurus source (not functional yet)",
                  "SOURCE");
    let parsed = parser.parse(&argv[1..]).unwrap();
    (parser, parsed)
}

fn get_sources()
    -> (HashMap<String, Box<Dictionary>>,
        HashMap<String, Box<Thesaurus>>)
{
    // insert your dictionaries here
    let mut dictionaries: HashMap<String, Box<Dictionary>> = HashMap::new();
    let wordnik = wordnik::Wordnik::new(KEY);
    dictionaries.insert(String::from("wordnik"), Box::new(wordnik.clone()));
    dictionaries.insert(String::from("example"),
                        Box::new(define::dictionaries::example::ExampleDictionary));
    dictionaries.insert(String::from("urban"),
                        Box::new(define::dictionaries::urban::Urban::new(UKEY)));
    let mut thesaureses: HashMap<String, Box<Thesaurus>> = HashMap::new();
    thesaureses.insert(String::from("wordnik"), Box::new(wordnik.clone()));
    (dictionaries, thesaureses)
}

fn print_definition<'a, T: Dictionary + ?Sized>(dict: &'a mut Box<T>,
                                                word: &str,
                                                max_definitions: Option<usize>)
                                                -> Result<(), &'a str> {
    let definitions = try!(dict.get_definitions(word));
    let max_definitions = max_definitions.unwrap_or(1);
    if max_definitions > 1 {
        for (wordnumber, word) in definitions.iter().take(max_definitions).enumerate() {
            println!("{}. {}", wordnumber + 1, word.text);
        }
    } else {
        println!("{}", definitions[0].text);
    }
    Ok(())
}

fn print_synonyms<'a, T: Thesaurus + ?Sized>(thes: &'a mut Box<T>,
                                             word: &str)
                                             -> Result<(), &'a str> {
    let synonyms = try!(thes.get_synonyms(word));
    println!("{}", synonyms.join(", "));
    Ok(())
}

fn get_source<'a, T: Dictionary + ?Sized, K: Thesaurus + ?Sized>
    (dictionaries: &'a mut HashMap<String, Box<T>>,
     thesaureses: &'a mut HashMap<String, Box<K>>,
     args: &Matches)
     -> (&'a mut Box<T>, &'a mut Box<K>) {

    let mut source: String = "wordnik".to_string();
    let tsource: String;
    tsource = args.opt_str("thesaurus-source").unwrap_or("wordnik".to_owned()).to_owned();
    if !args.opt_present("source") {
        for dictionary_source in dictionaries.keys() {
            if args.opt_present(&dictionary_source) {
                source = dictionary_source.clone();
            }
        }
    }
    else if args.opt_present("source") {
        source = args.opt_str("source").unwrap_or("wordnik".to_owned()).to_owned();
    }
    let dict: Option<&mut Box<T>> = dictionaries.get_mut(&source);
    let thes: Option<&mut Box<K>> = thesaureses.get_mut(&tsource);
    (dict.unwrap(), thes.unwrap())
}

fn main() {
    let (mut dictionaries, mut thesaureses) = get_sources();
    let (opts, args) = parse_args(); //we needs opts too for printing brief description
    let (dictionary, thesaurus) = get_source(&mut dictionaries, &mut thesaureses, &args);
    if args.free.is_empty() {
        println!("{}", opts.usage("USAGE: define WORD"));
    }
    for word in &args.free {
        println!("{}:", word.to_uppercase());
        print_definition(dictionary, word, Some(3)).unwrap_or_else(|err| println!("{}", err));
        if args.opt_present("t") {
            println!("SYNONYMS:");
            print_synonyms(thesaurus, word).unwrap_or_else(|err| println!("{}", err));
        }
    }
}
<|endoftext|>


<commit_before>extern crate specs;
extern crate yaml_rust;

use specs::Join;
use std::io::prelude::*;
use std::io;
use std::io::BufReader;
use std::fs::File;
use yaml_rust::{Yaml, YamlLoader, };

static MAP: &'static str = include_str!("../map.yaml");

#[derive(Copy, Clone, Debug, PartialEq)]
struct Tile {
    c: char,
}

impl specs::Component for Tile {
    type Storage = specs::VecStorage<Tile>;
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct PlayerController;

#[derive(Copy, Clone, Debug, PartialEq)]
struct NonPlayerController;

#[derive(Copy, Clone, Debug, PartialEq)]
struct ViewController;

#[derive(Copy, Clone, Debug, PartialEq)]
struct ImmovableController;

impl specs::Component for PlayerController {
    type Storage = specs::VecStorage<PlayerController>;
}

impl specs::Component for NonPlayerController {
    type Storage = specs::VecStorage<NonPlayerController>;
}

impl specs::Component for ViewController {
    type Storage = specs::VecStorage<ViewController>;
}

impl specs::Component for ImmovableController {
    type Storage = specs::VecStorage<ImmovableController>;
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct Position {
    x: i64,
    y: i64,
}

impl specs::Component for Position {
    type Storage = specs::VecStorage<Position>;
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct Velocity {
    dx: i64,
    dy: i64,
}

impl specs::Component for Velocity {
    type Storage = specs::VecStorage<Velocity>;
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct Size {
    w: i64,
    h: i64,
}

impl specs::Component for Size {
    type Storage = specs::VecStorage<Size>;
}

#[derive(Clone, Debug, PartialEq)]
struct WorldMap(Vec<char>);

#[derive(Clone, Debug)]
struct Command(String);

//#[cfg(not(feature="parallel"))]
//fn main() {
//}
//
//#[cfg(feature="parallel")]
fn main() {
    let ref map_cfg = YamlLoader::load_from_str(MAP).unwrap()[0];
    //println!("{:?}", map_cfg);
    let map_width = map_cfg["width"].as_i64().unwrap_or(3);
    let map_height = map_cfg["height"].as_i64().unwrap_or(3);
    let default_map = vec![Yaml::from_str("[
            'T','T', 'T',
            'T','.', 'T',
            'T','T', 'T'
    ]")];
    let map: Vec<char> = map_cfg["world_map"].as_vec()
        .unwrap_or(&default_map)
        .iter()
        .flat_map(Yaml::as_str)
        .flat_map(str::chars)
        .collect();

    let playable: Vec<char> = map_cfg["playable"].as_vec()
        .unwrap_or(&vec![Yaml::from_str("'X'")])
        .iter()
        .flat_map(Yaml::as_str)
        .flat_map(str::chars)
        .collect();

    let blocking: Vec<char> = map_cfg["blocking"].as_vec()
        .unwrap_or(&vec![Yaml::from_str("'T'")])
        .iter()
        .flat_map(Yaml::as_str)
        .flat_map(str::chars)
        .collect();

    let nonblocking: Vec<char> = map_cfg["nonblocking"].as_vec()
        .unwrap_or(&vec![Yaml::from_str("'.'")])
        .iter()
        .flat_map(Yaml::as_str)
        .flat_map(str::chars)
        .collect();

    for c in blocking {
        println!("{}", c);
    }

    let mut planner = {
        let mut w = specs::World::new();
        w.register::<Size>();
        w.register::<Tile>();
        w.register::<Position>();
        w.register::<Velocity>();
        w.register::<PlayerController>();
        w.register::<NonPlayerController>();
        w.register::<ViewController>();
        w.register::<ImmovableController>();

        // Entities
        let _player = w.create_now()
            .with(Tile { c: 'X' })
            .with(Velocity { dx: 0, dy: 0 })
            .with(Position { x: 0, y: 0 })
            .with(PlayerController)
            .with(Size { w: 1, h: 1 })
            .build();

        let _view = w.create_now()
            .with(Position { x: 0, y: 0 })
            .with(Size { w: 10, h: 10 })
            .with(ViewController)
            .build();

        for (i, tile) in map.iter().enumerate() {
            let _map_tile = w.create_now()
                .with(ImmovableController)
                .with(Size { w: 1, h: 1 })
                .with(Position { x: i as i64 % map_width, y: i as i64 / map_width, })
                .with(Tile { c: tile.clone() })
                .build();
        }

        // resources can be installed, these are nothing fancy, but allow you
        // to pass data to systems and follow the same sync strategy as the
        // component storage does.
        w.add_resource(Command(String::new()));

        // Planner is used to run systems on the specified world with a specified number of threads
        (specs::Planner::<()>::new(w, 4))
    };
    loop {
        // update positions
        planner.run_custom(|arg| {
            let (mut positions, velocities) = arg.fetch(|w| {
                (w.write::<Position>(), w.read::<Velocity>())
            });

            for (mut p, v) in (&mut positions, &velocities).iter() {
                p.x += v.dx;
                p.y += v.dy;
                println!("{:?}", p);
            }
        });

        planner.wait();

        // update view area
        planner.run_custom(|arg| {
            let (mut positions, players, views, sizes, entities) = arg.fetch(|w| {
                (w.write::<Position>(), w.read::<PlayerController>(), w.read::<ViewController>(),
                 w.read::<Size>(), w.entities())
            });

            let mut pos = (None, None);
            for (_, position) in (&players, &positions).iter() {
                pos.0 = Some(position.x);
                pos.1 = Some(position.y);
                break;
            }

            if let (Some(x), Some(y)) = pos {
                for (_, size, entity) in (&views, &sizes, &entities).iter() {
                    let view_pos = positions.get_mut(entity)
                        .expect("view controller expect position component");
                    if x > (size.w / 2) {
                        view_pos.x = x - (size.w / 2);
                    } else {
                        view_pos.x = x;
                    }
                    if y > (size.h / 2) {
                        view_pos.y = y - (size.h / 2);
                    } else {
                        view_pos.y = y;
                    }
                    println!("{:?}", view_pos);
                    println!("{:?}", size);
                }
            }
        });

        planner.wait();

        // render view
        planner.run_custom(|arg| {
            let (tiles, positions, non_players, players, map_objects, views, sizes) = arg.fetch(|w| {
                (w.read::<Tile>(), w.read::<Position>(), w.read::<NonPlayerController>(),
                w.read::<PlayerController>(), w.read::<ImmovableController>(), w.read::<ViewController>(),
                w.read::<Size>())
            });
            let mut output = vec![vec![' ';10];10];

            let mut view_state = (None, None, None, None);
            for (_, position, size) in (&views, &positions, &sizes).iter() {
                view_state.0 = Some(position.x);
                view_state.1 = Some(position.y);
                view_state.2 = Some(size.w);
                view_state.3 = Some(size.h);
                break;
            }

            // render in layers
            if let (Some(x), Some(y), Some(width), Some(height)) = view_state {
                for (tile, position, _) in (&tiles, &positions, &map_objects).iter() {
                    if position.x >= x && position.x < x + width {
                        if position.y >= y && position.y < y + height {
                            let _ = output[position.y as usize].remove(position.x as usize);
                            output[position.y as usize].insert(position.x as usize, tile.c);
                        }
                    }
                }
            }
            for (tile, position, _) in (&tiles, &positions, &non_players).iter() {
                let _ = output[position.y as usize].remove(position.x as usize);
                output[position.y as usize].insert(position.x as usize, tile.c);
            }
            for (tile, position, _) in (&tiles, &positions, &players).iter() {
                let _ = output[position.y as usize].remove(position.x as usize);
                output[position.y as usize].insert(position.x as usize, tile.c);
            }
            for out in output {
                let out: String = out.into_iter().collect();
                println!("{}", out);
            }
        });

        // get input
        planner.run_custom(|arg| {
            let mut cmd = arg.fetch(|w| {
                (w.write_resource::<Command>())
            });
            let mut input = String::new();
            if let Ok(_) = io::stdin().read_line(&mut input) {
                cmd.0 = input;
            }
        });

        planner.wait();

        // process input
        planner.run_custom(|arg| {
            let (mut velocities, players, cmds, entities) = arg.fetch(|w| {
                (w.write::<Velocity>(), w.read::<PlayerController>(),
                 w.read_resource::<Command>(), w.entities())
            });
            let mut commands: Vec<&str> = cmds.0.split_whitespace()
                .rev()
                .collect();

            for (_, entity) in (&players, &entities).iter() {
                let velocity = velocities.get_mut(entity)
                    .expect("player controller expect velocity");
                let mut dx = 0;
                let mut dy = 0;
                while let Some(word) = commands.pop() {
                    match word {
                        "left" | "l" => {
                            if let Some(val) = commands.pop() {
                                dx -= val.parse::<i64>().unwrap_or(1);
                            } else {
                                dx -= 1;
                            }
                        }
                        "right" | "r" => {
                            if let Some(val) = commands.pop() {
                                dx += val.parse::<i64>().unwrap_or(1);
                            } else {
                                dx += 1;
                            }
                        }
                        "up" | "u" => {
                            if let Some(val) = commands.pop() {
                                dy -= val.parse::<i64>().unwrap_or(1);
                            } else {
                                dy -= 1;
                            }
                        }
                        "down" | "d" => {
                            if let Some(val) = commands.pop() {
                                dy += val.parse::<i64>().unwrap_or(1);
                            } else {
                                dy += 1;
                            }
                        }
                        _ => {}
                    }
                }
                velocity.dx += dx;
                velocity.dy += dy;
                println!("{:?}", velocity);
            }
        });

        planner.wait();
    }
}
<commit_msg>Fix merge conflict.<commit_after>extern crate specs;
extern crate yaml_rust;

use specs::Join;
use std::io::prelude::*;
use std::io;
use std::io::BufReader;
use std::fs::File;
use yaml_rust::{Yaml, YamlLoader};

static MAP: &'static str = include_str!("../map.yaml");

#[derive(Copy, Clone, Debug, PartialEq)]
struct Tile {
    c: char,
}

impl specs::Component for Tile {
    type Storage = specs::VecStorage<Tile>;
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct PlayerController;

#[derive(Copy, Clone, Debug, PartialEq)]
struct NonPlayerController;

#[derive(Copy, Clone, Debug, PartialEq)]
struct ViewController;

#[derive(Copy, Clone, Debug, PartialEq)]
struct ImmovableController;

impl specs::Component for PlayerController {
    type Storage = specs::VecStorage<PlayerController>;
}

impl specs::Component for NonPlayerController {
    type Storage = specs::VecStorage<NonPlayerController>;
}

impl specs::Component for ViewController {
    type Storage = specs::VecStorage<ViewController>;
}

impl specs::Component for ImmovableController {
    type Storage = specs::VecStorage<ImmovableController>;
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct Position {
    x: i64,
    y: i64,
}

impl specs::Component for Position {
    type Storage = specs::VecStorage<Position>;
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct Velocity {
    dx: i64,
    dy: i64,
}

impl specs::Component for Velocity {
    type Storage = specs::VecStorage<Velocity>;
}

#[derive(Copy, Clone, Debug, PartialEq)]
struct Size {
    w: i64,
    h: i64,
}

impl specs::Component for Size {
    type Storage = specs::VecStorage<Size>;
}

#[derive(Clone, Debug)]
struct Command(String);

// #[cfg(not(feature="parallel"))]
// fn main() {
// }
//
// #[cfg(feature="parallel")]
fn main() {
    let ref map_cfg = YamlLoader::load_from_str(MAP).unwrap()[0];
    // println!("{:?}", map_cfg);
    let map_width = map_cfg["width"].as_i64().unwrap_or(3);
    let map_height = map_cfg["height"].as_i64().unwrap_or(3);
    let default_map = vec![Yaml::from_str("[
            'T','T', 'T',
            'T','.', 'T',
            'T','T', 'T'
    ]")];
    let map: Vec<char> = map_cfg["world_map"]
                             .as_vec()
                             .unwrap_or(&default_map)
                             .iter()
                             .flat_map(Yaml::as_str)
                             .flat_map(str::chars)
                             .collect();

    let playable: Vec<char> = map_cfg["playable"]
                                  .as_vec()
                                  .unwrap_or(&vec![Yaml::from_str("'X'")])
                                  .iter()
                                  .flat_map(Yaml::as_str)
                                  .flat_map(str::chars)
                                  .collect();

    let blocking: Vec<char> = map_cfg["blocking"]
                                  .as_vec()
                                  .unwrap_or(&vec![Yaml::from_str("'T'")])
                                  .iter()
                                  .flat_map(Yaml::as_str)
                                  .flat_map(str::chars)
                                  .collect();

    let nonblocking: Vec<char> = map_cfg["nonblocking"]
                                     .as_vec()
                                     .unwrap_or(&vec![Yaml::from_str("'.'")])
                                     .iter()
                                     .flat_map(Yaml::as_str)
                                     .flat_map(str::chars)
                                     .collect();

    for c in blocking {
        println!("{}", c);
    }

    let mut planner = {
        let mut w = specs::World::new();
        w.register::<Size>();
        w.register::<Tile>();
        w.register::<Position>();
        w.register::<Velocity>();
        w.register::<PlayerController>();
        w.register::<NonPlayerController>();
        w.register::<ViewController>();
        w.register::<ImmovableController>();

        // Entities
        let _player = w.create_now()
                       .with(Tile { c: 'X' })
                       .with(Velocity { dx: 0, dy: 0 })
                       .with(Position { x: 0, y: 0 })
                       .with(PlayerController)
                       .build();

        let _star = w.create_now()
                     .with(Tile { c: '*' })
                     .with(Velocity { dx: 0, dy: 0 })
                     .with(Position { x: 3, y: 3 })
                     .with(NonPlayerController)
                     .build();

        let _view = w.create_now()
                     .with(Position { x: 0, y: 0 })
                     .with(Size { w: 10, h: 10 })
                     .with(ViewController)
                     .build();

        let _map_view = w.create_now()
                         .with(Size {
                             w: map_width,
                             h: map_height,
                         })
                         .with(ImmovableController)
                         .build();

        for (i, tile) in map.iter().enumerate() {
            let _map_tile = w.create_now()
                             .with(ImmovableController)
                             .with(Size { w: 1, h: 1 })
                             .with(Position {
                                 x: i as i64 % map_width,
                                 y: i as i64 / map_width,
                             })
                             .with(Tile { c: tile.clone() })
                             .build();
        }

        // resources can be installed, these are nothing fancy, but allow you
        // to pass data to systems and follow the same sync strategy as the
        // component storage does.
        w.add_resource(Command(String::new()));

        // Planner is used to run systems on the specified world with a specified number of threads
        (specs::Planner::<()>::new(w, 4))
    };
    loop {
        // update positions
        planner.run_custom(|arg| {
            let (mut positions, velocities) = arg.fetch(|w| {
                (w.write::<Position>(), w.read::<Velocity>())
            });

            for (mut p, v) in (&mut positions, &velocities).iter() {
                p.x += v.dx;
                p.y += v.dy;
                println!("{:?}", p);
            }
        });

        planner.wait();

        // update view area
        planner.run_custom(|arg| {
            let (mut positions, players, views, maps, sizes, entities) = arg.fetch(|w| {
                (w.write::<Position>(),
                 w.read::<PlayerController>(),
                 w.read::<ViewController>(),
                 w.read::<ImmovableController>(),
                 w.read::<Size>(),
                 w.entities())
            });

            let mut player_pos = (None, None);
            for (_, position) in (&players, &positions).iter() {
                player_pos.0 = Some(position.x);
                player_pos.1 = Some(position.y);
                break;
            }

            let mut map_size = (None, None);
            for (_, size) in (&maps, &sizes).iter() {
                map_size.0 = Some(size.w);
                map_size.1 = Some(size.h);
                break;
            }

            if let (Some(x), Some(y)) = player_pos {
                if let (Some(w), Some(h)) = map_size {
                    for (_, size, entity) in (&views, &sizes, &entities).iter() {
                        let view_pos = positions.get_mut(entity)
                                                .expect("view controller expect position \
                                                         component");
                        view_pos.x = x - (size.w / 2);
                        view_pos.y = y - (size.h / 2);

                        while view_pos.x < 0 {
                            view_pos.x += 1;
                        }
                        while view_pos.x > w {
                            view_pos.x -= 1;
                        }
                        while view_pos.y < 0 {
                            view_pos.y += 1;
                        }
                        while view_pos.y > h {
                            view_pos.y -= 1;
                        }
                        println!("{:?}", view_pos);
                        println!("{:?}", size);
                    }
                }
            }
        });

        planner.wait();

        // render view
        planner.run_custom(|arg| {
            let (tiles, positions, non_players, players, map_objects, views, sizes) =
                arg.fetch(|w| {
                    (w.read::<Tile>(),
                     w.read::<Position>(),
                     w.read::<NonPlayerController>(),
                     w.read::<PlayerController>(),
                     w.read::<ImmovableController>(),
                     w.read::<ViewController>(),
                     w.read::<Size>())
                });
            let mut output = vec![vec![' ';10];10];

            let mut view_state = (None, None, None, None);
            for (_, position, size) in (&views, &positions, &sizes).iter() {
                view_state.0 = Some(position.x);
                view_state.1 = Some(position.y);
                view_state.2 = Some(size.w);
                view_state.3 = Some(size.h);
                break;
            }

            // render in layers
            if let (Some(x), Some(y), Some(width), Some(height)) = view_state {
                for (tile, position, _) in (&tiles, &positions, &map_objects).iter() {
                    if position.x >= x && position.x < x + width && position.y >= y &&
                       position.y < y + height {
                        let _ = output[position.y as usize].remove(position.x as usize);
                        output[position.y as usize].insert(position.x as usize, tile.c);
                    }
                }
                for (tile, position, _) in (&tiles, &positions, &non_players).iter() {
                    if position.x >= x && position.x < x + width && position.y >= y &&
                       position.y < y + height {
                        let _ = output[position.y as usize].remove(position.x as usize);
                        output[position.y as usize].insert(position.x as usize, tile.c);
                    }
                }
                for (tile, position, _) in (&tiles, &positions, &players).iter() {
                    if position.x >= x && position.x < x + width && position.y >= y &&
                       position.y < y + height {
                        let _ = output[position.y as usize].remove(position.x as usize);
                        output[position.y as usize].insert(position.x as usize, tile.c);
                    }
                }
            }
            for out in output {
                let out: String = out.into_iter().collect();
                println!("{}", out);
            }
        });

        // get input
        planner.run_custom(|arg| {
            let mut cmd = arg.fetch(|w| (w.write_resource::<Command>()));
            let mut input = String::new();
            if let Ok(_) = io::stdin().read_line(&mut input) {
                cmd.0 = input;
            }
        });

        planner.wait();

        // process input
        planner.run_custom(|arg| {
            let (mut velocities, players, cmds, entities) = arg.fetch(|w| {
                (w.write::<Velocity>(),
                 w.read::<PlayerController>(),
                 w.read_resource::<Command>(),
                 w.entities())
            });
            let mut commands: Vec<&str> = cmds.0
                                              .split_whitespace()
                                              .rev()
                                              .collect();

            for (_, entity) in (&players, &entities).iter() {
                let velocity = velocities.get_mut(entity)
                                         .expect("player controller expect velocity");
                let mut dx = 0;
                let mut dy = 0;
                while let Some(word) = commands.pop() {
                    match word {
                        "left" | "l" => {
                            if let Some(val) = commands.pop() {
                                dx -= val.parse::<i64>().unwrap_or(1);
                            } else {
                                dx -= 1;
                            }
                        }
                        "right" | "r" => {
                            if let Some(val) = commands.pop() {
                                dx += val.parse::<i64>().unwrap_or(1);
                            } else {
                                dx += 1;
                            }
                        }
                        "up" | "u" => {
                            if let Some(val) = commands.pop() {
                                dy -= val.parse::<i64>().unwrap_or(1);
                            } else {
                                dy -= 1;
                            }
                        }
                        "down" | "d" => {
                            if let Some(val) = commands.pop() {
                                dy += val.parse::<i64>().unwrap_or(1);
                            } else {
                                dy += 1;
                            }
                        }
                        _ => {}
                    }
                }
                velocity.dx += dx;
                velocity.dy += dy;
                println!("{:?}", velocity);
            }
        });

        planner.wait();
    }
}
<|endoftext|>


<commit_before>#![feature(box_syntax)]

extern crate turtle;

use std::fmt;
use std::fs::File;
use turtle::{Canvas, Turtle};

trait Alphabet: fmt::Debug + Eq + PartialEq + Clone  {}

type NumType = f32;

#[derive(Debug, Clone)]
enum Expr {
    // References an actual Argument by position
    Var(usize),
    Const(NumType),
    Add(Box<Expr>, Box<Expr>),
    Sub(Box<Expr>, Box<Expr>),
    Mul(Box<Expr>, Box<Expr>),
    Div(Box<Expr>, Box<Expr>),
}

struct Argument(pub NumType);

impl Expr {
    // XXX: Do we need those checks?
    fn evaluate(&self, args: &[Argument]) -> Result<NumType, &'static str> {
        match *self {
            Expr::Var(n) => Ok(try!(args.get(n).ok_or("Parameter out of bound")).0),
            Expr::Const(c) => Ok(c),
            Expr::Add(ref e1, ref e2) => Ok(try!(e1.evaluate(args)) + try!(e2.evaluate(args))),
            Expr::Sub(ref e1, ref e2) => Ok(try!(e1.evaluate(args)) - try!(e2.evaluate(args))),
            Expr::Mul(ref e1, ref e2) => Ok(try!(e1.evaluate(args)) * try!(e2.evaluate(args))),
            Expr::Div(ref e1, ref e2) => {
                let a = try!(e1.evaluate(args));
                let b = try!(e2.evaluate(args));
            if b == 0.0 {
                return Err("Division by 0");
                }
                Ok(a / b)
            }
        }
    }

    //fn max_argument()
}

#[test]
fn test_expr() {
    use Expr::{Var, Const, Add, Sub, Mul, Div};
    let expr = Sub(box Const(0.0), box Div(box Mul(box Add(box Const(1.0), box Var(0)), box Var(1)), box Const(2.0)));

    fn fun(a: NumType, b: NumType) -> NumType {
        0.0 - ((1.0 + a) * b) / 2.0
    }

    fn check(expr: &Expr, a: NumType, b: NumType) {
        assert_eq!(Ok(fun(a, b)), expr.evaluate(&[Argument(a), Argument(b)]))
    }

    check(&expr, 123.0, 4444.0);
    check(&expr, 0.0, -12.0);
}

// XXX: Clone?
#[derive(Clone)]
struct Symbol<A:Alphabet> {
    character: A,
    parameters: Vec<Expr>
}

impl<A:Alphabet> Symbol<A> {
    fn new(character: A) -> Symbol<A> {
        Symbol {
            character: character,
            parameters: Vec::new(),
        }
    }
}

struct Parameters;

impl<A:Alphabet> fmt::Debug for Symbol<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self.character)
    }
}

// XXX: Rename SymbolString to Word
#[derive(Clone)]
struct SymbolString<A:Alphabet>(Vec<Symbol<A>>);

impl<A:Alphabet> fmt::Debug for SymbolString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let v = &self.0;
        try!(write!(f, "\""));
        if !v.is_empty() {
            try!(write!(f, "{:?}", v[0]));
            for e in &v[1..] {
                try!(write!(f, " {:?}", e));
            }
        }
        write!(f, "\"")
    }
}

impl<A:Alphabet> SymbolString<A> {
    // XXX: Evaluate Parameters
    fn evaluate(&self, _parameters: Parameters) -> SymbolString<A> {
        self.clone()
    }
}

#[derive(Debug)]
struct Rule<A:Alphabet> {
    character: A,
    production: SymbolString<A>,
}

impl<A:Alphabet> Rule<A> {
    fn produce(&self, sym: &Symbol<A>) -> Option<SymbolString<A>> {
        if sym.character == self.character {
            // XXX: check if parameters match the conditions
            let parameters = Parameters;
            Some(self.production.evaluate(parameters))
        } else {
            None
        }
    }
}

#[derive(Debug)]
struct System<A:Alphabet> {
    rules: Vec<Rule<A>>,
}

impl<A:Alphabet> System<A> {
    fn develop(&self, axiom: SymbolString<A>, iterations: usize) -> (SymbolString<A>, usize) {
        let mut current = axiom;

        for iter in 0..iterations {
            let (next, progress) = self.develop1(&current);
            if !progress {
                return (current, iter);
            }
            current = next;
        }
        return (current, iterations);
    }

    fn develop1(&self, axiom: &SymbolString<A>) -> (SymbolString<A>, bool) {
        let mut expanded = Vec::new();
        let mut any_rule_applied = false;

        for symbol in axiom.0.iter() {
            let mut found = false;
            for rule in self.rules.iter() {
                if let Some(rhs) = rule.produce(&symbol) {
                    expanded.extend(rhs.0);
                    any_rule_applied = true;
                    found = true;
                    break;
                }
            }
            if !found {
                expanded.push(symbol.clone());
            }
        }

        (SymbolString(expanded), any_rule_applied)
    }
}

#[derive(Eq, PartialEq, Clone)]
struct Character(char);
impl Alphabet for Character {}

impl fmt::Debug for Character {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

fn symstr_from_str(s: &str) -> SymbolString<Character> {
    SymbolString(s.chars().filter(|&c| !c.is_whitespace()).map(|c| Symbol::new(Character(c))).collect())
}

fn draw(symstr: &SymbolString<Character>, init_direction: f32, angle: f32, distance: f32, filename: &str) {
    let mut t = Canvas::new();
    t.right(init_direction);
    for sym in symstr.0.iter() {
        match sym.character.0 {
            'F' => t.forward(distance),
            '+' => t.right(angle),
            '-' => t.left(angle),
            '[' => t.push(),
            ']' => t.pop(),
            _   => {}
        }
    }
    t.save_svg(&mut File::create(filename).unwrap()).unwrap();
}

fn koch_curve(maxiter: usize) {
    let axiom = symstr_from_str("F++F++F");

    let system = System { rules: vec![
        Rule {
            character: Character('F'),
            production: symstr_from_str("F-F++F-F")
        }
        ] };
    println!("{:?}", system);

    let (after, iters) = system.develop(axiom, maxiter);

    draw(&after, -90.0, 60.0, 10.0, &format!("koch_{:02}.svg", iters));
}

fn dragon_curve(maxiter: usize) {
    let axiom = symstr_from_str("FX");

    let system = System { rules: vec![
        Rule {
            character: Character('X'),
            production: symstr_from_str("X+YF+")
        },
        Rule {
            character: Character('Y'),
            production: symstr_from_str("-FX-Y")
        }
        ] };
    println!("{:?}", system);

    let (after, iters) = system.develop(axiom, maxiter);

    draw(&after, 0.0, 90.0, 10.0, &format!("dragon_{:02}.svg", iters));
}

fn sierpinski_triangle(maxiter: usize) {
    let axiom = symstr_from_str("A");

    let system = System { rules: vec![
        Rule {
            character: Character('A'),
            production: symstr_from_str("+B-A-B+")
        },
        Rule {
            character: Character('B'),
            production: symstr_from_str("-A+B+A-")
        }
        ] };
    println!("{:?}", system);

    let (after, iters) = system.develop(axiom, maxiter);

    // replace A and B with F
    let system = System { rules: vec![
        Rule {
            character: Character('A'),
            production: symstr_from_str("F")
        },
        Rule {
            character: Character('B'),
            production: symstr_from_str("F")
        }
        ] };
    let (after, _iters) = system.develop1(&after);

    draw(&after, -90.0, 60.0, 10.0, &format!("sierpinski_{:02}.svg", iters));
}

fn fractal_plant(maxiter: usize) {
    let axiom = symstr_from_str("X");

    let system = System { rules: vec![
        Rule {
            character: Character('X'),
            production: symstr_from_str("F-[[X]+X]+F[+FX]-X")
        },
        Rule {
            character: Character('F'),
            production: symstr_from_str("FF")
        }
        ] };
    println!("{:?}", system);

    let (after, iters) = system.develop(axiom, maxiter);

    draw(&after, 0.0, 25.0, 10.0, &format!("plant_{:02}.svg", iters));
}

fn main() {
    for i in 0..7 {
        koch_curve(i);
    }
    for i in 0..16 {
        dragon_curve(i);
    }
    for i in 0..10 {
        sierpinski_triangle(i);
    }
    for i in 4..8 {
        fractal_plant(i);
    }
}
<commit_msg>Implement conditions<commit_after>#![feature(box_syntax)]

extern crate turtle;

use std::fmt;
use std::fs::File;
use turtle::{Canvas, Turtle};

trait Alphabet: fmt::Debug + Eq + PartialEq + Clone  {}

type NumType = f32;

/// An argument is an "actual" parameter.
struct Argument(pub NumType);

/// An expression evaluates to a numeric value of `NumType`.
#[derive(Debug, Clone)]
enum Expr {
    // References an actual Argument by position
    Var(usize),
    Const(NumType),
    Add(Box<Expr>, Box<Expr>),
    Sub(Box<Expr>, Box<Expr>),
    Mul(Box<Expr>, Box<Expr>),
    Div(Box<Expr>, Box<Expr>),
}

impl Expr {
    // XXX: Do we need those checks?
    fn evaluate(&self, args: &[Argument]) -> Result<NumType, &'static str> {
        match *self {
            Expr::Var(n) => Ok(try!(args.get(n).ok_or("Parameter out of bound")).0),
            Expr::Const(c) => Ok(c),
            Expr::Add(ref e1, ref e2) => Ok(try!(e1.evaluate(args)) + try!(e2.evaluate(args))),
            Expr::Sub(ref e1, ref e2) => Ok(try!(e1.evaluate(args)) - try!(e2.evaluate(args))),
            Expr::Mul(ref e1, ref e2) => Ok(try!(e1.evaluate(args)) * try!(e2.evaluate(args))),
            Expr::Div(ref e1, ref e2) => {
                let a = try!(e1.evaluate(args));
                let b = try!(e2.evaluate(args));
            if b == 0.0 {
                return Err("Division by 0");
                }
                Ok(a / b)
            }
        }
    }
}

/// A condition evaluates to either `true` or `false`.
#[derive(Debug, Clone)]
enum Condition {
    Not(Box<Condition>),
    And(Box<Condition>, Box<Condition>),
    Or(Box<Condition>, Box<Condition>),

    /// If two expressions are equal
    Equal(Box<Expr>, Box<Expr>),

    Less(Box<Expr>, Box<Expr>),
    Greater(Box<Expr>, Box<Expr>),

    LessEqual(Box<Expr>, Box<Expr>),
    GreaterEqual(Box<Expr>, Box<Expr>),
}

impl Condition {
    // XXX: Do we need those checks?
    fn evaluate(&self, args: &[Argument]) -> Result<bool, &'static str> {
        Ok(match *self {
            Condition::Not(ref c) => ! try!(c.evaluate(args)),
            Condition::And(ref c1, ref c2) => try!(c1.evaluate(args)) && try!(c2.evaluate(args)),
            Condition::Or(ref c1, ref c2) => try!(c1.evaluate(args)) || try!(c2.evaluate(args)),
            Condition::Equal(ref e1, ref e2) => try!(e1.evaluate(args)) == try!(e2.evaluate(args)),
            Condition::Less(ref e1, ref e2) => try!(e1.evaluate(args)) < try!(e2.evaluate(args)),
            Condition::Greater(ref e1, ref e2) => try!(e1.evaluate(args)) > try!(e2.evaluate(args)),
            Condition::LessEqual(ref e1, ref e2) => try!(e1.evaluate(args)) <= try!(e2.evaluate(args)),
            Condition::GreaterEqual(ref e1, ref e2) => try!(e1.evaluate(args)) >= try!(e2.evaluate(args)),
        })
    }
}

#[test]
fn test_expr() {
    use Expr::{Var, Const, Add, Sub, Mul, Div};
    let expr = Sub(box Const(0.0), box Div(box Mul(box Add(box Const(1.0), box Var(0)), box Var(1)), box Const(2.0)));

    fn fun(a: NumType, b: NumType) -> NumType {
        0.0 - ((1.0 + a) * b) / 2.0
    }

    fn check(expr: &Expr, a: NumType, b: NumType) {
        assert_eq!(Ok(fun(a, b)), expr.evaluate(&[Argument(a), Argument(b)]))
    }

    check(&expr, 123.0, 4444.0);
    check(&expr, 0.0, -12.0);
}

#[test]
fn test_condition() {
    use Expr::{Var, Const, Add, Sub, Mul, Div};
    use Condition::{Not, And, Greater};
    let cond = Greater(box Var(0), box Const(0.0));

    fn fun(a: NumType) -> bool {
        a > 0.0
    }

    fn check(cond: &Condition, a: NumType) {
        assert_eq!(Ok(fun(a)), cond.evaluate(&[Argument(a)]))
    }

    check(&cond, 123.0);
    check(&cond, 0.0);
    check(&cond, -1.4);
}

// XXX: Clone?
#[derive(Clone)]
struct Symbol<A:Alphabet> {
    character: A,
    parameters: Vec<Expr>
}

impl<A:Alphabet> Symbol<A> {
    fn new(character: A) -> Symbol<A> {
        Symbol {
            character: character,
            parameters: Vec::new(),
        }
    }
}

struct Parameters;

impl<A:Alphabet> fmt::Debug for Symbol<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self.character)
    }
}

// XXX: Rename SymbolString to Word
#[derive(Clone)]
struct SymbolString<A:Alphabet>(Vec<Symbol<A>>);

impl<A:Alphabet> fmt::Debug for SymbolString<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let v = &self.0;
        try!(write!(f, "\""));
        if !v.is_empty() {
            try!(write!(f, "{:?}", v[0]));
            for e in &v[1..] {
                try!(write!(f, " {:?}", e));
            }
        }
        write!(f, "\"")
    }
}

impl<A:Alphabet> SymbolString<A> {
    // XXX: Evaluate Parameters
    fn evaluate(&self, _parameters: Parameters) -> SymbolString<A> {
        self.clone()
    }
}

#[derive(Debug)]
struct Rule<A:Alphabet> {
    character: A,
    production: SymbolString<A>,
}

impl<A:Alphabet> Rule<A> {
    fn produce(&self, sym: &Symbol<A>) -> Option<SymbolString<A>> {
        if sym.character == self.character {
            // XXX: check if parameters match the conditions
            let parameters = Parameters;
            Some(self.production.evaluate(parameters))
        } else {
            None
        }
    }
}

#[derive(Debug)]
struct System<A:Alphabet> {
    rules: Vec<Rule<A>>,
}

impl<A:Alphabet> System<A> {
    fn develop(&self, axiom: SymbolString<A>, iterations: usize) -> (SymbolString<A>, usize) {
        let mut current = axiom;

        for iter in 0..iterations {
            let (next, progress) = self.develop1(&current);
            if !progress {
                return (current, iter);
            }
            current = next;
        }
        return (current, iterations);
    }

    fn develop1(&self, axiom: &SymbolString<A>) -> (SymbolString<A>, bool) {
        let mut expanded = Vec::new();
        let mut any_rule_applied = false;

        for symbol in axiom.0.iter() {
            let mut found = false;
            for rule in self.rules.iter() {
                if let Some(rhs) = rule.produce(&symbol) {
                    expanded.extend(rhs.0);
                    any_rule_applied = true;
                    found = true;
                    break;
                }
            }
            if !found {
                expanded.push(symbol.clone());
            }
        }

        (SymbolString(expanded), any_rule_applied)
    }
}

#[derive(Eq, PartialEq, Clone)]
struct Character(char);
impl Alphabet for Character {}

impl fmt::Debug for Character {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

fn symstr_from_str(s: &str) -> SymbolString<Character> {
    SymbolString(s.chars().filter(|&c| !c.is_whitespace()).map(|c| Symbol::new(Character(c))).collect())
}

fn draw(symstr: &SymbolString<Character>, init_direction: f32, angle: f32, distance: f32, filename: &str) {
    let mut t = Canvas::new();
    t.right(init_direction);
    for sym in symstr.0.iter() {
        match sym.character.0 {
            'F' => t.forward(distance),
            '+' => t.right(angle),
            '-' => t.left(angle),
            '[' => t.push(),
            ']' => t.pop(),
            _   => {}
        }
    }
    t.save_svg(&mut File::create(filename).unwrap()).unwrap();
}

fn koch_curve(maxiter: usize) {
    let axiom = symstr_from_str("F++F++F");

    let system = System { rules: vec![
        Rule {
            character: Character('F'),
            production: symstr_from_str("F-F++F-F")
        }
        ] };
    println!("{:?}", system);

    let (after, iters) = system.develop(axiom, maxiter);

    draw(&after, -90.0, 60.0, 10.0, &format!("koch_{:02}.svg", iters));
}

fn dragon_curve(maxiter: usize) {
    let axiom = symstr_from_str("FX");

    let system = System { rules: vec![
        Rule {
            character: Character('X'),
            production: symstr_from_str("X+YF+")
        },
        Rule {
            character: Character('Y'),
            production: symstr_from_str("-FX-Y")
        }
        ] };
    println!("{:?}", system);

    let (after, iters) = system.develop(axiom, maxiter);

    draw(&after, 0.0, 90.0, 10.0, &format!("dragon_{:02}.svg", iters));
}

fn sierpinski_triangle(maxiter: usize) {
    let axiom = symstr_from_str("A");

    let system = System { rules: vec![
        Rule {
            character: Character('A'),
            production: symstr_from_str("+B-A-B+")
        },
        Rule {
            character: Character('B'),
            production: symstr_from_str("-A+B+A-")
        }
        ] };
    println!("{:?}", system);

    let (after, iters) = system.develop(axiom, maxiter);

    // replace A and B with F
    let system = System { rules: vec![
        Rule {
            character: Character('A'),
            production: symstr_from_str("F")
        },
        Rule {
            character: Character('B'),
            production: symstr_from_str("F")
        }
        ] };
    let (after, _iters) = system.develop1(&after);

    draw(&after, -90.0, 60.0, 10.0, &format!("sierpinski_{:02}.svg", iters));
}

fn fractal_plant(maxiter: usize) {
    let axiom = symstr_from_str("X");

    let system = System { rules: vec![
        Rule {
            character: Character('X'),
            production: symstr_from_str("F-[[X]+X]+F[+FX]-X")
        },
        Rule {
            character: Character('F'),
            production: symstr_from_str("FF")
        }
        ] };
    println!("{:?}", system);

    let (after, iters) = system.develop(axiom, maxiter);

    draw(&after, 0.0, 25.0, 10.0, &format!("plant_{:02}.svg", iters));
}

fn main() {
    for i in 0..7 {
        koch_curve(i);
    }
    for i in 0..16 {
        dragon_curve(i);
    }
    for i in 0..10 {
        sierpinski_triangle(i);
    }
    for i in 4..8 {
        fractal_plant(i);
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use std::string::String;
use std::collections::HashMap;
use std::vec::Vec;
use std::fs::{File};
use std::env;
use std::path::{Path};
use std::io::{self, BufReader, BufRead};
use std::iter;

use rand::{Closed01, Rng};
use rand::distributions::{IndependentSample, Sample, Gamma, LogNormal, RandSample};

type Bag = HashMap<usize, usize>;

fn load_bags<P: AsRef<Path>>(path: P) -> io::Result<(Vec<usize>, Vec<Bag>, usize)> {
    let mut bags = Vec::new();
    let mut labels = Vec::new();
    let mut vocab_size = 0;
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        let mut iter = line.split_whitespace();
        let label = iter.next().unwrap().parse::<usize>().unwrap();
        let mut bag = Bag::new();
        for elm in iter {
            let mut iter = elm.split(':');
            let index = iter.next().unwrap().parse::<usize>().unwrap();
            let value = iter.next().unwrap().parse::<usize>().unwrap();
            bag.insert(index - 1, value);    // We assume one-based indexing
            if vocab_size < index {
                vocab_size = index;
            }
        }
        labels.push(label);
        bags.push(bag);
    }
    Ok((labels, bags, vocab_size))
}

fn load_text_vocabulary<P: AsRef<Path>>(path: P) -> io::Result<Vec<String>> {
    let mut vocab = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        vocab.push(line);
    }
    Ok(vocab)
}

#[derive(Clone)]
struct Categorical {
    prop: Vec<f64>,
}

impl Categorical {
    fn new(weights: Vec<f64>) -> Categorical {
        let sum: f64 = weights.iter().sum();
        let prop: Vec<f64> = weights.iter().map(|w| w / sum).collect();
        Categorical {
            prop: prop,
        }
    }
}

impl Sample<usize> for Categorical {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> usize {
        self.ind_sample(rng)
    }
}

impl IndependentSample<usize> for Categorical {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> usize {
        let closed01 = RandSample::<Closed01<f64>>::new();
        let Closed01(x) = closed01.ind_sample(rng);

        let mut sum = 0.0;
        let mut ret = self.prop.len() - 1;
        for (k, &p) in self.prop.iter().enumerate() {
            sum += p;
            if x <= sum {
                ret = k;
                break;
            }
        }
        ret
    }
}

#[derive(Clone)]
struct Dirichlet {
    alpha: Vec<f64>,
}

impl Dirichlet {
    fn new(alpha: Vec<f64>) -> Dirichlet {
        Dirichlet {
            alpha: alpha,
        }
    }
}

impl Sample<Vec<f64>> for Dirichlet {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Vec<f64> {
        self.ind_sample(rng)
    }
}

impl IndependentSample<Vec<f64>> for Dirichlet {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Vec<f64> {
        let mut sum = 0.0;
        let mut xs = Vec::new();
        for &a in &self.alpha {
            let gamma = Gamma::new(a, 1.0);
            let y = gamma.ind_sample(rng);
            xs.push(y);
            sum += y;
        }
        for x in xs.iter_mut() {
            *x /= sum;
        }
        xs
    }
}

fn lda(dataset: Vec<Bag>, alpha: Vec<f64>, beta: Vec<f64>, burn_in: usize, num_samples: usize) {
    // Initialization
    let num_topics: usize = alpha.len();
    let vocab_size: usize = beta.len();
    println!("K = {}", num_topics);
    println!("M = {}", &dataset.len());
    println!("V = {}", vocab_size);

    let mut w: Vec<Vec<usize>> = Vec::with_capacity(dataset.len());
    let mut z: Vec<Vec<usize>> = Vec::with_capacity(dataset.len());
    let mut z_samples: Vec<Vec<Vec<usize>>> = Vec::with_capacity(dataset.len());
    let mut theta: Vec<Vec<f64>> = Vec::with_capacity(dataset.len());
    let mut ndk: Vec<Vec<usize>> = Vec::with_capacity(dataset.len());
    for bag in &dataset {
        // n_d
        let mut n_d = 0;
        for &count in bag.values() {
            n_d += count;
        }
        // w
        let mut w_d = Vec::with_capacity(n_d);
        for (&index, &count) in bag {
            for _ in 0..count {
                w_d.push(index);
            }
        }
        w.push(w_d);
        // z
        let mut z_d = Vec::with_capacity(n_d);
        let mut z_samples_d = Vec::with_capacity(n_d);
        for &count in bag.values() {
            for _ in 0..count {
                z_d.push(0);
                let zeros: Vec<usize> = iter::repeat(0).take(num_topics).collect();
                z_samples_d.push(zeros);
            }
        }
        z.push(z_d);
        z_samples.push(z_samples_d);
        // theta
        let mut theta_d = Vec::with_capacity(num_topics);
        for _k in 0..num_topics {
            theta_d.push(1.0 / num_topics as f64);
        }
        theta.push(theta_d);
        // ndk
        let mut ndk_d = Vec::with_capacity(num_topics);
        ndk_d.push(n_d);
        for _k in 1..num_topics {
            ndk_d.push(0);
        }
        ndk.push(ndk_d);
    }
    println!("z = {:?}", z);
    println!("theta = {:?}", theta);
    println!("ndk = {:?}", ndk);

    let mut phi: Vec<Vec<f64>> = Vec::with_capacity(num_topics);
    let mut nkv: Vec<Vec<usize>> = Vec::with_capacity(num_topics);
    // phi
    for _k in 0..num_topics {
        let mut phi_k = Vec::with_capacity(vocab_size);
        for _v in 0..vocab_size {
            phi_k.push(1.0 / vocab_size as f64);
        }
        phi.push(phi_k);
    }
    // nkv
    let mut nkv_0 = Vec::with_capacity(vocab_size);
    for _v in 0..vocab_size {
        nkv_0.push(0);
    }
    for bag in &dataset {
        for (&index, &count) in bag {
            nkv_0[index] += count;
        }
    }
    nkv.push(nkv_0);
    for _k in 1..num_topics {
        let mut nkv_k = Vec::with_capacity(vocab_size);
        for _v in 0..vocab_size {
            nkv_k.push(0);
        }
        nkv.push(nkv_k);
    }
    println!("phi = {:?}", phi);
    println!("nkv = {:?}", nkv);

    // Sampling
    let mut rng = rand::thread_rng();
    for s in 0..(burn_in + num_samples) {
        for (d, w_d) in w.iter().enumerate() {
            for (i, &w_di) in w_d.iter().enumerate() {
                let v = w_di;
                // Sample z_di
                let mut weights: Vec<f64> = Vec::with_capacity(num_topics);
                for k in 0..num_topics {
                    weights.push(theta[d][k] * phi[k][v]);
                }
                let cat = Categorical::new(weights);
                let old_z_di = z[d][i];
                let new_z_di = cat.ind_sample(&mut rng);
                z[d][i] = new_z_di;
                if s >= burn_in {
                    z_samples[d][i][new_z_di] += 1;
                }
                // Update ndk and nkv
                ndk[d][old_z_di] -= 1;
                ndk[d][new_z_di] += 1;
                nkv[old_z_di][v] -= 1;
                nkv[new_z_di][v] += 1;
            }
            // Sample theta_d
            let mut alpha_d: Vec<f64> = Vec::with_capacity(num_topics);
            for k in 0..num_topics {
                alpha_d.push(ndk[d][k] as f64 + alpha[k]);
            }
            let dir = Dirichlet::new(alpha_d);
            theta[d] = dir.ind_sample(&mut rng);
        }
        for k in 0..num_topics {
            // Sample phi_k
            let mut beta_k: Vec<f64> = Vec::with_capacity(vocab_size);
            for v in 0..vocab_size {
                beta_k.push(nkv[k][v] as f64 + beta[v]);
            }
            let dir = Dirichlet::new(beta_k);
            phi[k] = dir.ind_sample(&mut rng);
        }
        // Evaluate the log-likelihood value for the current parameters
        let mut log_likelihood = 0.0;
        for k in 0..num_topics {
            for v in 0..vocab_size {
                log_likelihood += nkv[k][v] as f64 * f64::ln(phi[k][v]);
            }
        }
        println!("log_likelihood = {}", log_likelihood);
    }
    // Distribution of z
    for (d, z_samples_d) in z_samples.iter().enumerate() {
        for (i, samples) in z_samples_d.iter().enumerate() {
            let mut sum = 0.0;
            for k in 0..num_topics {
                sum += samples[k] as f64;
            }
            print!("z[{:3}][{:3}] = ", d, i);
            for k in 0..num_topics {
                print!("{:3}:{:.2} ", k, samples[k] as f64 / sum);
            }
            println!("");
        }
    }
}

fn make_dataset(num_docs: usize, mean_nd: f64, std_dev_nd: f64, alpha: Vec<f64>, beta: Vec<f64>) -> Vec<Bag> {
    let num_topics: usize = alpha.len();
    let vocab_size: usize = beta.len();
    let mut rng = rand::thread_rng();
    // phi
    let dir_beta = Dirichlet::new(beta);
    let mut phi: Vec<Vec<f64>> = Vec::with_capacity(num_topics);
    for k in 0..num_topics {
        // Sample phi_k
        phi.push(dir_beta.ind_sample(&mut rng));
    }
    // theta, nd, z, w
    let dir_alpha = Dirichlet::new(alpha);
    let lognorm = LogNormal::new(mean_nd, std_dev_nd);
    let mut theta: Vec<Vec<f64>> = Vec::with_capacity(num_docs);
    let mut nd: Vec<usize> = Vec::with_capacity(num_docs);
    let mut z: Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    let mut w: Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    for d in 0..num_docs {
        theta.push(dir_alpha.ind_sample(&mut rng));
        nd.push(f64::floor(lognorm.ind_sample(&mut rng)) as usize);
        let cat_theta = Categorical::new(theta[d].clone());
        let mut z_d = Vec::with_capacity(nd[d]);
        let mut w_d = Vec::with_capacity(nd[d]);
        for i in 0..nd[d] {
            z_d.push(cat_theta.ind_sample(&mut rng));
            let cat_phi = Categorical::new(phi[z_d[i]].clone());
            w_d.push(cat_phi.ind_sample(&mut rng));
        }
        z.push(z_d);
        w.push(w_d);
    }
    // Make bags
    let mut bags: Vec<Bag> = Vec::new();
    for w_d in w {
        let mut bag: Bag = Bag::new();
        for v in w_d {
            let counter = bag.entry(v).or_insert(0);
            *counter += 1;
        }
        bags.push(bag);
    }
    bags
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let (labels, dataset, vocab_size) = load_bags(&args[1]).unwrap();
    let vocab: Option<Vec<String>> = if args.len() < 3 {
        None
    }
    else {
        Some(load_text_vocabulary(&args[2]).unwrap())
    };
    println!("{:?}", labels);
    println!("{:?}", dataset);
    println!("{:?}", vocab);

    let num_topics = 3;
    let alpha: Vec<f64> = iter::repeat(1.0).take(num_topics).collect();
    let beta: Vec<f64> = iter::repeat(1.0).take(vocab_size).collect();

    lda(dataset, alpha, beta, 1000, 10000);
}
<commit_msg>Randomly initialize variables<commit_after>extern crate rand;

use std::string::String;
use std::collections::HashMap;
use std::vec::Vec;
use std::fs::{File};
use std::env;
use std::path::{Path};
use std::io::{self, BufReader, BufRead};
use std::iter;

use rand::{Closed01, Rng};
use rand::distributions::{IndependentSample, Sample, Gamma, LogNormal, RandSample, Range};

type Bag = HashMap<usize, usize>;

fn load_bags<P: AsRef<Path>>(path: P) -> io::Result<(Vec<usize>, Vec<Bag>, usize)> {
    let mut bags = Vec::new();
    let mut labels = Vec::new();
    let mut vocab_size = 0;
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        let mut iter = line.split_whitespace();
        let label = iter.next().unwrap().parse::<usize>().unwrap();
        let mut bag = Bag::new();
        for elm in iter {
            let mut iter = elm.split(':');
            let index = iter.next().unwrap().parse::<usize>().unwrap();
            let value = iter.next().unwrap().parse::<usize>().unwrap();
            bag.insert(index - 1, value);    // We assume one-based indexing
            if vocab_size < index {
                vocab_size = index;
            }
        }
        labels.push(label);
        bags.push(bag);
    }
    Ok((labels, bags, vocab_size))
}

fn load_text_vocabulary<P: AsRef<Path>>(path: P) -> io::Result<Vec<String>> {
    let mut vocab = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        vocab.push(line);
    }
    Ok(vocab)
}

#[derive(Clone)]
struct Categorical {
    prop: Vec<f64>,
}

impl Categorical {
    fn new(weights: Vec<f64>) -> Categorical {
        let sum: f64 = weights.iter().sum();
        let prop: Vec<f64> = weights.iter().map(|w| w / sum).collect();
        Categorical {
            prop: prop,
        }
    }
}

impl Sample<usize> for Categorical {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> usize {
        self.ind_sample(rng)
    }
}

impl IndependentSample<usize> for Categorical {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> usize {
        let closed01 = RandSample::<Closed01<f64>>::new();
        let Closed01(x) = closed01.ind_sample(rng);

        let mut sum = 0.0;
        let mut ret = self.prop.len() - 1;
        for (k, &p) in self.prop.iter().enumerate() {
            sum += p;
            if x <= sum {
                ret = k;
                break;
            }
        }
        ret
    }
}

#[derive(Clone)]
struct Dirichlet {
    alpha: Vec<f64>,
}

impl Dirichlet {
    fn new(alpha: Vec<f64>) -> Dirichlet {
        Dirichlet {
            alpha: alpha,
        }
    }
}

impl Sample<Vec<f64>> for Dirichlet {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Vec<f64> {
        self.ind_sample(rng)
    }
}

impl IndependentSample<Vec<f64>> for Dirichlet {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Vec<f64> {
        let mut sum = 0.0;
        let mut xs = Vec::new();
        for &a in &self.alpha {
            let gamma = Gamma::new(a, 1.0);
            let y = gamma.ind_sample(rng);
            xs.push(y);
            sum += y;
        }
        for x in xs.iter_mut() {
            *x /= sum;
        }
        xs
    }
}

fn lda(dataset: Vec<Bag>, alpha: Vec<f64>, beta: Vec<f64>, burn_in: usize, num_samples: usize) {
    let num_docs: usize = dataset.len();
    let num_topics: usize = alpha.len();
    let vocab_size: usize = beta.len();
    let mut rng = rand::thread_rng();
    println!("K = {}", num_topics);
    println!("M = {}", num_docs);
    println!("V = {}", vocab_size);

    // Construct zero-filled nested arrays
    let mut w:     Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    let mut z:     Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    let mut theta: Vec<Vec<f64>>   = Vec::with_capacity(num_docs);
    let mut phi:   Vec<Vec<f64>>   = Vec::with_capacity(num_topics);
    let mut ndk:   Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    let mut nkv:   Vec<Vec<usize>> = Vec::with_capacity(num_topics);
    let mut z_samples: Vec<Vec<Vec<usize>>> = Vec::with_capacity(num_docs);
    for bag in &dataset {
        // n_d
        let mut n_d = 0;
        for &count in bag.values() {
            n_d += count;
        }
        w.push(vec![0; n_d]);
        z.push(vec![0; n_d]);
        theta.push(vec![0.0; num_topics]);
        ndk.push(vec![0; num_topics]);
        z_samples.push(vec![vec![0; num_topics]; n_d]);
    }
    for k in 0..num_topics {
        phi.push(vec![0.0; vocab_size]);
        nkv.push(vec![0; vocab_size]);
    }

    // Initialize w, z, ndk and nkv
    let among_topics = Range::new(0, num_topics);
    for (d, bag) in dataset.iter().enumerate() {
        let mut i = 0;
        for (&v, &count) in bag {
            for _ in 0..count {
                w[d][i] = v;
                let k = among_topics.ind_sample(&mut rng);
                z[d][i] = k;
                ndk[d][k] += 1;
                nkv[k][v] += 1;
                i += 1;
            }
        }
    }
    // Initialize theta, phi
    for d in 0..num_docs {
        let dir = Dirichlet::new(alpha.clone());
        theta[d] = dir.ind_sample(&mut rng);
    }
    for k in 0..num_topics {
        let dir = Dirichlet::new(beta.clone());
        phi[k] = dir.ind_sample(&mut rng);
    }

    println!("z = {:?}", z);
    println!("theta = {:?}", theta);
    println!("ndk = {:?}", ndk);
    println!("phi = {:?}", phi);
    println!("nkv = {:?}", nkv);

    // Sampling
    for s in 0..(burn_in + num_samples) {
        for (d, w_d) in w.iter().enumerate() {
            for (i, &w_di) in w_d.iter().enumerate() {
                let v = w_di;
                // Sample z_di
                let mut weights: Vec<f64> = Vec::with_capacity(num_topics);
                for k in 0..num_topics {
                    weights.push(theta[d][k] * phi[k][v]);
                }
                let cat = Categorical::new(weights);
                let old_z_di = z[d][i];
                let new_z_di = cat.ind_sample(&mut rng);
                z[d][i] = new_z_di;
                if s >= burn_in {
                    z_samples[d][i][new_z_di] += 1;
                }
                // Update ndk and nkv
                ndk[d][old_z_di] -= 1;
                ndk[d][new_z_di] += 1;
                nkv[old_z_di][v] -= 1;
                nkv[new_z_di][v] += 1;
            }
            // Sample theta_d
            let mut alpha_d: Vec<f64> = Vec::with_capacity(num_topics);
            for k in 0..num_topics {
                alpha_d.push(ndk[d][k] as f64 + alpha[k]);
            }
            let dir = Dirichlet::new(alpha_d);
            theta[d] = dir.ind_sample(&mut rng);
        }
        for k in 0..num_topics {
            // Sample phi_k
            let mut beta_k: Vec<f64> = Vec::with_capacity(vocab_size);
            for v in 0..vocab_size {
                beta_k.push(nkv[k][v] as f64 + beta[v]);
            }
            let dir = Dirichlet::new(beta_k);
            phi[k] = dir.ind_sample(&mut rng);
        }
        // Evaluate the log-likelihood value for the current parameters
        let mut log_likelihood = 0.0;
        for k in 0..num_topics {
            for v in 0..vocab_size {
                log_likelihood += nkv[k][v] as f64 * f64::ln(phi[k][v]);
            }
        }
        println!("log_likelihood = {}", log_likelihood);
    }
    // Distribution of z
    for (d, z_samples_d) in z_samples.iter().enumerate() {
        for (i, samples) in z_samples_d.iter().enumerate() {
            let mut sum = 0.0;
            for k in 0..num_topics {
                sum += samples[k] as f64;
            }
            print!("z[{:3}][{:3}] = ", d, i);
            for k in 0..num_topics {
                print!("{:3}:{:.2} ", k, samples[k] as f64 / sum);
            }
            println!("");
        }
    }
}

fn make_dataset(num_docs: usize, mean_nd: f64, std_dev_nd: f64, alpha: Vec<f64>, beta: Vec<f64>) -> Vec<Bag> {
    let num_topics: usize = alpha.len();
    let vocab_size: usize = beta.len();
    let mut rng = rand::thread_rng();
    // phi
    let dir_beta = Dirichlet::new(beta);
    let mut phi: Vec<Vec<f64>> = Vec::with_capacity(num_topics);
    for k in 0..num_topics {
        // Sample phi_k
        phi.push(dir_beta.ind_sample(&mut rng));
    }
    // theta, nd, z, w
    let dir_alpha = Dirichlet::new(alpha);
    let lognorm = LogNormal::new(mean_nd, std_dev_nd);
    let mut theta: Vec<Vec<f64>> = Vec::with_capacity(num_docs);
    let mut nd: Vec<usize> = Vec::with_capacity(num_docs);
    let mut z: Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    let mut w: Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    for d in 0..num_docs {
        theta.push(dir_alpha.ind_sample(&mut rng));
        nd.push(f64::floor(lognorm.ind_sample(&mut rng)) as usize);
        let cat_theta = Categorical::new(theta[d].clone());
        let mut z_d = Vec::with_capacity(nd[d]);
        let mut w_d = Vec::with_capacity(nd[d]);
        for i in 0..nd[d] {
            z_d.push(cat_theta.ind_sample(&mut rng));
            let cat_phi = Categorical::new(phi[z_d[i]].clone());
            w_d.push(cat_phi.ind_sample(&mut rng));
        }
        z.push(z_d);
        w.push(w_d);
    }
    // Make bags
    let mut bags: Vec<Bag> = Vec::new();
    for w_d in w {
        let mut bag: Bag = Bag::new();
        for v in w_d {
            let counter = bag.entry(v).or_insert(0);
            *counter += 1;
        }
        bags.push(bag);
    }
    bags
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let (labels, dataset, vocab_size) = load_bags(&args[1]).unwrap();
    let vocab: Option<Vec<String>> = if args.len() < 3 {
        None
    }
    else {
        Some(load_text_vocabulary(&args[2]).unwrap())
    };
    println!("{:?}", labels);
    println!("{:?}", dataset);
    println!("{:?}", vocab);

    let num_topics = 3;
    let alpha: Vec<f64> = iter::repeat(1.0).take(num_topics).collect();
    let beta: Vec<f64> = iter::repeat(1.0).take(vocab_size).collect();

    lda(dataset, alpha, beta, 1000, 10000);
}
<|endoftext|>


<commit_before>extern crate clock_ticks;
extern crate rand;
extern crate sdl2;

use rand::distributions::{IndependentSample, Range};

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::keyboard::Scancode;
use sdl2::rect::Rect;
use sdl2::render::Renderer;
use sdl2::Sdl;
use sdl2::TimerSubsystem;
use sdl2::VideoSubsystem;

use std::default::Default;
use std::f32;
use std::path::Path;
use std::thread;

pub const FPS: u32 = 40;
pub const SCREEN_WIDTH: f32 = 600.;
pub const SCREEN_HEIGHT: f32 = 300.;

pub struct Ui {
    sdl_ctx: Sdl,
    renderer: Renderer<'static>
}

impl Ui {
    pub fn new() -> Ui {
        let sdl_ctx = sdl2::init().unwrap();
        let video_subsystem = sdl_ctx.video().unwrap();
        let window = video_subsystem.window("pong",
                SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)
                .position_centered()
                .build()
                .unwrap();
        let renderer = window.renderer().build().unwrap();
        Ui {
            sdl_ctx: sdl_ctx,
            renderer: renderer
        }
    }

    pub fn poll_event(&self) -> Option<Event> {
        let mut event_pump = self.sdl_ctx.event_pump().unwrap();
        return event_pump.poll_event();
    }
}

pub struct Ball {
    pub x: f32,
    pub y: f32,
    pub width: f32,
    pub height: f32,
    pub speed: f32,
    pub vx: f32,
    pub vy: f32
}

impl Ball {
    pub fn new() -> Ball {
        let width = 10.;
        let height = 10.;
        // Place ball at center of screen.
        let x = (SCREEN_WIDTH - width) / 2.;
        let y = (SCREEN_HEIGHT - height) / 2.;
        let speed = 200.;
        let mut rng = rand::thread_rng();
        // Launch at an angle less than or equal to 45 degree.
        let angle = Range::new(0., f32::consts::PI/4.).ind_sample(&mut rng);
        let dir = [-1., 1.];
        // Use the sine of the angle to determine the vertical speed. Then,
        // choose a direction (up or down) to select a vertical velocity.
        let up_or_down = rand::sample(&mut rng, dir.into_iter(),1)[0];
        let vy = angle.sin() * speed * up_or_down;
        let left_or_right = rand::sample(&mut rng, dir.into_iter(),1)[0];
        // Use Pythagoras to determine the horizontal speed. Then, choose a
        // direction (left or right) to a horizontal velocity.
        let vx = ((speed * speed) - (vy * vy)).sqrt() * left_or_right;
        Ball {
            x: x,
            y: y,
            width: width,
            height: height,
            speed: speed,
            vx: vx,
            vy: vy
        }
    }
}

pub struct Game {
    ui: Ui,
    ball: Ball
}

impl Game {

    /// Create initial game state.
    pub fn new() -> Game {
        Game {
            ui: Ui::new(),
            ball: Ball::new()
        }
    }

    /// Start the game and block until finished.
    pub fn start(&mut self) {
        let mut time_last_invocation = clock_ticks::precise_time_ms();
        loop {
            let time_this_invocation = clock_ticks::precise_time_ms();
            let delta_time = time_this_invocation - time_last_invocation;
            if self.update(delta_time as f32 / 1000.) == false { return; }
            self.cap_fps(delta_time);
            time_last_invocation = time_this_invocation;
        }
    }

    /// Called once per frame.
    fn update(&mut self, dt_sec: f32) -> bool {
        self.ui.poll_event();
        let ball = &mut self.ball;
        ball.x += ball.vx * dt_sec;
        ball.y += ball.vy * dt_sec;
        self.ui.renderer.clear();
        let rect = Rect::new_unwrap(ball.x as i32,
                                    ball.y as i32,
                                    ball.width as u32,
                                    ball.height as u32);
        self.ui.renderer.fill_rect(rect);
        self.ui.renderer.present();
        true
    }

    // Ensure we run no faster than the desired fps by introducing
    // a delay if necessary.
    fn cap_fps(&self, took_ms: u64) {
        let max_ms = 1000 / FPS as u64;
        if max_ms > took_ms {
            thread::sleep_ms((max_ms - took_ms) as u32);
        }
    }
}

fn main() {
    let mut game = Game::new();
    game.start();
}
<commit_msg>Ball bouncing around screen.<commit_after>extern crate clock_ticks;
extern crate rand;
extern crate sdl2;

use rand::distributions::{IndependentSample, Range};

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::keyboard::Scancode;
use sdl2::rect::Rect;
use sdl2::render::Renderer;
use sdl2::Sdl;
use sdl2::TimerSubsystem;
use sdl2::VideoSubsystem;

use std::default::Default;
use std::f32;
use std::path::Path;
use std::thread;

pub const FPS: u32 = 40;
pub const SCREEN_WIDTH: f32 = 600.;
pub const SCREEN_HEIGHT: f32 = 300.;

pub struct Ui {
    sdl_ctx: Sdl,
    renderer: Renderer<'static>
}

impl Ui {
    pub fn new() -> Ui {
        let sdl_ctx = sdl2::init().unwrap();
        let video_subsystem = sdl_ctx.video().unwrap();
        let window = video_subsystem.window("pong",
                SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)
                .position_centered()
                .build()
                .unwrap();
        let renderer = window.renderer().build().unwrap();
        Ui {
            sdl_ctx: sdl_ctx,
            renderer: renderer
        }
    }

    pub fn poll_event(&self) -> Option<Event> {
        let mut event_pump = self.sdl_ctx.event_pump().unwrap();
        return event_pump.poll_event();
    }
}

pub struct Ball {
    pub x: f32,         // x pixel co-ordinate of top left corner
    pub y: f32,         // y pixel co-ordinate of top left corner
    pub width: f32,     // pixels
    pub height: f32,    // pixels
    pub speed: f32,     // pixels per second
    pub vx: f32,        // pixels per second
    pub vy: f32         // pixels per second
}

impl Ball {
    pub fn new() -> Ball {
        let width = 10.;
        let height = 10.;

        // Place ball at center of screen.
        let x = (SCREEN_WIDTH - width) / 2.;
        let y = (SCREEN_HEIGHT - height) / 2.;

        // Able to travel height of screen in 1 second
        let speed = SCREEN_HEIGHT;
        let mut rng = rand::thread_rng();

        // Launch at an angle less than or equal to 45 degrees.
        let angle = Range::new(0., f32::consts::PI/4.).ind_sample(&mut rng);
        let dir = [-1., 1.];

        // Use the sine of the angle to determine the vertical speed. Then,
        // choose a direction (up or down) to select a vertical velocity.
        let up_or_down = rand::sample(&mut rng, dir.into_iter(),1)[0];
        let vy = angle.sin() * speed * up_or_down;
        let left_or_right = rand::sample(&mut rng, dir.into_iter(),1)[0];

        // Use Pythagoras to determine the horizontal speed. Then, choose a
        // direction (left or right) to select a horizontal velocity.
        let vx = ((speed * speed) - (vy * vy)).sqrt() * left_or_right;
        Ball {
            x: x,
            y: y,
            width: width,
            height: height,
            speed: speed,
            vx: vx,
            vy: vy
        }
    }
}

pub struct Game {
    ui: Ui,
    ball: Ball,
    running: bool
}

impl Game {

    /// Create initial game state.
    pub fn new() -> Game {
        Game {
            ui: Ui::new(),
            ball: Ball::new(),
            running: false,
        }
    }

    /// Start the game and block until finished.
    pub fn start(&mut self) {
        self.running = true;
        let mut time_last_invocation = clock_ticks::precise_time_ms();
        while self.running {
            let time_this_invocation = clock_ticks::precise_time_ms();
            let delta_time = time_this_invocation - time_last_invocation;
            self.update(delta_time as f32 / 1000.);
            self.cap_fps(delta_time);
            time_last_invocation = time_this_invocation;
        }
    }

    /// Called once per frame.
    fn update(&mut self, dt_sec: f32) {
        self.handle_input();
        self.update_ball_position(dt_sec);
        self.check_for_ball_and_wall_collisions();
        self.ui.renderer.clear();
        let ball = &mut self.ball;
        let rect = Rect::new_unwrap(ball.x as i32,
                                    ball.y as i32,
                                    ball.width as u32,
                                    ball.height as u32);
        self.ui.renderer.fill_rect(rect);
        self.ui.renderer.present();
    }

    fn handle_input(&mut self) {
        match self.ui.poll_event() {
            Some(event) => {
                match event {
                    Event::Quit{..} => {
                        self.running = false;
                    },
                    Event::KeyDown{keycode,..} => match keycode {
                        Option::Some(Keycode::Escape) => {
                            self.running = false;
                        },
                        _ => {}
                    },
                    _ => {}
                }
            },
            None => {}
        }
    }

    fn update_ball_position(&mut self, dt_sec: f32) {
        let ball = &mut self.ball;
        ball.x += ball.vx * dt_sec;
        ball.y += ball.vy * dt_sec;
    }

    fn check_for_ball_and_wall_collisions(&mut self) {
        self.check_for_ball_and_top_wall_collision();
        self.check_for_ball_and_right_wall_collision();
        self.check_for_ball_and_bottom_wall_collision();
        self.check_for_ball_and_left_wall_collision();
    }

    fn check_for_ball_and_top_wall_collision(&mut self) {
        let ball = &mut self.ball;
        if ball.y <= 0. && ball.vy < -0. {
            ball.y = 0.;
            ball.vy = -ball.vy;
        }
    }

    fn check_for_ball_and_right_wall_collision(&mut self) {
        let ball = &mut self.ball;
        if ball.x + ball.width >= SCREEN_WIDTH && ball.vx > 0. {
            ball.x = SCREEN_WIDTH - ball.width;
            ball.vx = -ball.vx;
        }
    }

    fn check_for_ball_and_bottom_wall_collision(&mut self) {
        let ball = &mut self.ball;
        if ball.y + ball.height >= SCREEN_HEIGHT && ball.vy > 0. {
            ball.y = SCREEN_HEIGHT - ball.height;
            ball.vy = -ball.vy;
        }
    }

    fn check_for_ball_and_left_wall_collision(&mut self) {
        let ball = &mut self.ball;
        if ball.x <= 0. && ball.vx < -0. {
            ball.x = 0.;
            ball.vx = -ball.vx;
        }
    }

    // Ensure we run no faster than the desired fps by introducing
    // a delay if necessary.
    fn cap_fps(&self, took_ms: u64) {
        let max_ms = 1000 / FPS as u64;
        if max_ms > took_ms {
            thread::sleep_ms((max_ms - took_ms) as u32);
        }
    }
}

fn main() {
    let mut game = Game::new();
    game.start();
}
<|endoftext|>