1
// This file is part of hnefatafl-copenhagen.
2
//
3
// hnefatafl-copenhagen is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU Affero General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// hnefatafl-copenhagen is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU Affero General Public License for more details.
12
//
13
// You should have received a copy of the GNU Affero General Public License
14
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
//
16
// SPDX-License-Identifier: AGPL-3.0-or-later
17
// SPDX-FileCopyrightText: 2025 David Campbell <david@hnefatafl.org>
18

            
19
use hnefatafl_copenhagen::{
20
    board::Board, game::PreviousBoards, play::Plays, role::Role, server_game::ArchivedGame,
21
    status::Status, tree::Tree,
22
};
23

            
24
#[derive(Clone, Debug)]
25
pub(crate) struct ArchivedGameHandle {
26
    pub boards: Tree,
27
    pub game: ArchivedGame,
28
    pub play: usize,
29
}
30

            
31
impl ArchivedGameHandle {
32
    #[must_use]
33
    #[allow(clippy::missing_panics_doc)]
34
    #[allow(clippy::unwrap_used)]
35
    pub(crate) fn new(game: &ArchivedGame) -> ArchivedGameHandle {
36
        let mut board = Board::new(game.board_size);
37
        let mut boards = Tree::new(game.board_size);
38
        let mut turn = Role::default();
39

            
40
        let plays = match &game.plays {
41
            Plays::PlayRecordsTimed(plays) => {
42
                plays.iter().map(|record| record.play.clone()).collect()
43
            }
44
            Plays::PlayRecords(plays) => plays.clone(),
45
        };
46

            
47
        for play in &plays {
48
            if let Some(play) = &play {
49
                board
50
                    .play(
51
                        play,
52
                        &Status::Ongoing,
53
                        &turn,
54
                        &mut PreviousBoards::default(),
55
                    )
56
                    .unwrap();
57

            
58
                boards.insert(&board);
59
                turn = match turn {
60
                    Role::Attacker => Role::Defender,
61
                    Role::Roleless => Role::Roleless,
62
                    Role::Defender => Role::Attacker,
63
                };
64
            }
65
        }
66

            
67
        boards.backward_all();
68

            
69
        ArchivedGameHandle {
70
            boards,
71
            game: game.clone(),
72
            play: 0,
73
        }
74
    }
75
}