Last active
August 24, 2024 22:10
-
-
Save Dani4kor/e1e8b439115878f8c6dcf127a4ed5d3e to your computer and use it in GitHub Desktop.
Python FEN chess Validation with regular expression
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def fenPass(fen): | |
""" | |
""" | |
regexMatch=re.match('\s*^(((?:[rnbqkpRNBQKP1-8]+\/){7})[rnbqkpRNBQKP1-8]+)\s([b|w])\s([K|Q|k|q]{1,4})\s(-|[a-h][1-8])\s(\d+\s\d+)$', fen) | |
if regexMatch: | |
regexList = regexMatch.groups() | |
fen = regexList[0].split("/") | |
if len(fen) != 8: | |
raise ValueError("expected 8 rows in position part of fen: {0}".format(repr(fen))) | |
for fenPart in fen: | |
field_sum = 0 | |
previous_was_digit, previous_was_piece = False,False | |
for c in fenPart: | |
if c in ["1", "2", "3", "4", "5", "6", "7", "8"]: | |
if previous_was_digit: | |
raise ValueError("two subsequent digits in position part of fen: {0}".format(repr(fen))) | |
field_sum += int(c) | |
previous_was_digit = True | |
previous_was_piece = False | |
elif c == "~": | |
if not previous_was_piece: | |
raise ValueError("~ not after piece in position part of fen: {0}".format(repr(fen))) | |
previous_was_digit, previous_was_piece = False,False | |
elif c.lower() in ["p", "n", "b", "r", "q", "k"]: | |
field_sum += 1 | |
previous_was_digit = False | |
previous_was_piece = True | |
else: | |
raise ValueError("invalid character in position part of fen: {0}".format(repr(fen))) | |
if field_sum != 8: | |
raise ValueError("expected 8 columns per row in position part of fen: {0}".format(repr(fen))) | |
else: raise ValueError("fen doesn`t match follow this example: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 ") | |
def main(): | |
try: | |
fenPass('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1') | |
except ValueError as e: | |
print e.message | |
if __name__ == '__main__': | |
main() |
For regexList = regexMatch.groups(), it may be better to replace this with regexList = fen.split().
For this FEN: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", regexMatch.groups() sets regexList equal to:
["rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/", "w", "KQkq", "-", "0 1"]
In the gist provided this doesn't make any difference, but if someone wanted to test more than the first portion of their FEN, the subsequent elements might not be what they expect. In terms of FEN notation, the second element shouldn't exist, and the "0 1" should be two different elements.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@PanCave You can remove the condition since it is redundant. The regex expression matching will never allow
~
in the FEN notation