Lines
0 %
Functions
Branches
100 %
// This file is part of hnefatafl-copenhagen.
//
// hnefatafl-copenhagen is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// hnefatafl-copenhagen is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use std::collections::VecDeque;
use crate::{
board::{Board, BoardSize},
game::PreviousBoards,
play::Plays,
role::Role,
};
#[derive(Clone, Debug)]
pub struct Tree {
node: usize,
pub next_child: usize,
arena: Vec<Node>,
}
impl Tree {
pub fn next_child(&mut self) {
self.next_child += 1;
if self.next_child >= self.arena[self.node].children.len() {
self.next_child = 0;
pub fn backward(&mut self) {
if let Some(node) = self.arena[self.node].parent {
self.node = node;
pub fn backward_all(&mut self) {
let mut node = self.node;
while let Some(node_index) = self.arena[node].parent {
node = node_index;
pub fn forward(&mut self) {
if !self.arena[self.node].children.is_empty() {
self.node = self.arena[self.node].children[self.next_child];
#[must_use]
pub fn forward_all(&mut self) -> usize {
let mut count = 0;
while !self.arena[node].children.is_empty() {
node = self.arena[node].children[self.next_child];
count += 1;
count
pub fn has_children(&self) -> bool {
!self.arena[self.node].children.is_empty()
pub fn insert(&mut self, board: &Board) {
let index = self.arena.len();
let node = &mut self.arena[self.node];
self.node = index;
let old_index = node.index;
node.children.push(index);
let turn = node.turn.opposite();
self.arena.push(Node {
index,
board: board.clone(),
turn,
parent: Some(old_index),
children: Vec::new(),
});
pub fn here(&self) -> Node {
self.arena[self.node].clone()
pub fn here_board(&self) -> Board {
self.arena[self.node].board.clone()
pub fn new(board_size: BoardSize) -> Self {
Self {
node: 0,
next_child: 0,
arena: vec![Node {
index: 0,
board: Board::new(board_size),
turn: Role::Attacker,
parent: None,
}],
pub fn previous_boards(&self) -> (Plays, PreviousBoards) {
let mut node = &self.here();
let mut previous_boards = PreviousBoards::new(node.board.size());
let mut boards = VecDeque::new();
let mut plays = Vec::new();
previous_boards.0.insert(node.board.clone());
boards.push_front(node.board.clone());
while let Some(parent) = node.parent {
node = &self.arena[parent];
let boards: Vec<_> = boards.iter().collect();
for windows in boards.windows(2) {
let board_1 = windows[0];
let board_2 = windows[1];
let play = board_1.difference(board_2);
plays.push(play);
let plays = Plays::PlayRecords(plays);
(plays, previous_boards)
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Node {
index: usize,
pub board: Board,
pub turn: Role,
parent: Option<usize>,
children: Vec<usize>,