online multiplayer chess game (note server currently down)
Diffstat (limited to 'SanParse/SanParse.gd')
| -rw-r--r-- | SanParse/SanParse.gd | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/SanParse/SanParse.gd b/SanParse/SanParse.gd new file mode 100644 index 0000000..3669672 --- /dev/null +++ b/SanParse/SanParse.gd @@ -0,0 +1,156 @@ +extends Node +class_name SanParser + +const end := "(\\+|\\#)?(\\?\\?|\\?|\\?!|!|!!)?$" # annotation + +var regexs := { + "pawn_move": compile("^([a-h])([1-8])"), + "long_pawn_move": compile("^([a-h])([1-8])([a-h])([1-8])"), # long-san + "piece_movement": compile("^([KQBNR])([a-h])([1-8])"), + "specific_row_piece_movement": compile("^([KQBNR])([0-9])([a-h])([1-8])"), + "specific_column_piece_movement": compile("^([KQBNR])([a-h])([a-h])([1-8])"), + "long_piece_movement": compile("^([KQBNR])([a-h])([0-9])([a-h])([1-8])"), + "pawn_capture": compile("^([a-h])x([a-h])([1-8])(?:=?([KQBNR]))?"), + "long_pawn_capture": compile("^([a-h])([1-8])x([a-h])([1-8])(?:=?([KQBNR]))?"), + "piece_capture": compile("^([KQBNR])x([a-h])([1-8])"), + "specific_column_piece_capture": compile("^([KQBNR])([a-h])x([a-h])([1-8])"), + "specific_row_piece_capture": compile("^([KQBNR])([0-9])x([a-h])([1-8])"), + "long_piece_capture": compile("^([KQBNR])([a-h])([0-9])x([a-h])([1-8])"), + "pawn_promotion": compile("^([a-h])([1-8])=?([KQBNR])"), + "castling": compile("^(O-O-O|O-O)"), +} + + +static func pos(col: String, row: String) -> Vector2: + return Utils.from_algebraic(col + row) + + +const UNKNOWN_POS = Vector2(-1, -1) +enum { PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING } + + +func from_str(string: String) -> int: + var find = " NBRQK".find(string) + if find != -1: + return find + else: + return "PNBRQK".find(string) + + +func compile(regxstr: String, app_end := true) -> RegEx: #app_end because append end get it + var reg = RegEx.new() + reg.compile(regxstr + end if app_end else regxstr) + return reg + + +func parse(san: String) -> Move: + var mv = regexmatch(san) + mv.generated_from = san # for debugging i just moved the thing over so i can do this + return mv + + +func regexmatch(san: String) -> Move: + var re: RegExMatch = regexs.pawn_move.search(san) + if re: + var cap = re.strings + var mov = Move.new(PAWN, [UNKNOWN_POS, pos(cap[1], cap[2])]) + mov.set_check_type(cap[3]) + return mov + + re = regexs.long_pawn_move.search(san) + if re: + var cap = re.strings + var mov = Move.new(PAWN, [pos(cap[1], cap[2]), pos(cap[3], cap[4])]) + mov.set_check_type(cap[5]) + return mov + + re = regexs.piece_movement.search(san) + if re: + var cap = re.strings + var mov = Move.new(from_str(cap[1]), [UNKNOWN_POS, pos(cap[2], cap[3])]) + mov.set_check_type(cap[4]) + return mov + + re = regexs.specific_row_piece_movement.search(san) + if re: + var cap = re.strings + var mov = Move.new(from_str(cap[1]), [Vector2(-1, Utils.row_pos(cap[2])), pos(cap[3], cap[4])]) + mov.set_check_type(cap[5]) + return mov + + re = regexs.specific_column_piece_movement.search(san) + if re: + var cap = re.strings + var mov = Move.new(from_str(cap[1]), [Vector2(Utils.col_pos(cap[2]), -1), pos(cap[3], cap[4])]) + mov.set_check_type(cap[5]) + return mov + + re = regexs.long_piece_movement.search(san) + if re: + var cap = re.strings + var mov = Move.new(from_str(cap[1]), [pos(cap[2], cap[3]), pos(cap[4], cap[5])]) + mov.set_check_type(cap[6]) + return mov + + re = regexs.pawn_capture.search(san) + if re: + var cap = re.strings + var mov = Move.new(PAWN, [Vector2(Utils.col_pos(cap[1]), -1), pos(cap[2], cap[3])], true) + mov.promotion = from_str(cap[4]) + mov.set_check_type(cap[5]) + return mov + + re = regexs.long_pawn_capture.search(san) + if re: + var cap = re.strings + var mov = Move.new(PAWN, [pos(cap[1], cap[2]), pos(cap[3], cap[4])], true) + mov.promotion = from_str(cap[5]) + mov.set_check_type(cap[6]) + return mov + + re = regexs.piece_capture.search(san) + if re: + var cap = re.strings + var mov = Move.new(from_str(cap[1]), [Vector2(Utils.col_pos(cap[2]), -1), pos(cap[3], cap[4])], true) + mov.set_check_type(cap[5]) + return mov + + re = regexs.specific_column_piece_capture.search(san) + if re: + var cap = re.strings + var mov = Move.new(from_str(cap[1]), [Vector2(Utils.col_pos(cap[2]), -1), pos(cap[3], cap[4])], true) + mov.set_check_type(cap[5]) + return mov + + re = regexs.specific_row_piece_capture.search(san) + if re: + var cap = re.strings + var mov = Move.new(from_str(cap[1]), [Vector2(-1, Utils.row_pos(cap[2])), pos(cap[3], cap[4])], true) + mov.set_check_type(cap[5]) + return mov + + re = regexs.long_piece_capture.search(san) + if re: + var cap = re.strings + var mov = Move.new(from_str(cap[1]), [pos(cap[2], cap[3]), pos(cap[4], cap[5])], true) + mov.set_check_type(cap[6]) + return mov + + re = regexs.pawn_promotion.search(san) + if re: + var cap = re.strings + var mov = Move.new(PAWN, [UNKNOWN_POS, pos(cap[1], cap[2])], true) + mov.promotion = from_str(cap[3]) + mov.set_check_type(cap[4]) + return mov + + re = regexs.castling.search(san) + if re: + var cap = re.strings + var mov = Move.new(KING, Move.castle_type(cap[1])) + mov.set_check_type(cap[2]) + return mov + + push_error("regex exhausted: no matches(%s)" % san) + + return null |