В настоящее время я изучаю ржавчину, написав проект, который является клоном настольной игры "Пуэрто-Рико".
структура Game
: я выбрал элемент players
в качестве среза массивапотому что он может содержать только 3, 4 или 5 игроков (на мой взгляд, это идеальный вариант использования среза массива внутри структуры вместо Vec
)
функция Game::new
: возвращаетновый Game
экземпляр.Он берет список имен игроков и пустой Vec
и заполняет его соответствующими Player
экземплярами, а затем сохраняет его в Game
как фрагмент массива.
Проблема в том, что этометод создания структуры Game
кажется довольно громоздким, и я чувствую, что есть способ обойти его (например, передать только параметр names
и как-то создать срез массива внутри функции new
).
Итак, есть ли способ сделать это?Должен ли я просто изменить players
член на Vec
?
Я попытался переместить объявление vec!()
в функцию new
, но, конечно, он не работает, потому что его отбрасываютв конце блока.
use super::board::Board;
use super::player::Player;
use super::planatation::ResourceType;
#[derive(Debug)]
pub struct Game<'a> {
board: Board,
players: &'a [Player],
governor: &'a Player
}
impl<'a> Game<'a> {
pub fn new(names: &[String], players: &'a mut Vec<Player>) -> Self {
let num_of_players = names.len() as i32;
let board = Board::new(num_of_players);
if num_of_players < 3 || num_of_players > 5 {
panic!("Only 3, 4 or 5 players may play");
}
if num_of_players < 5 {
for (i, name) in names.iter().enumerate() {
if i < 2 {
players.push(Player::new(name.to_string(), ResourceType::Indigo));
} else {
players.push(Player::new(name.to_string(), ResourceType::Corn));
}
}
} else { // num_of_player == 5
for (i, name) in names.iter().enumerate() {
if i < 3 {
players.push(Player::new(name.to_string(), ResourceType::Indigo));
} else {
players.push(Player::new(name.to_string(), ResourceType::Corn));
}
}
}
Game {
board: board,
players: players,
governor: &players[0]
}
}
}