我正在尝试制作一个带有自定义棋盘尺寸的井字游戏。我希望这很难被破解,所以如果输入无效或出现错误,我使用递归来获取棋盘测量值。然而,这对我来说似乎不是很干净,我想知道是否有更好/更生疏的方法来实现同样的事情。
main函数中的代码
let board_size_str = get_board_size_string();
let (x_pos, width, height) = get_board_measurement(&board_size_str);
函数
fn get_board_size_string() -> String {
println!("Select the size of the board in the following format: 5x5 or 7x7");
println!("The size can be from 3x3 to 30x30");
print!("Size: ");
std::io::stdout().flush().expect("Failed to flush stdout!");
let mut board_size_str = String::new();
std::io::stdin().read_line(&mut board_size_str).expect("Failed to read board size!");
println!();
board_size_str
}
fn get_board_measurement(board_size_str: &str) -> (usize, i64, i64) {
let x_pos = get_x_pos(board_size_str);
let width = get_board_width(board_size_str, x_pos);
let height = get_board_height(board_size_str, x_pos);
(x_pos, width, height)
}
fn get_x_pos(board_size_str: &str) -> usize {
let x_pos_option = board_size_str.chars().position(|c| c == 'x');
match x_pos_option {
Some(x_pos) => x_pos,
None => {
println!("Board size must contain an x!");
let board_size_str = get_board_size_string();
get_x_pos(&board_size_str)
}
}
}
fn get_board_width(board_size_str: &str, x_pos: usize) -> i64 {
let width_result = board_size_str[..x_pos].parse::<i64>();
match width_result {
Ok(width) => width,
Err(_) => {
println!("Invalid board width!");
let board_size_str = get_board_size_string();
get_board_width(&board_size_str, get_x_pos(&board_size_str))
}
}
}
fn get_board_height(board_size_str: &str, x_pos: usize) -> i64 {
let height_result = board_size_str[x_pos + 1..].trim().parse::<i64>();
match height_result {
Ok(height) => height,
Err(_) => {
println!("Invalid board height!");
let board_size_str = get_board_size_string();
get_board_height(&board_size_str, get_x_pos(&board_size_str))
}
}
}
1条答案
按热度按时间watbbzwu1#
只使用迭代循环?
虽然结构很奇怪,因为正确的电路板大小是正确的模式('x'),所以将其拆分为三个不相关的例程没有任何意义,即使其中两个确实委托了
x
分隔符的本地化。使用你的方法,你可以输入
52xkf
这样的东西,得到一个错误,输入24x36
,我想你会得到一个52x36的电路板,而不是你可能期望的24x36,这很奇怪。如果您不关心单独报告每个错误案例,那么您可以使用
Option
进行解析,例如: