I'm currently learning rust by writing a project which is a clone of the board game "Puerto Rico".
the Game struct:
I chose the players member to be an array slice because it can only contain 3, 4 or 5 players (to my understanding, this is the perfect use case for an array slice inside a struct, instead of a Vec)
the Game::new function:
Returns a new Game instance. It takes a list of the names of the players and an empty Vec and populates it with the appropriate Player instances then stores it in the Game as an array slice.
The problem is that this method of instantiating the Game struct seems kind of cumbersome and I feel like there is a way around it (as in passing only the names parameter and somehow creating the array slice inside the new function).
So, is there a way to do it? Should I just change the players member to a Vec?
I tried to move the vec!() declaration inside the new function but, of course, it doesn't work becuase it is dropped at the end of the block.
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]
}
}
}