Added history managment
parent
6f6791e30e
commit
d0bbc4a14a
53
chess.py
53
chess.py
|
@ -119,15 +119,18 @@ class Piece:
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.index = 0
|
||||||
self.make_board()
|
self.make_board()
|
||||||
self.moves = []
|
self.moves = []
|
||||||
self.stack = []
|
self.AN_moves = []
|
||||||
|
self.history = []
|
||||||
self.turn = "white"
|
self.turn = "white"
|
||||||
self.can_castle = {"white" : {"queen" : True,
|
self.can_castle = {"white" : {"queen" : True,
|
||||||
"king" : True},
|
"king" : True},
|
||||||
"black" : {"queen" : True,
|
"black" : {"queen" : True,
|
||||||
"king" : True}
|
"king" : True}
|
||||||
}
|
}
|
||||||
|
self.history.append(deepcopy(self))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
# Unicode board representation
|
# Unicode board representation
|
||||||
|
@ -163,6 +166,31 @@ class Game:
|
||||||
self.board["h1"].side = "king"
|
self.board["h1"].side = "king"
|
||||||
self.board["h8"].side = "king"
|
self.board["h8"].side = "king"
|
||||||
|
|
||||||
|
def rebase(self):
|
||||||
|
self.moves = self.moves[:self.index+1]
|
||||||
|
self.history = self.history[:self.index+1]
|
||||||
|
|
||||||
|
def timetravel(self, i):
|
||||||
|
if i >= len(self.history) or i < 0:
|
||||||
|
return False
|
||||||
|
new = self.history[i]
|
||||||
|
self.board = new.board
|
||||||
|
self.turn = new.turn
|
||||||
|
self.can_castle = new.can_castle
|
||||||
|
self.index = i
|
||||||
|
|
||||||
|
def prev(self):
|
||||||
|
return self.timetravel(self.index-1)
|
||||||
|
|
||||||
|
def next(self):
|
||||||
|
return self.timetravel(self.index+1)
|
||||||
|
|
||||||
|
def last(self):
|
||||||
|
return self.timetravel(len(self.history)-1)
|
||||||
|
|
||||||
|
def first(self):
|
||||||
|
return self.timetravel(0)
|
||||||
|
|
||||||
def is_empty(self, sq):
|
def is_empty(self, sq):
|
||||||
return self.board[sq] == None
|
return self.board[sq] == None
|
||||||
|
|
||||||
|
@ -216,6 +244,7 @@ class Game:
|
||||||
if not (are_empty and not_attacked):
|
if not (are_empty and not_attacked):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
self.rebase()
|
||||||
self.board[king_move[1]] = self.board[king_move[0]]
|
self.board[king_move[1]] = self.board[king_move[0]]
|
||||||
self.board[rook_move[1]] = self.board[rook_move[0]]
|
self.board[rook_move[1]] = self.board[rook_move[0]]
|
||||||
self.board[king_move[0]] = Piece()
|
self.board[king_move[0]] = Piece()
|
||||||
|
@ -224,6 +253,8 @@ class Game:
|
||||||
self.can_castle[color]["king"] = False
|
self.can_castle[color]["king"] = False
|
||||||
self.moves.append(king_move)
|
self.moves.append(king_move)
|
||||||
self.turn = invert(self.turn)
|
self.turn = invert(self.turn)
|
||||||
|
self.history.append(deepcopy(self))
|
||||||
|
self.index += 1
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def move(self, source, target, promotion=None):
|
def move(self, source, target, promotion=None):
|
||||||
|
@ -261,10 +292,13 @@ class Game:
|
||||||
if new.is_check(self.turn):
|
if new.is_check(self.turn):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
self.rebase()
|
||||||
self.moves.append((source, target))
|
self.moves.append((source, target))
|
||||||
self.board = new.board
|
self.board = new.board
|
||||||
self.can_castle = new.can_castle
|
self.can_castle = new.can_castle
|
||||||
self.turn = invert(moved.color)
|
self.turn = invert(moved.color)
|
||||||
|
self.history.append(deepcopy(self))
|
||||||
|
self.index += 1
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def is_legal(self, source, target, promotion):
|
def is_legal(self, source, target, promotion):
|
||||||
|
@ -329,7 +363,8 @@ class Game:
|
||||||
r.append(jump)
|
r.append(jump)
|
||||||
for t in targets:
|
for t in targets:
|
||||||
a, b = move(t, dir), move(t, back)
|
a, b = move(t, dir), move(t, back)
|
||||||
en_passant = can_eat(b) and self.moves[-1] == (a,b)
|
en_passant = can_eat(b) and self.index>0 and\
|
||||||
|
self.moves[self.index-1] == (a,b)
|
||||||
if can_eat(t) or en_passant:
|
if can_eat(t) or en_passant:
|
||||||
r.append(t)
|
r.append(t)
|
||||||
return r
|
return r
|
||||||
|
@ -389,6 +424,7 @@ class Game:
|
||||||
return valid, new
|
return valid, new
|
||||||
|
|
||||||
def AN_move(self, move):
|
def AN_move(self, move):
|
||||||
|
AN = move
|
||||||
info = parse_AN(move)
|
info = parse_AN(move)
|
||||||
if info == False:
|
if info == False:
|
||||||
return False
|
return False
|
||||||
|
@ -415,17 +451,28 @@ class Game:
|
||||||
return False
|
return False
|
||||||
move = moves[0]
|
move = moves[0]
|
||||||
self.move(*move)
|
self.move(*move)
|
||||||
|
self.AN_moves.append(AN)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
game = Game()
|
game = Game()
|
||||||
while not game.is_stall():
|
move = ""
|
||||||
|
while not game.is_stall() and move!='q':
|
||||||
move = input(">> ")
|
move = input(">> ")
|
||||||
|
if move == "prev":
|
||||||
|
game.prev()
|
||||||
|
print(game)
|
||||||
|
continue
|
||||||
|
elif move == "next":
|
||||||
|
game.next()
|
||||||
|
print(game)
|
||||||
|
continue
|
||||||
v = game.AN_move(move)
|
v = game.AN_move(move)
|
||||||
if not v:
|
if not v:
|
||||||
print("Invalid")
|
print("Invalid")
|
||||||
continue
|
continue
|
||||||
print(game)
|
print(game)
|
||||||
|
print (game.history)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue