/
sfen_parser.js
119 lines (108 loc) · 3.66 KB
/
sfen_parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import XRegExp from "xregexp"
import _ from "lodash"
import { ParserBase } from "./parser_base"
import { Piece } from "./piece"
import { Place } from "./place"
import { Soldier } from "./soldier"
import { Location } from "./location"
class SfenParser extends ParserBase {
parse() {
this.kifu_body = this.kifu_body.replace(/startpos/, "sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1")
const regex = XRegExp("sfen\\s+(?<sfen>\\S+)\\s+(?<b_or_w>\\S+)\\s+(?<hold_pieces>\\S+)\\s+(?<turn_counter_next>\\d+)(\\s+moves\\s+(?<moves>.*))?")
this.attributes = XRegExp.exec(this.kifu_body, regex)
console.table(this.attributes)
if (process.env.NODE_ENV === "deveopment") {
console.log(this.attributes)
}
}
get board() {
let board = new Map()
this.attributes["sfen"].split("/").forEach((e, y) => {
let x = 0
XRegExp.forEach(e, XRegExp("(?<promoted>\\+?)(?<piece>\\S)"), (m, i) => {
if (/\d+/.test(m.piece)) {
x += Number(m.piece)
} else {
const soldier = new Soldier({
place: new Place([x, y]),
piece: Piece.fetch(m.piece),
promoted: (m.promoted === "+"),
location: this.__location_by_upper_or_lower_case(m.piece),
})
board.set(soldier.place.key, soldier)
x++
}
})
})
return board
}
get location_base() {
let key = null
if (this.attributes["b_or_w"] === "b") {
key = "black"
} else {
key = "white"
}
return Location.fetch(key)
}
get hold_pieces() {
const _hold_pieces = super.hold_pieces
if (this.attributes["hold_pieces"] !== "-") {
XRegExp.forEach(this.attributes["hold_pieces"], XRegExp("(?<count>\\d+)?(?<piece_char>\\S)"), (md, i) => {
const piece = Piece.fetch(md.piece_char)
let count = Number(md.count || 1)
const location = this.__location_by_upper_or_lower_case(md.piece_char)
count += _hold_pieces.get(location.key).get(piece.key) || 0
_hold_pieces.get(location.key).set(piece.key, count)
})
}
return _hold_pieces
}
get turn_min() {
return Number(this.attributes["turn_counter_next"]) - 1
}
get komaochi_p() {
return (this.turn_min % 2) === 0 && this.location_base.key === "white"
}
get move_infos() {
if (_.isNil(this.attributes["moves"])) {
return []
}
return this.attributes["moves"].split(/\s+/).map((e, i) => {
const attrs = {}
// if (true) {
// attrs["scene_index"] = this.turn_min + i
// attrs["scene_offset"] = i
// }
attrs["location"] = this.location_by_offset(i)
const md = XRegExp.exec(e, XRegExp("(?<origin_x>\\S)(?<origin_y>\\S)(?<pos_x>\\S)(?<pos_y>\\S)(?<promoted>\\+?)?"))
attrs["promoted_trigger"] = (md.promoted === "+")
if (md["origin_y"] === "*") {
attrs["drop_piece"] = Piece.fetch(md["origin_x"])
} else {
attrs["origin_place"] = Place.fetch(`${md["origin_x"]}${md["origin_y"]}`)
}
attrs["place"] = Place.fetch(`${md["pos_x"]}${md["pos_y"]}`)
return attrs
})
}
__location_by_upper_or_lower_case(v) {
let key = null
if (/[A-Z]/.test(v)) {
key = "black"
} else {
key = "white"
}
return Location.fetch(key)
}
}
export { SfenParser }
if (process.argv[1] === __filename) {
const sfen_parser = new SfenParser()
sfen_parser.kifu_body = "position sfen +lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b S2s 1 moves 7i6h S*2d"
sfen_parser.parse()
console.log(sfen_parser.board)
console.log(sfen_parser.location_base.key)
console.log(sfen_parser.hold_pieces)
console.log(sfen_parser.move_infos)
}