Added tree generation

This commit is contained in:
Gnarwhal 2019-07-26 10:42:50 -07:00
parent 09ec609d05
commit d71d282b48
Signed by: Gnarwhal
GPG key ID: 0989A73D8C421174

View file

@ -28,10 +28,13 @@ use std::io::{self, stdin, Write};
use rand::Rng; use rand::Rng;
const MINIMAX_TITLE: &str = r" const MINIMAX_TITLE: &str = r"
____ _ _ _ _ ____ ___ __ __ ******************************************
| \| | \| | | \| \\ \/ / * ____ _ _ _ _ ____ ___ __ __ *
| | | | | | | | | | |\ \> < * | \| | \| | | \| \\ \/ / *
|_|_|_|_|_|\_|_|_|_|_|_| \_\/\_\"; * | | | | | | | | | | |\ \> < *
* |_|_|_|_|_|\_|_|_|_|_|_| \_\/\_\ *
* *
******************************************";
enum Action { enum Action {
Example, Example,
@ -42,6 +45,12 @@ enum Action {
Invalid(String), Invalid(String),
} }
struct Parameters {
singleplayer: bool,
depth: u32,
parity: bool,
}
fn main() { fn main() {
println!("{}\n\n", MINIMAX_TITLE); println!("{}\n\n", MINIMAX_TITLE);
@ -65,8 +74,11 @@ intelligence. I won't always understand you, but I try my best.
So! Without further ado let's get this show on the road! So! Without further ado let's get this show on the road!
"); ");
let mut singleplayer = true; let mut params = Parameters {
let mut depth: u32 = 4; singleplayer: true,
depth: 4,
parity: true,
};
loop { loop {
print!("Please enter a command: "); print!("Please enter a command: ");
@ -78,16 +90,16 @@ So! Without further ado let's get this show on the road!
match action { match action {
Action::Example => walkthrough_example(), Action::Example => walkthrough_example(),
Action::Help => print_help(), Action::Help => print_help(),
Action::Begin => println!("You would like to begin"), Action::Begin => run_game(&params),
Action::Set(string) => match get_values(&string) { Action::Set(string) => match get_values(&string) {
Ok(("singleplayer", value)) => { Ok(("singleplayer", value)) => {
match parse_bool(&value) { match parse_bool(&value) {
Ok(boolean) => { singleplayer = boolean; }, Ok(boolean) => { params.singleplayer = boolean; },
Err(err) => println!("{}", err), Err(err) => println!("{}", err),
}; };
}, },
Ok(("depth", value)) => { Ok(("depth", value)) => {
depth = match value.parse::<u32>() { params.depth = match value.parse::<u32>() {
Ok(num) => { Ok(num) => {
if num > 0 { if num > 0 {
num num
@ -103,6 +115,26 @@ So! Without further ado let's get this show on the road!
}, },
}; };
}, },
Ok(("min", value)) => {
params.parity = match value {
"player_one" => false,
"player_two" => true,
_ => {
println!("Hmm. I am not familiar with player \"value\"!");
continue;
}
};
},
Ok(("max", value)) => {
params.parity = match value {
"player_one" => true,
"player_two" => false,
_ => {
println!("Hmm. I am not familiar with player \"value\"!");
continue;
}
};
},
Ok((key, _)) => println!("\"{}\" is not a key I recognize! Perhaps try something else!", key), Ok((key, _)) => println!("\"{}\" is not a key I recognize! Perhaps try something else!", key),
Err(_) => println!("Unfortunately I'm not sure what you are trying to set with the command \"{}\"!", string), Err(_) => println!("Unfortunately I'm not sure what you are trying to set with the command \"{}\"!", string),
}, },
@ -216,8 +248,10 @@ example > Runs you through an example game if still feel a little unclear on the
help > Well I think you already know about this command :) help > Well I think you already know about this command :)
begin > Begins the epic journey through the binary tree begin > Begins the epic journey through the binary tree
set {{key}} = {{value}} > Sets some paramaters for the game. Currently the available paramaters are: set {{key}} = {{value}} > Sets some paramaters for the game. Currently the available paramaters are:
singleplayer - a boolean value which switches between playing against me and playing against your mates singleplayer - A boolean value which which sets whether you play against me or play against your mates
depth - an integer value which sets the depth of the tree depth - An integer value which sets the depth of the tree
min - One of either \"player_one\" OR \"player_two\". Sets that player's goal to minimize the value
max - One of either \"player_one\" OR \"player_two\". Sets that player's goal to maximize the value
quit > I should think you would know what this one does as well"); quit > I should think you would know what this one does as well");
} }
@ -230,7 +264,7 @@ fn get_values(string: &str) -> Result<(&str, &str), ()> {
} }
} }
if split == string.len() - 1 { if split == string.len() - 1 {
return Err(()) return Err(());
} }
let key = string[..split].trim(); let key = string[..split].trim();
let value = string[(split + 1)..].trim(); let value = string[(split + 1)..].trim();
@ -248,4 +282,68 @@ fn parse_bool(value: &str) -> Result<bool, &'static str> {
"false" => Ok(false), "false" => Ok(false),
_ => Err("I do apologize, but I was expecting a boolean type!"), _ => Err("I do apologize, but I was expecting a boolean type!"),
} }
}
fn run_game(params: &Parameters) {
let tree = generate_tree(params.depth, params.parity);
type Input = fn() -> str;
//let player_one = user_input;
//let player_two = if params.singleplayer { computer_input } else { user_input };
//loop {
println!("Let the game begin!
Player one you are trying to maximize the value. Player two you are trying to minimize the value.");
print_tree(&tree);
//}
}
fn generate_tree(depth: u32, parity: bool) -> Vec<Vec<u32>> {
const TREE_RANGE: u32 = 1000;
let mut tree: Vec<Vec<u32>> = Vec::new();
let mut leaves: Vec<u32> = Vec::new();
let mut leaf_count = pow(2, depth - 1);
while leaf_count > 0 {
leaves.push(rand::thread_rng().gen_range(0, TREE_RANGE));
leaf_count -= 1;
}
tree.push(leaves);
expand_tree(&mut tree, depth % 2 == parity as u32);
tree
}
fn pow(mut base: u32, mut power: u32) -> u32 {
let mut result = 1;
while power > 0 {
if power & 1 != 0 { result = result * base; }
base *= base;
power >>= 1;
}
result
}
fn expand_tree(tree: &mut Vec<Vec<u32>>, parity: bool) {
if tree[0].len() == 1 { return; }
let mut write_layer: Vec<u32> = Vec::new();
for i in 0..tree[0].len() / 2 {
write_layer.push(
if (tree[0][i * 2] < tree[0][i * 2 + 1]) == parity { tree[0][i * 2] }
else { tree[0][i * 2 + 1] }
);
}
tree.insert(0, write_layer);
expand_tree(tree, !parity);
}
fn print_tree(tree: &Vec<Vec<u32>>) {
for layer in tree {
println!("{:?}", layer);
}
} }