Set up the game review page along with #229
|
@ -49,11 +49,11 @@ pub struct Player {
|
||||||
/// level, the interpreter will reject any games that have setup properties and move properties
|
/// level, the interpreter will reject any games that have setup properties and move properties
|
||||||
/// mixed in a single node. If there are other semantic problems, the interpreter will reject
|
/// mixed in a single node. If there are other semantic problems, the interpreter will reject
|
||||||
/// those, as well. Where the function of the parser is to understand and correct fundamental
|
/// those, as well. Where the function of the parser is to understand and correct fundamental
|
||||||
/// syntax issues, the result of the Game is to have a fully-understood game. However, this doesn't
|
/// syntax issues, the result of the GameRecord is to have a fully-understood game. However, this
|
||||||
/// (yet?) go quite to the level of apply the game type (i.e., this is Go, Chess, Yinsh, or
|
/// doesn't (yet?) go quite to the level of apply the game type (i.e., this is Go, Chess, Yinsh, or
|
||||||
/// whatever).
|
/// whatever).
|
||||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||||
pub struct Game {
|
pub struct GameRecord {
|
||||||
pub game_type: GameType,
|
pub game_type: GameType,
|
||||||
|
|
||||||
// TODO: board size is not necessary in all games. Hive has no defined board size.
|
// TODO: board size is not necessary in all games. Hive has no defined board size.
|
||||||
|
@ -81,7 +81,7 @@ pub struct Game {
|
||||||
pub children: Vec<GameNode>,
|
pub children: Vec<GameNode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl GameRecord {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
game_type: GameType,
|
game_type: GameType,
|
||||||
board_size: Size,
|
board_size: Size,
|
||||||
|
@ -116,7 +116,7 @@ impl Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node for Game {
|
impl Node for GameRecord {
|
||||||
fn children<'a>(&'a self) -> Vec<&'a GameNode> {
|
fn children<'a>(&'a self) -> Vec<&'a GameNode> {
|
||||||
self.children.iter().collect::<Vec<&'a GameNode>>()
|
self.children.iter().collect::<Vec<&'a GameNode>>()
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ impl Node for Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&parser::Tree> for Game {
|
impl TryFrom<&parser::Tree> for GameRecord {
|
||||||
type Error = GameError;
|
type Error = GameError;
|
||||||
|
|
||||||
fn try_from(tree: &parser::Tree) -> Result<Self, Self::Error> {
|
fn try_from(tree: &parser::Tree) -> Result<Self, Self::Error> {
|
||||||
|
@ -503,7 +503,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_can_create_an_empty_game_tree() {
|
fn it_can_create_an_empty_game_tree() {
|
||||||
let tree = Game::new(
|
let tree = GameRecord::new(
|
||||||
GameType::Go,
|
GameType::Go,
|
||||||
Size {
|
Size {
|
||||||
width: 19,
|
width: 19,
|
||||||
|
@ -517,7 +517,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_can_add_moves_to_a_game() {
|
fn it_can_add_moves_to_a_game() {
|
||||||
let mut game = Game::new(
|
let mut game = GameRecord::new(
|
||||||
GameType::Go,
|
GameType::Go,
|
||||||
Size {
|
Size {
|
||||||
width: 19,
|
width: 19,
|
||||||
|
@ -693,16 +693,16 @@ mod file_test {
|
||||||
use parser::parse_collection;
|
use parser::parse_collection;
|
||||||
use std::{fs::File, io::Read};
|
use std::{fs::File, io::Read};
|
||||||
|
|
||||||
fn with_text(text: &str, f: impl FnOnce(Vec<Game>)) {
|
fn with_text(text: &str, f: impl FnOnce(Vec<GameRecord>)) {
|
||||||
let (_, games) = parse_collection::<nom::error::VerboseError<&str>>(text).unwrap();
|
let (_, games) = parse_collection::<nom::error::VerboseError<&str>>(text).unwrap();
|
||||||
let games = games
|
let games = games
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|game| Game::try_from(&game).expect("game to parse"))
|
.map(|game| GameRecord::try_from(&game).expect("game to parse"))
|
||||||
.collect::<Vec<Game>>();
|
.collect::<Vec<GameRecord>>();
|
||||||
f(games);
|
f(games);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_file(path: &std::path::Path, f: impl FnOnce(Vec<Game>)) {
|
fn with_file(path: &std::path::Path, f: impl FnOnce(Vec<GameRecord>)) {
|
||||||
let mut file = File::open(path).unwrap();
|
let mut file = File::open(path).unwrap();
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
let _ = file.read_to_string(&mut text);
|
let _ = file.read_to_string(&mut text);
|
||||||
|
|
|
@ -5,7 +5,7 @@ mod types;
|
||||||
|
|
||||||
use std::{fs::File, io::Read};
|
use std::{fs::File, io::Read};
|
||||||
pub use date::Date;
|
pub use date::Date;
|
||||||
pub use game::Game;
|
pub use game::GameRecord;
|
||||||
pub use parser::parse_collection;
|
pub use parser::parse_collection;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
|
@ -58,16 +58,26 @@ impl From<nom::error::Error<&str>> for ParseError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_sgf(input: &str) -> Result<Vec<Result<Game, game::GameError>>, Error> {
|
/// Given raw text of an SGF file, parse all of the games within that file.
|
||||||
|
///
|
||||||
|
/// The outermost Result is for any errors that happen in opening and reading the file, or if hte
|
||||||
|
/// outermost part of the file format is invalid.
|
||||||
|
///
|
||||||
|
/// The inner Result is for errors in each individual game in the file. All of the other games can
|
||||||
|
/// still be kept as valid.
|
||||||
|
pub fn parse_sgf(input: &str) -> Result<Vec<Result<GameRecord, game::GameError>>, Error> {
|
||||||
let (_, games) = parse_collection::<nom::error::VerboseError<&str>>(&input)?;
|
let (_, games) = parse_collection::<nom::error::VerboseError<&str>>(&input)?;
|
||||||
let games = games.into_iter()
|
let games = games.into_iter()
|
||||||
.map(|game| Game::try_from(&game))
|
.map(|game| GameRecord::try_from(&game))
|
||||||
.collect::<Vec<Result<Game, game::GameError>>>();
|
.collect::<Vec<Result<GameRecord, game::GameError>>>();
|
||||||
|
|
||||||
Ok(games)
|
Ok(games)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_sgf_file(path: &std::path::Path) -> Result<Vec<Result<Game, game::GameError>>, Error> {
|
/// Given a path, parse all of the games stored in that file.
|
||||||
|
///
|
||||||
|
/// See also `parse_sgf`
|
||||||
|
pub fn parse_sgf_file(path: &std::path::Path) -> Result<Vec<Result<GameRecord, game::GameError>>, Error> {
|
||||||
let mut file = File::open(path).unwrap();
|
let mut file = File::open(path).unwrap();
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
let _ = file.read_to_string(&mut text);
|
let _ = file.read_to_string(&mut text);
|
||||||
|
|
Loading…
Reference in New Issue