alae auf eigenen Wunsch deaktiviert
Anmeldungsdatum: 23.03.2006 Beiträge: 7039
|
(#1963389) Verfasst am: 09.11.2014, 11:02 Titel: |
|
|
Hier noch mal der komplette Code:
Code: |
symbols = {
6: 'K', 5: 'D', 4: 'L', 3: 'S', 2: 'T', 1: 'B',
-6: 'k', -5: 'd', -4: 'l', -3: 's', -2: 't', -1: 'b',
0: '.'
}
long_index = (
21, 22, 23, 24, 25, 26, 27, 28,
31, 32, 33, 34, 35, 36, 37, 38,
41, 42, 43, 44, 45, 46, 47, 48,
51, 52, 53, 54, 55, 56, 57, 58,
61, 62, 63, 64, 65, 66, 67, 68,
71, 72, 73, 74, 75, 76, 77, 78,
81, 82, 83, 84, 85, 86, 87, 88,
91, 92, 93, 94, 95, 96, 97, 98,
)
white_king_table = (
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-20, -30, -30, -40, -40, -30, -30, -20,
-10, -20, -20, -20, -20, -20, -20, -10,
20, 20, 0, 0, 0, 0, 20, 20,
20, 30, 10, 0, 0, 10, 30, 20,
)
white_king_endgame_table = (
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-20, -30, -30, -40, -40, -30, -30, -20,
-10, -20, -20, -20, -20, -20, -20, -10,
20, 20, 0, 0, 0, 0, 20, 20,
20, 30, 10, 0, 0, 10, 30, 20,
)
white_queen_table = (
-20, -10, -10, -5, -5, -10, -10, -20,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, 0, 5, 5, 5, 5, 0, -10,
-5, 0, 5, 5, 5, 5, 0, -5,
0, 0, 5, 5, 5, 5, 0, -5,
-10, 5, 5, 5, 5, 5, 0, -10,
-10, 0, 5, 0, 0, 0, 0, -10,
-20, -10, -10, -5, -5, -10, -10, -20,
)
white_bishop_table = (
-20, -10, -10, -10, -10, -10, -10, -20,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 5, 5, 10, 10, 5, 5, -10,
-10, 0, 10, 10, 10, 10, 0, -10,
-10, 10, 10, 10, 10, 10, 10, -10,
-10, 5, 0, 0, 0, 0, 5, -10,
-20, -10, -10, -10, -10, -10, -10, -20,
)
white_knight_table = (
-20, -10, -10, -10, -10, -10, -10, -20,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 5, 5, 10, 10, 5, 5, -10,
-10, 0, 10, 10, 10, 10, 0, -10,
-10, 10, 10, 10, 10, 10, 10, -10,
-10, 5, 0, 0, 0, 0, 5, -10,
-20, -10, -10, -10, -10, -10, -10, -20,
)
white_rook_table = (
0, 0, 0, 0, 0, 0, 0, 0,
5, 10, 10, 10, 10, 10, 10, 5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
0, 0, 0, 5, 5, 0, 0, 0,
)
white_pawn_table = (
0, 0, 0, 0, 0, 0, 0, 0,
50, 50, 50, 50, 50, 50, 50, 50,
10, 10, 20, 30, 30, 20, 10, 10,
5, 5, 10, 25, 25, 10, 5, 5,
0, 0, 0, 20, 20, 0, 0, 0,
5, -5, -10, 0, 0, -10, -5, 5,
5, 10, 10, -20, -20, 10, 10, 5,
0, 0, 0, 0, 0, 0, 0, 0,
)
black_king_table = (
20, 30, 10, 0, 0, 10, 30, 20,
20, 20, 0, 0, 0, 0, 20, 20,
-10, -20, -20, -20, -20, -20, -20, -10,
-20, -30, -30, -40, -40, -30, -30, -20,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
)
black_king_endgame_table = (
20, 30, 10, 0, 0, 10, 30, 20,
20, 20, 0, 0, 0, 0, 20, 20,
-10, -20, -20, -20, -20, -20, -20, -10,
-20, -30, -30, -40, -40, -30, -30, -20,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
)
black_queen_table = (
-20, -10, -10, -5, -5, -10, -10, -20,
-10, 0, 5, 0, 0, 0, 0, -10,
-10, 5, 5, 5, 5, 5, 0, -10,
0, 0, 5, 5, 5, 5, 0, -5,
-5, 0, 5, 5, 5, 5, 0, -5,
-10, 0, 5, 5, 5, 5, 0, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-20, -10, -10, -5, -5, -10, -10, -20,
)
black_bishop_table = (
-20, -10, -10, -10, -10, -10, -10, -20,
-10, 5, 0, 0, 0, 0, 5, -10,
-10, 10, 10, 10, 10, 10, 10, -10,
-10, 0, 10, 10, 10, 10, 0, -10,
-10, 5, 5, 10, 10, 5, 5, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-20, -10, -10, -10, -10, -10, -10, -20,
)
black_knight_table = (
-20, -10, -10, -10, -10, -10, -10, -20,
-10, 5, 0, 0, 0, 0, 5, -10,
-10, 10, 10, 10, 10, 10, 10, -10,
-10, 0, 10, 10, 10, 10, 0, -10,
-10, 5, 5, 10, 10, 5, 5, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-20, -10, -10, -10, -10, -10, -10, -20,
)
black_rook_table = (
0, 0, 0, 5, 5, 0, 0, 0,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
5, 10, 10, 10, 10, 10, 10, 5,
0, 0, 0, 0, 0, 0, 0, 0,
)
black_pawn_table = (
0, 0, 0, 0, 0, 0, 0, 0,
5, 10, 10, -20, -20, 10, 10, 5,
5, -5, -10, 0, 0, -10, -5, 5,
0, 0, 0, 20, 20, 0, 0, 0,
5, 5, 10, 25, 25, 10, 5, 5,
10, 10, 20, 30, 30, 20, 10, 10,
50, 50, 50, 50, 50, 50, 50, 50,
0, 0, 0, 0, 0, 0, 0, 0,
)
king_offsets = (-11, -10, -9, -1, 1, 9, 10, 11)
queen_offsets = (-11, -10, -9, -1, 1, 9, 10, 11)
bishop_offsets = (-11, -9, 9, 11)
knight_offsets = (-21, -19, -12, -8, 8, 12, 19, 21)
rook_offsets = (-10, -1, 1, 10)
white_pawn_offsets = (-11, -9)
black_pawn_offsets = (9, 11)
class Position:
def __init__(self, position=None):
if position is not None:
self.board = list(position.board)
self.player = -position.player
self.castling = list(position.castling)
self.en_passant = None
self.halfmove_clock = position.halfmove_clock
self.move = None
else:
self.board = [
-7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
-7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
-7, -2, -3, -4, -5, -6, -4, -3, -2, -7,
-7, -1, -1, -1, -1, -1, -1, -1, -1, -7,
-7, 0, 0, 0, 0, 0, 0, 0, 0, -7,
-7, 0, 0, 0, 0, 0, 0, 0, 0, -7,
-7, 0, 0, 0, 0, 0, 0, 0, 0, -7,
-7, 0, 0, 0, 0, 0, 0, 0, 0, -7,
-7, 1, 1, 1, 1, 1, 1, 1, 1, -7,
-7, 2, 3, 4, 5, 6, 4, 3, 2, -7,
-7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
-7, -7, -7, -7, -7, -7, -7, -7, -7, -7,
]
self.player = 1
self.castling = [True, True, True, True]
self.en_passant = None
self.halfmove_clock = 0
self.move = None
def __eq__(self, other):
if self.board != other.board:
return False
if self.player != other.player:
return False
if self.castling != other.castling:
return False
if self.en_passant != other.en_passant:
return False
return True
def __str__(self):
s = ''
for i in range(64):
if i % 8 == 0:
s += str(8 - i // 8) + ' '
s += symbols[self.board[long_index[i]]] + ' '
if i % 8 == 7:
s += '\n'
s += ' a b c d e f g h \n'
return s
def attacked(self, target, attacker):
# Königsangriffe
for offset in king_offsets:
origin = target - offset
if attacker * self.board[origin] == 6:
return True
# Damenangriffe
for offset in queen_offsets:
origin = target - offset
while True:
if attacker * self.board[origin] == 5:
return True
elif self.board[origin] != 0:
break
else:
origin -= offset
# Läuferangriffe
for offset in bishop_offsets:
origin = target - offset
while True:
if attacker * self.board[origin] == 4:
return True
elif self.board[origin] != 0:
break
else:
origin -= offset
# Springerangriffe
for offset in knight_offsets:
origin = target - offset
if attacker * self.board[origin] == 3:
return True
# Turmangriffe
for offset in rook_offsets:
origin = target - offset
while True:
if attacker * self.board[origin] == 2:
return True
elif self.board[origin] != 0:
break
else:
origin -= offset
# weiße Bauernangriffe
if attacker == 1:
for offset in white_pawn_offsets:
origin = target - offset
if self.board[origin] == 1:
return True
# schwarze Bauernangriffe
else:
for offset in black_pawn_offsets:
origin = target - offset
if self.board[origin] == -1:
return True
return False
def capturable(self, square):
i = self.player * self.board[square]
return i <= -1 and i >= -6
def capturable_or_empty(self, square):
i = self.player * self.board[square]
return i <= 0 and i >= -6
def checkmate_impossible(self):
knights = 0
light_square_bishops = 0
dark_square_bishops = 0
for i in range(64):
square = long_index[i]
if abs(self.board[square]) in (5, 2, 1):
return False
elif abs(self.board[square]) == 4:
if i % 2 == i // 8 % 2:
light_square_bishops += 1
else:
dark_square_bishops += 1
elif abs(self.board[square]) == 3:
knights += 1
if knights > 1:
return False
if knights == 1 and light_square_bishops + black_square_bishops == 0:
return True
elif knights == 0 and (light_square_bishops == 0 or black_square_bishops == 0):
return True
else:
return False
def empty(self, square):
return self.board[square] == 0
def endgame(self):
white_queens = 0
white_rooks = 0
white_minor_pieces = 0
black_queens = 0
black_rooks = 0
black_minor_pieces = 0
for i in range(64):
piece = self.board[long_index[i]]
if piece == 5:
white_queens += 1
elif piece == 2:
white_rooks += 1
elif piece in (3, 4):
white_minor_pieces += 1
elif piece == -5:
black_queens += 1
elif piece == -2:
black_rooks += 1
elif piece in (-3, -4):
black_minor_pieces += 1
white_endgame = white_queens == 0 or white_queens == 1 and white_rooks == 0 and white_minor_pieces <= 1
black_endgame = black_queens == 0 or black_queens == 1 and black_rooks == 0 and black_minor_pieces <= 1
return white_endgame and black_endgame
def evaluate(self):
score = 0
endgame = self.endgame()
for i in range(64):
piece = self.board[long_index[i]]
if piece == 6:
if endgame:
score += white_king_endgame_table[i]
else:
score += white_king_table[i]
elif piece == 5:
score += 900 + white_queen_table[i]
elif piece == 4:
score += 330 + white_bishop_table[i]
elif piece == 3:
score += 320 + white_knight_table[i]
elif piece == 2:
score += 500 + white_rook_table[i]
elif piece == 1:
score += 100 + white_pawn_table[i]
elif piece == -6:
if endgame:
score -= black_king_endgame_table[i]
else:
score -= black_king_table[i]
elif piece == -5:
score -= 900 + black_queen_table[i]
elif piece == -4:
score -= 330 + black_bishop_table[i]
elif piece == -3:
score -= 320 + black_knight_table[i]
elif piece == -2:
score -= 500 + black_rook_table[i]
elif piece == -1:
score -= 100 + black_pawn_table[i]
return score
def generate_moves(self):
moves = []
for i in range(64):
origin = long_index[i]
if self.movable(origin):
# König
if abs(self.board[origin]) == 6:
for offset in king_offsets:
target = origin + offset
if self.capturable_or_empty(target):
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
# Dame
elif abs(self.board[origin]) == 5:
for offset in queen_offsets:
target = origin + offset
while self.capturable_or_empty(target):
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
if self.capturable(target):
break
target += offset
# Läufer
elif abs(self.board[origin]) == 4:
for offset in bishop_offsets:
target = origin + offset
while self.capturable_or_empty(target):
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
if self.capturable(target):
break
target += offset
# Springer
elif abs(self.board[origin]) == 3:
for offset in knight_offsets:
target = origin + offset
if self.capturable_or_empty(target):
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
# Turm
elif abs(self.board[origin]) == 2:
for offset in rook_offsets:
target = origin + offset
while self.capturable_or_empty(target):
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
if self.capturable(target):
break
target += offset
# weißer Bauer
elif self.board[origin] == 1:
target = origin - 10
if self.empty(target):
if target // 10 == 2:
for promotion in (5, 4, 3, 2):
move = self.make_move(origin, target, promotion)
if move.legal():
moves.append(move)
else:
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
if origin // 10 == 8:
target -= 10
if self.empty(target):
move = self.make_move(origin, target)
move.en_passant = target
if move.legal():
moves.append(move)
for offset in white_pawn_offsets:
target = origin + offset
if self.capturable(target):
if target // 10 == 2:
for promotion in (5, 4, 3, 2):
move = self.make_move(origin, target, promotion)
move.en_passant = target
if move.legal():
moves.append(move)
else:
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
# schwarzer Bauer
elif self.board[origin] == -1:
target = origin + 10
if self.empty(target):
if target // 10 == 9:
for promotion in (-5, -4, -3, -2):
move = self.make_move(origin, target, promotion)
if move.legal():
moves.append(move)
else:
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
if origin // 10 == 3:
target += 10
if self.empty(target):
move = self.make_move(origin, target)
move.en_passant = target
if move.legal():
moves.append(move)
for offset in black_pawn_offsets:
target = origin + offset
if self.capturable(target):
if target // 10 == 9:
for promotion in (-5, -4, -3, -2):
move = self.make_move(origin, target, promotion)
if move.legal():
moves.append(move)
else:
move = self.make_move(origin, target)
if move.legal():
moves.append(move)
# Rochade
if self.player == 1:
if self.castling[0] and self.board[96] == 0 and self.board[97] == 0 and not self.attacked(95, -1) and not self.attacked(96, -1) and not self.attacked(97, -1):
move = self.make_move(95, 97)
move.board[96] = 2
move.board[98] = 0
if move.legal():
moves.append(move)
if self.castling[1] and self.board[94] == 0 and self.board[93] == 0 and self.board[92] == 0 and not self.attacked(95, -1) and not self.attacked(94, -1) and not self.attacked(93, -1):
move = self.make_move(95, 93)
move.board[94] = 2
move.board[91] = 0
if move.legal():
moves.append(move)
else:
if self.castling[2] and self.board[26] == 0 and self.board[27] == 0 and not self.attacked(25, 1) and not self.attacked(26, 1) and not self.attacked(27, 1):
move = self.make_move(25, 27)
move.board[26] = -2
move.board[28] = 0
if move.legal():
moves.append(move)
if self.castling[3] and self.board[24] == 0 and self.board[23] == 0 and self.board[22] == 0 and not self.attacked(25, 1) and not self.attacked(24, 1) and not self.attacked(23, 1):
move = self.make_move(25, 23)
move.board[24] = -2
move.board[21] = 0
if move.legal():
moves.append(move)
# en passant
if self.en_passant is not None:
if self.player == 1:
target = self.en_passant - 10
origin = self.en_passant - 1
if self.board[origin] == 1:
move = self.make_move(origin, target)
move.board[self.en_passant] = 0
if move.legal():
moves.append(move)
origin = self.en_passant + 1
if self.board[origin] == 1:
move = self.make_move(origin, target)
move.board[self.en_passant] = 0
if move.legal():
moves.append(move)
else:
target = self.en_passant + 10
origin = self.en_passant - 1
if self.board[origin] == -1:
move = self.make_move(origin, target)
move.board[self.en_passant] = 0
if move.legal():
moves.append(move)
origin = self.en_passant + 1
if self.board[origin] == -1:
move = self.make_move(origin, target)
move.board[self.en_passant] = 0
if move.legal():
moves.append(move)
return moves
def king_in_check(self, defender):
for i in range(64):
target = long_index[i]
if defender * self.board[target] == 6:
return self.attacked(target, -defender)
def legal(self):
return not self.king_in_check(-self.player)
def make_move(self, origin, target, promotion=None):
move = Position(self)
if move.board[origin] == 1 or move.board[origin] == -1 or move.board[target] != 0:
move.halfmove_clock = 0
else:
move.halfmove_clock += 1
if promotion is not None:
move.board[target] = promotion
else:
move.board[target] = move.board[origin]
move.board[origin] = 0
if origin == 95 or origin == 98 or target == 98:
move.castling[0] = False
if origin == 95 or origin == 91 or target == 91:
move.castling[1] = False
if origin == 25 or origin == 28 or target == 28:
move.castling[2] = False
if origin == 25 or origin == 21 or target == 21:
move.castling[3] = False
move.move = chr(96 + origin % 10) + str(10 - origin // 10) + chr(96 + target % 10) + str(10 - target // 10)
if promotion is not None:
move.move += symbols[promotion]
return move
def movable(self, square):
i = self.player * self.board[square]
return i >= 1 and i <= 6
def maxi(position, depth, toplevel=True):
if depth == 0:
return position.evaluate()
moves = position.generate_moves()
if len(moves) == 0:
if position.king_in_check(1):
return -20000 # Schachmatt
else:
return 0 # Patt
score = -100000
for move in moves:
move_score = mini(move, depth - 1, False)
if toplevel:
print(move.move + ': ' + str(move_score))
if move_score > score:
score = move_score
if toplevel:
global best_move
best_move = move
return score
def mini(position, depth, toplevel=True):
if depth == 0:
return position.evaluate()
moves = position.generate_moves()
if len(moves) == 0:
if position.king_in_check(-1):
return 20000 # Schachmatt
else:
return 0 # Patt
score = 100000
for move in moves:
move_score = maxi(move, depth - 1, False)
if toplevel:
print(move.move + ': ' + str(move_score))
if move_score < score:
score = move_score
if toplevel:
global best_move
best_move = move
return score
def game_over(position, history):
moves = position.generate_moves()
if len(moves) == 0:
if position.king_in_check(position.player):
print('checkmate')
else:
print('stalemate')
return True
if position.checkmate_impossible():
print('checkmate impossible')
return True
repetitions = 1
for earlier_position in history:
if earlier_position == position:
repetitions += 1
if repetitions == 3:
print('threefold repetition')
return True
if position.halfmove_clock >= 100:
print('draw by fifty-move rule')
return True
return False
if __name__ == '__main__':
position = Position()
history = []
print(position)
move_count = 1
while True:
# weiß (Mensch)
legal = False
while not legal:
human_move = input(str(move_count) + '. ')
moves = position.generate_moves()
for move in moves:
if move.move == human_move:
history.append(position)
position = move
legal = True
break
print()
print(position)
if game_over(position, history):
break
# schwarz (Computer)
mini(position, 4)
print()
print(str(move_count) + '. ...' + best_move.move)
print()
history.append(position)
position = best_move
print(position)
if game_over(position, history):
break
move_count += 1
|
|
|