use super::*;
pub fn board_from(terms: &MatchTerms, seats: u8, beach: &[u8]) -> crate::sim::Board {
let Some(level) = beach_in_play(terms.map(), beach_from(beach), seats) else {
return board_for(terms, seats);
};
let mut board = level.table_board(terms.seed, seats);
apply_terms(&mut board, terms.gulls(), terms.round(), terms.posts());
board
}
pub fn board_for(terms: &MatchTerms, seats: u8) -> crate::sim::Board {
let mut board = versus_board(terms.map(), terms.seed, seats);
apply_terms(&mut board, terms.gulls(), terms.round(), terms.posts());
board
}
pub fn local_board(config: &MatchConfig, beaches: &CustomBeaches, seed: u64) -> crate::sim::Board {
let map = match holds(config.map, config.seats) {
true => config.map,
false => sized_for(config.seats),
};
let shelved = (map == MapChoice::Custom)
.then(|| beaches.fitting(config.seats).into_iter().nth(config.custom))
.flatten();
let mut board = match shelved {
Some(beach) => beach.level.table_board(seed, config.seats),
None => versus_board(map, seed, config.seats),
};
apply_terms(&mut board, config.gulls, config.round, config.posts);
board
}
pub fn versus_board(map: MapChoice, seed: u64, seats: u8) -> crate::sim::Board {
let generated = |map: MapChoice| {
let (w, h) = map.size();
crate::sim::generate_beach(seed, seats, w, h, map.wraps())
};
let (board, strip) = match map {
MapChoice::Classic => (crate::sim::classic_arena_seeded(seed, false, seats), 0),
MapChoice::GenSmall
| MapChoice::GenClassic
| MapChoice::GenLarge
| MapChoice::GenXl
| MapChoice::GenOcean
| MapChoice::Custom => (generated(map), 0),
MapChoice::TheGates
| MapChoice::TheMoat
| MapChoice::LogJam
| MapChoice::ThreeLanes
| MapChoice::RoundTable
| MapChoice::RoundTheWorld
| MapChoice::Duel
| MapChoice::TheFountain
| MapChoice::FourDoors
| MapChoice::GullRoad
| MapChoice::BackToBack => {
let level = crate::sim::versus_map(map.handmade().unwrap_or(0));
match level.fits(seats) {
true => {
let mut board = level.table_board(seed, seats);
crate::sim::deal_pairs(&mut board, seats, seed);
(board, level.roll)
}
false => (generated(sized_for(seats)), 0),
}
}
MapChoice::Surprise => {
let (w, h) = crate::sim::surprise_size(seats);
let style = crate::sim::surprise_style(seed, seats);
(
crate::sim::generate_styled(seed, seats, w, h, false, style),
0,
)
}
};
crate::sim::Orientation::for_round(seed, board.width(), strip).apply(&board)
}
pub fn apply_terms(
board: &mut crate::sim::Board,
gulls: GullPressure,
round: RoundLength,
posts: u8,
) {
crate::sim::set_versus_rules(board, gulls.period());
board.set_events_enabled(true);
board.rules_mut().round_length = Some(round.ticks());
board.set_signpost_rule(posts, crate::sim::CapPolicy::Evict);
}
pub fn bot_seats_from(terms: &MatchTerms, seats: u8) -> [Option<BotLevel>; MAX_PLAYERS] {
let level = terms.bot_level();
let mut out = [None; MAX_PLAYERS];
for seat in terms.ai_seats(seats) {
if let Some(slot) = out.get_mut(usize::from(seat)) {
*slot = Some(level);
}
}
out
}