Rust学习—示例4
描述:剪刀石头布
我们来玩吧!你必须返回哪个玩家赢了!如果是平局的话,则返回平局!
示例
"scissors", "paper" --> "Player 1 won!"
"scissors", "rock" --> "Player 2 won!"
"paper", "paper" --> "Draw!"
代码实现:
#[cfg(test)]
mod tests {
use rand::{thread_rng, Rng};
use super::rps;
const ERR_MSG: &str = "\nYour result (left) did not match the expected output (right)";
fn dotest(p1: &str, p2: &str, expected: &str) {
assert_eq!(rps(p1, p2), expected, "{ERR_MSG} with p1 = \"{p1}\", p2 = \"{p2}\"")
}
//一个官方发的解决方法
fn reference_solution(p1: &str, p2: &str) -> &'static str {
if p1 == p2 {
"Draw!"
} else {
let i = ["scissors", "paper", "rock"].iter().position(|x| x == &p1).unwrap() as i8 - ["scissors", "paper", "rock"].iter().position(|x| x == &p2).unwrap() as i8;
if i == -1 || i == 2 {
"Player 1 won!"
} else {
"Player 2 won!"
}
}
}
#[test]
fn fixed_tests() {
dotest("rock", "scissors", "Player 1 won!");
dotest("scissors", "rock", "Player 2 won!");
dotest("rock", "rock", "Draw!");
}
#[test]
fn random_tests() {
let mut rng = thread_rng();
let ans_arr = ["rock", "scissors", "paper"];
for _ in 0..100 {
let p1 = ans_arr[rng.gen_range(0..3)];
let p2 = ans_arr[rng.gen_range(0..3)];
dotest(p1, p2, reference_solution(p1, p2));
}
}
}
//我的笨办法
fn rps(p1: &str, p2: &str) -> &'static str {
//todo!()
match p1 {
"rock" if p2 =="scissors"=>"Player 1 won!",
"rock" if p2 =="paper"=>"Player 2 won!",
"scissors" if p2 =="paper"=>"Player 1 won!",
"scissors" if p2 =="rock"=>"Player 2 won!",
"paper" if p2 =="rock"=>"Player 1 won!",
"paper" if p2 =="scissors"=>"Player 2 won!",
_ => "Draw!"
}
}
其他参考示例
//思路其实都差不多,但是怎么把代码写的更简洁并且具有较高的可读性是一个技术活
fn rps(p1: &str, p2: &str) -> &'static str {
if (p1 == p2) {
return "Draw!";
}
match (p1, p2) {
("scissors", "paper") | ("paper", "rock") | ("rock", "scissors") => "Player 1 won!",
_ => "Player 2 won!",
}
}
//2
fn rps(p1: &str, p2: &str) -> &'static str {
match (p1, p2) {
("scissors", "paper") => "Player 1 won!",
("scissors", "rock") => "Player 2 won!",
("rock", "scissors") => "Player 1 won!",
("rock", "paper") => "Player 2 won!",
("paper", "rock") => "Player 1 won!",
("paper", "scissors") => "Player 2 won!",
_ => "Draw!",
}
}
//3
fn rps(p1: &str, p2: &str) -> &'static str {
match (p1, p2) {
("scissors", "paper")|("paper", "rock")|("rock", "scissors") => "Player 1 won!",
("paper", "scissors")|("scissors", "rock")|("rock", "paper") => "Player 2 won!",
_ => "Draw!"
}
}
//这个解决方法就不同了,用了hashmap来解决的
use std::collections::HashMap;
fn rps(p1: &str, p2: &str) -> &'static str {
let outcomes = HashMap::from([
("rock", "scissors"),
("scissors", "paper"),
("paper", "rock"),
]);
if p1 == p2 {
"Draw!"
} else if *outcomes.get(p1).unwrap() == p2 {
"Player 1 won!"
} else {
"Player 2 won!"
}
}
//5
fn rps(a: &str, b: &str) -> &'static str {
if a == b {return "Draw!";}
let m: std::collections::HashMap<&str, &str> =[("rock", "paper"), ("paper", "scissors"), ("scissors", "rock")].iter().cloned().collect();
if m[a] == b {return "Player 2 won!";}
"Player 1 won!"
}