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 {
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());
}
_ => (),
}
}
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,
}
}
}