use battlesnake::{
    simulation::{self, SnakeToken},
    Coord,
};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::{rngs::StdRng, SeedableRng};

fn random_moves(board: &battlesnake::Board) -> Option<SnakeToken> {
    let token_map = SnakeToken::from_board(board);
    let mut board = simulation::Board::from_game_board(board, &token_map, 0, 15, 1, false);
    let mut rng = StdRng::seed_from_u64(0);

    board.simulate_until(&mut rng, |board| board.alive_snakes() <= 1);

    let winner = board.snakes().next();
    winner
}

fn bench_duel_random_moves(c: &mut Criterion) {
    c.bench_function("duel random moves", |b| {
        b.iter(|| {
            random_moves(black_box(&battlesnake::Board {
                height: 11,
                width: 11,
                food: vec![Coord { x: 5, y: 5 }],
                snakes: vec![
                    battlesnake::Battlesnake {
                        id: "1".to_owned(),
                        name: "1".to_owned(),
                        health: 100,
                        body: vec![Coord { x: 5, y: 1 }; 3],
                        head: Coord { x: 5, y: 1 },
                        length: 3,
                        latency: "0".to_owned(),
                        shout: None,
                        squad: String::new(),
                    },
                    battlesnake::Battlesnake {
                        id: "2".to_owned(),
                        name: "2".to_owned(),
                        health: 100,
                        body: vec![Coord { x: 5, y: 9 }; 3],
                        head: Coord { x: 5, y: 9 },
                        length: 3,
                        latency: "0".to_owned(),
                        shout: None,
                        squad: String::new(),
                    },
                ],
                hazards: vec![],
            }))
        });
    });
}

fn bench_standard_random_moves(c: &mut Criterion) {
    c.bench_function("standard random moves", |b| {
        b.iter(|| {
            random_moves(black_box(&battlesnake::Board {
                height: 11,
                width: 11,
                food: vec![Coord { x: 5, y: 5 }],
                snakes: vec![
                    battlesnake::Battlesnake {
                        id: "1".to_owned(),
                        name: "1".to_owned(),
                        health: 100,
                        body: vec![Coord { x: 5, y: 1 }; 3],
                        head: Coord { x: 5, y: 1 },
                        length: 3,
                        latency: "0".to_owned(),
                        shout: None,
                        squad: String::new(),
                    },
                    battlesnake::Battlesnake {
                        id: "2".to_owned(),
                        name: "2".to_owned(),
                        health: 100,
                        body: vec![Coord { x: 5, y: 9 }; 3],
                        head: Coord { x: 5, y: 9 },
                        length: 3,
                        latency: "0".to_owned(),
                        shout: None,
                        squad: String::new(),
                    },
                    battlesnake::Battlesnake {
                        id: "3".to_owned(),
                        name: "3".to_owned(),
                        health: 100,
                        body: vec![Coord { x: 1, y: 5 }; 3],
                        head: Coord { x: 1, y: 5 },
                        length: 3,
                        latency: "0".to_owned(),
                        shout: None,
                        squad: String::new(),
                    },
                    battlesnake::Battlesnake {
                        id: "4".to_owned(),
                        name: "4".to_owned(),
                        health: 100,
                        body: vec![Coord { x: 9, y: 5 }; 3],
                        head: Coord { x: 9, y: 5 },
                        length: 3,
                        latency: "0".to_owned(),
                        shout: None,
                        squad: String::new(),
                    },
                ],
                hazards: vec![],
            }))
        });
    });
}

criterion_group!(
    benches,
    bench_duel_random_moves,
    bench_standard_random_moves
);
criterion_main!(benches);
