-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplayflask.py
More file actions
150 lines (122 loc) · 4.44 KB
/
playflask.py
File metadata and controls
150 lines (122 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from flask import Flask, render_template, request, jsonify
import chess
import numpy as np
import random
import tensorflow as tf
import chess.engine
app = Flask(__name__)
# Initialize a chess board
board = chess.Board()
# Load the model once to avoid loading it for every move
model = tf.keras.models.load_model('chess_model1.keras')
def encode_board(board):
# first lets turn the board into a string
board_str = str(board)
# then lets remove all the spaces
material_dict = {
'p': -1,
'b': -3.5,
'n': -3,
'r': -5,
'q': -9,
'k': -4,
'K': 4,
'.': 0,
'P': 1,
'B': 3.5,
'N': 3,
'R': 5,
'Q': 9,
}
board_str = board_str.replace(' ', '')
board_list = []
for row in board_str.split('\n'):
row_list = []
for piece in row:
# print(piece)
row_list.append(material_dict.get(piece))
board_list.append(row_list)
return np.array(board_list)
def evaluate_board(board):
piece_values = {
chess.PAWN: 1,
chess.KNIGHT: 3,
chess.BISHOP: 3,
chess.ROOK: 5,
chess.QUEEN: 9,
chess.KING: 0
}
score = 0
for piece_type in piece_values.keys():
score += len(board.pieces(piece_type, chess.WHITE)) * piece_values[piece_type]
score -= len(board.pieces(piece_type, chess.BLACK)) * piece_values[piece_type]
return score
def get_random_move(board):
# Create a chess board from the FEN string
legal_moves = list(board.legal_moves) # Get all legal moves as a list
if legal_moves: # Check if there are any legal moves
random_move = random.choice(legal_moves) # Choose a random legal move
return str(random_move) # Return the move as a string
else:
return None
def calculate_best_move(board, stockfish_path='./stockfish/stockfish-windows-x86-64-avx2.exe', elo=1320):
# Initialize Stockfish engine
with chess.engine.SimpleEngine.popen_uci(stockfish_path) as engine:
# Set Stockfish to use a limited strength (ELO)
engine.configure({"UCI_LimitStrength": True, "UCI_Elo": elo})
# Play the best move for the current position with the given ELO level
result = engine.play(board, chess.engine.Limit(time=1.0))
best_move = result.move
return str(best_move)
def play_nn(fen, player='b'):
board = chess.Board(fen=fen)
stockmove = calculate_best_move(board)
best_move = None
worst_move = None
min_score = float('inf')
max_score = float('-inf')
for move in board.legal_moves:
if move is None:
continue
candidate_board = board.copy()
candidate_board.push(move)
input_vector = encode_board(candidate_board).astype(np.float32)
# Reshape to match the input shape expected by the model (8x8x1)
input_vector = input_vector.reshape(1, 8, 8, 1)
# Predict the board score using the CNN model
score = model.predict(input_vector, verbose=0)[0][0]
if move.uci() == stockmove:
stock_incentive = (max_score - min_score) * 0.5
score += stock_incentive
# Update best and worst moves based on the predicted score
if score > max_score:
best_move = move
max_score = score
if score < min_score:
worst_move = move
min_score = score
# Return the worst move for 'b' (AI playing as black), or best move otherwise
print(f"bestmove:{best_move} worstmove:{worst_move}")
return str(best_move)
# return str(worst_move) if player == 'b' else str(best_move)
@app.route('/')
def index():
return render_template('index.html', board_svg=board._repr_svg_())
@app.route('/make_move', methods=['POST'])
def make_move():
global board
user_move = request.json.get('move')
if user_move and user_move in [str(move) for move in board.legal_moves]:
board.push_san(user_move)
if board.outcome() is not None:
return jsonify({'board_svg': board._repr_svg_(), 'game_over': True})
ai_move = play_nn(board.fen(), player='b')
board.push_san(ai_move)
return jsonify({
'board_svg': board._repr_svg_(),
'ai_move': ai_move,
'game_over': board.outcome() is not None
})
return jsonify({'error': 'Invalid move'})
if __name__ == '__main__':
app.run(debug=True)