Last active
March 21, 2016 19:10
-
-
Save mekhami/08634d36007a5eba0a14 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| import sys | |
| import unittest | |
| class ChessGame(object): | |
| fen_startpos = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" | |
| fen_test = "rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -" | |
| def __init__(self): | |
| self.board = [["#"]*12 for i in range(12)] | |
| self.turn = "-" | |
| self.castling = "-" | |
| self.ep = "-" | |
| self.set_fen(ChessGame.fen_startpos) | |
| def set_fen(self, fen): | |
| parts = fen.split(" ") | |
| # Board setup | |
| sq = 110 | |
| for a in range(0, len(parts[0])): | |
| if(parts[0][a].isalpha()): | |
| self.board[sq%12][sq/12] = parts[0][a] | |
| sq += 1 | |
| elif(parts[0][a] == "/"): | |
| sq -= 20 | |
| else: | |
| for b in range(0, int(parts[0][a])): | |
| self.board[(sq+b)%12][(sq+b)/12] = "-" | |
| sq += int(parts[0][a]) | |
| # Side to play | |
| if(len(parts) >= 1): | |
| if(parts[1] == "w"): | |
| self.turn = "w" | |
| elif(parts[1] == "b"): | |
| self.turn = "b" | |
| else: | |
| self.turn = "w" | |
| # Castling | |
| if(len(parts) >= 2): | |
| self.castling = parts[2] | |
| def get_fen(self): | |
| fen = "" | |
| fen += " " | |
| fen += self.turn | |
| fen += " " | |
| fen += self.castling | |
| fen += " -" | |
| return fen | |
| def get_url(self): | |
| return "http://lichess.org/editor/{}".format(self.fen) | |
| def print_board(self): | |
| for y in range(0, 8): | |
| for x in range(0, 8): | |
| sys.stdout.write(self.board[x+2][7-y+2]) | |
| sys.stdout.write("\n") | |
| print("Turn: {}".format(self.turn)) | |
| print("Castling: {}".format(self.castling)) | |
| def pos_get_col(self, str): | |
| if(str[0] == "a"): | |
| return 0; | |
| if(str[0] == "b"): | |
| return 1; | |
| if(str[0] == "c"): | |
| return 2; | |
| if(str[0] == "d"): | |
| return 3; | |
| if(str[0] == "e"): | |
| return 4; | |
| if(str[0] == "f"): | |
| return 5; | |
| if(str[0] == "g"): | |
| return 6; | |
| if(str[0] == "h"): | |
| return 7; | |
| def pos_get_row(self, str): | |
| if(str[1] == "1"): | |
| return 0; | |
| if(str[1] == "2"): | |
| return 1; | |
| if(str[1] == "3"): | |
| return 2; | |
| if(str[1] == "4"): | |
| return 3; | |
| if(str[1] == "5"): | |
| return 4; | |
| if(str[1] == "6"): | |
| return 5; | |
| if(str[1] == "7"): | |
| return 6; | |
| if(str[1] == "8"): | |
| return 7; | |
| def board_get(self, col, row): | |
| return self.board[col+2][row+2] | |
| def find_move_wP(self, col_to, row_to, hint="-"): | |
| if(hint != "-"): | |
| return [self.pos_get_col(hint), row_to-1] | |
| else: | |
| if(self.board_get(col_to, row_to-1) == "P"): | |
| return [col_to, row_to-1] | |
| elif(self.board_get(col_to, row_to-2) == "P"): | |
| return [col_to, row_to-2] | |
| else: | |
| return None | |
| def find_move_bP(self, col_to, row_to, hint="-"): | |
| if(hint != "-"): | |
| return [self.pos_get_col(hint), row_to+1] | |
| else: | |
| if(self.board_get(col_to, row_to+1) == "p"): | |
| return [col_to, row_to+1] | |
| elif(self.board_get(col_to, row_to+2) == "p"): | |
| return [col_to, row_to+2] | |
| else: | |
| return None | |
| def find_move_N(self, piece, col_to, row_to, hint="-"): | |
| if(self.board_get(col_to-1, row_to+2) == piece): # Up 2 left 1 | |
| return [col_to-1, row_to+2] | |
| elif(self.board_get(col_to+1, row_to+2) == piece): # Up 2 right 1 | |
| return [col_to+1, row_to+2] | |
| elif(self.board_get(col_to-1, row_to-2) == piece): # Down 2 left 1 | |
| return [col_to-1, row_to-2] | |
| elif(self.board_get(col_to+1, row_to-2) == piece): # Down 2 right 1 | |
| return [col_to+1, row_to-2] | |
| elif(self.board_get(col_to+2, row_to+1) == piece): # Right 2 up 1 | |
| return [col_to+2, row_to+1] | |
| elif(self.board_get(col_to+2, row_to-1) == piece): # Right 2 down 1 | |
| return [col_to+2, row_to-1] | |
| elif(self.board_get(col_to-2, row_to+1) == piece): # Left 2 up 1 | |
| return [col_to-2, row_to+1] | |
| elif(self.board_get(col_to-2, row_to-1) == piece): # Left 2 down 1 | |
| return [col_to-2, row_to-1] | |
| else: | |
| return None | |
| def find_move_B(self, piece, col_to, row_to, hint="-"): | |
| # Up and right | |
| for a in range(0, 8): | |
| if(self.board_get(col_to+a, row_to+a) != "-"): | |
| if(self.board_get(col_to+a, row_to+a) == piece): | |
| return [col_to+a, row_to+a] | |
| else: | |
| break | |
| # Up and left | |
| for a in range(0, 8): | |
| if(self.board_get(col_to-a, row_to+a) != "-"): | |
| if(self.board_get(col_to-a, row_to+a) == piece): | |
| return [col_to-a, row_to+a] | |
| else: | |
| break | |
| # Down and right | |
| for a in range(0, 8): | |
| if(self.board_get(col_to+a, row_to-a) != "-"): | |
| if(self.board_get(col_to+a, row_to-a) == piece): | |
| return [col_to+a, row_to-a] | |
| else: | |
| break | |
| # Down and left | |
| for a in range(0, 8): | |
| if(self.board_get(col_to-a, row_to-a) != "-"): | |
| if(self.board_get(col_to-a, row_to-a) == piece): | |
| return [col_to-a, row_to-a] | |
| else: | |
| break | |
| return None | |
| def find_move_R(self, piece, col_to, row_to, hint="-"): | |
| # Right | |
| for a in range(0, 8): | |
| if(self.board_get(col_to+a, row_to) != "-"): | |
| if(self.board_get(col_to+a, row_to) == piece): | |
| return [col_to+a, row_to] | |
| else: | |
| break | |
| # Left | |
| for a in range(0, 8): | |
| if(self.board_get(col_to-a, row_to) != "-"): | |
| if(self.board_get(col_to-a, row_to) == piece): | |
| return [col_to-a, row_to] | |
| else: | |
| break | |
| # Up | |
| for a in range(0, 8): | |
| if(self.board_get(col_to, row_to+a) != "-"): | |
| if(self.board_get(col_to, row_to+a) == piece): | |
| return [col_to, row_to+a] | |
| else: | |
| break | |
| # Down | |
| for a in range(0, 8): | |
| if(self.board_get(col_to, row_to-a) != "-"): | |
| if(self.board_get(col_to, row_to-a) == piece): | |
| return [col_to, row_to-a] | |
| else: | |
| break | |
| return None | |
| def find_move_Q(self, piece, col_to, row_to, hint="-"): | |
| result = self.find_move_B(piece, col_to, row_to, hint); | |
| if(result != None): | |
| return result | |
| result = self.find_move_R(piece, col_to, row_to, hint); | |
| if(result): | |
| return result | |
| return None | |
| def make_move(self, from_col, from_row, to_col, to_row, promotion="-"): | |
| if(from_col < 0 or from_col >= 8 or to_col < 0 or to_row >= 8): | |
| return | |
| if(promotion == "-"): | |
| self.board[to_col+2][to_row+2] = self.board[from_col+2][from_row+2] | |
| else: | |
| self.board[to_col+2][to_row+2] = promotion | |
| self.board[from_col+2][from_row+2] = "-" | |
| return | |
| def make_move_wKSC(self): | |
| self.make_move(4,0, 6,0) | |
| self.make_move(7,0, 5,0) | |
| def make_move_bKSC(self): | |
| self.make_move(4,7, 6,7) | |
| self.make_move(7,7, 5,7) | |
| def parse_move(self, move): | |
| # Special case of castling | |
| if(move == "O-O"): | |
| if(self.turn == "w"): | |
| self.make_move_wKSC() | |
| return | |
| elif(self.turn == "b"): | |
| self.make_move_bKSC() | |
| return | |
| elif(move == "O-O-O"): | |
| if(self.turn == "w"): | |
| self.make_move_wQSC() | |
| return | |
| elif(self.turn == "b"): | |
| self.make_move_bQSC() | |
| return | |
| strip = "!?+#x-:=" | |
| for a in strip: | |
| move = move.replace(a, "") | |
| sys.stdout.write(move + "\t") | |
| type = "P" | |
| if(move[0].isupper()): | |
| type = move[0] | |
| move = move[1:] | |
| promotion = "-" | |
| if(move[-1:].isalpha()): | |
| promotion = move[-1:] | |
| move = move[:-1] | |
| sys.stdout.write(type + " ") | |
| str_from = move[:2] | |
| sys.stdout.write(str_from + " ") | |
| str_to = move[-2:] | |
| sys.stdout.write(str_to + " ") | |
| col_to = self.pos_get_col(str_to) | |
| row_to = self.pos_get_row(str_to) | |
| sys.stdout.write("(" + str(col_to) + "," + str(row_to) + ") ") | |
| sys.stdout.write(promotion + " ") | |
| hint = "-" | |
| if(str_from == str_to): | |
| pass | |
| else: | |
| hint = str_from[0] | |
| sys.stdout.write(hint + " ") | |
| move_found = None | |
| if(self.turn == "w"): | |
| if(type == "P"): | |
| move_found = self.find_move_wP(col_to, row_to, hint) | |
| elif(type == "N"): | |
| move_found = self.find_move_N("N", col_to, row_to, hint) | |
| elif(type == "B"): | |
| move_found = self.find_move_B("B", col_to, row_to, hint) | |
| elif(type == "R"): | |
| move_found = self.find_move_R("R", col_to, row_to, hint) | |
| elif(type == "Q"): | |
| move_found = self.find_move_Q("Q", col_to, row_to, hint) | |
| elif(self.turn == "b"): | |
| if(type == "P"): | |
| move_found = self.find_move_bP(col_to, row_to, hint) | |
| elif(type == "N"): | |
| move_found = self.find_move_N("n", col_to, row_to, hint) | |
| elif(type == "B"): | |
| move_found = self.find_move_B("b", col_to, row_to, hint) | |
| elif(type == "R"): | |
| move_found = self.find_move_R("r", col_to, row_to, hint) | |
| elif(type == "Q"): | |
| move_found = self.find_move_Q("q", col_to, row_to, hint) | |
| if(move_found != None): | |
| sys.stdout.write("(" + str(move_found[0]) + "," + str(move_found[1]) + ") ") | |
| self.make_move(move_found[0], move_found[1], col_to, row_to, promotion) | |
| sys.stdout.write("\n") | |
| return | |
| def parse_moves(self, moves): | |
| split = moves.split(" ") | |
| for a in split: | |
| if(a[0].isdigit() == True): | |
| continue | |
| self.parse_move(a) | |
| if(self.turn == "w"): | |
| self.turn = "b" | |
| else: | |
| self.turn = "w" | |
| self.print_board() | |
| print("") | |
| return | |
| class FenTest(unittest.TestCase): | |
| def test_get_fen_of_new_game(self): | |
| board = ChessGame() | |
| self.assertEqual(board.get_fen(), | |
| "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1") | |
| if __name__ == '__main__': | |
| unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment