1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::rules::game::{Game, GameBuilder};
use crate::rules::{EndGame, Move, Player};
use sgf_parser::{Action, Color, Outcome, SgfToken};

impl Game {
    pub fn from_sgf(sgf_str: &str) -> Result<Self, String> {
        let game_tree = match sgf_parser::parse(sgf_str) {
            Ok(game) => Ok(game),
            Err(e) => Err(e.to_string()),
        }?;
        let mut gamebuilder: GameBuilder = Default::default();
        let mut first = true;
        let mut moves = vec![];

        for node in game_tree.iter() {
            if first {
                // first token if the root token
                // Game information
                for token in &node.tokens {
                    match token {
                        SgfToken::Komi(komi) => {
                            gamebuilder.komi(*komi);
                        }
                        SgfToken::Size(x, y) => {
                            gamebuilder.size((*x, *y));
                        }
                        SgfToken::Result(o) => {
                            gamebuilder.outcome((*o).into());
                        }
                        //TODO another options
                        _ => (),
                    }
                }
                first = false;
            } else if !node.tokens.is_empty() {
                let token = node.tokens.first().unwrap();
                if let SgfToken::Move { action, .. } = token {
                    moves.push((*action).into());
                }
            }
        }
        gamebuilder.moves(&moves);
        gamebuilder.build()
    }
}

impl From<Outcome> for EndGame {
    fn from(o: Outcome) -> Self {
        match o {
            Outcome::WinnerByResign(c) => EndGame::WinnerByResign(c.into()),
            Outcome::WinnerByForfeit(c) => EndGame::WinnerByForfeit(c.into()),
            Outcome::WinnerByPoints(c, p) => EndGame::WinnerByScore(c.into(), p),
            Outcome::WinnerByTime(c) => EndGame::WinnerByTime(c.into()),
            Outcome::Draw => EndGame::Draw,
        }
    }
}

impl From<Color> for Player {
    fn from(c: Color) -> Self {
        match c {
            Color::Black => Player::Black,
            Color::White => Player::White,
        }
    }
}

impl From<Action> for Move {
    fn from(a: Action) -> Self {
        match a {
            Action::Move(col, line) => Move::Play((line - 1) as usize, (col - 1) as usize),
            Action::Pass => Move::Pass,
        }
    }
}