mirror of
https://github.com/LukasKalbertodt/programmieren-in-rust.git
synced 2026-05-05 06:51:12 +02:00
Add solution for sheet5
This commit is contained in:
Executable
+162
@@ -0,0 +1,162 @@
|
||||
use db::types::*;
|
||||
use db;
|
||||
use engine::Pokemon;
|
||||
|
||||
use term_painter::Color::*;
|
||||
use term_painter::ToStyle;
|
||||
|
||||
pub fn fight(mut red: Pokemon, mut blue: Pokemon) {
|
||||
loop {
|
||||
fn check_dead(poki: &Pokemon) -> bool {
|
||||
if poki.is_alive() {
|
||||
false
|
||||
} else {
|
||||
println!(">>>>> {} fainted!", Yellow.paint(poki.name()));
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// Print status
|
||||
println!(
|
||||
">>>>> Status: {} has {} HP, {} has {} HP",
|
||||
Yellow.paint(red.name()),
|
||||
Red.paint(red.stats().hp),
|
||||
Yellow.paint(blue.name()),
|
||||
Red.paint(blue.stats().hp),
|
||||
);
|
||||
|
||||
// Execute both attack
|
||||
if red.stats().speed > blue.stats().speed {
|
||||
// Red attacks blue
|
||||
execute_round(&red, &mut blue);
|
||||
if check_dead(&blue) {
|
||||
break;
|
||||
}
|
||||
|
||||
// BLue attacks red
|
||||
execute_round(&blue, &mut red);
|
||||
if check_dead(&red) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// BLue attacks red
|
||||
execute_round(&blue, &mut red);
|
||||
if check_dead(&red) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Red attacks blue
|
||||
execute_round(&red, &mut blue);
|
||||
if check_dead(&blue) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Executes one round of one player:
|
||||
///
|
||||
/// - the player chooses one attack to execute
|
||||
/// - the attack is excuted and the enemy's HP
|
||||
fn execute_round(attacker: &Pokemon, defender: &mut Pokemon) {
|
||||
// Tell the user to choose an attack
|
||||
println!(
|
||||
">>>>> {} is about to attack! Which move shall it execute?",
|
||||
Yellow.paint(attacker.model().name)
|
||||
);
|
||||
|
||||
// Print a list of available attacks
|
||||
let num_attacks = attacker.model().attacks.len();
|
||||
for i in 0..num_attacks {
|
||||
println!(
|
||||
" {}: {}",
|
||||
i,
|
||||
Blue.paint(attacker.model().attacks[i].name)
|
||||
);
|
||||
}
|
||||
println!(" !!! Please give me the attack ID:");
|
||||
|
||||
// Read attack ID from the user
|
||||
let attack_id;
|
||||
loop {
|
||||
let input = read_usize();
|
||||
if input >= num_attacks {
|
||||
println!(" !!! There is no attack with index {}!", input);
|
||||
} else {
|
||||
attack_id = input;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute attack
|
||||
let attack = *attacker.model().attacks[attack_id];
|
||||
defender.endure_attack(attacker, attack);
|
||||
|
||||
// Status update
|
||||
println!(
|
||||
">>>>> {} uses {}! ({} has {} HP left)",
|
||||
Yellow.paint(attacker.model().name),
|
||||
Blue.paint(attack.name),
|
||||
Yellow.paint(defender.model().name),
|
||||
Red.paint(defender.stats().hp),
|
||||
);
|
||||
}
|
||||
|
||||
/// Let's the player choose a Pokemon from the database.
|
||||
pub fn choose_pokemon(player: &str) -> PokemonModel {
|
||||
// Loop forever until the user has chosen a Pokemon
|
||||
loop {
|
||||
println!(
|
||||
"{}, please choose a Pokemon (or type '?' to get a complete list)",
|
||||
player,
|
||||
);
|
||||
|
||||
let input = read_string();
|
||||
if input == "?" {
|
||||
print_pokemon_list();
|
||||
} else {
|
||||
// Try to find a Pokemon with the given name
|
||||
match db::pokemon_by_name(&input) {
|
||||
Some(poki) => return poki,
|
||||
None => {
|
||||
println!("No pokemon with the name '{}' was found!", input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints a list of all Pokemon in the database.
|
||||
fn print_pokemon_list() {
|
||||
for poki in db::data::POKEDEX {
|
||||
// This strange formatter will print the pokemon ID with three digits,
|
||||
// filling in 0 from the left if necessary (#003).
|
||||
println!("#{:0>3} {}", poki.id, poki.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Reads a string from the terminal/user.
|
||||
fn read_string() -> String {
|
||||
let mut buffer = String::new();
|
||||
::std::io::stdin()
|
||||
.read_line(&mut buffer)
|
||||
.expect("something went horribly wrong...");
|
||||
|
||||
// Discard trailing newline
|
||||
let new_len = buffer.trim_right().len();
|
||||
buffer.truncate(new_len);
|
||||
|
||||
buffer
|
||||
}
|
||||
|
||||
/// Reads a valid `usize` integer from the terminal/user.
|
||||
fn read_usize() -> usize {
|
||||
loop {
|
||||
match read_string().parse() {
|
||||
Ok(res) => return res,
|
||||
Err(_) => println!("That was not an integer! Please try again!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user