Compare commits
No commits in common. "084a558740887bd40bc3ad40c574d7e2ee30a964" and "d9531c69ad726992e72c0aaaefaaa48f5b789585" have entirely different histories.
084a558740
...
d9531c69ad
|
@ -71,7 +71,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "emseries"
|
name = "emseries"
|
||||||
version = "0.6.0"
|
version = "0.5.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
|
|
|
@ -1,446 +0,0 @@
|
||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android-tzdata"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android_system_properties"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bumpalo"
|
|
||||||
version = "3.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.0.79"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chrono"
|
|
||||||
version = "0.4.26"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
|
|
||||||
dependencies = [
|
|
||||||
"android-tzdata",
|
|
||||||
"iana-time-zone",
|
|
||||||
"js-sys",
|
|
||||||
"num-traits",
|
|
||||||
"serde",
|
|
||||||
"time",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "core-foundation-sys"
|
|
||||||
version = "0.8.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "go-sgf"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"nom",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"typeshare",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iana-time-zone"
|
|
||||||
version = "0.1.57"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
|
|
||||||
dependencies = [
|
|
||||||
"android_system_properties",
|
|
||||||
"core-foundation-sys",
|
|
||||||
"iana-time-zone-haiku",
|
|
||||||
"js-sys",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"windows",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iana-time-zone-haiku"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itoa"
|
|
||||||
version = "1.0.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "js-sys"
|
|
||||||
version = "0.3.64"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
|
|
||||||
dependencies = [
|
|
||||||
"wasm-bindgen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.146"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.4.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell"
|
|
||||||
version = "1.18.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.60"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.28"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ryu"
|
|
||||||
version = "1.0.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde"
|
|
||||||
version = "1.0.164"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
|
|
||||||
dependencies = [
|
|
||||||
"serde_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive"
|
|
||||||
version = "1.0.164"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.18",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_json"
|
|
||||||
version = "1.0.99"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
|
|
||||||
dependencies = [
|
|
||||||
"itoa",
|
|
||||||
"ryu",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.109"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "2.0.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "1.0.40"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "1.0.40"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.18",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "time"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"wasi",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typeshare"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f44d1a2f454cb35fbe05b218c410792697e76bd868f48d3a418f2cd1a7d527d6"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"typeshare-annotation",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typeshare-annotation"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc670d0e358428857cc3b4bf504c691e572fccaec9542ff09212d3f13d74b7a9"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.10.0+wasi-snapshot-preview1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen"
|
|
||||||
version = "0.2.87"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"wasm-bindgen-macro",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-backend"
|
|
||||||
version = "0.2.87"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
|
|
||||||
dependencies = [
|
|
||||||
"bumpalo",
|
|
||||||
"log",
|
|
||||||
"once_cell",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.18",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-macro"
|
|
||||||
version = "0.2.87"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
|
|
||||||
dependencies = [
|
|
||||||
"quote",
|
|
||||||
"wasm-bindgen-macro-support",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-macro-support"
|
|
||||||
version = "0.2.87"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.18",
|
|
||||||
"wasm-bindgen-backend",
|
|
||||||
"wasm-bindgen-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasm-bindgen-shared"
|
|
||||||
version = "0.2.87"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu",
|
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm",
|
|
||||||
"windows_aarch64_msvc",
|
|
||||||
"windows_i686_gnu",
|
|
||||||
"windows_i686_msvc",
|
|
||||||
"windows_x86_64_gnu",
|
|
||||||
"windows_x86_64_gnullvm",
|
|
||||||
"windows_x86_64_msvc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
|
|
@ -1,13 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "go-sgf"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
chrono = { version = "0.4", features = [ "serde" ] }
|
|
||||||
nom = { version = "7" }
|
|
||||||
serde = { version = "1", features = [ "derive" ] }
|
|
||||||
thiserror = { version = "1"}
|
|
||||||
typeshare = { version = "1" }
|
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
test:
|
|
||||||
cargo watch -x 'nextest run'
|
|
||||||
|
|
||||||
test-oneshot:
|
|
||||||
cargo nextest run
|
|
|
@ -1,150 +0,0 @@
|
||||||
use chrono::{Datelike, NaiveDate};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::num::ParseIntError;
|
|
||||||
use thiserror::Error;
|
|
||||||
use typeshare::typeshare;
|
|
||||||
|
|
||||||
#[derive(Debug, Error, PartialEq)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error("Failed to parse integer {0}")]
|
|
||||||
ParseNumberError(ParseIntError),
|
|
||||||
|
|
||||||
#[error("Invalid date")]
|
|
||||||
InvalidDate,
|
|
||||||
|
|
||||||
#[error("unsupported date format")]
|
|
||||||
Unsupported,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)]
|
|
||||||
#[typeshare]
|
|
||||||
pub enum Date {
|
|
||||||
Year(i32),
|
|
||||||
YearMonth(i32, u32),
|
|
||||||
Date(chrono::NaiveDate),
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
impl TryFrom<&str> for Date {
|
|
||||||
type Error = String;
|
|
||||||
fn try_from(s: &str) -> Result<Date, Self::Error> {
|
|
||||||
let date_parts = s.split("-").collect::<Vec<&str>>();
|
|
||||||
|
|
||||||
if date_parts.len() >= 1 {
|
|
||||||
let year = date_parts[0]
|
|
||||||
.parse::<i32>()
|
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
|
||||||
|
|
||||||
if date_parts.len() >= 2 {
|
|
||||||
let month = date_parts[1]
|
|
||||||
.parse::<u32>()
|
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
|
||||||
|
|
||||||
if date_parts.len() >= 3 {
|
|
||||||
let day = date_parts[2]
|
|
||||||
.parse::<u32>()
|
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
|
||||||
let date =
|
|
||||||
chrono::NaiveDate::from_ymd_opt(year, month, day).ok_or("invalid date")?;
|
|
||||||
Ok(Date::Date(date))
|
|
||||||
} else {
|
|
||||||
Ok(Date::YearMonth(year, month))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(Date::Year(year))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err("no elements".to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
fn parse_numbers(s: &str) -> Result<Vec<i32>, Error> {
|
|
||||||
s.split("-")
|
|
||||||
.map(|s| s.parse::<i32>().map_err(|err| Error::ParseNumberError(err)))
|
|
||||||
.collect::<Result<Vec<i32>, Error>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_date_field(s: &str) -> Result<Vec<Date>, Error> {
|
|
||||||
let date_elements = s.split(",");
|
|
||||||
let mut dates = Vec::new();
|
|
||||||
|
|
||||||
let mut most_recent: Option<Date> = None;
|
|
||||||
for element in date_elements {
|
|
||||||
let fields = parse_numbers(element)?;
|
|
||||||
|
|
||||||
let new_date = match fields.as_slice() {
|
|
||||||
[] => panic!("all segments must have a field"),
|
|
||||||
[v1] => match most_recent {
|
|
||||||
Some(Date::Year(_)) => Date::Year(*v1),
|
|
||||||
Some(Date::YearMonth(y, _)) => Date::YearMonth(y, *v1 as u32),
|
|
||||||
Some(Date::Date(d)) => {
|
|
||||||
Date::Date(d.clone().with_day(*v1 as u32).ok_or(Error::InvalidDate)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
None => Date::Year(*v1),
|
|
||||||
},
|
|
||||||
[v1, v2] => Date::YearMonth(*v1, *v2 as u32),
|
|
||||||
[v1, v2, v3, ..] => Date::Date(
|
|
||||||
NaiveDate::from_ymd_opt(v1.clone(), v2.clone() as u32, v3.clone() as u32).unwrap(),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
dates.push(new_date.clone());
|
|
||||||
most_recent = Some(new_date);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(dates)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_a_year() {
|
|
||||||
assert_eq!(parse_date_field("1996"), Ok(vec![Date::Year(1996)]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_a_month() {
|
|
||||||
assert_eq!(
|
|
||||||
parse_date_field("1996-12"),
|
|
||||||
Ok(vec![Date::YearMonth(1996, 12)])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_a_date() {
|
|
||||||
assert_eq!(
|
|
||||||
parse_date_field("1996-12-27"),
|
|
||||||
Ok(vec![Date::Date(
|
|
||||||
NaiveDate::from_ymd_opt(1996, 12, 27).unwrap()
|
|
||||||
)])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_date_continuation() {
|
|
||||||
assert_eq!(
|
|
||||||
parse_date_field("1996-12-27,28"),
|
|
||||||
Ok(vec![
|
|
||||||
Date::Date(NaiveDate::from_ymd_opt(1996, 12, 27).unwrap()),
|
|
||||||
Date::Date(NaiveDate::from_ymd_opt(1996, 12, 28).unwrap())
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_date_crossing_year_boundary() {
|
|
||||||
assert_eq!(
|
|
||||||
parse_date_field("1996-12-27,28,1997-01-03,04"),
|
|
||||||
Ok(vec![
|
|
||||||
Date::Date(NaiveDate::from_ymd_opt(1996, 12, 27).unwrap()),
|
|
||||||
Date::Date(NaiveDate::from_ymd_opt(1996, 12, 28).unwrap()),
|
|
||||||
Date::Date(NaiveDate::from_ymd_opt(1997, 1, 3).unwrap()),
|
|
||||||
Date::Date(NaiveDate::from_ymd_opt(1997, 1, 4).unwrap()),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
423
go-sgf/src/go.rs
423
go-sgf/src/go.rs
|
@ -1,423 +0,0 @@
|
||||||
// https://red-bean.com/sgf/
|
|
||||||
// https://red-bean.com/sgf/user_guide/index.html
|
|
||||||
// https://red-bean.com/sgf/sgf4.html
|
|
||||||
|
|
||||||
// todo: support collections in a file
|
|
||||||
// Properties to support. Remove each one as it gets support.
|
|
||||||
// B
|
|
||||||
// KO
|
|
||||||
// MN
|
|
||||||
// W
|
|
||||||
// AB
|
|
||||||
// AE
|
|
||||||
// AW
|
|
||||||
// PL
|
|
||||||
// C
|
|
||||||
// DM
|
|
||||||
// GB
|
|
||||||
// GW
|
|
||||||
// HO
|
|
||||||
// N
|
|
||||||
// UC
|
|
||||||
// V
|
|
||||||
// BM
|
|
||||||
// DO
|
|
||||||
// IT
|
|
||||||
// TE
|
|
||||||
// AR
|
|
||||||
// CR
|
|
||||||
// DD
|
|
||||||
// LB
|
|
||||||
// LN
|
|
||||||
// MA
|
|
||||||
// SL
|
|
||||||
// SQ
|
|
||||||
// TR
|
|
||||||
// AP
|
|
||||||
// CA
|
|
||||||
// FF
|
|
||||||
// GM
|
|
||||||
// ST
|
|
||||||
// SZ
|
|
||||||
// AN
|
|
||||||
// BR
|
|
||||||
// BT
|
|
||||||
// CP
|
|
||||||
// DT
|
|
||||||
// EV
|
|
||||||
// GN
|
|
||||||
// GC
|
|
||||||
// ON
|
|
||||||
// OT
|
|
||||||
// PB
|
|
||||||
// PC
|
|
||||||
// PW
|
|
||||||
// RE
|
|
||||||
// RO
|
|
||||||
// RU
|
|
||||||
// SO
|
|
||||||
// TM
|
|
||||||
// US
|
|
||||||
// WR
|
|
||||||
// WT
|
|
||||||
// BL
|
|
||||||
// OB
|
|
||||||
// OW
|
|
||||||
// WL
|
|
||||||
// FG
|
|
||||||
// PM
|
|
||||||
// VW
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
date::{self, parse_date_field, Date},
|
|
||||||
tree::{parse_collection, ParseSizeError, Size},
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use typeshare::typeshare;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error<'a> {
|
|
||||||
InvalidField,
|
|
||||||
InvalidBoardSize,
|
|
||||||
Incomplete,
|
|
||||||
InvalidSgf(nom::error::VerboseError<&'a str>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<nom::Err<nom::error::VerboseError<&'a str>>> for Error<'a> {
|
|
||||||
fn from(err: nom::Err<nom::error::VerboseError<&'a str>>) -> Self {
|
|
||||||
match err {
|
|
||||||
nom::Err::Incomplete(_) => Error::Incomplete,
|
|
||||||
nom::Err::Error(e) => Error::InvalidSgf(e.clone()),
|
|
||||||
nom::Err::Failure(e) => Error::InvalidSgf(e.clone()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<ParseSizeError> for Error<'a> {
|
|
||||||
fn from(_: ParseSizeError) -> Self {
|
|
||||||
Self::InvalidBoardSize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
#[typeshare]
|
|
||||||
pub enum Rank {
|
|
||||||
Kyu(u8),
|
|
||||||
Dan(u8),
|
|
||||||
Pro(u8),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&str> for Rank {
|
|
||||||
type Error = String;
|
|
||||||
fn try_from(r: &str) -> Result<Rank, Self::Error> {
|
|
||||||
let parts = r.split(" ").map(|s| s.to_owned()).collect::<Vec<String>>();
|
|
||||||
let cnt = parts[0].parse::<u8>().map_err(|err| format!("{:?}", err))?;
|
|
||||||
match parts[1].to_ascii_lowercase().as_str() {
|
|
||||||
"kyu" => Ok(Rank::Kyu(cnt)),
|
|
||||||
"dan" => Ok(Rank::Dan(cnt)),
|
|
||||||
"pro" => Ok(Rank::Pro(cnt)),
|
|
||||||
_ => Err("unparsable".to_owned()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToString for Rank {
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct GameTree {
|
|
||||||
pub file_format: i8,
|
|
||||||
pub app_name: Option<String>,
|
|
||||||
pub game_type: GameType,
|
|
||||||
pub board_size: Size,
|
|
||||||
pub info: GameInfo,
|
|
||||||
// pub text: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
|
||||||
pub struct GameInfo {
|
|
||||||
pub annotator: Option<String>,
|
|
||||||
pub copyright: Option<String>,
|
|
||||||
pub event: Option<String>,
|
|
||||||
// Games can be played across multiple days, even multiple years. The format specifies
|
|
||||||
// shortcuts.
|
|
||||||
pub date: Vec<Date>,
|
|
||||||
pub location: Option<String>,
|
|
||||||
// special rules for the round-number and type
|
|
||||||
pub round: Option<String>,
|
|
||||||
pub ruleset: Option<String>,
|
|
||||||
pub source: Option<String>,
|
|
||||||
pub time_limits: Option<std::time::Duration>,
|
|
||||||
pub game_keeper: Option<String>,
|
|
||||||
pub komi: Option<f32>,
|
|
||||||
|
|
||||||
pub game_name: Option<String>,
|
|
||||||
pub game_comments: Option<String>,
|
|
||||||
|
|
||||||
pub black_player: Option<String>,
|
|
||||||
pub black_rank: Option<Rank>,
|
|
||||||
pub black_team: Option<String>,
|
|
||||||
|
|
||||||
pub white_player: Option<String>,
|
|
||||||
pub white_rank: Option<Rank>,
|
|
||||||
pub white_team: Option<String>,
|
|
||||||
|
|
||||||
pub opening: Option<String>,
|
|
||||||
pub overtime: Option<String>,
|
|
||||||
pub result: Option<GameResult>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum GameResult {
|
|
||||||
Annulled,
|
|
||||||
Draw,
|
|
||||||
Black(Win),
|
|
||||||
White(Win),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&str> for GameResult {
|
|
||||||
type Error = String;
|
|
||||||
fn try_from(s: &str) -> Result<GameResult, Self::Error> {
|
|
||||||
if s == "0" {
|
|
||||||
Ok(GameResult::Draw)
|
|
||||||
} else if s == "Void" {
|
|
||||||
Ok(GameResult::Annulled)
|
|
||||||
} else {
|
|
||||||
let parts = s.split("+").collect::<Vec<&str>>();
|
|
||||||
let res = match parts[0].to_ascii_lowercase().as_str() {
|
|
||||||
"b" => GameResult::Black,
|
|
||||||
"w" => GameResult::White,
|
|
||||||
_ => panic!("unknown result format"),
|
|
||||||
};
|
|
||||||
match parts[1].to_ascii_lowercase().as_str() {
|
|
||||||
"r" | "resign" => Ok(res(Win::Resignation)),
|
|
||||||
"t" | "time" => Ok(res(Win::Time)),
|
|
||||||
"f" | "forfeit" => Ok(res(Win::Forfeit)),
|
|
||||||
_ => {
|
|
||||||
let score = parts[1].parse::<f32>().unwrap();
|
|
||||||
Ok(res(Win::Score(score)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum Win {
|
|
||||||
Score(f32),
|
|
||||||
Resignation,
|
|
||||||
Forfeit,
|
|
||||||
Time,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum GameType {
|
|
||||||
Go,
|
|
||||||
Unsupported,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
enum PropType {
|
|
||||||
Move,
|
|
||||||
Setup,
|
|
||||||
Root,
|
|
||||||
GameInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum PropValue {
|
|
||||||
Empty,
|
|
||||||
Number,
|
|
||||||
Real,
|
|
||||||
Double,
|
|
||||||
Color,
|
|
||||||
SimpleText,
|
|
||||||
Text,
|
|
||||||
Point,
|
|
||||||
Move,
|
|
||||||
Stone,
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub fn parse_sgf<'a>(input: &'a str) -> Result<Vec<GameTree>, Error<'a>> {
|
|
||||||
let (_, trees) = parse_collection::<nom::error::VerboseError<&'a str>>(input)?;
|
|
||||||
|
|
||||||
let games = trees
|
|
||||||
.into_iter()
|
|
||||||
.map(|tree| {
|
|
||||||
let file_format = match tree.sequence[0].find_prop("FF") {
|
|
||||||
Some(prop) => prop.values[0].parse::<i8>().unwrap(),
|
|
||||||
None => 4,
|
|
||||||
};
|
|
||||||
let app_name = tree.sequence[0]
|
|
||||||
.find_prop("AP")
|
|
||||||
.map(|prop| prop.values[0].clone());
|
|
||||||
let board_size = match tree.sequence[0].find_prop("SZ") {
|
|
||||||
Some(prop) => Size::try_from(prop.values[0].as_str())?,
|
|
||||||
None => Size {
|
|
||||||
width: 19,
|
|
||||||
height: 19,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let mut info = GameInfo::default();
|
|
||||||
info.black_player = tree.sequence[0]
|
|
||||||
.find_prop("PB")
|
|
||||||
.map(|prop| prop.values.join(", "));
|
|
||||||
|
|
||||||
info.black_rank = tree.sequence[0]
|
|
||||||
.find_prop("BR")
|
|
||||||
.and_then(|prop| Rank::try_from(prop.values[0].as_str()).ok());
|
|
||||||
|
|
||||||
info.white_player = tree.sequence[0]
|
|
||||||
.find_prop("PW")
|
|
||||||
.map(|prop| prop.values.join(", "));
|
|
||||||
|
|
||||||
info.white_rank = tree.sequence[0]
|
|
||||||
.find_prop("WR")
|
|
||||||
.and_then(|prop| Rank::try_from(prop.values[0].as_str()).ok());
|
|
||||||
|
|
||||||
info.result = tree.sequence[0]
|
|
||||||
.find_prop("RE")
|
|
||||||
.and_then(|prop| GameResult::try_from(prop.values[0].as_str()).ok());
|
|
||||||
|
|
||||||
info.time_limits = tree.sequence[0]
|
|
||||||
.find_prop("TM")
|
|
||||||
.and_then(|prop| prop.values[0].parse::<u64>().ok())
|
|
||||||
.and_then(|seconds| Some(std::time::Duration::from_secs(seconds)));
|
|
||||||
|
|
||||||
info.date = tree.sequence[0]
|
|
||||||
.find_prop("DT")
|
|
||||||
.and_then(|prop| {
|
|
||||||
let v = prop
|
|
||||||
.values
|
|
||||||
.iter()
|
|
||||||
.map(|val| parse_date_field(val))
|
|
||||||
.fold(Ok(vec![]), |acc, v| match (acc, v) {
|
|
||||||
(Ok(mut acc), Ok(mut values)) => {
|
|
||||||
acc.append(&mut values);
|
|
||||||
Ok(acc)
|
|
||||||
}
|
|
||||||
(Ok(_), Err(err)) => Err(err),
|
|
||||||
(Err(err), _) => Err(err),
|
|
||||||
})
|
|
||||||
.ok()?;
|
|
||||||
Some(v)
|
|
||||||
})
|
|
||||||
.unwrap_or(vec![]);
|
|
||||||
|
|
||||||
info.event = tree.sequence[0]
|
|
||||||
.find_prop("EV")
|
|
||||||
.map(|prop| prop.values.join(", "));
|
|
||||||
|
|
||||||
info.round = tree.sequence[0]
|
|
||||||
.find_prop("RO")
|
|
||||||
.map(|prop| prop.values.join(", "));
|
|
||||||
|
|
||||||
info.source = tree.sequence[0]
|
|
||||||
.find_prop("SO")
|
|
||||||
.map(|prop| prop.values.join(", "));
|
|
||||||
|
|
||||||
info.game_keeper = tree.sequence[0]
|
|
||||||
.find_prop("US")
|
|
||||||
.map(|prop| prop.values.join(", "));
|
|
||||||
|
|
||||||
Ok(GameTree {
|
|
||||||
file_format,
|
|
||||||
app_name,
|
|
||||||
game_type: GameType::Go,
|
|
||||||
board_size,
|
|
||||||
info,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<GameTree>, Error>>()?;
|
|
||||||
Ok(games)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use crate::{date::Date, tree::Size};
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Read;
|
|
||||||
|
|
||||||
const EXAMPLE: &'static str = "(;FF[4]C[root](;C[a];C[b](;C[c])
|
|
||||||
(;C[d];C[e]))
|
|
||||||
(;C[f](;C[g];C[h];C[i])
|
|
||||||
(;C[j])))";
|
|
||||||
|
|
||||||
fn with_text(text: &str, f: impl FnOnce(Vec<GameTree>)) {
|
|
||||||
let games = parse_sgf(text).unwrap();
|
|
||||||
f(games);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_file(path: &std::path::Path, f: impl FnOnce(Vec<GameTree>)) {
|
|
||||||
let mut file = File::open(path).unwrap();
|
|
||||||
let mut text = String::new();
|
|
||||||
let _ = file.read_to_string(&mut text);
|
|
||||||
with_text(&text, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_game_root() {
|
|
||||||
with_text(EXAMPLE, |trees| {
|
|
||||||
assert_eq!(trees.len(), 1);
|
|
||||||
let tree = &trees[0];
|
|
||||||
assert_eq!(tree.file_format, 4);
|
|
||||||
assert_eq!(tree.app_name, None);
|
|
||||||
assert_eq!(tree.game_type, GameType::Go);
|
|
||||||
assert_eq!(
|
|
||||||
tree.board_size,
|
|
||||||
Size {
|
|
||||||
width: 19,
|
|
||||||
height: 19
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// assert_eq!(tree.text, EXAMPLE.to_owned());
|
|
||||||
});
|
|
||||||
|
|
||||||
with_file(std::path::Path::new("test_data/print1.sgf"), |trees| {
|
|
||||||
assert_eq!(trees.len(), 1);
|
|
||||||
let tree = &trees[0];
|
|
||||||
assert_eq!(tree.file_format, 4);
|
|
||||||
assert_eq!(tree.app_name, None);
|
|
||||||
assert_eq!(tree.game_type, GameType::Go);
|
|
||||||
assert_eq!(
|
|
||||||
tree.board_size,
|
|
||||||
Size {
|
|
||||||
width: 19,
|
|
||||||
height: 19
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_game_info() {
|
|
||||||
with_file(std::path::Path::new("test_data/print1.sgf"), |trees| {
|
|
||||||
assert_eq!(trees.len(), 1);
|
|
||||||
let tree = &trees[0];
|
|
||||||
assert_eq!(tree.info.black_player, Some("Takemiya Masaki".to_owned()));
|
|
||||||
assert_eq!(tree.info.black_rank, Some(Rank::Dan(9)));
|
|
||||||
assert_eq!(tree.info.white_player, Some("Cho Chikun".to_owned()));
|
|
||||||
assert_eq!(tree.info.white_rank, Some(Rank::Dan(9)));
|
|
||||||
assert_eq!(tree.info.result, Some(GameResult::White(Win::Resignation)));
|
|
||||||
assert_eq!(
|
|
||||||
tree.info.time_limits,
|
|
||||||
Some(std::time::Duration::from_secs(28800))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
tree.info.date,
|
|
||||||
vec![
|
|
||||||
Date::Date(chrono::NaiveDate::from_ymd_opt(1996, 10, 18).unwrap()),
|
|
||||||
Date::Date(chrono::NaiveDate::from_ymd_opt(1996, 10, 19).unwrap()),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(tree.info.event, Some("21st Meijin".to_owned()));
|
|
||||||
assert_eq!(tree.info.round, Some("2 (final)".to_owned()));
|
|
||||||
assert_eq!(tree.info.source, Some("Go World #78".to_owned()));
|
|
||||||
assert_eq!(tree.info.game_keeper, Some("Arno Hollosi".to_owned()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
mod date;
|
|
||||||
pub use date::Date;
|
|
||||||
|
|
||||||
mod go;
|
|
||||||
pub use go::{parse_sgf, GameTree, GameType, Rank};
|
|
||||||
|
|
||||||
mod tree;
|
|
||||||
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
pub enum Warning {}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Error)]
|
|
||||||
pub enum ParseError {
|
|
||||||
#[error("An unknown error was found")]
|
|
||||||
NomError(nom::error::Error<String>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<nom::error::Error<&str>> for ParseError {
|
|
||||||
fn from(err: nom::error::Error<&str>) -> Self {
|
|
||||||
Self::NomError(nom::error::Error {
|
|
||||||
input: err.input.to_owned(),
|
|
||||||
code: err.code.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
impl From<(&str, VerboseErrorKind)> for
|
|
||||||
|
|
||||||
impl From<nom::error::VerboseError<&str>> for ParseError {
|
|
||||||
fn from(err: nom::error::VerboseError<&str>) -> Self {
|
|
||||||
Self::NomErrors(
|
|
||||||
err.errors
|
|
||||||
.into_iter()
|
|
||||||
.map(|err| ParseError::from(err))
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
/*
|
|
||||||
Self::NomError(nom::error::Error {
|
|
||||||
input: err.input.to_owned(),
|
|
||||||
code: err.code.clone(),
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -1,490 +0,0 @@
|
||||||
use nom::{
|
|
||||||
branch::alt,
|
|
||||||
bytes::complete::{escaped_transform, tag},
|
|
||||||
character::complete::{alpha1, digit1, multispace0, multispace1, none_of},
|
|
||||||
combinator::{opt, value},
|
|
||||||
multi::{many0, many1, separated_list1},
|
|
||||||
sequence::delimited,
|
|
||||||
IResult,
|
|
||||||
};
|
|
||||||
use std::num::ParseIntError;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ParseSizeError {
|
|
||||||
ParseIntError(ParseIntError),
|
|
||||||
InsufficientArguments,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ParseIntError> for ParseSizeError {
|
|
||||||
fn from(e: ParseIntError) -> Self {
|
|
||||||
Self::ParseIntError(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct Size {
|
|
||||||
pub width: i32,
|
|
||||||
pub height: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<&str> for Size {
|
|
||||||
type Error = ParseSizeError;
|
|
||||||
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
|
||||||
let parts = s
|
|
||||||
.split(':')
|
|
||||||
.map(|v| v.parse::<i32>())
|
|
||||||
.collect::<Result<Vec<i32>, ParseIntError>>()?;
|
|
||||||
match parts[..] {
|
|
||||||
[width, height, ..] => Ok(Size { width, height }),
|
|
||||||
[dim] => Ok(Size {
|
|
||||||
width: dim,
|
|
||||||
height: dim,
|
|
||||||
}),
|
|
||||||
[] => Err(ParseSizeError::InsufficientArguments),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub struct Tree {
|
|
||||||
pub sequence: Vec<Node>,
|
|
||||||
pub sub_sequences: Vec<Tree>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToString for Tree {
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
let sequence = self
|
|
||||||
.sequence
|
|
||||||
.iter()
|
|
||||||
.map(|node| node.to_string())
|
|
||||||
.collect::<String>();
|
|
||||||
let subsequences = self
|
|
||||||
.sub_sequences
|
|
||||||
.iter()
|
|
||||||
.map(|seq| seq.to_string())
|
|
||||||
.collect::<String>();
|
|
||||||
format!("({}{})", sequence, subsequences)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub struct Node {
|
|
||||||
pub properties: Vec<Property>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToString for Node {
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
let props = self
|
|
||||||
.properties
|
|
||||||
.iter()
|
|
||||||
.map(|prop| prop.to_string())
|
|
||||||
.collect::<String>();
|
|
||||||
format!(";{}", props)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Node {
|
|
||||||
pub fn find_prop(&self, ident: &str) -> Option<Property> {
|
|
||||||
self.properties
|
|
||||||
.iter()
|
|
||||||
.find(|prop| prop.ident == ident)
|
|
||||||
.cloned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct Property {
|
|
||||||
pub ident: String,
|
|
||||||
pub values: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToString for Property {
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
let values = self
|
|
||||||
.values
|
|
||||||
.iter()
|
|
||||||
.map(|val| format!("[{}]", val))
|
|
||||||
.collect::<String>();
|
|
||||||
format!("{}{}", self.ident, values)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_collection<'a, E: nom::error::ParseError<&'a str>>(
|
|
||||||
input: &'a str,
|
|
||||||
) -> IResult<&'a str, Vec<Tree>, E> {
|
|
||||||
separated_list1(multispace1, parse_tree)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: must preserve unknown properties
|
|
||||||
// note: must fix or preserve illegally formatted game-info properties
|
|
||||||
// note: must correct or delete illegally foramtted properties, but display a warning
|
|
||||||
fn parse_tree<'a, E: nom::error::ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Tree, E> {
|
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
delimited(tag("("), parse_sequence, tag(")"))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_sequence<'a, E: nom::error::ParseError<&'a str>>(
|
|
||||||
input: &'a str,
|
|
||||||
) -> IResult<&'a str, Tree, E> {
|
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
let (input, nodes) = many1(parse_node)(input)?;
|
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
let (input, sub_sequences) = many0(parse_tree)(input)?;
|
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
|
|
||||||
Ok((
|
|
||||||
input,
|
|
||||||
Tree {
|
|
||||||
sequence: nodes,
|
|
||||||
sub_sequences,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_node<'a, E: nom::error::ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, Node, E> {
|
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
let (input, _) = tag(";")(input)?;
|
|
||||||
let (input, properties) = many1(parse_property)(input)?;
|
|
||||||
Ok((input, Node { properties }))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_property<'a, E: nom::error::ParseError<&'a str>>(
|
|
||||||
input: &'a str,
|
|
||||||
) -> IResult<&'a str, Property, E> {
|
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
let (input, ident) = alpha1(input)?;
|
|
||||||
let (input, values) = many1(parse_propval)(input)?;
|
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
|
|
||||||
let values = values
|
|
||||||
.into_iter()
|
|
||||||
.map(|v| v.to_owned())
|
|
||||||
.collect::<Vec<String>>();
|
|
||||||
Ok((
|
|
||||||
input,
|
|
||||||
Property {
|
|
||||||
ident: ident.to_owned(),
|
|
||||||
values,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_propval<'a, E: nom::error::ParseError<&'a str>>(
|
|
||||||
input: &'a str,
|
|
||||||
) -> IResult<&'a str, String, E> {
|
|
||||||
let (input, _) = multispace0(input)?;
|
|
||||||
let (input, _) = tag("[")(input)?;
|
|
||||||
let (input, value) = parse_propval_text(input)?;
|
|
||||||
let (input, _) = tag("]")(input)?;
|
|
||||||
|
|
||||||
Ok((input, value.unwrap_or(String::new())))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_propval_text<'a, E: nom::error::ParseError<&'a str>>(
|
|
||||||
input: &'a str,
|
|
||||||
) -> IResult<&'a str, Option<String>, E> {
|
|
||||||
let (input, value) = opt(escaped_transform(
|
|
||||||
none_of("\\]"),
|
|
||||||
'\\',
|
|
||||||
alt((
|
|
||||||
value("]", tag("]")),
|
|
||||||
value("\\", tag("\\")),
|
|
||||||
value("", tag("\n")),
|
|
||||||
)),
|
|
||||||
))(input)?;
|
|
||||||
Ok((input, value.map(|v| v.to_owned())))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_size<'a, E: nom::error::ParseError<&'a str>>(
|
|
||||||
input: &'a str,
|
|
||||||
) -> IResult<&'a str, Size, E> {
|
|
||||||
let (input, dimensions) = separated_list1(tag(":"), digit1)(input)?;
|
|
||||||
let (width, height) = match dimensions.as_slice() {
|
|
||||||
[width] => (width.parse::<i32>().unwrap(), width.parse::<i32>().unwrap()),
|
|
||||||
[width, height] => (
|
|
||||||
width.parse::<i32>().unwrap(),
|
|
||||||
height.parse::<i32>().unwrap(),
|
|
||||||
),
|
|
||||||
_ => (19, 19),
|
|
||||||
};
|
|
||||||
Ok((input, Size { width, height }))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use std::{fs::File, io::Read};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const EXAMPLE: &'static str = "(;FF[4]C[root](;C[a];C[b](;C[c])
|
|
||||||
(;C[d];C[e]))
|
|
||||||
(;C[f](;C[g];C[h];C[i])
|
|
||||||
(;C[j])))";
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_parse_properties() {
|
|
||||||
let (_, prop) = parse_property::<nom::error::VerboseError<&str>>("C[a]").unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
prop,
|
|
||||||
Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["a".to_owned()]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let (_, prop) = parse_property::<nom::error::VerboseError<&str>>("C[a][b][c]").unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
prop,
|
|
||||||
Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["a".to_owned(), "b".to_owned(), "c".to_owned()]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_parse_a_standalone_node() {
|
|
||||||
let (_, node) = parse_node::<nom::error::VerboseError<&str>>(";B[ab]").unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
node,
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "B".to_owned(),
|
|
||||||
values: vec!["ab".to_owned()]
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let (_, node) =
|
|
||||||
parse_node::<nom::error::VerboseError<&str>>(";B[ab];W[dp];B[pq]C[some comments]")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
node,
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "B".to_owned(),
|
|
||||||
values: vec!["ab".to_owned()]
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_parse_a_simple_sequence() {
|
|
||||||
let (_, sequence) =
|
|
||||||
parse_tree::<nom::error::VerboseError<&str>>("(;B[ab];W[dp];B[pq]C[some comments])")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sequence,
|
|
||||||
Tree {
|
|
||||||
sequence: vec![
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "B".to_owned(),
|
|
||||||
values: vec!["ab".to_owned()]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "W".to_owned(),
|
|
||||||
values: vec!["dp".to_owned()]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
Node {
|
|
||||||
properties: vec![
|
|
||||||
Property {
|
|
||||||
ident: "B".to_owned(),
|
|
||||||
values: vec!["pq".to_owned()]
|
|
||||||
},
|
|
||||||
Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["some comments".to_owned()]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
sub_sequences: vec![],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_parse_a_sequence_with_subsequences() {
|
|
||||||
let text = "(;C[a];C[b](;C[c])(;C[d];C[e]))";
|
|
||||||
let (_, sequence) = parse_tree::<nom::error::VerboseError<&str>>(text).unwrap();
|
|
||||||
|
|
||||||
let main_sequence = vec![
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["a".to_owned()],
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["b".to_owned()],
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
let subsequence_1 = Tree {
|
|
||||||
sequence: vec![Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["c".to_owned()],
|
|
||||||
}],
|
|
||||||
}],
|
|
||||||
sub_sequences: vec![],
|
|
||||||
};
|
|
||||||
let subsequence_2 = Tree {
|
|
||||||
sequence: vec![
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["d".to_owned()],
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["e".to_owned()],
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sub_sequences: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sequence,
|
|
||||||
Tree {
|
|
||||||
sequence: main_sequence,
|
|
||||||
sub_sequences: vec![subsequence_1, subsequence_2],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_parse_example_1() {
|
|
||||||
let (_, ex_tree) = parse_tree::<nom::error::VerboseError<&str>>(EXAMPLE).unwrap();
|
|
||||||
assert_eq!(ex_tree.sequence.len(), 1);
|
|
||||||
|
|
||||||
assert_eq!(ex_tree.sequence[0].properties.len(), 2);
|
|
||||||
assert_eq!(
|
|
||||||
ex_tree.sequence[0].properties[0],
|
|
||||||
Property {
|
|
||||||
ident: "FF".to_owned(),
|
|
||||||
values: vec!["4".to_owned()]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
assert_eq!(ex_tree.sub_sequences.len(), 2);
|
|
||||||
|
|
||||||
assert_eq!(ex_tree.sub_sequences[0].sequence.len(), 2);
|
|
||||||
assert_eq!(
|
|
||||||
ex_tree.sub_sequences[0].sequence,
|
|
||||||
vec![
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["a".to_owned()]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
Node {
|
|
||||||
properties: vec![Property {
|
|
||||||
ident: "C".to_owned(),
|
|
||||||
values: vec!["b".to_owned()]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(ex_tree.sub_sequences[0].sub_sequences.len(), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_regenerate_the_tree() {
|
|
||||||
let (_, tree1) = parse_tree::<nom::error::VerboseError<&str>>(EXAMPLE).unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
tree1.to_string(),
|
|
||||||
"(;FF[4]C[root](;C[a];C[b](;C[c])(;C[d];C[e]))(;C[f](;C[g];C[h];C[i])(;C[j])))"
|
|
||||||
);
|
|
||||||
let (_, tree2) = parse_tree::<nom::error::VerboseError<&str>>(&tree1.to_string()).unwrap();
|
|
||||||
assert_eq!(tree1, tree2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_propvals() {
|
|
||||||
let (_, propval) = parse_propval::<nom::error::VerboseError<&str>>("[]").unwrap();
|
|
||||||
assert_eq!(propval, "".to_owned());
|
|
||||||
|
|
||||||
let (_, propval) =
|
|
||||||
parse_propval::<nom::error::VerboseError<&str>>("[normal propval]").unwrap();
|
|
||||||
assert_eq!(propval, "normal propval".to_owned());
|
|
||||||
|
|
||||||
let (_, propval) =
|
|
||||||
parse_propval::<nom::error::VerboseError<&str>>(r"[need an [escape\] in the propval]")
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(propval, "need an [escape] in the propval".to_owned());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_propvals_with_hard_linebreaks() {
|
|
||||||
let (_, propval) = parse_propval_text::<nom::error::VerboseError<&str>>(
|
|
||||||
"There are hard linebreaks & soft linebreaks.
|
|
||||||
Soft linebreaks...",
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
propval,
|
|
||||||
Some(
|
|
||||||
"There are hard linebreaks & soft linebreaks.
|
|
||||||
Soft linebreaks..."
|
|
||||||
.to_owned()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_propvals_with_escaped_closing_brackets() {
|
|
||||||
let (_, propval) =
|
|
||||||
parse_propval_text::<nom::error::VerboseError<&str>>(r"escaped closing \] bracket")
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
propval,
|
|
||||||
Some(r"escaped closing ] bracket".to_owned()).to_owned()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_propvals_with_soft_linebreaks() {
|
|
||||||
let (_, propval) = parse_propval_text::<nom::error::VerboseError<&str>>(
|
|
||||||
r"Soft linebreaks are linebreaks preceeded by '\\' like this one >o\
|
|
||||||
k<. Hard line breaks are all other linebreaks.",
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
propval,
|
|
||||||
Some("Soft linebreaks are linebreaks preceeded by '\\' like this one >ok<. Hard line breaks are all other linebreaks.".to_owned())
|
|
||||||
.to_owned()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_sgf_with_newline_in_sequence() {
|
|
||||||
let data = String::from(
|
|
||||||
"(;FF[4]C[root](;C[a];C[b](;C[c])(;C[d];C[e]
|
|
||||||
))(;C[f](;C[g];C[h];C[i])(;C[j])))",
|
|
||||||
);
|
|
||||||
parse_tree::<nom::error::VerboseError<&str>>(&data).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_parses_sgf_with_newline_between_two_sequence_closings() {
|
|
||||||
let data = String::from(
|
|
||||||
"(;FF[4]C[root](;C[a];C[b](;C[c])(;C[d];C[e])
|
|
||||||
)(;C[f](;C[g];C[h];C[i])(;C[j])))",
|
|
||||||
);
|
|
||||||
parse_tree::<nom::error::VerboseError<&str>>(&data).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,266 +0,0 @@
|
||||||
(;GM[1]FF[4]CA[UTF-8]AP[CGoban:3]ST[2]
|
|
||||||
RU[AGA]SZ[19]KM[7.50]TM[1800]OT[5x30 byo-yomi]
|
|
||||||
PW[Geckoz]PB[savanni]BR[23k]DT[2020-08-05]PC[The KGS Go Server at http://www.gokgs.com/]RE[W+17.50]
|
|
||||||
;B[pp]BL[1795.449]C[Geckoz [?\]: Good game
|
|
||||||
savanni [23k?\]: There we go! This UI is... tough.
|
|
||||||
savanni [23k?\]: Have fun! Talk to you at the end.
|
|
||||||
Geckoz [?\]: Yeah, OGS is much better; I'm a UX professional
|
|
||||||
]
|
|
||||||
;W[dp]WL[1765.099]
|
|
||||||
;B[pd]BL[1791.862]
|
|
||||||
;W[dd]WL[1760.024]C[savanni [23k?\]: I'm a developer who gets to work with very good UX people.
|
|
||||||
]
|
|
||||||
;B[pj]BL[1783.511]C[Geckoz [?\]: Cool!
|
|
||||||
]
|
|
||||||
;W[nq]WL[1747.495]
|
|
||||||
;B[lq]BL[1780.848]
|
|
||||||
;W[qq]WL[1740.178]
|
|
||||||
;B[qp]BL[1775.668]
|
|
||||||
;W[pq]WL[1737.173]
|
|
||||||
;B[op]BL[1770.516]
|
|
||||||
;W[np]WL[1732.279]
|
|
||||||
;B[no]BL[1746.663]
|
|
||||||
;W[lp]WL[1725.072]
|
|
||||||
;B[oq]BL[1726.113]
|
|
||||||
;W[or]WL[1720.259]
|
|
||||||
;B[nr]BL[1711.422]
|
|
||||||
;W[mr]WL[1717.537]
|
|
||||||
;B[pr]BL[1709.874]
|
|
||||||
;W[ns]WL[1713.592]
|
|
||||||
;B[qr]BL[1708.243]
|
|
||||||
;W[rq]WL[1712.11]
|
|
||||||
;B[rr]BL[1701.351]
|
|
||||||
;W[mo]WL[1708.385]
|
|
||||||
;B[nn]BL[1697.491]
|
|
||||||
;W[mn]WL[1705.435]
|
|
||||||
;B[mm]BL[1691.421]
|
|
||||||
;W[lm]WL[1682.338]
|
|
||||||
;B[ml]BL[1688.896]
|
|
||||||
;W[nc]WL[1677.555]
|
|
||||||
;B[oc]BL[1685.925]
|
|
||||||
;W[kc]WL[1673.098]
|
|
||||||
;B[cf]BL[1665.92]
|
|
||||||
;W[fd]WL[1667.233]
|
|
||||||
;B[cd]BL[1660.587]
|
|
||||||
;W[cc]WL[1663.954]
|
|
||||||
;B[bc]BL[1659.001]
|
|
||||||
;W[dc]WL[1657.2]
|
|
||||||
;B[bd]BL[1657.088]
|
|
||||||
;W[ne]WL[1653.192]
|
|
||||||
;B[pf]BL[1655.388]
|
|
||||||
;W[df]WL[1647.379]
|
|
||||||
;B[ch]BL[1647.604]
|
|
||||||
;W[cn]WL[1644.955]
|
|
||||||
;B[cq]BL[1636.75]
|
|
||||||
;W[dq]WL[1641.583]
|
|
||||||
;B[cp]BL[1635.546]
|
|
||||||
;W[co]WL[1639.784]
|
|
||||||
;B[bo]BL[1634.909]
|
|
||||||
;W[bn]WL[1638.319]
|
|
||||||
;B[dr]BL[1632.049]
|
|
||||||
;W[er]WL[1636.391]
|
|
||||||
;B[ap]BL[1618.986]
|
|
||||||
;W[cj]WL[1612.201]
|
|
||||||
;B[dg]BL[1609.695]
|
|
||||||
;W[eg]WL[1609.247]
|
|
||||||
;B[eh]BL[1599.795]
|
|
||||||
;W[fg]WL[1603.614]
|
|
||||||
;B[ej]BL[1576.819]
|
|
||||||
;W[dl]WL[1599.94]
|
|
||||||
;B[fh]BL[1561.575]
|
|
||||||
;W[gh]WL[1597.845]
|
|
||||||
;B[gg]BL[1558.244]
|
|
||||||
;W[gf]WL[1593.694]
|
|
||||||
;B[hg]BL[1555.933]
|
|
||||||
;W[ef]WL[1586.388]
|
|
||||||
;B[hi]BL[1539.907]
|
|
||||||
;W[gi]WL[1578.524]
|
|
||||||
;B[gj]BL[1512.259]
|
|
||||||
;W[ll]WL[1575.328]
|
|
||||||
;B[mj]BL[1499.694]
|
|
||||||
;W[ro]WL[1560.837]
|
|
||||||
;B[rp]BL[1479.361]
|
|
||||||
;W[ql]WL[1552.749]
|
|
||||||
;B[rj]BL[1470.356]
|
|
||||||
;W[om]WL[1546.936]
|
|
||||||
;B[pn]BL[1453.785]
|
|
||||||
;W[qn]WL[1540.374]
|
|
||||||
;B[rl]BL[1377.862]
|
|
||||||
;W[rm]WL[1536.066]
|
|
||||||
;B[sm]BL[1292.099]
|
|
||||||
;W[rk]WL[1527.585]
|
|
||||||
;B[qk]BL[1277.126]
|
|
||||||
;W[sl]WL[1524.56]
|
|
||||||
;B[pm]BL[1216.574]
|
|
||||||
;W[qm]WL[1520.212]
|
|
||||||
;B[so]BL[1207.027]
|
|
||||||
;W[sn]WL[1518.651]
|
|
||||||
;B[qo]BL[1192.73]
|
|
||||||
;W[sp]WL[1516.356]
|
|
||||||
;B[sq]BL[1190.55]
|
|
||||||
;W[so]WL[1514.801]
|
|
||||||
;B[pl]BL[1182.312]
|
|
||||||
;W[mk]WL[1502.372]
|
|
||||||
;B[nk]BL[1164.324]
|
|
||||||
;W[lk]WL[1499.36]
|
|
||||||
;B[nj]BL[1127.171]
|
|
||||||
;W[ng]WL[1496.873]
|
|
||||||
;B[oh]BL[1124.603]
|
|
||||||
;W[qc]WL[1494.565]
|
|
||||||
;B[qd]BL[1120.501]
|
|
||||||
;W[pc]WL[1489.568]
|
|
||||||
;B[ob]BL[1116.997]
|
|
||||||
;W[nb]WL[1486.84]
|
|
||||||
;B[rd]BL[1086.655]
|
|
||||||
;W[pb]WL[1480.38]
|
|
||||||
;B[pa]BL[1072.72]
|
|
||||||
;W[od]WL[1474.251]
|
|
||||||
;B[rc]BL[1038.043]
|
|
||||||
;W[oa]WL[1472.062]
|
|
||||||
;B[jd]BL[1019.159]
|
|
||||||
;W[jc]WL[1463.559]
|
|
||||||
;B[id]BL[1014.024]
|
|
||||||
;W[hc]WL[1460.615]
|
|
||||||
;B[hd]BL[998.298]
|
|
||||||
;W[gc]WL[1456.201]
|
|
||||||
;B[hf]BL[985.927]
|
|
||||||
;W[he]WL[1451.422]
|
|
||||||
;B[ge]BL[973.563]
|
|
||||||
;W[ff]WL[1440.06]
|
|
||||||
;B[ie]BL[971.615]
|
|
||||||
;W[kd]WL[1434.328]
|
|
||||||
;B[ke]BL[967.858]
|
|
||||||
;W[le]WL[1432.153]
|
|
||||||
;B[kf]BL[927.888]
|
|
||||||
;W[lf]WL[1430.185]
|
|
||||||
;B[lg]BL[912.589]
|
|
||||||
;W[kg]WL[1423.112]
|
|
||||||
;B[kh]BL[910.745]
|
|
||||||
;W[jg]WL[1421.126]
|
|
||||||
;B[lh]BL[901.085]
|
|
||||||
;W[ri]WL[1344.735]
|
|
||||||
;B[sj]BL[888.449]
|
|
||||||
;W[qi]WL[1341.345]
|
|
||||||
;B[qj]BL[870.857]
|
|
||||||
;W[pg]WL[1334.618]
|
|
||||||
;B[og]BL[864.763]
|
|
||||||
;W[of]WL[1331.734]
|
|
||||||
;B[pe]BL[851.728]
|
|
||||||
;W[rf]WL[1325.363]
|
|
||||||
;B[qg]BL[842.606]
|
|
||||||
;W[ph]WL[1322.094]
|
|
||||||
;B[oi]BL[828.944]
|
|
||||||
;W[qf]WL[1309.994]
|
|
||||||
;B[pi]BL[769.609]
|
|
||||||
;W[qh]WL[1304.282]
|
|
||||||
;B[si]BL[728.901]
|
|
||||||
;W[rg]WL[1301.328]
|
|
||||||
;B[sh]BL[719.674]
|
|
||||||
;W[rh]WL[1268.121]
|
|
||||||
;B[cr]BL[687.129]
|
|
||||||
;W[fq]WL[1262.909]
|
|
||||||
;B[gl]BL[653.633]
|
|
||||||
;W[fk]WL[1256.072]
|
|
||||||
;B[gk]BL[644.973]
|
|
||||||
;W[fm]WL[1243.372]
|
|
||||||
;B[fj]BL[610.014]
|
|
||||||
;W[ek]WL[1236.428]
|
|
||||||
;B[gn]BL[599.689]
|
|
||||||
;W[gm]WL[1234.254]
|
|
||||||
;B[hm]BL[597.574]
|
|
||||||
;W[hl]WL[1231.768]
|
|
||||||
;B[il]BL[586.885]
|
|
||||||
;W[hn]WL[1227.158]
|
|
||||||
;B[im]BL[583.013]
|
|
||||||
;W[in]WL[1225.66]
|
|
||||||
;B[kj]BL[505.561]
|
|
||||||
;W[jk]WL[1222.444]
|
|
||||||
;B[ik]BL[491.135]
|
|
||||||
;W[jj]WL[1220.13]
|
|
||||||
;B[kk]BL[484.158]
|
|
||||||
;W[lj]WL[1215.952]
|
|
||||||
;B[kl]BL[470.386]
|
|
||||||
;W[km]WL[1214.379]
|
|
||||||
;B[ki]BL[443.18]
|
|
||||||
;W[jm]WL[1208.656]
|
|
||||||
;B[jl]BL[441.844]
|
|
||||||
;W[bb]WL[1202.059]
|
|
||||||
;B[ab]BL[422.408]
|
|
||||||
;W[cb]WL[1198.915]
|
|
||||||
;B[bj]BL[418.07]
|
|
||||||
;W[bk]WL[1196.222]
|
|
||||||
;B[bi]BL[415.539]
|
|
||||||
;W[ci]WL[1194.051]
|
|
||||||
;B[fe]BL[235.911]
|
|
||||||
;W[ee]WL[1189.835]
|
|
||||||
;B[ce]BL[205.478]
|
|
||||||
;W[if]WL[1179.115]
|
|
||||||
;B[ig]BL[185.788]
|
|
||||||
;W[gd]WL[1153.85]
|
|
||||||
;B[he]BL[179.636]
|
|
||||||
;W[bg]WL[1139.605]
|
|
||||||
;B[bh]BL[172.391]
|
|
||||||
;W[di]WL[1123.929]
|
|
||||||
;B[dh]BL[153.781]
|
|
||||||
;W[nh]WL[1111.72]
|
|
||||||
;B[rb]BL[138.364]
|
|
||||||
;W[qa]WL[1101.144]
|
|
||||||
;B[ra]BL[126.888]
|
|
||||||
;W[ak]WL[1086.882]
|
|
||||||
;B[ic]BL[48.75]
|
|
||||||
;W[ib]WL[1084.535]
|
|
||||||
;B[de]BL[44.527]
|
|
||||||
;W[ed]WL[1082.288]
|
|
||||||
;B[sk]BL[34.033]
|
|
||||||
;W[rl]WL[1080.285]
|
|
||||||
;B[es]BL[15.495]
|
|
||||||
;W[fs]WL[1078.273]
|
|
||||||
;B[ds]BL[13.677]
|
|
||||||
;W[aj]WL[1072.485]
|
|
||||||
;B[ai]BL[12.155]
|
|
||||||
;W[ei]WL[1068.233]
|
|
||||||
;B[fi]BL[9.728]
|
|
||||||
;W[ck]WL[1057.998]
|
|
||||||
;B[li]BL[30]OB[5]
|
|
||||||
;W[oe]WL[1029.525]
|
|
||||||
;B[hb]BL[30]OB[4]
|
|
||||||
;W[gb]WL[1026.087]
|
|
||||||
;B[bq]BL[30]OB[4]
|
|
||||||
;W[an]WL[1021.3]
|
|
||||||
;B[ao]BL[30]OB[4]
|
|
||||||
;W[os]WL[1014.224]
|
|
||||||
;B[ps]BL[30]OB[4]
|
|
||||||
;W[se]WL[993.876]
|
|
||||||
;B[sg]BL[30]OB[4]
|
|
||||||
;W[ba]WL[964.913]
|
|
||||||
;B[fl]BL[30]OB[4]
|
|
||||||
;W[em]WL[952.955]
|
|
||||||
;B[el]BL[30]OB[4]
|
|
||||||
;W[dk]WL[950.865]
|
|
||||||
;B[hh]BL[30]OB[3]
|
|
||||||
;W[mg]WL[939.223]
|
|
||||||
;B[]BL[30]OB[3]
|
|
||||||
;W[sd]WL[919.518]
|
|
||||||
;B[sf]BL[30]OB[3]
|
|
||||||
;W[re]WL[904.074]
|
|
||||||
;B[sc]BL[30]OB[3]
|
|
||||||
;W[qb]WL[896.673]
|
|
||||||
;B[qe]BL[30]OB[3]
|
|
||||||
;W[nl]WL[885.974]
|
|
||||||
;B[nm]BL[30]OB[3]
|
|
||||||
;W[ni]WL[839.049]
|
|
||||||
;B[]BL[30]OB[3]
|
|
||||||
;W[mi]WL[812.445]
|
|
||||||
;B[mh]BL[30]OB[3]
|
|
||||||
;W[ok]WL[805.58]
|
|
||||||
;B[ol]BL[30]OB[3]
|
|
||||||
;W[mf]WL[737.585]
|
|
||||||
;B[]BL[30]OB[2]
|
|
||||||
;W[aa]WL[694.721]
|
|
||||||
;B[ac]BL[30]OB[2]
|
|
||||||
;W[jn]WL[617.07]
|
|
||||||
;B[]BL[30]OB[2]
|
|
||||||
;W[]WL[580.595]TW[ca][da][ea][fa][ga][ha][ia][ja][ka][la][ma][na][pa][db][eb][fb][hb][jb][kb][lb][mb][ob][ec][fc][lc][mc][oc][ld][md][nd][me][nf][al][bl][cl][am][bm][cm][dm][sm][dn][en][fn][gn][kn][ln][rn][do][eo][fo][go][ho][io][jo][ko][lo][ep][fp][gp][hp][ip][jp][kp][mp][eq][gq][hq][iq][jq][kq][lq][mq][fr][gr][hr][ir][jr][kr][lr][nr][gs][hs][is][js][ks][ls][ms]TB[sa][sb][ad][sd][ae][be][je][re][se][af][bf][if][jf][qf][rf][ag][bg][cg][jg][kg][pg][qg][rg][ah][gh][ih][jh][ph][qh][rh][gi][ii][ji][qi][ri][hj][ij][jj][oj][hk][jk][ok][pk][hl][nl][om][on][oo][po][bp][aq][pq][qq][rq][ar][br][sr][as][bs][cs][qs][rs][ss]C[savanni [23k?\]: Good game! Thank you for playing.
|
|
||||||
savanni [23k?\]: There were a few points where you made a move and I just wilted as I realized what you had done.
|
|
||||||
Geckoz [?\]: That was a really good game; I thought you were ahead once you saved to top corner
|
|
||||||
])
|
|
|
@ -1,239 +0,0 @@
|
||||||
(;GM[1]FF[4]CA[UTF-8]AP[CGoban:3]ST[2]
|
|
||||||
RU[AGA]SZ[19]KM[7.50]TM[1800]OT[5x30 byo-yomi]
|
|
||||||
PW[savanni]PB[st2018]WR[23k]BR[13k]DT[2020-08-06]PC[The KGS Go Server at http://www.gokgs.com/]RE[W+32.50]
|
|
||||||
;B[pd]BL[1794.346]C[st2018 [13k?\]: hi
|
|
||||||
]
|
|
||||||
;W[pp]WL[1796.897]C[st2018 [13k?\]: gl hf
|
|
||||||
]
|
|
||||||
;B[dd]BL[1790.214]C[savanni [23k?\]: Hi! Have fun!
|
|
||||||
]
|
|
||||||
;W[dp]WL[1792.254]
|
|
||||||
;B[nq]BL[1784.226]
|
|
||||||
;W[qn]WL[1778.851]
|
|
||||||
;B[pr]BL[1775.007]
|
|
||||||
;W[qq]WL[1776.817]
|
|
||||||
;B[kq]BL[1768.385]
|
|
||||||
;W[qf]WL[1768.272]
|
|
||||||
;B[qh]BL[1752.314]
|
|
||||||
;W[of]WL[1754.511]
|
|
||||||
;B[oh]BL[1747.099]
|
|
||||||
;W[nd]WL[1709.276]
|
|
||||||
;B[rd]BL[1728.764]
|
|
||||||
;W[oc]WL[1681.839]
|
|
||||||
;B[pc]BL[1725.606]
|
|
||||||
;W[jc]WL[1677.824]
|
|
||||||
;B[qk]BL[1718.135]
|
|
||||||
;W[fc]WL[1653.531]
|
|
||||||
;B[cf]BL[1706.542]
|
|
||||||
;W[dc]WL[1650.569]
|
|
||||||
;B[cc]BL[1702.631]
|
|
||||||
;W[cb]WL[1649.16]
|
|
||||||
;B[db]BL[1699.265]
|
|
||||||
;W[eb]WL[1630.993]
|
|
||||||
;B[ec]BL[1692.571]
|
|
||||||
;W[ed]WL[1630.111]
|
|
||||||
;B[dc]BL[1689.323]
|
|
||||||
;W[fb]WL[1626.061]
|
|
||||||
;B[ee]BL[1686.591]
|
|
||||||
;W[fd]WL[1624.467]
|
|
||||||
;B[dg]BL[1677.655]
|
|
||||||
;W[dj]WL[1607.118]
|
|
||||||
;B[fq]BL[1672.255]
|
|
||||||
;W[eq]WL[1605.126]
|
|
||||||
;B[fp]BL[1670.244]
|
|
||||||
;W[dn]WL[1603.098]
|
|
||||||
;B[iq]BL[1668.707]
|
|
||||||
;W[np]WL[1580.211]
|
|
||||||
;B[mp]BL[1662.333]
|
|
||||||
;W[no]WL[1575.799]
|
|
||||||
;B[mo]BL[1659.214]
|
|
||||||
;W[nn]WL[1573.009]
|
|
||||||
;B[mn]BL[1657.074]
|
|
||||||
;W[nl]WL[1554.384]
|
|
||||||
;B[mk]BL[1651.673]
|
|
||||||
;W[ml]WL[1548.098]
|
|
||||||
;B[ll]BL[1647.866]
|
|
||||||
;W[lk]WL[1528.579]
|
|
||||||
;B[lm]BL[1639.849]
|
|
||||||
;W[lj]WL[1516.832]
|
|
||||||
;B[nj]BL[1632.254]
|
|
||||||
;W[mg]WL[1486.1]
|
|
||||||
;B[mh]BL[1627.088]
|
|
||||||
;W[lh]WL[1482.107]
|
|
||||||
;B[mi]BL[1621.573]
|
|
||||||
;W[li]WL[1471.357]
|
|
||||||
;B[mj]BL[1615.645]
|
|
||||||
;W[kf]WL[1463.941]
|
|
||||||
;B[gf]BL[1611.134]
|
|
||||||
;W[he]WL[1460.929]
|
|
||||||
;B[hf]BL[1608.344]
|
|
||||||
;W[ie]WL[1447.516]
|
|
||||||
;B[if]BL[1600.785]
|
|
||||||
;W[ge]WL[1444.945]
|
|
||||||
;B[fi]BL[1594.562]
|
|
||||||
;W[fj]WL[1437.513]
|
|
||||||
;B[gj]BL[1591.794]
|
|
||||||
;W[fk]WL[1434.924]
|
|
||||||
;B[gk]BL[1589.742]
|
|
||||||
;W[gl]WL[1425.063]
|
|
||||||
;B[hl]BL[1586.72]
|
|
||||||
;W[gm]WL[1422.277]
|
|
||||||
;B[hm]BL[1585.201]
|
|
||||||
;W[gn]WL[1419.374]
|
|
||||||
;B[ho]BL[1581.577]
|
|
||||||
;W[fo]WL[1411.073]
|
|
||||||
;B[hn]BL[1575.645]
|
|
||||||
;W[ob]WL[1395.563]
|
|
||||||
;B[pb]BL[1572.9]
|
|
||||||
;W[ch]WL[1376.069]
|
|
||||||
;B[dh]BL[1565.663]
|
|
||||||
;W[ci]WL[1374.441]
|
|
||||||
;B[di]BL[1562.191]
|
|
||||||
;W[er]WL[1350.848]
|
|
||||||
;B[fr]BL[1556.708]
|
|
||||||
;W[bf]WL[1295.484]
|
|
||||||
;B[bg]BL[1520.307]
|
|
||||||
;W[cg]WL[1255.691]
|
|
||||||
;B[be]BL[1518.338]
|
|
||||||
;W[bh]WL[1254.818]
|
|
||||||
;B[af]BL[1515.239]
|
|
||||||
;W[oq]WL[1243.269]
|
|
||||||
;B[or]BL[1512.18]
|
|
||||||
;W[nr]WL[1239.457]
|
|
||||||
;B[mq]BL[1508.142]
|
|
||||||
;W[qr]WL[1221.76]
|
|
||||||
;B[mr]BL[1487.272]
|
|
||||||
;W[ok]WL[1207.507]
|
|
||||||
;B[oj]BL[1484.016]
|
|
||||||
;W[pk]WL[1199.655]
|
|
||||||
;B[pj]BL[1482.391]
|
|
||||||
;W[ql]WL[1197.655]
|
|
||||||
;B[rk]BL[1479.891]
|
|
||||||
;W[rl]WL[1196.5]
|
|
||||||
;B[sl]BL[1475.596]
|
|
||||||
;W[sm]WL[1189.805]
|
|
||||||
;B[sk]BL[1472.706]
|
|
||||||
;W[rn]WL[1182.744]
|
|
||||||
;B[nk]BL[1466.219]
|
|
||||||
;W[nh]WL[1159.103]
|
|
||||||
;B[ng]BL[1450.869]
|
|
||||||
;W[nf]WL[1148.599]
|
|
||||||
;B[nm]BL[1445.559]
|
|
||||||
;W[om]WL[1141.63]
|
|
||||||
;B[pl]BL[1433.116]
|
|
||||||
;W[ol]WL[1126.891]
|
|
||||||
;B[mm]BL[1415.217]
|
|
||||||
;W[og]WL[1092.018]
|
|
||||||
;B[ni]BL[1405.022]
|
|
||||||
;W[pi]WL[1082.359]
|
|
||||||
;B[qi]BL[1387.615]
|
|
||||||
;W[ph]WL[1073.301]
|
|
||||||
;B[pg]BL[1381.034]
|
|
||||||
;W[qg]WL[1064.163]
|
|
||||||
;B[oi]BL[1375.876]
|
|
||||||
;W[pf]WL[1060.347]
|
|
||||||
;B[ph]BL[1373.317]
|
|
||||||
;W[rh]WL[1045.166]
|
|
||||||
;B[ri]BL[1371.289]
|
|
||||||
;W[sh]WL[1037.21]
|
|
||||||
;B[si]BL[1365.05]
|
|
||||||
;W[sf]WL[1024.931]
|
|
||||||
;B[re]BL[1356.151]
|
|
||||||
;W[rf]WL[1017.771]
|
|
||||||
;B[jf]BL[1349.33]
|
|
||||||
;W[je]WL[1015.006]
|
|
||||||
;B[kg]BL[1347.513]
|
|
||||||
;W[lf]WL[1007.953]
|
|
||||||
;B[kh]BL[1325.784]
|
|
||||||
;W[lg]WL[994.687]
|
|
||||||
;B[ki]BL[1315.213]
|
|
||||||
;W[jk]WL[990.63]
|
|
||||||
;B[kk]BL[1275.07]
|
|
||||||
;W[kj]WL[984.878]
|
|
||||||
;B[jj]BL[1272.539]
|
|
||||||
;W[kl]WL[983.779]
|
|
||||||
;B[ii]BL[1267.318]
|
|
||||||
;W[km]WL[973.938]
|
|
||||||
;B[kn]BL[1264.208]
|
|
||||||
;W[ik]WL[970.518]
|
|
||||||
;B[ij]BL[1257.676]
|
|
||||||
;W[pa]WL[920.127]
|
|
||||||
;B[qa]BL[1254.29]
|
|
||||||
;W[oa]WL[918.756]
|
|
||||||
;B[rb]BL[1238.063]
|
|
||||||
;W[fs]WL[914.189]
|
|
||||||
;B[gs]BL[1235.854]
|
|
||||||
;W[es]WL[911.585]
|
|
||||||
;B[hr]BL[1234.483]
|
|
||||||
;W[ei]WL[907.975]
|
|
||||||
;B[eh]BL[1232.979]
|
|
||||||
;W[ej]WL[902.926]
|
|
||||||
;B[hi]BL[1230.778]
|
|
||||||
;W[fe]WL[883.087]
|
|
||||||
;B[ff]BL[1229.404]
|
|
||||||
;W[ef]WL[869.692]
|
|
||||||
;B[de]BL[1223.898]
|
|
||||||
;W[fh]WL[867.954]
|
|
||||||
;B[gi]BL[1219.266]
|
|
||||||
;W[go]WL[858.282]
|
|
||||||
;B[gp]BL[1216.889]
|
|
||||||
;W[ep]WL[857.198]
|
|
||||||
;B[bb]BL[1210.104]
|
|
||||||
;W[da]WL[847.972]
|
|
||||||
;B[ca]BL[1202.769]
|
|
||||||
;W[ea]WL[846.662]
|
|
||||||
;B[ah]BL[1201.368]
|
|
||||||
;W[ai]WL[839.457]
|
|
||||||
;B[ag]BL[1198.539]
|
|
||||||
;W[bj]WL[838.584]
|
|
||||||
;B[cq]BL[1192.059]
|
|
||||||
;W[bp]WL[816.329]
|
|
||||||
;B[bq]BL[1187.402]
|
|
||||||
;W[cp]WL[799.182]
|
|
||||||
;B[dr]BL[1175.109]
|
|
||||||
;W[cs]WL[784.066]
|
|
||||||
;B[br]BL[1163.37]
|
|
||||||
;W[bs]WL[776.864]
|
|
||||||
;B[ds]BL[1147.742]
|
|
||||||
;W[aq]WL[749.309]
|
|
||||||
;B[od]BL[1123.221]
|
|
||||||
;W[mc]WL[732.116]
|
|
||||||
;B[oe]BL[1118.436]
|
|
||||||
;W[ne]WL[730.184]
|
|
||||||
;B[qe]BL[1115.467]
|
|
||||||
;W[pq]WL[716.339]
|
|
||||||
;B[ps]BL[1104.729]
|
|
||||||
;W[qs]WL[714.303]
|
|
||||||
;B[ns]BL[1103.082]
|
|
||||||
;W[dq]WL[695.662]
|
|
||||||
;B[jm]BL[1098.467]
|
|
||||||
;W[jl]WL[648.937]
|
|
||||||
;B[il]BL[1087.713]
|
|
||||||
;W[ng]WL[641.827]
|
|
||||||
;B[hk]BL[1085.146]
|
|
||||||
;W[kk]WL[640.029]
|
|
||||||
;B[se]BL[1075.646]
|
|
||||||
;W[pm]WL[600.229]
|
|
||||||
;B[cm]BL[1050.771]
|
|
||||||
;W[bn]WL[574.629]
|
|
||||||
;B[cn]BL[1038.123]
|
|
||||||
;W[bl]WL[548.976]
|
|
||||||
;B[bm]BL[1033.585]
|
|
||||||
;W[bo]WL[538.979]
|
|
||||||
;B[cl]BL[1026.736]
|
|
||||||
;W[bk]WL[535.297]
|
|
||||||
(;B[pe]BL[1021.423]
|
|
||||||
;W[]WL[511.235]
|
|
||||||
;B[]BL[1021.421]TW[fa][ga][ha][ia][ja][ka][la][ma][na][gb][hb][ib][jb][kb][lb][mb][nb][gc][hc][ic][kc][lc][nc][gd][hd][id][jd][kd][ld][md][ke][le][me][mf][rg][sg][bi][aj][cj][ak][ck][dk][ek][al][cl][dl][el][fl][pl][am][bm][cm][dm][em][fm][qm][rm][an][cn][en][fn][on][pn][sn][ao][co][do][eo][oo][po][qo][ro][so][ap][op][qp][rp][sp][bq][cq][rq][sq][ar][br][cr][dr][rr][sr][as][ds][rs][ss]TB[aa][ba][ra][sa][ab][cb][qb][sb][ac][bc][qc][rc][sc][ad][bd][cd][qd][sd][ae][ce][bf][df][ef][eg][fg][gg][hg][ig][jg][fh][gh][hh][ih][jh][ji][pi][hj][qj][rj][sj][im][in][jn][ln][io][jo][ko][lo][hp][ip][jp][kp][lp][gq][hq][jq][lq][gr][ir][jr][kr][lr][nr][hs][is][js][ks][ls][ms][os]C[savanni [23k?\]: Thank you for the game!
|
|
||||||
st2018 [13k?\]: gg
|
|
||||||
st2018 [13k?\]: thx
|
|
||||||
savanni [23k?\]: I'll report it to the tournament directors.
|
|
||||||
st2018 [13k?\]: ok
|
|
||||||
st2018 [13k?\]: there is a link where u report it
|
|
||||||
savanni [23k?\]: Yes. I already have it open.
|
|
||||||
st2018 [13k?\]: ok
|
|
||||||
st2018 [13k?\]: thx
|
|
||||||
st2018 [13k?\]: bye
|
|
||||||
])
|
|
||||||
(;B[]BL[1026.735]
|
|
||||||
;W[]WL[535.296]TW[fa][ga][ha][ia][ja][ka][la][ma][na][gb][hb][ib][jb][kb][lb][mb][nb][gc][hc][ic][kc][lc][nc][gd][hd][id][jd][kd][ld][md][ke][le][me][mf][rg][sg][bi][aj][cj][ak][ck][dk][ek][al][cl][dl][el][fl][pl][am][bm][cm][dm][em][fm][qm][rm][an][cn][en][fn][on][pn][sn][ao][co][do][eo][oo][po][qo][ro][so][ap][op][qp][rp][sp][bq][cq][rq][sq][ar][br][cr][dr][rr][sr][as][ds][rs][ss]TB[aa][ba][ra][sa][ab][cb][qb][sb][ac][bc][qc][rc][sc][ad][bd][cd][qd][sd][ae][ce][bf][df][ef][eg][fg][gg][hg][ig][jg][fh][gh][hh][ih][jh][ji][pi][hj][qj][rj][sj][im][in][jn][ln][io][jo][ko][lo][hp][ip][jp][kp][lp][gq][hq][jq][lq][gr][ir][jr][kr][lr][nr][hs][is][js][ks][ls][ms][os]))
|
|
|
@ -1,239 +0,0 @@
|
||||||
(;FF[4]
|
|
||||||
CA[UTF-8]
|
|
||||||
GM[1]
|
|
||||||
DT[2021-05-16]
|
|
||||||
PC[OGS: https://online-go.com/game/33745402]
|
|
||||||
GN[Tournament Game: Teaching Tree: Handicap Elimination (68688) R:2 (Ormos vs savanni.dgerinel)]
|
|
||||||
PB[savanni.dgerinel]
|
|
||||||
PW[Ormos]
|
|
||||||
BR[9k]
|
|
||||||
WR[3k]
|
|
||||||
TM[259200]OT[86400 fischer]
|
|
||||||
RE[W+R]
|
|
||||||
SZ[19]
|
|
||||||
KM[0.5]
|
|
||||||
RU[Japanese]
|
|
||||||
HA[5]
|
|
||||||
AB[jj][dd][pp][pd][dp]
|
|
||||||
C[Ormos: Hello Good game
|
|
||||||
savanni.dgerinel: Hello! You, too.
|
|
||||||
]
|
|
||||||
;W[qf]
|
|
||||||
C[savanni.dgerinel: Hello! You, too.
|
|
||||||
]
|
|
||||||
(;B[qe]
|
|
||||||
(;W[pf]
|
|
||||||
(;B[nd]
|
|
||||||
(;W[qj]
|
|
||||||
(;B[gd]
|
|
||||||
(;W[lc]
|
|
||||||
(;B[mc]
|
|
||||||
(;W[ld]
|
|
||||||
(;B[jp]
|
|
||||||
(;W[nq]
|
|
||||||
(;B[lq]
|
|
||||||
(;W[no]
|
|
||||||
(;B[pn]
|
|
||||||
(;W[ql]
|
|
||||||
(;B[qm]
|
|
||||||
(;W[pl]
|
|
||||||
(;B[dj]
|
|
||||||
(;W[cm]
|
|
||||||
(;B[dl]
|
|
||||||
(;W[bk]
|
|
||||||
(;B[bj]
|
|
||||||
(;W[ck]
|
|
||||||
(;B[cj]
|
|
||||||
(;W[bp]
|
|
||||||
(;B[cq]
|
|
||||||
(;W[co]
|
|
||||||
(;B[gp]
|
|
||||||
(;W[fn]
|
|
||||||
(;B[dg]
|
|
||||||
(;W[cc]
|
|
||||||
(;B[dc]
|
|
||||||
(;W[cd]
|
|
||||||
(;B[cf]
|
|
||||||
(;W[hc]
|
|
||||||
(;B[jc]
|
|
||||||
(;W[id]
|
|
||||||
(;B[jd]
|
|
||||||
(;W[je]
|
|
||||||
(;B[ie]
|
|
||||||
(;W[ke]
|
|
||||||
(;B[mb]
|
|
||||||
(;W[lb]
|
|
||||||
(;B[ic]
|
|
||||||
(;W[hd]
|
|
||||||
(;B[he]
|
|
||||||
(;W[hb]
|
|
||||||
(;B[ig]
|
|
||||||
(;W[fb]
|
|
||||||
(;B[pi]
|
|
||||||
(;W[qi]
|
|
||||||
(;B[ph]
|
|
||||||
(;W[qh]
|
|
||||||
(;B[og]
|
|
||||||
(;W[lg]
|
|
||||||
(;B[re]
|
|
||||||
(;W[de]
|
|
||||||
(;B[ee]
|
|
||||||
(;W[ce]
|
|
||||||
(;B[ef]
|
|
||||||
(;W[db]
|
|
||||||
(;B[fd]
|
|
||||||
(;W[df]
|
|
||||||
(;B[bf]
|
|
||||||
(;W[eg]
|
|
||||||
(;B[dh]
|
|
||||||
(;W[fg]
|
|
||||||
(;B[fl]
|
|
||||||
(;W[gi]
|
|
||||||
(;B[hl]
|
|
||||||
(;W[ek]
|
|
||||||
(;B[dk]
|
|
||||||
(;W[el]
|
|
||||||
(;B[dm]
|
|
||||||
(;W[em]
|
|
||||||
(;B[en]
|
|
||||||
(;W[eo]
|
|
||||||
(;B[dn]
|
|
||||||
(;W[do]
|
|
||||||
(;B[ep]
|
|
||||||
(;W[fp]
|
|
||||||
(;B[fq]
|
|
||||||
(;W[fo]
|
|
||||||
(;B[fm]
|
|
||||||
(;W[fk]
|
|
||||||
(;B[hm]
|
|
||||||
(;W[ii]
|
|
||||||
(;B[ji]
|
|
||||||
(;W[ih]
|
|
||||||
(;B[jh]
|
|
||||||
(;W[jg]
|
|
||||||
(;B[hg]
|
|
||||||
(;W[gh]
|
|
||||||
(;B[gg]
|
|
||||||
(;W[ff]
|
|
||||||
(;B[fh]
|
|
||||||
(;W[eh]
|
|
||||||
(;B[fi]
|
|
||||||
(;W[ei]
|
|
||||||
(;B[fj]
|
|
||||||
(;W[ej]
|
|
||||||
(;B[gj]
|
|
||||||
(;W[gk]
|
|
||||||
(;B[hj]
|
|
||||||
(;W[hk]
|
|
||||||
(;B[ij]
|
|
||||||
(;W[ge]
|
|
||||||
(;B[gf]
|
|
||||||
(;W[fe]
|
|
||||||
(;B[jl]
|
|
||||||
(;W[cl]
|
|
||||||
(;B[hh]
|
|
||||||
(;W[if]
|
|
||||||
(;B[or]
|
|
||||||
(;W[nr]
|
|
||||||
(;B[oq]
|
|
||||||
(;W[oo]
|
|
||||||
(;B[om]
|
|
||||||
(;W[mm]
|
|
||||||
(;B[ol]
|
|
||||||
(;W[ok]
|
|
||||||
(;B[ml]
|
|
||||||
(;W[ll]
|
|
||||||
(;B[mk]
|
|
||||||
(;W[ln]
|
|
||||||
(;B[jn]
|
|
||||||
(;W[lk]
|
|
||||||
(;B[mj]
|
|
||||||
(;W[nm]
|
|
||||||
(;B[mg]
|
|
||||||
(;W[on]
|
|
||||||
(;B[lh]
|
|
||||||
(;W[pm]
|
|
||||||
(;B[qn]
|
|
||||||
(;W[nl]
|
|
||||||
(;B[mf]
|
|
||||||
(;W[rl]
|
|
||||||
(;B[sm]
|
|
||||||
(;W[po]
|
|
||||||
(;B[qo]
|
|
||||||
(;W[qp]
|
|
||||||
(;B[qq]
|
|
||||||
(;W[rp]
|
|
||||||
(;B[rq]
|
|
||||||
(;W[ro]
|
|
||||||
(;B[sp]
|
|
||||||
(;W[sn]
|
|
||||||
(;B[sh]
|
|
||||||
(;W[rh]
|
|
||||||
(;B[rg]
|
|
||||||
(;W[rf]
|
|
||||||
(;B[sf]
|
|
||||||
(;W[si]
|
|
||||||
(;B[sg]
|
|
||||||
(;W[ho]
|
|
||||||
(;B[go]
|
|
||||||
(;W[gn]
|
|
||||||
(;B[hn]
|
|
||||||
(;W[gq]
|
|
||||||
(;B[hp]
|
|
||||||
(;W[hq]
|
|
||||||
(;B[ip]
|
|
||||||
(;W[fr]
|
|
||||||
(;B[eq]
|
|
||||||
(;W[er]
|
|
||||||
(;B[bq]
|
|
||||||
(;W[cp]
|
|
||||||
(;B[dq]
|
|
||||||
(;W[dr]
|
|
||||||
(;B[cn]
|
|
||||||
(;W[bn]
|
|
||||||
(;B[ao]
|
|
||||||
(;W[ap]
|
|
||||||
(;B[gm]
|
|
||||||
(;W[bm]
|
|
||||||
(;B[ir]
|
|
||||||
(;W[qg]
|
|
||||||
(;B[se]
|
|
||||||
(;W[pe]
|
|
||||||
(;B[qc]
|
|
||||||
(;W[ne]
|
|
||||||
(;B[oj]
|
|
||||||
(;W[lj]
|
|
||||||
(;B[li]
|
|
||||||
(;W[nj]
|
|
||||||
(;B[ni]
|
|
||||||
(;W[nk]
|
|
||||||
(;B[mi]
|
|
||||||
(;W[bh]
|
|
||||||
(;B[ch]
|
|
||||||
(;W[bi]
|
|
||||||
(;B[ai]
|
|
||||||
(;W[be]
|
|
||||||
(;B[bg]
|
|
||||||
(;W[ah]
|
|
||||||
(;B[aj]
|
|
||||||
(;W[ak]
|
|
||||||
(;B[ag]
|
|
||||||
(;W[ks]
|
|
||||||
(;B[mr]
|
|
||||||
(;W[ms]
|
|
||||||
(;B[kr]
|
|
||||||
(;W[ls]
|
|
||||||
(;B[js]
|
|
||||||
(;W[mp]
|
|
||||||
(;B[lp]
|
|
||||||
(;W[lo]
|
|
||||||
(;B[ko]
|
|
||||||
(;W[pr]
|
|
||||||
(;B[os]
|
|
||||||
(;W[qr]
|
|
||||||
(;B[rr]
|
|
||||||
(;W[pq]
|
|
||||||
C[savanni.dgerinel: Thank you for playing.
|
|
||||||
Ormos: Thank you for game, see you for rematch.
|
|
||||||
]
|
|
||||||
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
|
|
|
@ -1,656 +0,0 @@
|
||||||
(;FF[4]
|
|
||||||
CA[UTF-8]
|
|
||||||
GM[1]
|
|
||||||
PC[OGS: https://online-go.com/game/review/395780]
|
|
||||||
BR[2d]
|
|
||||||
WR[2d]
|
|
||||||
CP[online-go.com]
|
|
||||||
TM[0]OT[0 none]
|
|
||||||
RE[?]
|
|
||||||
SZ[19]
|
|
||||||
KM[6.5]
|
|
||||||
RU[japanese]
|
|
||||||
|
|
||||||
(;B[qd]
|
|
||||||
;W[dd]
|
|
||||||
;B[pp]
|
|
||||||
;W[dp]
|
|
||||||
;B[fq]
|
|
||||||
;W[cn]
|
|
||||||
;B[pj]
|
|
||||||
;W[jd]
|
|
||||||
;B[cf]
|
|
||||||
(;W[gc]
|
|
||||||
)(;W[ce]
|
|
||||||
;B[df]
|
|
||||||
;W[gc]
|
|
||||||
;B[ci]
|
|
||||||
;W[ck]
|
|
||||||
;B[cj]
|
|
||||||
;W[dk]
|
|
||||||
;B[ei]
|
|
||||||
(;W[nq]
|
|
||||||
;B[qn]
|
|
||||||
;W[eq]
|
|
||||||
;B[er]
|
|
||||||
;W[fp]
|
|
||||||
;B[gq]
|
|
||||||
;W[gp]
|
|
||||||
;B[hq]
|
|
||||||
;W[bf]
|
|
||||||
;B[bg]
|
|
||||||
;W[be]
|
|
||||||
;B[dr]
|
|
||||||
)(;W[bf]
|
|
||||||
;B[bg]
|
|
||||||
;W[be]
|
|
||||||
;B[dr]
|
|
||||||
;W[nq]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
snakesss: fixing people's existential crisis would be an easier promise imo
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[qn]
|
|
||||||
;W[eq]
|
|
||||||
;B[er]
|
|
||||||
;W[fp]
|
|
||||||
;B[gq]
|
|
||||||
;W[gp]
|
|
||||||
;B[hq]C[Hi! This lesson is about opening rules. There are two things you should be aware of in the opening. First, you shouldn't try to play endgame moves in the opening. In a way, that sounds too obvious. Some players, however, try to. Let's look at an example.
|
|
||||||
|
|
||||||
This game was played by two 9 kyu players. There were many big points on the board.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: Hello everyone. This is a text-based lecture about what to do and no to do in the opening.
|
|
||||||
mark5000: There's no audio or anything, so if you're here, you're good. :)
|
|
||||||
Shakes Fish At Sky: nice
|
|
||||||
Cactus Juice: Buyt are we really here?
|
|
||||||
Xv8: Is Plato still stuck in his cave?
|
|
||||||
Shakes Fish At Sky: lets not get metaphysical cactus
|
|
||||||
mark5000: I can fix your Go. I can't fix your existential crisis.
|
|
||||||
Shakes Fish At Sky: lol
|
|
||||||
Shakes Fish At Sky: please fix my go
|
|
||||||
adamomo: lol
|
|
||||||
Xv8: My Go has yet to work at all, let alone need fixing
|
|
||||||
spiritstar42: my existential crises needs fixing but if you can't ill settle for my go
|
|
||||||
Napster: I agree with cacti
|
|
||||||
Sukkubix: Thank you for the lecture :)
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[cq]C[In the game, White played at 3-3. It's clear that this was big, but there were many urgent points. That move was fine though.
|
|
||||||
]
|
|
||||||
|
|
||||||
(;B[cr]C[Black, however, played here next. What do you think of this move? Many players follow their opponents around the board, like an eager puppy.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
akr: too slow
|
|
||||||
chess_player: Black probably gained 3-4 points here
|
|
||||||
Executive Calamari: Not gaining enough
|
|
||||||
chess_player: But he could have made bigger play in the top right
|
|
||||||
mayomoyo: Top right or extending to bottom right seems bigger
|
|
||||||
Metropolis: B's group cant' die, and can't kill w, so the 2nd line move isn't threatening anything.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[bq]C[It was time for White to tenuki and play elsewhere. But White responded here. We see such sequences from time to time. It isn't good to make endgame plays when you have many other places to play.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Undercover2019: 017
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;AE[cq]C[Where should both players have played then?
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
snakesss: Friendly SYNC reminder, if the moves don't make sense with the text, try hitting the sync button.
|
|
||||||
mark5000: Thanks.
|
|
||||||
chess_player: If I was white, I would have played P17
|
|
||||||
chess_player: Or may be 017
|
|
||||||
mark5000: Good thought
|
|
||||||
snakesss: black can do that as well
|
|
||||||
snakesss: perhaps m3 is an option
|
|
||||||
chess_player: Is m3 a good option?
|
|
||||||
mark5000: Good, so all of you are as better than 9 kyu players :)
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;B[od]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: here. From move 0: R16 D16 Q4 D4 F3 C6 Q10 K16 C14 C15 D14 G17 C11 C9 C10 D9 E11 B14 B13 B15 D2 O3 R6 E3 E2 F4 G3 G4 H3 C3 C3 P16
|
|
||||||
chess_player: Nice
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;AW[pr]C[First, White needed to slide into the corner.
|
|
||||||
]
|
|
||||||
|
|
||||||
(;B[qq]
|
|
||||||
;W[kq]C[Then this extension is very big. In addition, the upper right corner was unfinished. Rule 1 of the opening is (1) Don't play endgame moves in the opening. As I've said before, corner enclosures and approaches are huge. Remember not to play endgame moves in the opening! Let's learn the second rule of the opening.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
p6109: how about c3
|
|
||||||
mark5000: c3 was the game move and it was actually ok.
|
|
||||||
p6109: thx
|
|
||||||
mark5000: around q2 and p17 were bigger.
|
|
||||||
chess_player: Can you please suggest how much point is playing L3 worth?
|
|
||||||
chess_player: As in, c3 probably was worth 8 points? Am I right?
|
|
||||||
chess_player: Or is this a bad question?
|
|
||||||
Metropolis: The w group can be badly attacked without l3
|
|
||||||
snakesss: if black has l3 instead of white on this board, i think white is dead, so l3 is worth the entire bottom
|
|
||||||
mark5000: I think in the opening it's not a good question for most players to be asking. It's not because this information isn't useful, but if you're a DDK player, painting in broad strokes is more important.
|
|
||||||
mark5000: If you're liable to follow your opponent around the board and make endgame plays without thinking, it's of no consequence that you can count point values precisely.
|
|
||||||
mark5000: Yes, that's fine too.
|
|
||||||
mayomoyo: Can L3 be played before Q2? If black secures the corner, can't white make a base on the other side, with J2, for example?
|
|
||||||
chess_player: Hmm
|
|
||||||
Kryswilx: i see this borad bad for white
|
|
||||||
mark5000: Let's move on.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;B[lq]
|
|
||||||
;W[qq]
|
|
||||||
(;B[lo]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: mark, is this ok too?. From move 0: R16 D16 Q4 D4 F3 C6 Q10 K16 C14 C15 D14 G17 C11 C9 C10 D9 E11 B14 B13 B15 D2 O3 R6 E3 E2 F4 G3 G4 H3 C3 C3 Q2 M3 R3 M5
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;B[np]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
chess_player: Not precisely, but I usually think if l3 is worth more points, lets play it there
|
|
||||||
mark5000: I would play around here though.
|
|
||||||
mark5000: It's good to surround things, since Go is literally the surrounding game.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;B[oq]
|
|
||||||
;W[or]
|
|
||||||
;B[np]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: Also this.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)))))))(;B[pd]
|
|
||||||
;W[dp]
|
|
||||||
;B[pp]
|
|
||||||
;W[dd]
|
|
||||||
(;B[pj]
|
|
||||||
(;W[nc]
|
|
||||||
;B[jp]
|
|
||||||
;W[dj]
|
|
||||||
;B[pf]
|
|
||||||
;W[jd]
|
|
||||||
;B[cc]
|
|
||||||
;W[cd]
|
|
||||||
;B[dc]
|
|
||||||
;W[ec]
|
|
||||||
;B[eb]
|
|
||||||
;W[fb]
|
|
||||||
;B[fc]
|
|
||||||
;W[ed]
|
|
||||||
;B[gb]
|
|
||||||
;W[fd]
|
|
||||||
;B[fa]
|
|
||||||
;W[gc]
|
|
||||||
;B[fb]
|
|
||||||
;W[qn]
|
|
||||||
;B[qo]
|
|
||||||
;W[pn]
|
|
||||||
;B[np]
|
|
||||||
;W[pl]C[The second rule of the opening is (2) Never tenuki in the middle of a fight. Even if there are big points, don't tenuki while fighting.
|
|
||||||
|
|
||||||
This is from a game played between two pros. What's the biggest point now? of the opening is (2) Never tenuki in the middle of a fight. Even if there are big points, don't tenuki while fighting.
|
|
||||||
|
|
||||||
This is from a game played between two pros. What's the biggest point now?
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
snakesss: o9?
|
|
||||||
mayomoyo: F3?
|
|
||||||
mayomoyo: F3 is biggest move but not most urgent, I mean
|
|
||||||
mark5000: Good clarification
|
|
||||||
ZedSG: I like cactus' variation
|
|
||||||
mark5000: Cactus Juice, White surely won't play move 2, will she?
|
|
||||||
ZedSG: I mean, us ddk would
|
|
||||||
Decros: hello, wat's this?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;B[qk]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: If this,
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;W[ql]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: :O why not? doesn't it keep eyeshape?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[nk]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: this for surrounding?. From move 0: Q16 D4 Q4 D16 Q10 O17 K4 D10 Q14 K16 C17 C16 D17 E17 E18 F18 F17 E16 G18 F16 F19 G17 F18 R6 R5 Q6 O4 Q8 R9 R8 O9
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;W[mm]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Kryswilx: n7
|
|
||||||
mark5000: I jump out.
|
|
||||||
Cactus Juice: ooh, cool
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))(;B[fq]C[For Black, this approach is huge.
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;AW[hq]C[On the other hand, White would also like to play here.
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;B[hc]C[Black, however, ataried here in the actual game. Moves on the right side were also possible, since there's an unresolved, but stable, fight there, too.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
snakesss: hi, demo board text lecture by 5dan
|
|
||||||
snakesss: about opening
|
|
||||||
mark5000: Would you all answer this atari?
|
|
||||||
Cactus Juice: I wouldn't, feels small
|
|
||||||
snakesss: ^^
|
|
||||||
Decros: nope
|
|
||||||
ZedSG: not that small to me, black can follow with k17 or k18
|
|
||||||
Undercover2019: jump 07
|
|
||||||
chess_player: Yes
|
|
||||||
mark5000: Would you allow Black a flower (ponnuki)?
|
|
||||||
snakesss: i might cuz of k16
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;W[gd]C[Even though playing in the lower left corner is big, you mustn't allow Black a ponnuki.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
chess_player: I would want to do that because the group in the top right mid is actually very weak
|
|
||||||
snakesss: cool
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[hd]C[So White connected and Black pushed.
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[he]C[White still couldn't tenuki, so White haned.
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[ie]C[Black haned too,
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[id]C[And White cut immediately.
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[hf]
|
|
||||||
;W[ge]
|
|
||||||
;B[ib]C[In response, Black played a tiger's mouth to defend his two stones. Here's a question: Can White tenuki now? The fight was still underway up here, so a tenuki wasn't a good idea.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
chess_player: No
|
|
||||||
p6109: no
|
|
||||||
Soineanta: I don't think so.
|
|
||||||
chess_player: It would still leave the white group in the mid center in danger
|
|
||||||
ZedSG: no, that top group looks like it needs some help
|
|
||||||
mark5000: You all are too good.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;W[pc]C[White needed to continue, so White attached and settled in the corner.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Xv8: Or all the bad players are keeping quiet
|
|
||||||
chess_player: (I don't manage to think all that in the game)
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[qc]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
杯酒释兵权: instead of p16, i felt like r18 is better
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;W[od]
|
|
||||||
;B[pe]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Shakes Fish At Sky: i am not keeping quiet
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;W[if]C[After these exchanges, White cut here and began fighting. What do you think of this sequence? Had White tenukied, Black would have attacked White's group at the top, taking control of the game. Previously, we talked about how a battle can sometimes begin in the opening. When that happens, don't rush to tenuki!
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Shakes Fish At Sky: its just I am having dinner
|
|
||||||
chess_player: Still in the fight, so black should respond
|
|
||||||
Cactus Juice: mark, why did white attach q17 instead of slide?
|
|
||||||
Shakes Fish At Sky: Q18
|
|
||||||
p6109: I would have finished L18
|
|
||||||
snakesss: white had one weak group that needed help
|
|
||||||
mark5000: White attached at q17 instead of sliding to keep sente.
|
|
||||||
Shakes Fish At Sky: or C3
|
|
||||||
mayomoyo: I was also thinking L18
|
|
||||||
Cactus Juice: l18*
|
|
||||||
snakesss: so, white has to cut? so black cant fix?
|
|
||||||
Cactus Juice: snakesss: yeah, fixing there is huge for black, works well with botom and right :/
|
|
||||||
mark5000: Correct.
|
|
||||||
mark5000: This is secondary to my lesson though.
|
|
||||||
mark5000: This part of the lesson is that White should not tenuki the first move.
|
|
||||||
Shakes Fish At Sky: I would have made that mistake I think
|
|
||||||
Shakes Fish At Sky: cause i am bad
|
|
||||||
mark5000: It's suspiciously easy to fall into this trap.
|
|
||||||
snakesss: which mistake? i would have done most of these mistakes in the 2nd rule part
|
|
||||||
mark5000: When it's highlighted as a Go problem, like here, it's easy for everyone to see it.
|
|
||||||
mark5000: But when you put it in your own games, suddenly you lose all good sense and start making these mistakes you know you shouldn't make.
|
|
||||||
mark5000: That's why it's important to talk about it so much that it becomes second nature.
|
|
||||||
chess_player: So, how long do we keep this fight so that it doesn't contradict the first rule?
|
|
||||||
mark5000: If it's second nature, you'll do it in your games by instinct, and you improve your Go skill.
|
|
||||||
mark5000: Good question.
|
|
||||||
mark5000: If a battle for the health and security of groups is underway, don't tenuki, per rule 2.
|
|
||||||
mark5000: If the battle is no longer underway, or if the battle no longer concerns the health and security of groups, but only points, then rule 1 applies.
|
|
||||||
snakesss: but first ponnuki was just one stone and good shape - no security of groups endangered
|
|
||||||
mark5000: It did endanger the upper right white stones, if you recall.
|
|
||||||
snakesss: ok
|
|
||||||
chess_player: Which three black stones?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;W[kb]
|
|
||||||
;B[if]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Shakes Fish At Sky: yeah Q18
|
|
||||||
mark5000: Right, it's a bit peaceful for this board.
|
|
||||||
mark5000: Cutting here was important, since it cracks open White's left side like an egg
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[pb]LB[fg:A]LB[eh:B]LB[di:C]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: p6109, I'd think about A B or C
|
|
||||||
p6109: thx
|
|
||||||
p6109: E11 is too high
|
|
||||||
snakesss: even if it puts white stones in danger?
|
|
||||||
Alma Pacifica: is for academy alma pacifica is ?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;B[ei]
|
|
||||||
;W[di]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: It's a bit hard to continue here.
|
|
||||||
p6109: thx
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;B[eh]
|
|
||||||
;W[dh]
|
|
||||||
;B[eg]
|
|
||||||
;W[dg]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: Like this, and you're not attacking.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;B[dh]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: i think that for that wall to die only if white lets it die
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ch]
|
|
||||||
;B[cg]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
snakesss: was that last one bad for black considering the board?
|
|
||||||
mark5000: This could be better, but I'm not sure Black is strong enough.
|
|
||||||
snakesss: there is a white group on the right
|
|
||||||
Shakes Fish At Sky: e13?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;W[eh]
|
|
||||||
;B[dg]
|
|
||||||
(;W[eg]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: Probably this
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;W[fh]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: Or here
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))(;W[dg]
|
|
||||||
;B[eh]
|
|
||||||
;W[bg]
|
|
||||||
;B[cf]
|
|
||||||
;W[bf]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: white can just connect, no?. From move 0: Q16 D4 Q4 D16 Q10 O17 K4 D10 Q14 K16 C17 C16 D17 E17 E18 F18 F17 E16 G18 F16 F19 G17 F18 R6 R5 Q6 O4 Q8 H17 G16 H16 H15 J15 J16 H14 G15 J18 Q17 R17 P16 Q15 L18 J14 Q18 E11 D11 D12 C12 C13 D13 E12 B13 C14 B14
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[fk]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: It feels like BLack profited enough.
|
|
||||||
mark5000: Yes
|
|
||||||
Cactus Juice: yeah, it's a big profit :s
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)))(;B[eh]
|
|
||||||
;W[ch]
|
|
||||||
;B[cg]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: Compare to something like this, which I like a bit more.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;B[di]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: this is over my ddk head xD
|
|
||||||
mark5000: Or this attachment, which forces local moves that have to coordinate with the upper group AND keep Black out of the left side.
|
|
||||||
mark5000: XD
|
|
||||||
mark5000: That's why it's not part of the DDK lecture.
|
|
||||||
chess_player: :)
|
|
||||||
mark5000: The important part was the two opening rules.
|
|
||||||
mark5000: Your opponents will not follow them, and it's a chance to seize control of the game each time it happens.
|
|
||||||
snakesss: it is still a situational judgement call
|
|
||||||
snakesss: that ponnuki thing is a little vague for me :S
|
|
||||||
Alma Pacifica: im DDK
|
|
||||||
Alma Pacifica: thx for lecture
|
|
||||||
snakesss: maybe including when to ignore a sitation that looks fighty would have clarified it
|
|
||||||
mark5000: It's ok. It's enough to consider a ponnuki valuable and deny it to your opponent when possible, regardless of the situation.
|
|
||||||
snakesss: ok
|
|
||||||
p6109: It is harder to use a wall than its is to use a ponnuki for me...
|
|
||||||
mark5000: The right side is a good example of that, actually.
|
|
||||||
mark5000: The three WHite stones look to be in danger, but actually they have miai to move out or settle.
|
|
||||||
mark5000: So it's stable, ok to leave.
|
|
||||||
mark5000: Part of the balance of Go is between taking big moves and attacking weaknesses.
|
|
||||||
mark5000: Sometimes, you want to ignore a big play and attack in hopes of profiting more than the big play would profit you.
|
|
||||||
mark5000: On the other hand, sometimes you really do want the big play.
|
|
||||||
mark5000: In such cases, you should mind your weak group only as long as you have to.
|
|
||||||
mark5000: The right side is an example. White left to take a big point because the group was stable, for now.
|
|
||||||
mark5000: Play in one area as much as necessary and no more.
|
|
||||||
mark5000: That flows into rule 1: don't play endgame moves in the opening. Endgame moves are moves that take only points
|
|
||||||
mark5000: I hope that's clear as mud now...
|
|
||||||
p6109: :-)
|
|
||||||
mark5000: Next lecture topic is: how to destroy enemy shapes.
|
|
||||||
mark5000: See you all next time!
|
|
||||||
p6109: See you,
|
|
||||||
Shakes Fish At Sky: thx mark5000
|
|
||||||
Shakes Fish At Sky: Its not exactly obvious but seeing though mud is what go is all about
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))(;W[pb]
|
|
||||||
;B[if]TR[ec]TR[gc]SQ[bd]TR[cd]TR[dd]TR[ed]TR[fd]TR[gd]SQ[ce]SQ[de]SQ[ee]SQ[fe]TR[ge]TR[he]SQ[gf]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: Same with this.
|
|
||||||
mark5000: No matter what White does, besides cutting, Black will fix the cutting point.
|
|
||||||
Shakes Fish At Sky: you asume a aspiring 9k would do that?
|
|
||||||
mark5000: Six liberties may seem like a lot, but you'll have to watch that left white group.
|
|
||||||
Cactus Juice: well, answering the question on the cut there, i think white has too much to worry about, but if well played can build a big left
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))(;W[qb]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Shakes Fish At Sky: ah - its whites move
|
|
||||||
mark5000: MoI think this could be better, too. It suits my modern eyes.
|
|
||||||
mark5000: I think*
|
|
||||||
Cactus Juice: L!8 just lives somewhat peacefully, doesn't strike me as white's goal here
|
|
||||||
Shakes Fish At Sky: if it was black then Q3 would be big
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))(;W[pb]
|
|
||||||
;B[if]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: White didn't want this.
|
|
||||||
Cactus Juice: ah, makes sense, thanks :D
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;W[oe]
|
|
||||||
;B[pe]
|
|
||||||
;W[kf]C[AI would play like this, in case anyone is wondering about it. But this game was played in 1974. In the 70s, no player would ever peep at a high approach like this, because they liked to preserve aji for living underneath later.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
tpnZbonek: becouse its confident enough to kill 3 black stones..
|
|
||||||
mark5000: Right.
|
|
||||||
mark5000: That's all I had prepared for today.
|
|
||||||
p6109: thanks a lot
|
|
||||||
tpnZbonek: thank you for the lesson
|
|
||||||
mark5000: I'll answer any further questions you may have.
|
|
||||||
ZedSG: thank you for teaching us!
|
|
||||||
mayomoyo: Thank you very much for the lesson.
|
|
||||||
tpnZbonek: i wanted to ask, you do lessons in the same time?
|
|
||||||
tpnZbonek: i catched it luckily for 2. time
|
|
||||||
chess_player: Thank you so much mark5000, for this and for the puzzles in the puzzles sections as well, they have contributed a lot to whatever skill I have
|
|
||||||
Cactus Juice: oh, the ai play is pretty cool
|
|
||||||
mark5000: I don't have a schedule, unfortunately. I just do them on Sundays when I find time.
|
|
||||||
tpnZbonek: ok thanks for the lesson
|
|
||||||
mark5000: This is the earliest I would do one. Sometimes I do one a bit later.
|
|
||||||
mark5000: Any questions about the opening?
|
|
||||||
chess_player: Can you please play this situation down to when the F3 is decided
|
|
||||||
Shakes Fish At Sky: intresting that ai plays on 6th line
|
|
||||||
p6109: how would you start attacking the white group with six liberties? E11 maybe
|
|
||||||
Shakes Fish At Sky: humans might discount it
|
|
||||||
chess_player: As in, was it a matter of keeping sente or is somebody reading ahead enough to know that either black or white know they will get the F3
|
|
||||||
mark5000: Unfortunately, f3 was never decided in the actual game. Fighting continued for the rest of the game.
|
|
||||||
Cactus Juice: Shakes Fish At Sky: yeah, but pretty cool move, kinda encloses the two stones, preserves corner aji and goes to the center
|
|
||||||
Shakes Fish At Sky: yeah - all is obvious in hindsight
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))(;W[hq]
|
|
||||||
;B[gd]
|
|
||||||
;W[ge]
|
|
||||||
;B[he]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: oh interesting, but doesn't the double hane work for white here?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;W[gf]
|
|
||||||
;B[hf]TR[nc]TR[jd]C[This is a liability I don't think you want. The pro player says connecting is necessary.connecting is necessary.
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Cactus Juice: I don't see the ponnuki here as a problem for W, beucase the right side goroup is not weak itself, b will only get 2 points and there are bigger stuff
|
|
||||||
snakesss: that's how "ponnuki is worth 30 points" works then xD
|
|
||||||
mark5000: Ah, maybe. It's a close call to my eyes.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;W[hf]
|
|
||||||
;B[gf]
|
|
||||||
;W[fe]
|
|
||||||
;B[ie]TR[nc]TR[jd]TR[pl]TR[pn]TR[qn]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: Similar when you double hane
|
|
||||||
Decros: even worse for the top group
|
|
||||||
mark5000: White already had a second group that's not 100% secure, so extra fighting like this isn't what White wants.
|
|
||||||
mark5000: But it's possible. I'm not saying this way is terrible. Actually, AI thinks it's about even with the pro continuation.
|
|
||||||
snakesss: so, after that ponnuki, there are a few moves played
|
|
||||||
snakesss: h15 and j15 are what rly put white in danger
|
|
||||||
snakesss: those moves are a must for white to build a large left?
|
|
||||||
snakesss: and surround black?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))))(;W[dj]
|
|
||||||
;B[fq]
|
|
||||||
;W[dn]
|
|
||||||
;B[jp]
|
|
||||||
))(;B[jp]
|
|
||||||
(;W[dj]
|
|
||||||
;B[np]
|
|
||||||
;W[nc]
|
|
||||||
;B[pf]
|
|
||||||
;W[jd]
|
|
||||||
;B[cc]
|
|
||||||
;W[cd]
|
|
||||||
;B[dc]
|
|
||||||
;W[ec]
|
|
||||||
;B[eb]
|
|
||||||
;W[fb]
|
|
||||||
;B[fc]
|
|
||||||
;W[ed]
|
|
||||||
;B[gb]
|
|
||||||
;W[fd]
|
|
||||||
;B[fa]
|
|
||||||
;W[gc]
|
|
||||||
;B[fb]
|
|
||||||
)(;W[nc]
|
|
||||||
;B[pf]
|
|
||||||
;W[jd]
|
|
||||||
;B[qn]
|
|
||||||
;W[dj]
|
|
||||||
;B[cc]
|
|
||||||
;W[cd]
|
|
||||||
;B[dc]
|
|
||||||
;W[ec]
|
|
||||||
;B[eb]
|
|
||||||
;W[fb]
|
|
||||||
;B[fc]
|
|
||||||
;W[ed]
|
|
||||||
;B[gb]
|
|
||||||
;W[fd]
|
|
||||||
;B[fa]
|
|
||||||
;W[gc]
|
|
||||||
;B[fb]
|
|
||||||
))))
|
|
|
@ -1,118 +0,0 @@
|
||||||
(;FF[4]AP[Primiview:3.1]GM[1]SZ[19]GN[Gametree 1: properties]US[Arno Hollosi]
|
|
||||||
|
|
||||||
(;B[pd]N[Moves, comments, annotations]
|
|
||||||
C[Nodename set to: "Moves, comments, annotations"];W[dp]GW[1]
|
|
||||||
C[Marked as "Good for White"];B[pp]GB[2]
|
|
||||||
C[Marked as "Very good for Black"];W[dc]GW[2]
|
|
||||||
C[Marked as "Very good for White"];B[pj]DM[1]
|
|
||||||
C[Marked as "Even position"];W[ci]UC[1]
|
|
||||||
C[Marked as "Unclear position"];B[jd]TE[1]
|
|
||||||
C[Marked as "Tesuji" or "Good move"];W[jp]BM[2]
|
|
||||||
C[Marked as "Very bad move"];B[gd]DO[]
|
|
||||||
C[Marked as "Doubtful move"];W[de]IT[]
|
|
||||||
C[Marked as "Interesting move"];B[jj];
|
|
||||||
C[White "Pass" move]W[];
|
|
||||||
C[Black "Pass" move]B[tt])
|
|
||||||
|
|
||||||
(;AB[dd][de][df][dg][do:gq]
|
|
||||||
AW[jd][je][jf][jg][kn:lq][pn:pq]
|
|
||||||
N[Setup]C[Black & white stones at the top are added as single stones.
|
|
||||||
|
|
||||||
Black & white stones at the bottom are added using compressed point lists.]
|
|
||||||
;AE[ep][fp][kn][lo][lq][pn:pq]
|
|
||||||
C[AddEmpty
|
|
||||||
|
|
||||||
Black stones & stones of left white group are erased in FF[3\] way.
|
|
||||||
|
|
||||||
White stones at bottom right were erased using compressed point list.]
|
|
||||||
;AB[pd]AW[pp]PL[B]C[Added two stones.
|
|
||||||
|
|
||||||
Node marked with "Black to play".];PL[W]
|
|
||||||
C[Node marked with "White to play"])
|
|
||||||
|
|
||||||
(;AB[dd][de][df][dg][dh][di][dj][nj][ni][nh][nf][ne][nd][ij][ii][ih][hq]
|
|
||||||
[gq][fq][eq][dr][ds][dq][dp][cp][bp][ap][iq][ir][is][bo][bn][an][ms][mr]
|
|
||||||
AW[pd][pe][pf][pg][ph][pi][pj][fd][fe][ff][fh][fi][fj][kh][ki][kj][os][or]
|
|
||||||
[oq][op][pp][qp][rp][sp][ro][rn][sn][nq][mq][lq][kq][kr][ks][fs][gs][gr]
|
|
||||||
[er]N[Markup]C[Position set up without compressed point lists.]
|
|
||||||
|
|
||||||
;TR[dd][de][df][ed][ee][ef][fd:ff]
|
|
||||||
MA[dh][di][dj][ej][ei][eh][fh:fj]
|
|
||||||
CR[nd][ne][nf][od][oe][of][pd:pf]
|
|
||||||
SQ[nh][ni][nj][oh][oi][oj][ph:pj]
|
|
||||||
SL[ih][ii][ij][jj][ji][jh][kh:kj]
|
|
||||||
TW[pq:ss][so][lr:ns]
|
|
||||||
TB[aq:cs][er:hs][ao]
|
|
||||||
C[Markup at top partially using compressed point lists (for markup on white stones); listed clockwise, starting at upper left:
|
|
||||||
- TR (triangle)
|
|
||||||
- CR (circle)
|
|
||||||
- SQ (square)
|
|
||||||
- SL (selected points)
|
|
||||||
- MA ('X')
|
|
||||||
|
|
||||||
Markup at bottom: black & white territory (using compressed point lists)]
|
|
||||||
;LB[dc:1][fc:2][nc:3][pc:4][dj:a][fj:b][nj:c]
|
|
||||||
[pj:d][gs:ABCDEFGH][gr:ABCDEFG][gq:ABCDEF][gp:ABCDE][go:ABCD][gn:ABC][gm:AB]
|
|
||||||
[mm:12][mn:123][mo:1234][mp:12345][mq:123456][mr:1234567][ms:12345678]
|
|
||||||
C[Label (LB property)
|
|
||||||
|
|
||||||
Top: 8 single char labels (1-4, a-d)
|
|
||||||
|
|
||||||
Bottom: Labels up to 8 char length.]
|
|
||||||
|
|
||||||
;DD[kq:os][dq:hs]
|
|
||||||
AR[aa:sc][sa:ac][aa:sa][aa:ac][cd:cj]
|
|
||||||
[gd:md][fh:ij][kj:nh]
|
|
||||||
LN[pj:pd][nf:ff][ih:fj][kh:nj]
|
|
||||||
C[Arrows, lines and dimmed points.])
|
|
||||||
|
|
||||||
(;B[qd]N[Style & text type]
|
|
||||||
C[There are hard linebreaks & soft linebreaks.
|
|
||||||
Soft linebreaks are linebreaks preceeded by '\\' like this one >o\
|
|
||||||
k<. Hard line breaks are all other linebreaks.
|
|
||||||
Soft linebreaks are converted to >nothing<, i.e. removed.
|
|
||||||
|
|
||||||
Note that linebreaks are coded differently on different systems.
|
|
||||||
|
|
||||||
Examples (>ok< shouldn't be split):
|
|
||||||
|
|
||||||
linebreak 1 "\\n": >o\
|
|
||||||
k<
|
|
||||||
linebreak 2 "\\n\\r": >o\
|
|
||||||
k<
|
|
||||||
linebreak 3 "\\r\\n": >o\
|
|
||||||
k<
|
|
||||||
linebreak 4 "\\r": >o\
k<]
|
|
||||||
|
|
||||||
(;W[dd]N[W d16]C[Variation C is better.](;B[pp]N[B q4])
|
|
||||||
(;B[dp]N[B d4])
|
|
||||||
(;B[pq]N[B q3])
|
|
||||||
(;B[oq]N[B p3])
|
|
||||||
)
|
|
||||||
(;W[dp]N[W d4])
|
|
||||||
(;W[pp]N[W q4])
|
|
||||||
(;W[cc]N[W c17])
|
|
||||||
(;W[cq]N[W c3])
|
|
||||||
(;W[qq]N[W r3])
|
|
||||||
)
|
|
||||||
|
|
||||||
(;B[qr]N[Time limits, captures & move numbers]
|
|
||||||
BL[120.0]C[Black time left: 120 sec];W[rr]
|
|
||||||
WL[300]C[White time left: 300 sec];B[rq]
|
|
||||||
BL[105.6]OB[10]C[Black time left: 105.6 sec
|
|
||||||
Black stones left (in this byo-yomi period): 10];W[qq]
|
|
||||||
WL[200]OW[2]C[White time left: 200 sec
|
|
||||||
White stones left: 2];B[sr]
|
|
||||||
BL[87.00]OB[9]C[Black time left: 87 sec
|
|
||||||
Black stones left: 9];W[qs]
|
|
||||||
WL[13.20]OW[1]C[White time left: 13.2 sec
|
|
||||||
White stones left: 1];B[rs]
|
|
||||||
C[One white stone at s2 captured];W[ps];B[pr];W[or]
|
|
||||||
MN[2]C[Set move number to 2];B[os]
|
|
||||||
C[Two white stones captured
|
|
||||||
(at q1 & r1)]
|
|
||||||
;MN[112]W[pq]C[Set move number to 112];B[sq];W[rp];B[ps]
|
|
||||||
;W[ns];B[ss];W[nr]
|
|
||||||
;B[rr];W[sp];B[qs]C[Suicide move
|
|
||||||
(all B stones get captured)])
|
|
||||||
)
|
|
|
@ -1,47 +0,0 @@
|
||||||
(;FF[4]AP[Primiview:3.1]GM[1]SZ[19]C[Gametree 2: game-info
|
|
||||||
|
|
||||||
Game-info properties are usually stored in the root node.
|
|
||||||
If games are merged into a single game-tree, they are stored in the node\
|
|
||||||
where the game first becomes distinguishable from all other games in\
|
|
||||||
the tree.]
|
|
||||||
;B[pd]
|
|
||||||
(;PW[W. Hite]WR[6d]RO[2]RE[W+3.5]
|
|
||||||
PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[dp]
|
|
||||||
C[Game-info:
|
|
||||||
Black: B. Lack, 5d
|
|
||||||
White: W. Hite, 6d
|
|
||||||
Place: London
|
|
||||||
Event: Go Congress
|
|
||||||
Round: 2
|
|
||||||
Result: White wins by 3.5])
|
|
||||||
(;PW[T. Suji]WR[7d]RO[1]RE[W+Resign]
|
|
||||||
PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[cp]
|
|
||||||
C[Game-info:
|
|
||||||
Black: B. Lack, 5d
|
|
||||||
White: T. Suji, 7d
|
|
||||||
Place: London
|
|
||||||
Event: Go Congress
|
|
||||||
Round: 1
|
|
||||||
Result: White wins by resignation])
|
|
||||||
(;W[ep];B[pp]
|
|
||||||
(;PW[S. Abaki]WR[1d]RO[3]RE[B+63.5]
|
|
||||||
PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[ed]
|
|
||||||
C[Game-info:
|
|
||||||
Black: B. Lack, 5d
|
|
||||||
White: S. Abaki, 1d
|
|
||||||
Place: London
|
|
||||||
Event: Go Congress
|
|
||||||
Round: 3
|
|
||||||
Result: Balck wins by 63.5])
|
|
||||||
(;PW[A. Tari]WR[12k]KM[-59.5]RO[4]RE[B+R]
|
|
||||||
PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[cd]
|
|
||||||
C[Game-info:
|
|
||||||
Black: B. Lack, 5d
|
|
||||||
White: A. Tari, 12k
|
|
||||||
Place: London
|
|
||||||
Event: Go Congress
|
|
||||||
Round: 4
|
|
||||||
Komi: -59.5 points
|
|
||||||
Result: Black wins by resignation])
|
|
||||||
))
|
|
||||||
|
|
|
@ -1,165 +0,0 @@
|
||||||
(;FF[4]AP[Primiview:3.1]GM[1]SZ[19]GN[Gametree 1: properties]US[Arno Hollosi]
|
|
||||||
|
|
||||||
(;B[pd]N[Moves, comments, annotations]
|
|
||||||
C[Nodename set to: "Moves, comments, annotations"];W[dp]GW[1]
|
|
||||||
C[Marked as "Good for White"];B[pp]GB[2]
|
|
||||||
C[Marked as "Very good for Black"];W[dc]GW[2]
|
|
||||||
C[Marked as "Very good for White"];B[pj]DM[1]
|
|
||||||
C[Marked as "Even position"];W[ci]UC[1]
|
|
||||||
C[Marked as "Unclear position"];B[jd]TE[1]
|
|
||||||
C[Marked as "Tesuji" or "Good move"];W[jp]BM[2]
|
|
||||||
C[Marked as "Very bad move"];B[gd]DO[]
|
|
||||||
C[Marked as "Doubtful move"];W[de]IT[]
|
|
||||||
C[Marked as "Interesting move"];B[jj];
|
|
||||||
C[White "Pass" move]W[];
|
|
||||||
C[Black "Pass" move]B[tt])
|
|
||||||
|
|
||||||
(;AB[dd][de][df][dg][do:gq]
|
|
||||||
AW[jd][je][jf][jg][kn:lq][pn:pq]
|
|
||||||
N[Setup]C[Black & white stones at the top are added as single stones.
|
|
||||||
|
|
||||||
Black & white stones at the bottom are added using compressed point lists.]
|
|
||||||
;AE[ep][fp][kn][lo][lq][pn:pq]
|
|
||||||
C[AddEmpty
|
|
||||||
|
|
||||||
Black stones & stones of left white group are erased in FF[3\] way.
|
|
||||||
|
|
||||||
White stones at bottom right were erased using compressed point list.]
|
|
||||||
;AB[pd]AW[pp]PL[B]C[Added two stones.
|
|
||||||
|
|
||||||
Node marked with "Black to play".];PL[W]
|
|
||||||
C[Node marked with "White to play"])
|
|
||||||
|
|
||||||
(;AB[dd][de][df][dg][dh][di][dj][nj][ni][nh][nf][ne][nd][ij][ii][ih][hq]
|
|
||||||
[gq][fq][eq][dr][ds][dq][dp][cp][bp][ap][iq][ir][is][bo][bn][an][ms][mr]
|
|
||||||
AW[pd][pe][pf][pg][ph][pi][pj][fd][fe][ff][fh][fi][fj][kh][ki][kj][os][or]
|
|
||||||
[oq][op][pp][qp][rp][sp][ro][rn][sn][nq][mq][lq][kq][kr][ks][fs][gs][gr]
|
|
||||||
[er]N[Markup]C[Position set up without compressed point lists.]
|
|
||||||
|
|
||||||
;TR[dd][de][df][ed][ee][ef][fd:ff]
|
|
||||||
MA[dh][di][dj][ej][ei][eh][fh:fj]
|
|
||||||
CR[nd][ne][nf][od][oe][of][pd:pf]
|
|
||||||
SQ[nh][ni][nj][oh][oi][oj][ph:pj]
|
|
||||||
SL[ih][ii][ij][jj][ji][jh][kh:kj]
|
|
||||||
TW[pq:ss][so][lr:ns]
|
|
||||||
TB[aq:cs][er:hs][ao]
|
|
||||||
C[Markup at top partially using compressed point lists (for markup on white stones); listed clockwise, starting at upper left:
|
|
||||||
- TR (triangle)
|
|
||||||
- CR (circle)
|
|
||||||
- SQ (square)
|
|
||||||
- SL (selected points)
|
|
||||||
- MA ('X')
|
|
||||||
|
|
||||||
Markup at bottom: black & white territory (using compressed point lists)]
|
|
||||||
;LB[dc:1][fc:2][nc:3][pc:4][dj:a][fj:b][nj:c]
|
|
||||||
[pj:d][gs:ABCDEFGH][gr:ABCDEFG][gq:ABCDEF][gp:ABCDE][go:ABCD][gn:ABC][gm:AB]
|
|
||||||
[mm:12][mn:123][mo:1234][mp:12345][mq:123456][mr:1234567][ms:12345678]
|
|
||||||
C[Label (LB property)
|
|
||||||
|
|
||||||
Top: 8 single char labels (1-4, a-d)
|
|
||||||
|
|
||||||
Bottom: Labels up to 8 char length.]
|
|
||||||
|
|
||||||
;DD[kq:os][dq:hs]
|
|
||||||
AR[aa:sc][sa:ac][aa:sa][aa:ac][cd:cj]
|
|
||||||
[gd:md][fh:ij][kj:nh]
|
|
||||||
LN[pj:pd][nf:ff][ih:fj][kh:nj]
|
|
||||||
C[Arrows, lines and dimmed points.])
|
|
||||||
|
|
||||||
(;B[qd]N[Style & text type]
|
|
||||||
C[There are hard linebreaks & soft linebreaks.
|
|
||||||
Soft linebreaks are linebreaks preceeded by '\\' like this one >o\
|
|
||||||
k<. Hard line breaks are all other linebreaks.
|
|
||||||
Soft linebreaks are converted to >nothing<, i.e. removed.
|
|
||||||
|
|
||||||
Note that linebreaks are coded differently on different systems.
|
|
||||||
|
|
||||||
Examples (>ok< shouldn't be split):
|
|
||||||
|
|
||||||
linebreak 1 "\\n": >o\
|
|
||||||
k<
|
|
||||||
linebreak 2 "\\n\\r": >o\
|
|
||||||
k<
|
|
||||||
linebreak 3 "\\r\\n": >o\
|
|
||||||
k<
|
|
||||||
linebreak 4 "\\r": >o\
k<]
|
|
||||||
|
|
||||||
(;W[dd]N[W d16]C[Variation C is better.](;B[pp]N[B q4])
|
|
||||||
(;B[dp]N[B d4])
|
|
||||||
(;B[pq]N[B q3])
|
|
||||||
(;B[oq]N[B p3])
|
|
||||||
)
|
|
||||||
(;W[dp]N[W d4])
|
|
||||||
(;W[pp]N[W q4])
|
|
||||||
(;W[cc]N[W c17])
|
|
||||||
(;W[cq]N[W c3])
|
|
||||||
(;W[qq]N[W r3])
|
|
||||||
)
|
|
||||||
|
|
||||||
(;B[qr]N[Time limits, captures & move numbers]
|
|
||||||
BL[120.0]C[Black time left: 120 sec];W[rr]
|
|
||||||
WL[300]C[White time left: 300 sec];B[rq]
|
|
||||||
BL[105.6]OB[10]C[Black time left: 105.6 sec
|
|
||||||
Black stones left (in this byo-yomi period): 10];W[qq]
|
|
||||||
WL[200]OW[2]C[White time left: 200 sec
|
|
||||||
White stones left: 2];B[sr]
|
|
||||||
BL[87.00]OB[9]C[Black time left: 87 sec
|
|
||||||
Black stones left: 9];W[qs]
|
|
||||||
WL[13.20]OW[1]C[White time left: 13.2 sec
|
|
||||||
White stones left: 1];B[rs]
|
|
||||||
C[One white stone at s2 captured];W[ps];B[pr];W[or]
|
|
||||||
MN[2]C[Set move number to 2];B[os]
|
|
||||||
C[Two white stones captured
|
|
||||||
(at q1 & r1)]
|
|
||||||
;MN[112]W[pq]C[Set move number to 112];B[sq];W[rp];B[ps]
|
|
||||||
;W[ns];B[ss];W[nr]
|
|
||||||
;B[rr];W[sp];B[qs]C[Suicide move
|
|
||||||
(all B stones get captured)])
|
|
||||||
)
|
|
||||||
|
|
||||||
(;FF[4]AP[Primiview:3.1]GM[1]SZ[19]C[Gametree 2: game-info
|
|
||||||
|
|
||||||
Game-info properties are usually stored in the root node.
|
|
||||||
If games are merged into a single game-tree, they are stored in the node\
|
|
||||||
where the game first becomes distinguishable from all other games in\
|
|
||||||
the tree.]
|
|
||||||
;B[pd]
|
|
||||||
(;PW[W. Hite]WR[6d]RO[2]RE[W+3.5]
|
|
||||||
PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[dp]
|
|
||||||
C[Game-info:
|
|
||||||
Black: B. Lack, 5d
|
|
||||||
White: W. Hite, 6d
|
|
||||||
Place: London
|
|
||||||
Event: Go Congress
|
|
||||||
Round: 2
|
|
||||||
Result: White wins by 3.5])
|
|
||||||
(;PW[T. Suji]WR[7d]RO[1]RE[W+Resign]
|
|
||||||
PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[cp]
|
|
||||||
C[Game-info:
|
|
||||||
Black: B. Lack, 5d
|
|
||||||
White: T. Suji, 7d
|
|
||||||
Place: London
|
|
||||||
Event: Go Congress
|
|
||||||
Round: 1
|
|
||||||
Result: White wins by resignation])
|
|
||||||
(;W[ep];B[pp]
|
|
||||||
(;PW[S. Abaki]WR[1d]RO[3]RE[B+63.5]
|
|
||||||
PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[ed]
|
|
||||||
C[Game-info:
|
|
||||||
Black: B. Lack, 5d
|
|
||||||
White: S. Abaki, 1d
|
|
||||||
Place: London
|
|
||||||
Event: Go Congress
|
|
||||||
Round: 3
|
|
||||||
Result: Balck wins by 63.5])
|
|
||||||
(;PW[A. Tari]WR[12k]KM[-59.5]RO[4]RE[B+R]
|
|
||||||
PB[B. Lack]BR[5d]PC[London]EV[Go Congress]W[cd]
|
|
||||||
C[Game-info:
|
|
||||||
Black: B. Lack, 5d
|
|
||||||
White: A. Tari, 12k
|
|
||||||
Place: London
|
|
||||||
Event: Go Congress
|
|
||||||
Round: 4
|
|
||||||
Komi: -59.5 points
|
|
||||||
Result: Black wins by resignation])
|
|
||||||
))
|
|
|
@ -1,18 +0,0 @@
|
||||||
(;FF[4]AP[Primiview:3.1]GM[1]SZ[19]GN[Gametree 1: properties]US[Arno Hollosi]
|
|
||||||
C[There are hard linebreaks & soft linebreaks.
|
|
||||||
Soft linebreaks are linebreaks preceeded by '\\' like this one >o\
|
|
||||||
k<. Hard line breaks are all other linebreaks.
|
|
||||||
Soft linebreaks are converted to >nothing<, i.e. removed.
|
|
||||||
|
|
||||||
Note that linebreaks are coded differently on different systems.
|
|
||||||
|
|
||||||
Examples (>ok< shouldn't be split):
|
|
||||||
|
|
||||||
linebreak 1 "\\n": >o\
|
|
||||||
k<
|
|
||||||
linebreak 2 "\\n\\r": >o\
|
|
||||||
k<
|
|
||||||
linebreak 3 "\\r\\n": >o\
|
|
||||||
k<
|
|
||||||
linebreak 4 "\\r": >o\
k<]
|
|
||||||
)
|
|
|
@ -1,35 +0,0 @@
|
||||||
(;FF[4]GM[1]SZ[19]FG[257:Figure 1]PM[1]
|
|
||||||
PB[Takemiya Masaki]BR[9 dan]PW[Cho Chikun]
|
|
||||||
WR[9 dan]RE[W+Resign]KM[5.5]TM[28800]DT[1996-10-18,19]
|
|
||||||
EV[21st Meijin]RO[2 (final)]SO[Go World #78]US[Arno Hollosi]
|
|
||||||
;B[pd];W[dp];B[pp];W[dd];B[pj];W[nc];B[oe];W[qc];B[pc];W[qd]
|
|
||||||
(;B[qf];W[rf];B[rg];W[re];B[qg];W[pb];B[ob];W[qb]
|
|
||||||
(;B[mp];W[fq];B[ci];W[cg];B[dl];W[cn];B[qo];W[ec];B[jp];W[jd]
|
|
||||||
;B[ei];W[eg];B[kk]LB[qq:a][dj:b][ck:c][qp:d]N[Figure 1]
|
|
||||||
|
|
||||||
;W[me]FG[257:Figure 2];B[kf];W[ke];B[lf];W[jf];B[jg]
|
|
||||||
(;W[mf];B[if];W[je];B[ig];W[mg];B[mj];W[mq];B[lq];W[nq]
|
|
||||||
(;B[lr];W[qq];B[pq];W[pr];B[rq];W[rr];B[rp];W[oq];B[mr];W[oo];B[mn]
|
|
||||||
(;W[nr];B[qp]LB[kd:a][kh:b]N[Figure 2]
|
|
||||||
|
|
||||||
;W[pk]FG[257:Figure 3];B[pm];W[oj];B[ok];W[qr];B[os];W[ol];B[nk];W[qj]
|
|
||||||
;B[pi];W[pl];B[qm];W[ns];B[sr];W[om];B[op];W[qi];B[oi]
|
|
||||||
(;W[rl];B[qh];W[rm];B[rn];W[ri];B[ql];W[qk];B[sm];W[sk];B[sh];W[og]
|
|
||||||
;B[oh];W[np];B[no];W[mm];B[nn];W[lp];B[kp];W[lo];B[ln];W[ko];B[mo]
|
|
||||||
;W[jo];B[km]N[Figure 3])
|
|
||||||
|
|
||||||
(;W[ql]VW[ja:ss]FG[257:Dia. 6]MN[1];B[rm];W[ph];B[oh];W[pg];B[og];W[pf]
|
|
||||||
;B[qh];W[qe];B[sh];W[of];B[sj]TR[oe][pd][pc][ob]LB[pe:a][sg:b][si:c]
|
|
||||||
N[Diagram 6]))
|
|
||||||
|
|
||||||
(;W[no]VW[jj:ss]FG[257:Dia. 5]MN[1];B[pn]N[Diagram 5]))
|
|
||||||
|
|
||||||
(;B[pr]FG[257:Dia. 4]MN[1];W[kq];B[lp];W[lr];B[jq];W[jr];B[kp];W[kr];B[ir]
|
|
||||||
;W[hr]LB[is:a][js:b][or:c]N[Diagram 4]))
|
|
||||||
|
|
||||||
(;W[if]FG[257:Dia. 3]MN[1];B[mf];W[ig];B[jh]LB[ki:a]N[Diagram 3]))
|
|
||||||
|
|
||||||
(;W[oc]VW[aa:sk]FG[257:Dia. 2]MN[1];B[md];W[mc];B[ld]N[Diagram 2]))
|
|
||||||
|
|
||||||
(;B[qe]VW[aa:sj]FG[257:Dia. 1]MN[1];W[re];B[qf];W[rf];B[qg];W[pb];B[ob]
|
|
||||||
;W[qb]LB[rg:a]N[Diagram 1]))
|
|
|
@ -1,50 +0,0 @@
|
||||||
(;FF[4]GM[1]SZ[19]FG[257:Figure 1]PM[2]
|
|
||||||
PB[Cho Chikun]BR[9 dan]PW[Ryu Shikun]WR[9 dan]RE[W+2.5]KM[5.5]
|
|
||||||
DT[1996-08]EV[51st Honinbo]RO[5 (final)]SO[Go World #78]US[Arno Hollosi]
|
|
||||||
;B[qd];W[dd];B[fc];W[df];B[pp];W[dq];B[kc];W[cn];B[pj];W[jp];B[lq];W[oe]
|
|
||||||
;B[pf];W[ke];B[id];W[lc];B[lb];W[kb];B[jb];W[kd];B[ka];W[jc];B[ic];W[kb]
|
|
||||||
;B[mc];W[qc]N[Figure 1]
|
|
||||||
|
|
||||||
;B[pd]FG[257:Figure 2];W[pc];B[od];W[oc];B[kc];W[nd];B[nc];W[kb];B[rd];W[pe]
|
|
||||||
(;B[rf];W[md];B[kc];W[qe];B[re];W[kb];B[mb];W[qf];B[qg];W[pg];B[qh];W[kc]
|
|
||||||
;B[hb];W[nf];B[ch];W[cj];B[eh];W[ob]
|
|
||||||
(;B[cc];W[dc];B[db];W[bf];B[bb]
|
|
||||||
;W[bh]LB[of:a][mf:b][rc:c][di:d][ja:e]N[Figure 2]
|
|
||||||
|
|
||||||
;B[qp]FG[257:Figure 3];W[lo];B[ej];W[oq]
|
|
||||||
(;B[np];W[mq];B[mp];W[lp]
|
|
||||||
(;B[kq];W[nq];B[op];W[jq];B[mr];W[nr];B[lr];W[qr];B[jr];W[ir];B[hr];W[iq]
|
|
||||||
;B[is];W[ks];B[js];W[gq];B[gr];W[fq];B[pq];W[pr];B[ns];W[or];B[rq];W[hq]
|
|
||||||
;B[rr];W[cl];B[cg];W[bg];B[og];W[ng]
|
|
||||||
(;B[ci];W[bi];B[dj];W[dk];B[mm];W[gk];B[gi];W[mn];B[nm];W[kl];B[nh];W[mh]
|
|
||||||
;B[mi];W[li];B[lh];W[mg];B[ek];W[el];B[ik]LB[kr:a]N[Figure 3]
|
|
||||||
|
|
||||||
;W[ki]FG[257:Figure 4];B[fl];W[fk];B[gl];W[hk];B[hl];W[hj];B[jl];W[kk];B[km]
|
|
||||||
;W[lm];B[ll];W[jm];B[jj];W[ji];B[kj];W[lj];B[ij];W[hi];B[em];W[dl];B[ii]
|
|
||||||
;W[hh];B[ih];W[hg];B[ln];W[kn];B[lm];W[im];B[il];W[fg];B[lk];W[ni];B[ef]
|
|
||||||
;W[eg];B[dg];W[ff];B[oh];W[of];B[oj];W[ph];B[oi];W[mj];B[ee];W[fe];B[de]
|
|
||||||
;W[ed];B[ce];W[cf];B[rb];W[rc];B[sc];W[qb];B[sb];W[la];B[ma];W[na];B[ja]
|
|
||||||
;W[nb];B[la];W[pa];B[be];W[fd];B[bj];W[ck];B[ec];W[hs];B[gs];W[fr];B[os]
|
|
||||||
;W[ps];B[ms];W[nk];B[ok];W[kp];B[fo];W[fs];B[qq];W[hs];B[do];W[co];B[ig]
|
|
||||||
;W[gc];B[gb];W[jf];B[di];W[fi];B[hf];W[gf];B[af];W[mo];B[he];W[kr];B[qs]
|
|
||||||
;W[no];B[oo];W[nn];B[on];W[nl];B[ol];W[gn];B[fn];W[in];B[nj];W[mk];B[jg]
|
|
||||||
;W[kg];B[mi];W[jh];B[ag];W[bk];B[ah];W[aj];B[fh];W[fj];B[gd];W[ra];B[dp]
|
|
||||||
;W[cp];B[go];W[gm];B[fm];W[sd];B[se];W[ho];B[hm];W[hn];B[ep];W[eq];B[cd]
|
|
||||||
;W[ei];B[dn];W[gp];B[pi];W[pf];B[dm];W[cm];B[je];W[jd];B[if];W[ie];B[ko]
|
|
||||||
;W[jo];B[je];W[kf];B[ni];W[dh];B[ge];W[ie];B[rg];W[je]N[Figure 4])
|
|
||||||
|
|
||||||
(;B[dk]FG[257:Dia. 6]MN[1];W[ck];B[gk]N[Diagram 6]))
|
|
||||||
|
|
||||||
(;B[nq]VW[ai:ss]FG[257:Dia. 5]MN[1];W[mr];B[nr];W[lr]TR[oq]N[Diagram 5]))
|
|
||||||
|
|
||||||
(;B[mp]VW[ai:ss]FG[257:Dia. 4]MN[1];W[op];B[oo];W[no];B[mo];W[on];B[po]
|
|
||||||
;W[mn];B[np];W[nn];B[or]N[Diagram 4]))
|
|
||||||
|
|
||||||
(;B[rc]VW[aa:sj]FG[257:Dia. 2]MN[1];W[rb];B[sb];W[la];B[ma];W[na];B[ja]
|
|
||||||
;W[pa]N[Diagram 2])
|
|
||||||
|
|
||||||
(;B[rb]VW[aa:sj]FG[257:Dia. 3]MN[1];W[rc];B[sc];W[qb];B[pa];W[sb];B[sa]
|
|
||||||
;W[sd];B[qa]N[Diagram 3]))
|
|
||||||
|
|
||||||
(;B[qf]VW[aa:sj]FG[257:Dia. 1]MN[1];W[mb];B[kc];W[qe];B[ne];W[kb];B[md]
|
|
||||||
;W[la];B[nb];W[eb]LB[ob:a][na:b][rc:c][sd:d]N[Diagram 1]))
|
|
|
@ -45,8 +45,6 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
|
||||||
"time",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
@ -61,15 +59,6 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cool_asserts"
|
|
||||||
version = "2.0.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ee9f254e53f61e2688d3677fa2cbe4e9b950afd56f48819c98817417cf6b28ec"
|
|
||||||
dependencies = [
|
|
||||||
"indent_write",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation-sys"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
|
@ -120,17 +109,6 @@ dependencies = [
|
||||||
"syn 2.0.12",
|
"syn 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "go-sgf"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"nom",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"typeshare",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grid"
|
name = "grid"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -164,12 +142,6 @@ dependencies = [
|
||||||
"cxx-build",
|
"cxx-build",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "indent_write"
|
|
||||||
version = "2.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0cfe9645a18782869361d9c8732246be7b410ad4e919d3609ebabdac00ba12c3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
|
@ -189,9 +161,6 @@ dependencies = [
|
||||||
name = "kifu-core"
|
name = "kifu-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
|
||||||
"cool_asserts",
|
|
||||||
"go-sgf",
|
|
||||||
"grid",
|
"grid",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -223,34 +192,12 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "no-std-compat"
|
name = "no-std-compat"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.45"
|
version = "0.1.45"
|
||||||
|
@ -388,17 +335,6 @@ dependencies = [
|
||||||
"syn 2.0.12",
|
"syn 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "time"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"wasi",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typeshare"
|
name = "typeshare"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -433,12 +369,6 @@ version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.10.0+wasi-snapshot-preview1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.84"
|
version = "0.2.84"
|
||||||
|
|
|
@ -6,13 +6,8 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = { version = "0.4" }
|
|
||||||
go-sgf = { path = "../../go-sgf" }
|
|
||||||
grid = { version = "0.9" }
|
grid = { version = "0.9" }
|
||||||
serde_json = { version = "1" }
|
|
||||||
serde = { version = "1", features = [ "derive" ] }
|
serde = { version = "1", features = [ "derive" ] }
|
||||||
|
serde_json = { version = "1" }
|
||||||
thiserror = { version = "1" }
|
thiserror = { version = "1" }
|
||||||
typeshare = { version = "1" }
|
typeshare = { version = "1" }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
cool_asserts = { version = "2" }
|
|
||||||
|
|
|
@ -1,432 +0,0 @@
|
||||||
(;FF[4]
|
|
||||||
CA[UTF-8]
|
|
||||||
GM[1]
|
|
||||||
GN[2019 Masters R7 B1]
|
|
||||||
PC[https://online-go.com/review/404377]
|
|
||||||
PB[Zhongfan Jian]
|
|
||||||
PW[Mark Lee]
|
|
||||||
BR[7d]
|
|
||||||
WR[7d]
|
|
||||||
TM[0]OT[0 none]
|
|
||||||
RE[B+R]
|
|
||||||
SZ[19]
|
|
||||||
KM[7.5]
|
|
||||||
RU[AGA]
|
|
||||||
C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
krnzmb: hi
|
|
||||||
FrostedNuke: hi
|
|
||||||
USGO1: Hello! As most of you know, this is the final round of the US Open Master's division at the US Go Congress between Mark Lee 7d (w) and Zhongfan Jian 7d (b)
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[dp]
|
|
||||||
;W[pp]
|
|
||||||
;B[dd]
|
|
||||||
;W[pd]
|
|
||||||
;B[nc]
|
|
||||||
;W[fc]
|
|
||||||
;B[hc]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
snakesss: h16
|
|
||||||
BHydden: close
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[cc]
|
|
||||||
;B[dc]
|
|
||||||
;W[cd]
|
|
||||||
;B[de]
|
|
||||||
;W[db]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hardstone: Mark Lee is B?
|
|
||||||
hardstone: ok, W
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[eb]
|
|
||||||
;W[cb]
|
|
||||||
;B[fb]
|
|
||||||
;W[cf]
|
|
||||||
;B[qf]
|
|
||||||
;W[pf]
|
|
||||||
;B[pg]
|
|
||||||
;W[of]
|
|
||||||
;B[qd]
|
|
||||||
;W[qc]
|
|
||||||
;B[qe]
|
|
||||||
;W[pb]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
MeiGuoTang: crosstabs
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[og]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
MeiGuoTang: please
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[md]
|
|
||||||
;B[qn]
|
|
||||||
;W[jc]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
shipshape: https://www.usgo.org/tournaments/crosstab/band-matrix/187
|
|
||||||
snakesss: lol he played the only move i just checked on my bot and saw was a bad one
|
|
||||||
snakesss: feels good to have the same bad instinct as a pro
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[nq]
|
|
||||||
;W[pn]
|
|
||||||
;B[pm]
|
|
||||||
;W[on]
|
|
||||||
;B[qp]
|
|
||||||
;W[gc]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: tenuki from the lower right is very interesting
|
|
||||||
snakesss: "interesting" like "haylee
|
|
||||||
snakesss: 's interestings"?
|
|
||||||
redreoicy: First guess is to make a ladder breaker to play r7
|
|
||||||
Cyanriddle: h16 would be simple
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[gd]
|
|
||||||
;W[fd]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: so black resists the ladder
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[gb]
|
|
||||||
;W[hd]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
redreoicy: but, i thought white's intention was to follow up a few more moves than just g17 before playing r7
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[id]
|
|
||||||
;W[ge]
|
|
||||||
;B[ic]
|
|
||||||
;W[qm]
|
|
||||||
;B[qo]
|
|
||||||
;W[pl]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
redreoicy: ok g15 makes a lot more sense
|
|
||||||
USGO1: Sorry about that, table shook a bit as I placed G15
|
|
||||||
BHydden: if you're the pedantic type, you can click onto the wrong move 40 and then click the trashcan :)
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[hf]
|
|
||||||
;W[om]
|
|
||||||
;B[df]
|
|
||||||
;W[cg]
|
|
||||||
;B[fg]
|
|
||||||
;W[oq]
|
|
||||||
;B[qr]
|
|
||||||
;W[pr]
|
|
||||||
;B[fq]
|
|
||||||
;W[pe]
|
|
||||||
;B[qi]
|
|
||||||
;W[ie]
|
|
||||||
;B[jd]
|
|
||||||
;W[he]
|
|
||||||
;B[mc]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO1: Zhongfan put that one down with no small amount of vigor
|
|
||||||
BHydden: this area is mine, don't at me
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[hg]
|
|
||||||
;B[oc]
|
|
||||||
;W[pc]
|
|
||||||
;B[ld]
|
|
||||||
;W[if]
|
|
||||||
;B[jp]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: white upper right right not having local live has got to feel annoying for white
|
|
||||||
BHydden: eh, he tenukid from an approach... it's to be expected, right?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[bp]
|
|
||||||
;B[cp]
|
|
||||||
;W[bo]
|
|
||||||
;B[bq]
|
|
||||||
;W[br]
|
|
||||||
;B[cq]
|
|
||||||
;W[cl]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: it used to be okay,but black got to dig out the top area while white had to defend the center group
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[dk]
|
|
||||||
;W[ck]
|
|
||||||
;B[dj]
|
|
||||||
;W[dn]
|
|
||||||
;B[cn]
|
|
||||||
;W[bn]
|
|
||||||
;B[dg]
|
|
||||||
;W[ho]
|
|
||||||
;B[iq]
|
|
||||||
;W[dh]
|
|
||||||
;B[ch]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
BHydden: quiet in here
|
|
||||||
hexahedron: friday night, not surprising :)
|
|
||||||
BHydden: final round of USGC, who could have more important plans than this? :D
|
|
||||||
USGO1: I agree with BHydden:)
|
|
||||||
BHydden: ;)
|
|
||||||
USGO1: Mark has used more than half his time, now being at 42 minutes
|
|
||||||
xed_over: on this one move? :)
|
|
||||||
hexahedron: maybe white didn't expect this move by black
|
|
||||||
USGO1: I'm not sure about Zhongfan's time left, but he IS 2/3 of the way through a starbucks
|
|
||||||
USGO1: I'm now told by our fearless recording leader that Black has an hour and ten minutes left
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ei]
|
|
||||||
;B[bh]
|
|
||||||
;W[ce]
|
|
||||||
;B[fj]
|
|
||||||
;W[ej]
|
|
||||||
;B[ek]
|
|
||||||
;W[fi]
|
|
||||||
;B[di]
|
|
||||||
;W[eh]
|
|
||||||
;B[gi]
|
|
||||||
;W[gj]
|
|
||||||
;B[fk]
|
|
||||||
;W[gh]
|
|
||||||
;B[hi]
|
|
||||||
;W[fh]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
樱桃花: what's popping
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[bj]
|
|
||||||
;W[co]
|
|
||||||
;B[ec]
|
|
||||||
;W[hj]
|
|
||||||
;B[fn]
|
|
||||||
;W[aq]
|
|
||||||
;B[cr]
|
|
||||||
;W[bk]
|
|
||||||
;B[ii]
|
|
||||||
;W[ij]
|
|
||||||
;B[ji]
|
|
||||||
;W[jj]
|
|
||||||
;B[ki]
|
|
||||||
;W[eg]
|
|
||||||
;B[kj]
|
|
||||||
;W[hl]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: what did it say the % was at move 114?
|
|
||||||
hexahedron: around 95% for black
|
|
||||||
Falchion: wow, already that bad
|
|
||||||
hexahedron: keep in mind not to trust all these percents too much, we've seen in plenty of games at this tournament that it can swing quite a bit
|
|
||||||
hexahedron: bot is assuming superhuman-level tactics, in a sharp position it's very possible for one mistake to swing it all the way back to even
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[dm]
|
|
||||||
;W[cm]
|
|
||||||
;B[jl]
|
|
||||||
;W[jm]
|
|
||||||
;B[km]
|
|
||||||
;W[jn]
|
|
||||||
;B[kn]
|
|
||||||
;W[il]
|
|
||||||
;B[jk]
|
|
||||||
;W[kl]
|
|
||||||
;B[kk]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: last few moves feel good for B
|
|
||||||
hexahedron: KG says 97% for B (white lives in the middle, but black got a lot of profit
|
|
||||||
hexahedron: )
|
|
||||||
hexahedron: and connects his own group on the left in the process
|
|
||||||
hexahedron: we'll see what happens though, the tactics are so complicated
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[gn]
|
|
||||||
;B[en]
|
|
||||||
;W[dl]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: B would have to mess up pretty badly to throw such an advantage away though
|
|
||||||
hexahedron: after the last 3 moves KG is thinking the white group in the middle dies now
|
|
||||||
Falchion: ouch, that's even worse
|
|
||||||
hexahedron: it's not entirely confident though, territory map shows it as all blackish, but not completely
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[fm]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Zhadow: what is KG?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[jo]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: bot that is around LZ-ELFv2 strength, but with score estimation and territory prediction
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[ko]
|
|
||||||
;W[hq]
|
|
||||||
;B[in]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: oooh black's going for the kill!
|
|
||||||
Falchion: J5 here?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[io]
|
|
||||||
;B[gq]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: G3 nice
|
|
||||||
Falchion: J4 now maybe?
|
|
||||||
hexahedron: no, J4 makes no eyeshape
|
|
||||||
hexahedron: all it would do is strengthen black and immediately kill any hope of black messing up
|
|
||||||
hexahedron: (the only point that J4 could help turn into an eye is H4, but notice how G3 and J3 already make H4 false)
|
|
||||||
hexahedron: do you see?
|
|
||||||
hexahedron: right, and that would help black
|
|
||||||
hexahedron: there's no ko
|
|
||||||
hexahedron: the only bit that remains not entirely clear to my lowly amateur reading is the L4 cut aji
|
|
||||||
hexahedron: but maybe I"m also missing some other variations
|
|
||||||
USGO1: The clock now tells us that Mark has only 10 minutes of main time remaining
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;W[fo]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: G5 then?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;W[ip]
|
|
||||||
;B[jq]
|
|
||||||
;W[gr]
|
|
||||||
;B[hr]
|
|
||||||
;W[ir]
|
|
||||||
;B[hp]
|
|
||||||
;W[hs]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: J4 would make B play at K3 probably?
|
|
||||||
Falchion: maybe it sets up a ko
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;W[gp]
|
|
||||||
;B[fp]
|
|
||||||
;W[kp]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: hey, he played your L4 cut
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[lp]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: ooh maybe white does have something
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[kq]
|
|
||||||
;B[lq]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: hm, not sure it works tho
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[kr]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO1: Mark kept his finger on that stone for a long while before releaing and pressing the clock
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[hr]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO1: Zhongfan is now down to an eighth of his coffee
|
|
||||||
dy_baduk: hmmr
|
|
||||||
dy_baduk: j2 might actually be reasonable
|
|
||||||
hexahedron: ko?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ir]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: nice dy
|
|
||||||
hexahedron: I guess there might be a ko after all :)
|
|
||||||
Falchion: I think you found it
|
|
||||||
dy_baduk: lol
|
|
||||||
dy_baduk: it's cause I do a shit ton of tsumego
|
|
||||||
Falchion: wait, what about K2 next, does W still die?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;B[jq]
|
|
||||||
;W[ip]
|
|
||||||
;B[hp]
|
|
||||||
;W[fl]
|
|
||||||
;B[go]C[B+r
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: board is different tho
|
|
||||||
USGO1: W resigns
|
|
||||||
Falchion: ouch
|
|
||||||
hexahedron: congrats to black (zhongfan)
|
|
||||||
hexahedron: really nice play at the end
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;B[jr]
|
|
||||||
;W[ip]
|
|
||||||
;B[is]
|
|
||||||
;W[jq]
|
|
||||||
;B[ir]
|
|
||||||
;W[lr]
|
|
||||||
;B[mr]
|
|
||||||
;W[lo]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
hexahedron: @Falchion - something like this. From move 0: D4 Q4 D16 Q16 O17 F17 H17 C17 D17 C16 D15 D18 E18 C18 F18 C14 R14 Q14 Q13 P14 R16 R17 R15 Q18 P13 N16 R6 K17 O3 Q6 Q7 P6 R4 G17 G16 F16 G18 H16 J16 G15 J17 R7 R5 Q8 H14 P7 D14 C13 F13 P3 R2 Q2 F3 Q15 R11 J15 K16 H15 N17 H13 P17 Q17 M16 J14 K4 B4 C4 B5 B3 B2 C3 C8 D9 C9 D10 D6 C6 B6 D13 H5 J3 D12 C12 E11 B12 C15 F10 E10 E9 F11 D11 E12 G11 G10 F9 G12 H11 F12 B10 C5 E17 H10 F6 A3 C2 B9 J11 J10 K11 K10 L11 E13 L10 H8 D7 C7 K8 K7 L7 K6 L6 J8 K9 L8 L9 G6 E6 D8 F7 K5 L5 H3 J6 J5 G3 G4 F4 L4 M4 L3 M3 L2 H2 J2 K2 J4 J1 K3 J2 M2 N2 M5
|
|
||||||
Falchion: yeah
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)))
|
|
|
@ -1,499 +0,0 @@
|
||||||
(;FF[4]
|
|
||||||
CA[UTF-8]
|
|
||||||
GM[1]
|
|
||||||
GN[2019 Masters R7 B2]
|
|
||||||
PC[https://online-go.com/review/404376]
|
|
||||||
PB[Eric Lui]
|
|
||||||
PW[Nyu Eiko]
|
|
||||||
BR[1p]
|
|
||||||
WR[2p]
|
|
||||||
TM[0]OT[0 none]
|
|
||||||
RE[W+r]
|
|
||||||
SZ[19]
|
|
||||||
KM[7.5]
|
|
||||||
RU[AGA]
|
|
||||||
C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
dogbert: when will the game start?
|
|
||||||
USGO2: in approximately 15 minutes
|
|
||||||
USGO2: After the ceremonies the game should begin any minute now
|
|
||||||
USGO2: Putting phones into the designated bins
|
|
||||||
USGO2: TD Josh Lee yells out "2 minutes"
|
|
||||||
USGO2: Both players have sat, game should begin soon
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[pd]
|
|
||||||
;W[dd]
|
|
||||||
;B[pq]
|
|
||||||
;W[dp]
|
|
||||||
;B[qk]
|
|
||||||
;W[nc]
|
|
||||||
;B[pf]
|
|
||||||
;W[qc]
|
|
||||||
;B[pc]
|
|
||||||
;W[pb]
|
|
||||||
;B[qd]
|
|
||||||
;W[rb]
|
|
||||||
;B[rc]
|
|
||||||
;W[qb]
|
|
||||||
;B[fq]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
BHydden: wow lightning opening
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[cn]
|
|
||||||
;B[lp]
|
|
||||||
;W[hq]
|
|
||||||
;B[fo]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
mark5000: This is a traditional and well-studied opening pattern, if you excuse the 2016-era joseki in the upper left.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[jp]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
BHydden: looks at upper left... sees lonely isolated 4-4 stone... yes, such joseki o.o
|
|
||||||
mark5000: Ha, which one is left again? ;)
|
|
||||||
mark5000: It's been a long day.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[dm]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
BHydden: if you hold up both your hands, the left one can make an L between index and thumb with palm facing away from you ;)
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[dn]
|
|
||||||
;B[em]
|
|
||||||
;W[en]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
pyv: I thought you were referring to the fact that noone went 3-3 yet
|
|
||||||
pyv: as an old joseki
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[fn]
|
|
||||||
;W[fm]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
BHydden: i accept that it was a standard and well known pattern... but I'm still not used to pros putting stones on the board that quickly :P
|
|
||||||
BHydden: we had a move 8 3-3 so they can hold off a bit on the other one ;)
|
|
||||||
USGO2: Nyu dug into her purse and got out what appeared to be a piece of gum or a breathmint
|
|
||||||
BHydden: for herself or as a subtle insult to her opponent to throw Eric off his game?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[gm]
|
|
||||||
;W[fl]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: For herself as far as i can tell
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[kn]
|
|
||||||
;W[hn]
|
|
||||||
;B[gn]
|
|
||||||
;W[jn]
|
|
||||||
;B[km]
|
|
||||||
;W[il]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: Hmm, I wonder if saving f5 worth W extending f8.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[dr]
|
|
||||||
;W[cq]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: Or can B live in the lower left somehow?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[im]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: Eric has almost played a move a few times now but always puts the stone back in the bowl. but finally committed to this one
|
|
||||||
USGO2: then steps out of the room
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[hm]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
BHydden: ominous
|
|
||||||
USGO2: Nyu's focus has completely unwavered meanwhile
|
|
||||||
USGO2: Eric has returned
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[gl]
|
|
||||||
;W[fk]
|
|
||||||
;B[jm]
|
|
||||||
;W[hl]
|
|
||||||
;B[gk]
|
|
||||||
;W[fj]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: white must feel pretty confident about living along the bottom
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[gj]
|
|
||||||
;W[fi]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: B f5 is not out of the woods yet tho...
|
|
||||||
unholysix1: pretty close to being out of them
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[in]
|
|
||||||
;W[ho]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: ohh neat
|
|
||||||
Аlрhа - 1 5 2: W can still harras that group to help save h5 if h5 can't live at the bottom.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[kq]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: hmm... I thought b had to deend the f4 cut after white's move. guess not
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ij]
|
|
||||||
;B[jk]
|
|
||||||
;W[hj]
|
|
||||||
;B[gi]
|
|
||||||
(;W[fh]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: I think f4 cut douesn't work because of W's h4 aji.
|
|
||||||
unholysix1: no i just misread it. b has a sequence to make it fail
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[gh]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: that one seems to work
|
|
||||||
unholysix1: white just relentlessly takes that 6 line territory. fun stuff
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ih]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: Eric has used 40 minutes so far. Deducting from the start of the game, that means Nyu has used maybe 10 or so minutes
|
|
||||||
USGO2: Can't see Nyu's time unless Eric checks it
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[hg]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: Looks like B is determined to kill h5 no matter the cost.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ki]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: whites like sorry, noly need one eye and now i've got stones to connect to
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[cf]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: Hmm.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ce]
|
|
||||||
;B[df]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: so cool. :-D
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[gg]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: B doesn't need to connect at h12 I think. He can kill f12 if he cuts.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(;B[hh]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: c8 net. 6 libs w to 3 for b
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ee]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: ok b cuts w extend im guessing you want b to e13? i play c8 net
|
|
||||||
unholysix1: doe
|
|
||||||
unholysix1: er done
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[cj]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: now hes using your plan haha
|
|
||||||
unholysix1: only net still works
|
|
||||||
Аlрhа - 1 5 2: He's not going for the kill tho.
|
|
||||||
unholysix1: hes trying to live
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[bk]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: thats most of whites points so far. its huge if he pulls it off
|
|
||||||
USGO2: Eric slips on his jacket. Despite it being almost 100F today its fairly ccomfortable in the strong players room
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[bj]
|
|
||||||
;W[di]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: d9?
|
|
||||||
unholysix1: And the heat is on black in this game! :-P
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[ch]
|
|
||||||
;W[be]
|
|
||||||
;B[bf]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: she still chewing that gum?
|
|
||||||
USGO2: I never saw a chewing motion so i assume it was a mint instead of gum
|
|
||||||
unholysix1: ooohhhh that explains a lot
|
|
||||||
USGO2: I think this is the longest she has spent on a move so far
|
|
||||||
unholysix1: this is exciting.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[gf]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: wow. make a move and save those if you want. I'll just trap this string
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[dh]
|
|
||||||
;W[jf]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: !
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[jh]
|
|
||||||
;W[ii]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: the B stick is contained and needs to find 2 eyes, right?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[hr]
|
|
||||||
;W[gp]
|
|
||||||
;B[gq]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: thats the way it is
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[fp]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: he just traded the tail for the rest
|
|
||||||
aesalon: fat tail
|
|
||||||
unholysix1: for sure
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[kh]
|
|
||||||
;W[lh]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: Nyu leaves the room
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[lg]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: and returns
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[kg]
|
|
||||||
;B[he]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: Eric dropped the stone onto the board but fortunately it fell into an empty area
|
|
||||||
unholysix1: This looks like making it worse to me.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[jg]
|
|
||||||
;B[hf]
|
|
||||||
;W[id]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
S_Alexander: white feels good?
|
|
||||||
Falchion: ya, think so
|
|
||||||
Falchion: B is going to have to make a huge territory on the right side to even it up
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[hd]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: I mean what black's doing, it would work on me 100%
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ic]
|
|
||||||
;B[fg]
|
|
||||||
;W[ff]
|
|
||||||
;B[eg]
|
|
||||||
;W[dl]
|
|
||||||
;B[ec]
|
|
||||||
;W[dc]
|
|
||||||
;B[db]
|
|
||||||
;W[cb]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Nova Luna: ko. From move 0: Q16 D16 Q3 D4 R9 O17 Q14 R17 Q17 Q18 R16 S18 S17 R18 F3 C6 M4 H3 F5 K4 D7 D6 E7 E6 F6 F7 G7 F8 L6 H6 G6 K6 L7 J8 D2 C3 J7 H7 G8 F9 K7 H8 G9 F10 G10 F11 J6 H5 L3 J10 K9 H10 G11 F12 G12 J12 H13 L11 C14 C15 D14 G13 H12 E15 C10 B9 B10 D11 C12 B15 B14 G14 D12 K14 K12 J11 H2 G4 G3 F4 L12 M12 M13 L13 H15 K13 H14 J16 H16 J17 F13 F14 E13 D8 E17 D17 D18 C18
|
|
||||||
Zhadow: where
|
|
||||||
Zhadow: cant white G17 if black F18
|
|
||||||
Zhadow: ?
|
|
||||||
unholysix1: could he be thinking of e18 and just maing whte play a defensive move in the corner? he has a couple of forcing moves around the cut points?
|
|
||||||
USGO2: Eric has 10 minutes main time left. Nyu has approximately 50
|
|
||||||
mekriff 白金花: Anybody got a win rate?
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[fe]
|
|
||||||
;W[ge]
|
|
||||||
;B[fd]
|
|
||||||
;W[ef]
|
|
||||||
;B[fb]
|
|
||||||
;W[eh]
|
|
||||||
;B[dg]
|
|
||||||
;W[gd]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: Given the info that Mark Lee lost on board 1, if Nyu wins this game she will very likely be the Masters winner
|
|
||||||
aesalon: Yeah
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[gc]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
aesalon: and it looks near impossible for W to lose
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[bc]
|
|
||||||
;B[hc]
|
|
||||||
;W[bg]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: Nyu steps across the room to refill her cup of water. Theres many water coolers in this building which is great given the heat this week
|
|
||||||
unholysix1: so at this point leela says white is winning 90% and the black group is dead
|
|
||||||
Zhadow: which one, left side or the stick
|
|
||||||
unholysix1: left side although there are variations where the stick dies instead
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[ae]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: it also expects fighting to start soon with an invasion around the Q3 stone
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ad]
|
|
||||||
;B[bl]
|
|
||||||
;W[ck]
|
|
||||||
;B[cm]
|
|
||||||
;W[bm]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: Eric has entered byo yomi. 5 periods of 30 seconds
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[bn]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
unholysix1: wow now it wants black to pla d15, w e16 b c16 and white take the f16 stones. b lives on the side the string dies
|
|
||||||
aesalon: It's difficult to parse bot variations when it's so lopsided
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[am]
|
|
||||||
;B[al]
|
|
||||||
;W[cl]
|
|
||||||
;B[an]
|
|
||||||
;W[bm]
|
|
||||||
;B[ak]
|
|
||||||
;W[el]C[W+Resign
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO2: 4 periods left
|
|
||||||
USGO2: 3 periods left
|
|
||||||
USGO2: Eric shuts off the clock. White wins the game. Thanks for watching!
|
|
||||||
savanni.dgerinel: Thank you for transcribing!
|
|
||||||
S_Alexander: gg
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)(;B[fg]
|
|
||||||
;W[gf]
|
|
||||||
;B[dk]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: ?. From move 0: Q16 D16 Q3 D4 R9 O17 Q14 R17 Q17 Q18 R16 S18 S17 R18 F3 C6 M4 H3 F5 K4 D7 D6 E7 E6 F6 F7 G7 F8 L6 H6 G6 K6 L7 J8 D2 C3 J7 H7 G8 F9 K7 H8 G9 F10 G10 F11 J6 H5 L3 J10 K9 H10 G11 F12 G12 J12 H13 L11 C14 C15 D14 G13 F13 G14 D9
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))(;W[fp]
|
|
||||||
;B[ep]
|
|
||||||
;W[gp]
|
|
||||||
;B[eo]
|
|
||||||
;W[eq]
|
|
||||||
;B[dq]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Аlрhа - 1 5 2: this one?. From move 0: Q16 D16 Q3 D4 R9 O17 Q14 R17 Q17 Q18 R16 S18 S17 R18 F3 C6 M4 H3 F5 K4 D7 D6 E7 E6 F6 F7 G7 F8 L6 H6 G6 K6 L7 J8 D2 C3 J7 H7 G8 F9 K7 H8 G9 F10 G10 F11 J6 H5 L3 J10 K9 H10 G11 F4 E4 G4 E5 E3 D3
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
))
|
|
|
@ -1,395 +0,0 @@
|
||||||
(;FF[4]
|
|
||||||
CA[UTF-8]
|
|
||||||
GM[1]
|
|
||||||
GN[2019 Masters R7 B3]
|
|
||||||
PC[https://online-go.com/review/404375]
|
|
||||||
PB[Alan Huang]
|
|
||||||
PW[Yongfei Ge]
|
|
||||||
BR[7d]
|
|
||||||
WR[7d]
|
|
||||||
TM[0]OT[0 none]
|
|
||||||
RE[B+7.5]
|
|
||||||
SZ[19]
|
|
||||||
KM[7.5]
|
|
||||||
RU[AGA]
|
|
||||||
C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: Welcome to Round 7 of the US Masters. This is the last round. This is table 3.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[pd]
|
|
||||||
;W[dc]
|
|
||||||
;B[qp]
|
|
||||||
;W[dq]
|
|
||||||
;B[np]
|
|
||||||
;W[nc]
|
|
||||||
;B[qf]
|
|
||||||
;W[pc]
|
|
||||||
;B[qc]
|
|
||||||
;W[qb]
|
|
||||||
;B[oc]
|
|
||||||
;W[pb]
|
|
||||||
;B[od]
|
|
||||||
;W[ob]
|
|
||||||
;B[nd]
|
|
||||||
;W[mc]
|
|
||||||
;B[ce]
|
|
||||||
;W[dh]
|
|
||||||
;B[co]
|
|
||||||
;W[cl]
|
|
||||||
;B[ep]
|
|
||||||
;W[dp]
|
|
||||||
;B[do]
|
|
||||||
;W[eo]
|
|
||||||
;B[eq]
|
|
||||||
;W[er]
|
|
||||||
;B[fr]
|
|
||||||
;W[dr]
|
|
||||||
;B[en]
|
|
||||||
;W[fo]
|
|
||||||
;B[gp]
|
|
||||||
;W[dn]
|
|
||||||
;B[cn]
|
|
||||||
;W[dm]
|
|
||||||
;B[gn]
|
|
||||||
;W[fn]
|
|
||||||
;B[fm]
|
|
||||||
;W[em]
|
|
||||||
;B[go]
|
|
||||||
;W[fl]
|
|
||||||
;B[gm]
|
|
||||||
;W[bp]
|
|
||||||
;B[pk]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
redreoicy: Go Alan! I'm sure AI prefers black here :)
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[lq]
|
|
||||||
;B[lp]
|
|
||||||
;W[kp]
|
|
||||||
;B[lo]
|
|
||||||
;W[nq]
|
|
||||||
;B[oq]
|
|
||||||
;W[mr]
|
|
||||||
;B[or]
|
|
||||||
;W[ko]
|
|
||||||
;B[ln]
|
|
||||||
;W[iq]
|
|
||||||
;B[kn]
|
|
||||||
;W[hr]
|
|
||||||
;B[dd]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: The game has been underway for about 30 minutes...B has used about 19 minutes.
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ec]
|
|
||||||
;B[cc]
|
|
||||||
;W[cb]
|
|
||||||
;B[bb]
|
|
||||||
;W[bc]
|
|
||||||
;B[bd]
|
|
||||||
;W[cd]
|
|
||||||
;B[kr]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
redreoicy: Good part about that joseki in lower left is that it leaves so many easy threats
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[kq]
|
|
||||||
;B[cc]
|
|
||||||
;W[qi]
|
|
||||||
;B[qj]
|
|
||||||
;W[oi]
|
|
||||||
;B[mi]
|
|
||||||
;W[qg]
|
|
||||||
;B[pf]
|
|
||||||
;W[rj]
|
|
||||||
;B[rk]
|
|
||||||
;W[rf]
|
|
||||||
;B[rh]
|
|
||||||
;W[pj]
|
|
||||||
;B[qk]
|
|
||||||
;W[rg]
|
|
||||||
;B[rd]
|
|
||||||
;W[ri]
|
|
||||||
;B[ph]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: About 1 hour into the game...B has used 39 minutes of time
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[pg]
|
|
||||||
;B[oh]
|
|
||||||
;W[og]
|
|
||||||
;B[nh]
|
|
||||||
;W[qh]
|
|
||||||
;B[md]
|
|
||||||
;W[re]
|
|
||||||
;B[lc]
|
|
||||||
;W[rc]
|
|
||||||
;B[qd]
|
|
||||||
;W[sd]
|
|
||||||
;B[ac]
|
|
||||||
;W[hc]
|
|
||||||
;B[lb]
|
|
||||||
;W[mb]
|
|
||||||
;B[ma]
|
|
||||||
;W[nb]
|
|
||||||
;B[ke]
|
|
||||||
;W[pi]
|
|
||||||
;B[nk]
|
|
||||||
;W[nj]
|
|
||||||
;B[mj]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: B needs to play F4 at some point, no? It's forcing too
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[gk]
|
|
||||||
;B[cj]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: 90 minutes in...B has used 52 minutes
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[ci]
|
|
||||||
;B[dj]
|
|
||||||
;W[fi]
|
|
||||||
;B[bj]
|
|
||||||
;W[bk]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: is that B group just going to die? jumping in like that was pretty risky
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[bh]
|
|
||||||
;W[gh]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Falchion: guess it lives, but low, and W wasn't reduced very much
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[ek]
|
|
||||||
;W[el]
|
|
||||||
;B[hi]
|
|
||||||
;W[gj]
|
|
||||||
;B[ik]
|
|
||||||
;W[hh]
|
|
||||||
;B[ii]
|
|
||||||
;W[ih]
|
|
||||||
;B[ed]
|
|
||||||
;W[fd]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
Zhadow: how much time does each player have left?
|
|
||||||
USGO3: B has 21 min
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[ni]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: They have been playing 117 minutes
|
|
||||||
USGO3: I will let you do the math for W
|
|
||||||
Zhadow: thanks
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;W[kg]
|
|
||||||
;B[ic]
|
|
||||||
;W[id]
|
|
||||||
;B[jc]
|
|
||||||
;W[hb]
|
|
||||||
;B[jr]
|
|
||||||
;W[gr]
|
|
||||||
;B[fs]
|
|
||||||
;W[io]
|
|
||||||
;B[jn]
|
|
||||||
;W[gq]
|
|
||||||
;B[fq]
|
|
||||||
;W[hp]
|
|
||||||
;B[fp]
|
|
||||||
;W[en]
|
|
||||||
;B[jo]
|
|
||||||
;W[jp]
|
|
||||||
;B[ir]
|
|
||||||
;W[gs]
|
|
||||||
;B[ho]
|
|
||||||
;W[in]
|
|
||||||
;B[im]
|
|
||||||
;W[is]
|
|
||||||
;B[fe]
|
|
||||||
;W[gd]
|
|
||||||
;B[db]
|
|
||||||
;W[eb]
|
|
||||||
;B[ca]
|
|
||||||
;W[jd]
|
|
||||||
;B[kd]
|
|
||||||
;W[jb]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: B has 10 minutes basic time left
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[mf]
|
|
||||||
;W[sk]
|
|
||||||
;B[sl]
|
|
||||||
;W[sj]
|
|
||||||
;B[ql]
|
|
||||||
;W[bi]
|
|
||||||
;B[ai]
|
|
||||||
;W[ch]
|
|
||||||
;B[bg]
|
|
||||||
;W[ib]
|
|
||||||
;B[jh]
|
|
||||||
;W[jg]
|
|
||||||
;B[kh]
|
|
||||||
;W[ok]
|
|
||||||
;B[ol]
|
|
||||||
;W[oj]
|
|
||||||
;B[mk]
|
|
||||||
;W[nr]
|
|
||||||
;B[os]
|
|
||||||
;W[lg]
|
|
||||||
;B[ng]
|
|
||||||
;W[lh]
|
|
||||||
;B[li]
|
|
||||||
;W[ge]
|
|
||||||
;B[ff]
|
|
||||||
;W[df]
|
|
||||||
;B[cf]
|
|
||||||
;W[dg]
|
|
||||||
;B[fg]
|
|
||||||
;W[fh]
|
|
||||||
;B[de]
|
|
||||||
;W[je]
|
|
||||||
;B[ei]
|
|
||||||
;W[eh]
|
|
||||||
;B[rb]
|
|
||||||
;W[sc]
|
|
||||||
;B[se]
|
|
||||||
;W[sf]
|
|
||||||
;B[ra]
|
|
||||||
;W[sb]
|
|
||||||
;B[na]
|
|
||||||
;W[qa]
|
|
||||||
;B[ea]
|
|
||||||
;W[fb]
|
|
||||||
;B[kf]
|
|
||||||
;W[jf]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: B in byomi
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[gf]
|
|
||||||
;W[hf]
|
|
||||||
;B[of]
|
|
||||||
;W[kc]
|
|
||||||
;B[hn]
|
|
||||||
;W[ns]
|
|
||||||
;B[mp]
|
|
||||||
;W[ls]
|
|
||||||
;B[ip]
|
|
||||||
;W[io]
|
|
||||||
;B[lr]
|
|
||||||
;W[mq]
|
|
||||||
;B[js]
|
|
||||||
;W[jq]
|
|
||||||
;B[hs]
|
|
||||||
;W[hq]
|
|
||||||
;B[cp]
|
|
||||||
;W[cq]
|
|
||||||
;B[ds]
|
|
||||||
;W[br]
|
|
||||||
;B[es]
|
|
||||||
;W[cs]
|
|
||||||
;B[kb]
|
|
||||||
;W[jc]
|
|
||||||
;B[hk]
|
|
||||||
;W[hj]
|
|
||||||
;B[ij]
|
|
||||||
;W[gl]
|
|
||||||
;B[hl]
|
|
||||||
;W[ak]
|
|
||||||
;B[aj]
|
|
||||||
;W[qe]
|
|
||||||
;B[ck]
|
|
||||||
;W[bl]
|
|
||||||
;B[gg]
|
|
||||||
;W[pe]
|
|
||||||
;B[oe]
|
|
||||||
;W[lf]
|
|
||||||
;B[le]
|
|
||||||
;W[fa]
|
|
||||||
;B[da]
|
|
||||||
;W[hg]
|
|
||||||
;B[oa]
|
|
||||||
;W[sa]
|
|
||||||
;B[cg]
|
|
||||||
;W[ja]
|
|
||||||
;B[la]
|
|
||||||
;W[is]
|
|
||||||
;B[in]
|
|
||||||
;W[ks]
|
|
||||||
;B[ip]
|
|
||||||
;W[rm]
|
|
||||||
;B[rl]
|
|
||||||
;W[io]
|
|
||||||
;B[bs]
|
|
||||||
;W[as]
|
|
||||||
;B[ip]
|
|
||||||
;W[pm]
|
|
||||||
;B[pl]
|
|
||||||
;W[io]
|
|
||||||
;B[ej]
|
|
||||||
;W[dl]
|
|
||||||
;B[ip]
|
|
||||||
;W[op]
|
|
||||||
;B[pq]
|
|
||||||
;W[io]
|
|
||||||
;B[ee]
|
|
||||||
;W[ip]
|
|
||||||
;B[ah]
|
|
||||||
;W[fj]
|
|
||||||
;B[mg]
|
|
||||||
;W[mh]
|
|
||||||
;B[ld]
|
|
||||||
;W[ka]
|
|
||||||
;B[dk]
|
|
||||||
;W[di]
|
|
||||||
;B[pa]
|
|
||||||
;W[eg]
|
|
||||||
;B[ef]
|
|
||||||
;W[fk]
|
|
||||||
;B[gi]
|
|
||||||
;W[]C[
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: Counting
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
;B[]
|
|
||||||
;W[]C[B+7.5
|
|
||||||
|
|
||||||
-- chat --
|
|
||||||
USGO3: B wins
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
)
|
|
|
@ -1,224 +0,0 @@
|
||||||
(;FF[4]GM[1]AP[gobandroid:0]SZ[19]GN[Kat vs. Savanni]DT[2022-10-05]PB[Kat]PW[Savanni]BR[10k]WR[10k]KM[6.5]RE[W+15.5]
|
|
||||||
;B[dp]
|
|
||||||
;W[pd]
|
|
||||||
;B[qp]
|
|
||||||
;W[cd]
|
|
||||||
;B[oq]
|
|
||||||
;W[fd]
|
|
||||||
;B[qf]
|
|
||||||
;W[qh]
|
|
||||||
(;B[pf]
|
|
||||||
)(;B[of]
|
|
||||||
;W[nd]
|
|
||||||
;B[mf]
|
|
||||||
;W[pk]
|
|
||||||
;B[ql]
|
|
||||||
;W[qk]
|
|
||||||
;B[cj]
|
|
||||||
;W[jp]
|
|
||||||
;B[hq]
|
|
||||||
;W[le]
|
|
||||||
;B[jc]
|
|
||||||
;W[lc]
|
|
||||||
;B[gc]
|
|
||||||
;W[fc]
|
|
||||||
;B[qd]
|
|
||||||
;W[qc]
|
|
||||||
;B[rd]
|
|
||||||
;W[rc]
|
|
||||||
;B[pe]
|
|
||||||
;W[od]
|
|
||||||
;B[ri]
|
|
||||||
;W[qi]
|
|
||||||
;B[rh]
|
|
||||||
;W[di]
|
|
||||||
;B[dl]
|
|
||||||
;W[ci]
|
|
||||||
;B[lp]
|
|
||||||
;W[jn]
|
|
||||||
;B[hn]
|
|
||||||
;W[cq]
|
|
||||||
;B[dq]
|
|
||||||
;W[cp]
|
|
||||||
;B[co]
|
|
||||||
;W[bo]
|
|
||||||
;B[cn]
|
|
||||||
;W[bn]
|
|
||||||
;B[cm]
|
|
||||||
;W[dr]
|
|
||||||
;B[er]
|
|
||||||
;W[cr]
|
|
||||||
;B[fq]
|
|
||||||
;W[ln]
|
|
||||||
;B[nm]
|
|
||||||
;W[nk]
|
|
||||||
;B[ol]
|
|
||||||
;W[ok]
|
|
||||||
;B[lk]
|
|
||||||
;W[ng]
|
|
||||||
;B[nf]
|
|
||||||
;W[mj]
|
|
||||||
;B[ml]
|
|
||||||
;W[pl]
|
|
||||||
;B[qm]
|
|
||||||
;W[om]
|
|
||||||
;B[nn]
|
|
||||||
;W[nl]
|
|
||||||
;B[mm]
|
|
||||||
;W[kl]
|
|
||||||
;B[hk]
|
|
||||||
;W[ho]
|
|
||||||
;B[io]
|
|
||||||
;W[in]
|
|
||||||
;B[ip]
|
|
||||||
;W[hm]
|
|
||||||
;B[gn]
|
|
||||||
;W[jo]
|
|
||||||
;B[jq]
|
|
||||||
;W[mp]
|
|
||||||
;B[np]
|
|
||||||
;W[mo]
|
|
||||||
;B[no]
|
|
||||||
;W[kq]
|
|
||||||
;B[jr]
|
|
||||||
;W[mq]
|
|
||||||
;B[hf]
|
|
||||||
;W[ff]
|
|
||||||
;B[lf]
|
|
||||||
;W[jd]
|
|
||||||
;B[ic]
|
|
||||||
;W[jf]
|
|
||||||
;B[jk]
|
|
||||||
;W[kk]
|
|
||||||
;B[fk]
|
|
||||||
;W[kr]
|
|
||||||
;B[nr]
|
|
||||||
;W[mr]
|
|
||||||
;B[lj]
|
|
||||||
;W[mi]
|
|
||||||
;B[li]
|
|
||||||
;W[jh]
|
|
||||||
;B[ji]
|
|
||||||
;W[lg]
|
|
||||||
;B[hl]
|
|
||||||
;W[dj]
|
|
||||||
;B[ck]
|
|
||||||
;W[fj]
|
|
||||||
;B[jl]
|
|
||||||
;W[ll]
|
|
||||||
;B[mk]
|
|
||||||
;W[jm]
|
|
||||||
;B[gm]
|
|
||||||
;W[gh]
|
|
||||||
;B[hi]
|
|
||||||
;W[hd]
|
|
||||||
;B[hc]
|
|
||||||
;W[hh]
|
|
||||||
;B[fi]
|
|
||||||
;W[fh]
|
|
||||||
;B[ei]
|
|
||||||
;W[eh]
|
|
||||||
;B[ej]
|
|
||||||
;W[ek]
|
|
||||||
;B[gj]
|
|
||||||
;W[gi]
|
|
||||||
;B[fj]
|
|
||||||
;W[dk]
|
|
||||||
;B[el]
|
|
||||||
;W[pg]
|
|
||||||
;B[dh]
|
|
||||||
;W[ch]
|
|
||||||
;B[dg]
|
|
||||||
;W[cf]
|
|
||||||
;B[mg]
|
|
||||||
;W[og]
|
|
||||||
;B[kb]
|
|
||||||
;W[lb]
|
|
||||||
;B[fb]
|
|
||||||
;W[eb]
|
|
||||||
;B[gb]
|
|
||||||
;W[ec]
|
|
||||||
;B[ig]
|
|
||||||
;W[ih]
|
|
||||||
;B[kf]
|
|
||||||
;W[kg]
|
|
||||||
;B[je]
|
|
||||||
;W[ie]
|
|
||||||
;B[ke]
|
|
||||||
;W[if]
|
|
||||||
;B[id]
|
|
||||||
;W[gd]
|
|
||||||
;B[ld]
|
|
||||||
;W[md]
|
|
||||||
;B[me]
|
|
||||||
;W[pm]
|
|
||||||
;B[qn]
|
|
||||||
;W[rj]
|
|
||||||
;B[rg]
|
|
||||||
;W[rl]
|
|
||||||
;B[rm]
|
|
||||||
;W[bj]
|
|
||||||
;B[bk]
|
|
||||||
;W[cg]
|
|
||||||
;B[bi]
|
|
||||||
;W[bh]
|
|
||||||
;B[aj]
|
|
||||||
;W[mh]
|
|
||||||
;B[kc]
|
|
||||||
;W[kj]
|
|
||||||
;B[pn]
|
|
||||||
;W[on]
|
|
||||||
;B[oo]
|
|
||||||
;W[jj]
|
|
||||||
;B[ij]
|
|
||||||
;W[ki]
|
|
||||||
;B[lh]
|
|
||||||
;W[ii]
|
|
||||||
;B[hj]
|
|
||||||
;W[lm]
|
|
||||||
;B[im]
|
|
||||||
;W[ns]
|
|
||||||
;B[os]
|
|
||||||
;W[ms]
|
|
||||||
;B[bm]
|
|
||||||
;W[bp]
|
|
||||||
;B[la]
|
|
||||||
;W[ma]
|
|
||||||
;B[ka]
|
|
||||||
;W[mb]
|
|
||||||
;B[sk]
|
|
||||||
;W[sl]
|
|
||||||
;B[sj]
|
|
||||||
;W[rk]
|
|
||||||
;B[si]
|
|
||||||
;W[sm]
|
|
||||||
;B[sn]
|
|
||||||
;W[js]
|
|
||||||
;B[ir]
|
|
||||||
;W[is]
|
|
||||||
;B[hs]
|
|
||||||
;W[ks]
|
|
||||||
;B[ea]
|
|
||||||
;W[da]
|
|
||||||
;B[fa]
|
|
||||||
;W[db]
|
|
||||||
;B[sc]
|
|
||||||
;W[sb]
|
|
||||||
;B[sd]
|
|
||||||
;W[rb]
|
|
||||||
;B[ds]
|
|
||||||
;W[cs]
|
|
||||||
;B[es]
|
|
||||||
;W[nq]
|
|
||||||
;B[or]
|
|
||||||
;W[am]
|
|
||||||
;B[al]
|
|
||||||
;W[an]
|
|
||||||
;B[kh]
|
|
||||||
;W[jg]
|
|
||||||
;B[ah]
|
|
||||||
;W[ag]
|
|
||||||
;B[ai]
|
|
||||||
;W[qg]
|
|
||||||
;B[pf]
|
|
||||||
))
|
|
|
@ -1,179 +0,0 @@
|
||||||
(;FF[4]GM[1]AP[gobandroid:0]SZ[19]DT[2023-04-19]PB[Steve]PW[Savanni]KM[6.5]
|
|
||||||
;B[dd]
|
|
||||||
;W[pp]
|
|
||||||
;B[pd]
|
|
||||||
;W[dp]
|
|
||||||
;B[qn]
|
|
||||||
;W[qo]
|
|
||||||
;B[pn]
|
|
||||||
;W[np]
|
|
||||||
;B[qj]
|
|
||||||
;W[cf]
|
|
||||||
;B[fc]
|
|
||||||
;W[cd]
|
|
||||||
;B[cc]
|
|
||||||
;W[bc]
|
|
||||||
;B[cb]
|
|
||||||
;W[bb]
|
|
||||||
;B[ce]
|
|
||||||
;W[bd]
|
|
||||||
;B[de]
|
|
||||||
;W[be]
|
|
||||||
;B[df]
|
|
||||||
;W[cg]
|
|
||||||
;B[ck]
|
|
||||||
;W[dg]
|
|
||||||
;B[cn]
|
|
||||||
;W[co]
|
|
||||||
;B[bn]
|
|
||||||
;W[en]
|
|
||||||
;B[ek]
|
|
||||||
;W[ef]
|
|
||||||
;B[ee]
|
|
||||||
;W[db]
|
|
||||||
;B[dc]
|
|
||||||
;W[ca]
|
|
||||||
;B[eb]
|
|
||||||
;W[da]
|
|
||||||
;B[ge]
|
|
||||||
;W[ff]
|
|
||||||
;B[fe]
|
|
||||||
;W[dj]
|
|
||||||
;B[bo]
|
|
||||||
;W[bp]
|
|
||||||
;B[di]
|
|
||||||
;W[dk]
|
|
||||||
;B[cj]
|
|
||||||
;W[dl]
|
|
||||||
;B[cl]
|
|
||||||
;W[ei]
|
|
||||||
;B[ci]
|
|
||||||
;W[eh]
|
|
||||||
;B[ej]
|
|
||||||
;W[el]
|
|
||||||
;B[fm]
|
|
||||||
;W[gn]
|
|
||||||
;B[do]
|
|
||||||
;W[cp]
|
|
||||||
;B[dn]
|
|
||||||
;W[eo]
|
|
||||||
;B[em]
|
|
||||||
;W[fl]
|
|
||||||
;B[gk]
|
|
||||||
;W[gl]
|
|
||||||
;B[gm]
|
|
||||||
;W[hm]
|
|
||||||
;B[fn]
|
|
||||||
;W[fo]
|
|
||||||
;B[dm]
|
|
||||||
;W[hl]
|
|
||||||
;B[go]
|
|
||||||
;W[hn]
|
|
||||||
;B[gp]
|
|
||||||
;W[ep]
|
|
||||||
;B[gq]
|
|
||||||
;W[ip]
|
|
||||||
;B[er]
|
|
||||||
;W[dr]
|
|
||||||
;B[iq]
|
|
||||||
;W[jq]
|
|
||||||
;B[ir]
|
|
||||||
;W[jr]
|
|
||||||
;B[hp]
|
|
||||||
;W[jp]
|
|
||||||
;B[eq]
|
|
||||||
;W[dq]
|
|
||||||
;B[fp]
|
|
||||||
;W[br]
|
|
||||||
;B[ds]
|
|
||||||
;W[cs]
|
|
||||||
;B[es]
|
|
||||||
;W[nn]
|
|
||||||
;B[nj]
|
|
||||||
;W[nc]
|
|
||||||
;B[lc]
|
|
||||||
;W[qc]
|
|
||||||
;B[pc]
|
|
||||||
;W[qd]
|
|
||||||
;B[qe]
|
|
||||||
;W[pb]
|
|
||||||
;B[ob]
|
|
||||||
;W[qb]
|
|
||||||
;B[oc]
|
|
||||||
;W[nb]
|
|
||||||
;B[oa]
|
|
||||||
;W[pe]
|
|
||||||
;B[oe]
|
|
||||||
;W[pf]
|
|
||||||
;B[of]
|
|
||||||
;W[pg]
|
|
||||||
;B[re]
|
|
||||||
;W[sc]
|
|
||||||
;B[nd]
|
|
||||||
;W[kd]
|
|
||||||
;B[kc]
|
|
||||||
;W[jd]
|
|
||||||
;B[ic]
|
|
||||||
;W[md]
|
|
||||||
;B[mc]
|
|
||||||
;W[ne]
|
|
||||||
;B[od]
|
|
||||||
;W[me]
|
|
||||||
;B[og]
|
|
||||||
;W[oh]
|
|
||||||
;B[ph]
|
|
||||||
;W[qh]
|
|
||||||
;B[pi]
|
|
||||||
;W[rf]
|
|
||||||
;B[qg]
|
|
||||||
;W[qf]
|
|
||||||
;B[rg]
|
|
||||||
;W[rd]
|
|
||||||
;B[sf]
|
|
||||||
;W[mg]
|
|
||||||
;B[nh]
|
|
||||||
;W[om]
|
|
||||||
;B[ql]
|
|
||||||
;W[mh]
|
|
||||||
;B[mi]
|
|
||||||
;W[li]
|
|
||||||
;B[lj]
|
|
||||||
;W[kj]
|
|
||||||
;B[lh]
|
|
||||||
;W[ki]
|
|
||||||
;B[lg]
|
|
||||||
;W[ng]
|
|
||||||
;B[oi]
|
|
||||||
;W[lk]
|
|
||||||
;B[mf]
|
|
||||||
;W[nf]
|
|
||||||
;B[lf]
|
|
||||||
;W[ld]
|
|
||||||
;B[jg]
|
|
||||||
;W[hf]
|
|
||||||
;B[ie]
|
|
||||||
;W[id]
|
|
||||||
;B[hd]
|
|
||||||
;W[jc]
|
|
||||||
;B[jb]
|
|
||||||
;W[ib]
|
|
||||||
;B[hb]
|
|
||||||
;W[kb]
|
|
||||||
;B[lb]
|
|
||||||
;W[ja]
|
|
||||||
;B[na]
|
|
||||||
;W[hc]
|
|
||||||
;B[gc]
|
|
||||||
;W[he]
|
|
||||||
;B[gd]
|
|
||||||
;W[ic]
|
|
||||||
;B[ha]
|
|
||||||
;W[if]
|
|
||||||
;B[je]
|
|
||||||
;W[ih]
|
|
||||||
;B[ke]
|
|
||||||
;W[kh]
|
|
||||||
;B[le]
|
|
||||||
;W[kg]
|
|
||||||
;B[ia]
|
|
||||||
)
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{AppState, GameState, Player, Rank},
|
types::{AppState, GameState, Player, Rank},
|
||||||
ui::{home, playing_field, HomeView, PlayingFieldView},
|
ui::{new_game, playing_field, NewGameView, PlayingFieldView},
|
||||||
Config, DatabasePath,
|
Config,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
@ -12,7 +12,8 @@ use typeshare::typeshare;
|
||||||
#[serde(tag = "type", content = "content")]
|
#[serde(tag = "type", content = "content")]
|
||||||
pub enum CoreRequest {
|
pub enum CoreRequest {
|
||||||
CreateGame(CreateGameRequest),
|
CreateGame(CreateGameRequest),
|
||||||
Home,
|
LaunchScreen,
|
||||||
|
NewGame,
|
||||||
PlayingField,
|
PlayingField,
|
||||||
PlayStone(PlayStoneRequest),
|
PlayStone(PlayStoneRequest),
|
||||||
StartGame,
|
StartGame,
|
||||||
|
@ -58,7 +59,7 @@ impl From<HotseatPlayerRequest> for Player {
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
#[serde(tag = "type", content = "content")]
|
#[serde(tag = "type", content = "content")]
|
||||||
pub enum CoreResponse {
|
pub enum CoreResponse {
|
||||||
HomeView(HomeView),
|
NewGameView(NewGameView),
|
||||||
PlayingFieldView(PlayingFieldView),
|
PlayingFieldView(PlayingFieldView),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,14 +71,8 @@ pub struct CoreApp {
|
||||||
|
|
||||||
impl CoreApp {
|
impl CoreApp {
|
||||||
pub fn new(config_path: std::path::PathBuf) -> Self {
|
pub fn new(config_path: std::path::PathBuf) -> Self {
|
||||||
println!("config_path: {:?}", config_path);
|
|
||||||
let config = Config::from_path(config_path).expect("configuration to open");
|
let config = Config::from_path(config_path).expect("configuration to open");
|
||||||
|
let state = Arc::new(RwLock::new(AppState::new()));
|
||||||
let db_path: DatabasePath = config.get();
|
|
||||||
let state = Arc::new(RwLock::new(AppState::new(db_path)));
|
|
||||||
|
|
||||||
println!("config: {:?}", config);
|
|
||||||
println!("games database: {:?}", state.read().unwrap().database.len());
|
|
||||||
|
|
||||||
Self { config, state }
|
Self { config, state }
|
||||||
}
|
}
|
||||||
|
@ -118,9 +113,8 @@ impl CoreApp {
|
||||||
let game_state = app_state.game.as_ref().unwrap();
|
let game_state = app_state.game.as_ref().unwrap();
|
||||||
CoreResponse::PlayingFieldView(playing_field(game_state))
|
CoreResponse::PlayingFieldView(playing_field(game_state))
|
||||||
}
|
}
|
||||||
CoreRequest::Home => {
|
CoreRequest::LaunchScreen => CoreResponse::NewGameView(new_game()),
|
||||||
CoreResponse::HomeView(home(self.state.read().unwrap().database.all_games()))
|
CoreRequest::NewGame => CoreResponse::NewGameView(new_game()),
|
||||||
}
|
|
||||||
CoreRequest::PlayingField => {
|
CoreRequest::PlayingField => {
|
||||||
let app_state = self.state.read().unwrap();
|
let app_state = self.state.read().unwrap();
|
||||||
let game = app_state.game.as_ref().unwrap();
|
let game = app_state.game.as_ref().unwrap();
|
||||||
|
|
|
@ -36,7 +36,6 @@ enum OptionNames {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum ConfigOption {
|
pub enum ConfigOption {
|
||||||
DatabasePath(DatabasePath),
|
DatabasePath(DatabasePath),
|
||||||
Me(Me),
|
Me(Me),
|
||||||
|
@ -97,14 +96,14 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, val: ConfigOption) {
|
fn set(&mut self, val: ConfigOption) {
|
||||||
let _ = match val {
|
let _ = match val {
|
||||||
ConfigOption::DatabasePath(_) => self.values.insert(OptionNames::DatabasePath, val),
|
ConfigOption::DatabasePath(_) => self.values.insert(OptionNames::DatabasePath, val),
|
||||||
ConfigOption::Me(_) => self.values.insert(OptionNames::Me, val),
|
ConfigOption::Me(_) => self.values.insert(OptionNames::Me, val),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<'a, T>(&'a self) -> T
|
fn get<'a, T>(&'a self) -> T
|
||||||
where
|
where
|
||||||
T: From<&'a Self>,
|
T: From<&'a Self>,
|
||||||
{
|
{
|
||||||
|
@ -112,16 +111,9 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct DatabasePath(PathBuf);
|
pub struct DatabasePath(PathBuf);
|
||||||
|
|
||||||
impl std::ops::Deref for DatabasePath {
|
|
||||||
type Target = PathBuf;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Config> for DatabasePath {
|
impl From<&Config> for DatabasePath {
|
||||||
fn from(config: &Config) -> Self {
|
fn from(config: &Config) -> Self {
|
||||||
match config.values.get(&OptionNames::DatabasePath) {
|
match config.values.get(&OptionNames::DatabasePath) {
|
||||||
|
@ -131,7 +123,7 @@ impl From<&Config> for DatabasePath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Me(Player);
|
pub struct Me(Player);
|
||||||
|
|
||||||
impl From<&Config> for Option<Me> {
|
impl From<&Config> for Option<Me> {
|
||||||
|
@ -145,54 +137,3 @@ impl From<&Config> for Option<Me> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for Me {
|
|
||||||
type Target = Player;
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
use crate::types::Rank;
|
|
||||||
use cool_asserts::assert_matches;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_set_and_get_options() {
|
|
||||||
let mut config = Config::new(PathBuf::from("."));
|
|
||||||
config.set(ConfigOption::DatabasePath(DatabasePath(PathBuf::from(
|
|
||||||
"fixtures/five_games",
|
|
||||||
))));
|
|
||||||
config.set(ConfigOption::Me(Me(Player {
|
|
||||||
name: "Savanni".to_owned(),
|
|
||||||
rank: Some(Rank::Kyu(10)),
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_can_serialize_and_deserialize() {
|
|
||||||
let mut config = Config::new(PathBuf::from("."));
|
|
||||||
config.set(ConfigOption::DatabasePath(DatabasePath(PathBuf::from(
|
|
||||||
"fixtures/five_games",
|
|
||||||
))));
|
|
||||||
config.set(ConfigOption::Me(Me(Player {
|
|
||||||
name: "Savanni".to_owned(),
|
|
||||||
rank: Some(Rank::Kyu(10)),
|
|
||||||
})));
|
|
||||||
let s = serde_json::to_string(&config.values).unwrap();
|
|
||||||
println!("{}", s);
|
|
||||||
let values: HashMap<OptionNames, ConfigOption> = serde_json::from_str(s.as_ref()).unwrap();
|
|
||||||
println!("options: {:?}", values);
|
|
||||||
|
|
||||||
assert_matches!(values.get(&OptionNames::DatabasePath),
|
|
||||||
Some(ConfigOption::DatabasePath(db_path)) =>
|
|
||||||
assert_eq!(*db_path, config.get())
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_matches!(values.get(&OptionNames::Me), Some(ConfigOption::Me(val)) =>
|
|
||||||
assert_eq!(Some(val.clone()), config.get())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
use std::{ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf};
|
|
||||||
|
|
||||||
use go_sgf::{parse_sgf, GameTree};
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error("Database permission denied")]
|
|
||||||
PermissionDenied,
|
|
||||||
#[error("An IO error occurred: {0}")]
|
|
||||||
IOError(std::io::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<std::io::Error> for Error {
|
|
||||||
fn from(err: std::io::Error) -> Self {
|
|
||||||
Error::IOError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Database {
|
|
||||||
path: PathBuf,
|
|
||||||
games: Vec<GameTree>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Database {
|
|
||||||
pub fn open_path(path: PathBuf) -> Result<Database, Error> {
|
|
||||||
let mut games: Vec<GameTree> = Vec::new();
|
|
||||||
|
|
||||||
let extension = PathBuf::from("sgf").into_os_string();
|
|
||||||
|
|
||||||
let path_iter = std::fs::read_dir(path.clone())?;
|
|
||||||
for entry in path_iter {
|
|
||||||
match entry {
|
|
||||||
Ok(entry) => {
|
|
||||||
if entry.path().extension() == Some(&extension) {
|
|
||||||
let mut buffer = String::new();
|
|
||||||
std::fs::File::open(entry.path())
|
|
||||||
.unwrap()
|
|
||||||
.read_to_string(&mut buffer)
|
|
||||||
.unwrap();
|
|
||||||
let sgf = parse_sgf(&buffer).unwrap();
|
|
||||||
games.extend(sgf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => println!("failed entry: {:?}", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Database { path, games })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.games.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn all_games(&self) -> impl Iterator<Item = &GameTree> {
|
|
||||||
self.games.iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
use cool_asserts::assert_matches;
|
|
||||||
use go_sgf::{Date, GameType};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_reads_empty_database() {
|
|
||||||
let db = Database::open_path(PathBuf::from("fixtures/empty_database/"))
|
|
||||||
.expect("database to open");
|
|
||||||
assert_eq!(db.all_games().count(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_reads_five_games_from_database() {
|
|
||||||
let db =
|
|
||||||
Database::open_path(PathBuf::from("fixtures/five_games/")).expect("database to open");
|
|
||||||
assert_eq!(db.all_games().count(), 5);
|
|
||||||
for game in db.all_games() {
|
|
||||||
assert_eq!(game.game_type, GameType::Go);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_matches!(db.all_games().find(|g| g.info.black_player == Some("Steve".to_owned())),
|
|
||||||
Some(game) => {
|
|
||||||
assert_eq!(game.info.black_player, Some("Steve".to_owned()));
|
|
||||||
assert_eq!(game.info.white_player, Some("Savanni".to_owned()));
|
|
||||||
assert_eq!(game.info.date, vec![Date::Date(chrono::NaiveDate::from_ymd_opt(2023, 4, 19).unwrap())]);
|
|
||||||
assert_eq!(game.info.komi, Some(6.5));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,15 +3,12 @@ pub use api::{
|
||||||
CoreApp, CoreRequest, CoreResponse, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest,
|
CoreApp, CoreRequest, CoreResponse, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod types;
|
||||||
|
pub use types::{BoardError, Color, Rank, Size};
|
||||||
|
pub mod ui;
|
||||||
|
|
||||||
mod board;
|
mod board;
|
||||||
pub use board::*;
|
pub use board::*;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
pub use config::*;
|
pub use config::*;
|
||||||
|
|
||||||
mod database;
|
|
||||||
|
|
||||||
mod types;
|
|
||||||
pub use types::{BoardError, Color, Rank, Size};
|
|
||||||
|
|
||||||
pub mod ui;
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
api::PlayStoneRequest,
|
api::PlayStoneRequest,
|
||||||
board::{Board, Coordinate},
|
board::{Board, Coordinate},
|
||||||
config::DatabasePath,
|
|
||||||
database::Database,
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{path::PathBuf, time::Duration};
|
use std::time::Duration;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
|
|
||||||
|
@ -45,14 +43,12 @@ impl Default for Size {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub game: Option<GameState>,
|
pub game: Option<GameState>,
|
||||||
pub database: Database,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
pub fn new(database_path: DatabasePath) -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
game: Some(GameState::new()),
|
game: Some(GameState::new()),
|
||||||
database: Database::open_path(database_path.to_path_buf()).unwrap(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +91,7 @@ impl From<Rank> for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub rank: Option<Rank>,
|
pub rank: Option<Rank>,
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
use go_sgf::{Date, GameTree, Rank};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use typeshare::typeshare;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
#[typeshare]
|
|
||||||
pub struct GamePreviewElement {
|
|
||||||
pub date: Vec<Date>,
|
|
||||||
pub black_player: String,
|
|
||||||
pub black_rank: Option<Rank>,
|
|
||||||
pub white_player: String,
|
|
||||||
pub white_rank: Option<Rank>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GamePreviewElement {
|
|
||||||
pub fn new(game: &GameTree) -> GamePreviewElement {
|
|
||||||
GamePreviewElement {
|
|
||||||
date: game.info.date.clone(),
|
|
||||||
black_player: game
|
|
||||||
.info
|
|
||||||
.black_player
|
|
||||||
.clone()
|
|
||||||
.unwrap_or("black_player".to_owned()),
|
|
||||||
black_rank: game.info.black_rank.clone(),
|
|
||||||
white_player: game
|
|
||||||
.info
|
|
||||||
.white_player
|
|
||||||
.clone()
|
|
||||||
.unwrap_or("white_player".to_owned()),
|
|
||||||
white_rank: game.info.white_rank.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod action;
|
pub mod action;
|
||||||
pub mod game_preview;
|
|
||||||
pub mod menu;
|
pub mod menu;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod elements;
|
mod elements;
|
||||||
pub use elements::{action::Action, game_preview::GamePreviewElement, menu::Menu};
|
pub use elements::{action::Action, menu::Menu};
|
||||||
|
|
||||||
mod playing_field;
|
mod playing_field;
|
||||||
pub use playing_field::{playing_field, PlayingFieldView};
|
pub use playing_field::{playing_field, PlayingFieldView};
|
||||||
|
@ -7,8 +7,8 @@ pub use playing_field::{playing_field, PlayingFieldView};
|
||||||
// mod launch_screen;
|
// mod launch_screen;
|
||||||
// pub use launch_screen::{launch_screen, LaunchScreenView};
|
// pub use launch_screen::{launch_screen, LaunchScreenView};
|
||||||
|
|
||||||
mod home;
|
mod new_game;
|
||||||
pub use home::{home, HomeView, HotseatPlayerElement, PlayerElement};
|
pub use new_game::{new_game, HotseatPlayerElement, NewGameView, PlayerElement};
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
pub use types::{
|
pub use types::{
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::ui::{Action, GamePreviewElement};
|
use crate::ui::Action;
|
||||||
use go_sgf::GameTree;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use typeshare::typeshare;
|
use typeshare::typeshare;
|
||||||
|
|
||||||
|
@ -49,14 +48,13 @@ pub struct BotPlayerElement {}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[typeshare]
|
#[typeshare]
|
||||||
pub struct HomeView {
|
pub struct NewGameView {
|
||||||
pub black_player: PlayerElement,
|
pub black_player: PlayerElement,
|
||||||
pub white_player: PlayerElement,
|
pub white_player: PlayerElement,
|
||||||
pub games: Vec<GamePreviewElement>,
|
|
||||||
pub start_game: Action<()>,
|
pub start_game: Action<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn home<'a>(games: impl Iterator<Item = &'a GameTree>) -> HomeView {
|
pub fn new_game() -> NewGameView {
|
||||||
let black_player = PlayerElement::Hotseat(HotseatPlayerElement {
|
let black_player = PlayerElement::Hotseat(HotseatPlayerElement {
|
||||||
placeholder: Some("black player".to_owned()),
|
placeholder: Some("black player".to_owned()),
|
||||||
default_rank: None,
|
default_rank: None,
|
||||||
|
@ -67,10 +65,9 @@ pub fn home<'a>(games: impl Iterator<Item = &'a GameTree>) -> HomeView {
|
||||||
default_rank: None,
|
default_rank: None,
|
||||||
ranks: rank_strings(),
|
ranks: rank_strings(),
|
||||||
});
|
});
|
||||||
HomeView {
|
NewGameView {
|
||||||
black_player,
|
black_player,
|
||||||
white_player,
|
white_player,
|
||||||
games: games.map(GamePreviewElement::new).collect(),
|
|
||||||
start_game: Action {
|
start_game: Action {
|
||||||
id: "start-game-action".to_owned(),
|
id: "start-game-action".to_owned(),
|
||||||
label: "New Game".to_owned(),
|
label: "New Game".to_owned(),
|
|
@ -121,8 +121,6 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
|
||||||
"time",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
@ -444,7 +442,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -545,17 +543,6 @@ dependencies = [
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "go-sgf"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"nom",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"typeshare",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gobject-sys"
|
name = "gobject-sys"
|
||||||
version = "0.17.4"
|
version = "0.17.4"
|
||||||
|
@ -798,8 +785,6 @@ dependencies = [
|
||||||
name = "kifu-core"
|
name = "kifu-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
|
||||||
"go-sgf",
|
|
||||||
"grid",
|
"grid",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -877,12 +862,6 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
|
@ -900,7 +879,7 @@ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -919,16 +898,6 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.45"
|
version = "0.1.45"
|
||||||
|
@ -1361,17 +1330,6 @@ dependencies = [
|
||||||
"weezl",
|
"weezl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "time"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.26.0"
|
version = "1.26.0"
|
||||||
|
@ -1475,12 +1433,6 @@ version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.10.0+wasi-snapshot-preview1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -2,7 +2,6 @@ release:
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
dev:
|
dev:
|
||||||
export CONFIG=.
|
|
||||||
cargo watch -x 'run --bin kifu-gtk'
|
cargo watch -x 'run --bin kifu-gtk'
|
||||||
|
|
||||||
screenplay:
|
screenplay:
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
{"Me":{"name":"Savanni","rank":{"Kyu":10}},"DatabasePath":"../core/fixtures/five_games"}
|
|
|
@ -2,7 +2,7 @@ use gtk::prelude::*;
|
||||||
use kifu_core::{CoreApp, CoreRequest, CoreResponse};
|
use kifu_core::{CoreApp, CoreRequest, CoreResponse};
|
||||||
use kifu_gtk::{
|
use kifu_gtk::{
|
||||||
perftrace,
|
perftrace,
|
||||||
ui::{Home, PlayingField},
|
ui::{NewGame, PlayingField},
|
||||||
CoreApi,
|
CoreApi,
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
@ -10,10 +10,10 @@ use std::sync::{Arc, RwLock};
|
||||||
fn handle_response(api: CoreApi, window: gtk::ApplicationWindow, message: CoreResponse) {
|
fn handle_response(api: CoreApi, window: gtk::ApplicationWindow, message: CoreResponse) {
|
||||||
let playing_field = Arc::new(RwLock::new(None));
|
let playing_field = Arc::new(RwLock::new(None));
|
||||||
match message {
|
match message {
|
||||||
CoreResponse::HomeView(view) => perftrace("HomeView", || {
|
CoreResponse::NewGameView(view) => perftrace("NewGameView", || {
|
||||||
let api = api.clone();
|
let api = api.clone();
|
||||||
|
|
||||||
let new_game = Home::new(api, view);
|
let new_game = NewGame::new(api, view);
|
||||||
window.set_child(Some(&new_game));
|
window.set_child(Some(&new_game));
|
||||||
}),
|
}),
|
||||||
CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || {
|
CoreResponse::PlayingFieldView(view) => perftrace("PlayingFieldView", || {
|
||||||
|
@ -44,17 +44,10 @@ fn main() {
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let config_path = std::env::var("CONFIG")
|
let user_home = std::env::var("HOME").expect("the user's home directory isn't set");
|
||||||
.and_then(|config| Ok(std::path::PathBuf::from(config)))
|
let mut config_path = std::path::PathBuf::from(user_home);
|
||||||
.or({
|
|
||||||
std::env::var("HOME").and_then(|base| {
|
|
||||||
let mut config_path = std::path::PathBuf::from(base);
|
|
||||||
config_path.push(".config");
|
config_path.push(".config");
|
||||||
config_path.push("kifu");
|
config_path.push("kifu");
|
||||||
Ok(config_path)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.expect("no config path could be found");
|
|
||||||
|
|
||||||
let core = CoreApp::new(config_path);
|
let core = CoreApp::new(config_path);
|
||||||
|
|
||||||
|
@ -94,7 +87,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
api.dispatch(CoreRequest::Home);
|
api.dispatch(CoreRequest::NewGame);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
use glib::Object;
|
|
||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
|
||||||
use kifu_core::ui::GamePreviewElement;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct GamePreviewPrivate;
|
|
||||||
|
|
||||||
#[glib::object_subclass]
|
|
||||||
impl ObjectSubclass for GamePreviewPrivate {
|
|
||||||
const NAME: &'static str = "GamePreview";
|
|
||||||
type Type = GamePreview;
|
|
||||||
type ParentType = gtk::Box;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectImpl for GamePreviewPrivate {}
|
|
||||||
impl WidgetImpl for GamePreviewPrivate {}
|
|
||||||
impl BoxImpl for GamePreviewPrivate {}
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct GamePreview(ObjectSubclass<GamePreviewPrivate>) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GamePreview {
|
|
||||||
pub fn new(element: GamePreviewElement) -> GamePreview {
|
|
||||||
let s: Self = Object::builder().build();
|
|
||||||
s.set_orientation(gtk::Orientation::Horizontal);
|
|
||||||
|
|
||||||
println!("game_preview: {:?}", element);
|
|
||||||
let black_player = match element.black_rank {
|
|
||||||
Some(rank) => format!("{} ({})", element.black_player, rank.to_string()),
|
|
||||||
None => element.black_player,
|
|
||||||
};
|
|
||||||
let white_player = match element.white_rank {
|
|
||||||
Some(rank) => format!("{} ({})", element.white_player, rank.to_string()),
|
|
||||||
None => element.white_player,
|
|
||||||
};
|
|
||||||
s.append(>k::Label::new(Some(&black_player)));
|
|
||||||
s.append(>k::Label::new(Some(&white_player)));
|
|
||||||
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +1,14 @@
|
||||||
mod chat;
|
|
||||||
pub use chat::Chat;
|
|
||||||
|
|
||||||
mod game_preview;
|
|
||||||
pub use game_preview::GamePreview;
|
|
||||||
|
|
||||||
mod player_card;
|
mod player_card;
|
||||||
pub use player_card::PlayerCard;
|
pub use player_card::PlayerCard;
|
||||||
|
|
||||||
|
mod chat;
|
||||||
|
pub use chat::Chat;
|
||||||
|
|
||||||
mod playing_field;
|
mod playing_field;
|
||||||
pub use playing_field::PlayingField;
|
pub use playing_field::PlayingField;
|
||||||
|
|
||||||
mod home;
|
mod new_game;
|
||||||
pub use home::Home;
|
pub use new_game::NewGame;
|
||||||
|
|
||||||
mod board;
|
mod board;
|
||||||
pub use board::Board;
|
pub use board::Board;
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use crate::ui::GamePreview;
|
|
||||||
use crate::CoreApi;
|
use crate::CoreApi;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||||
use kifu_core::{
|
use kifu_core::{
|
||||||
ui::{HomeView, PlayerElement},
|
ui::{NewGameView, PlayerElement},
|
||||||
CoreRequest, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest,
|
CoreRequest, CreateGameRequest, HotseatPlayerRequest, PlayerInfoRequest,
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
@ -83,12 +82,12 @@ impl PlayerDataEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HomePrivate {
|
pub struct NewGamePrivate {
|
||||||
black_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
black_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
||||||
white_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
white_player: Rc<RefCell<Option<PlayerDataEntry>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for HomePrivate {
|
impl Default for NewGamePrivate {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
black_player: Rc::new(RefCell::new(None)),
|
black_player: Rc::new(RefCell::new(None)),
|
||||||
|
@ -98,22 +97,22 @@ impl Default for HomePrivate {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for HomePrivate {
|
impl ObjectSubclass for NewGamePrivate {
|
||||||
const NAME: &'static str = "Home";
|
const NAME: &'static str = "NewGame";
|
||||||
type Type = Home;
|
type Type = NewGame;
|
||||||
type ParentType = gtk::Grid;
|
type ParentType = gtk::Grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectImpl for HomePrivate {}
|
impl ObjectImpl for NewGamePrivate {}
|
||||||
impl WidgetImpl for HomePrivate {}
|
impl WidgetImpl for NewGamePrivate {}
|
||||||
impl GridImpl for HomePrivate {}
|
impl GridImpl for NewGamePrivate {}
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct Home(ObjectSubclass<HomePrivate>) @extends gtk::Grid, gtk::Widget;
|
pub struct NewGame(ObjectSubclass<NewGamePrivate>) @extends gtk::Grid, gtk::Widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Home {
|
impl NewGame {
|
||||||
pub fn new(api: CoreApi, view: HomeView) -> Home {
|
pub fn new(api: CoreApi, view: NewGameView) -> NewGame {
|
||||||
let s: Self = Object::builder().build();
|
let s: Self = Object::builder().build();
|
||||||
|
|
||||||
let black_player = PlayerDataEntry::new(view.black_player);
|
let black_player = PlayerDataEntry::new(view.black_player);
|
||||||
|
@ -139,12 +138,6 @@ impl Home {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let game_list = gtk::Box::new(gtk::Orientation::Vertical, 0);
|
|
||||||
s.attach(&game_list, 1, 3, 2, 1);
|
|
||||||
view.games
|
|
||||||
.iter()
|
|
||||||
.for_each(|game_preview| game_list.append(&GamePreview::new(game_preview.clone())));
|
|
||||||
|
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue