File size: 6,681 Bytes
1a3554c
0efcaab
1a3554c
 
 
 
 
7bc796e
aa815df
1a3554c
7bc796e
1a3554c
0efcaab
1a3554c
 
 
 
 
 
 
 
 
 
0efcaab
1a3554c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7bc796e
 
 
0efcaab
7bc796e
1a3554c
 
 
 
aa815df
1a3554c
 
 
 
0efcaab
1a3554c
0efcaab
1a3554c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0efcaab
1a3554c
0cc968c
1a3554c
 
 
 
 
 
 
0efcaab
1a3554c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0efcaab
1a3554c
 
 
 
 
 
 
 
 
 
 
0efcaab
1a3554c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0efcaab
 
 
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# app.py
from flask import Flask, render_template, request, jsonify, session
from stockfish import Stockfish
import uuid
import chess
import chess.pgn
from datetime import datetime

app = Flask(__name__)
app.secret_key = 'your-secret-key-change-this'

# Configuration Stockfish
try:
    stockfish = Stockfish(
        path="/usr/local/bin/stockfish",  # Ajustez selon votre installation
        parameters={
            "Threads": 2,
            "Hash": 256,
            "Skill Level": 15,  # Niveau IA (0-20)
            "Minimum Thinking Time": 100
        }
    )
except:
    stockfish = None
    print("Stockfish non trouvé. Mode IA désactivé.")

class ChessGame:
    def __init__(self, game_id, mode='human'):
        self.game_id = game_id
        self.mode = mode  # 'human' ou 'ai'
        self.board = chess.Board()
        self.moves_history = []
        self.current_player = 'white'
        self.game_status = 'active'  # 'active', 'checkmate', 'stalemate', 'draw'
        self.created_at = datetime.now()
        
    def make_move(self, move_uci):
        """Effectue un coup et retourne le résultat"""
        try:
            move = chess.Move.from_uci(move_uci)
            
            if move in self.board.legal_moves:
                self.board.push(move)
                self.moves_history.append(move_uci)
                
                # Changer de joueur
                self.current_player = 'black' if self.current_player == 'white' else 'white'
                
                # Vérifier l'état du jeu
                self._update_game_status()
                
                return {
                    'success': True,
                    'move': move_uci,
                    'board_fen': self.board.fen(),
                    'current_player': self.current_player,
                    'game_status': self.game_status,
                    'legal_moves': [move.uci() for move in self.board.legal_moves],
                    'is_check': self.board.is_check()
                }
            else:
                return {'success': False, 'error': 'Coup illégal'}
                
        except Exception as e:
            return {'success': False, 'error': str(e)}
    
    def get_ai_move(self):
        """Obtient le coup de l'IA via Stockfish"""
        if not stockfish or self.mode != 'ai':
            return None
            
        try:
            stockfish.set_fen_position(self.board.fen())
            ai_move = stockfish.get_best_move()
            return ai_move
        except:
            return None
    
    def _update_game_status(self):
        """Met à jour l'état du jeu"""
        if self.board.is_checkmate():
            winner = 'black' if self.current_player == 'white' else 'white'
            self.game_status = f'checkmate_{winner}'
        elif self.board.is_stalemate():
            self.game_status = 'stalemate'
        elif self.board.is_insufficient_material():
            self.game_status = 'draw_material'
        elif self.board.is_seventyfive_moves():
            self.game_status = 'draw_75moves'
        elif self.board.is_fivefold_repetition():
            self.game_status = 'draw_repetition'
    
    def get_board_state(self):
        """Retourne l'état complet du plateau"""
        return {
            'fen': self.board.fen(),
            'current_player': self.current_player,
            'game_status': self.game_status,
            'legal_moves': [move.uci() for move in self.board.legal_moves],
            'is_check': self.board.is_check(),
            'moves_history': self.moves_history,
            'move_count': len(self.moves_history)
        }

# Stockage des parties en mémoire (remplacez par une base de données en production)
games = {}

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/game/<mode>')
def game(mode):
    if mode not in ['human', 'ai']:
        return "Mode de jeu invalide", 400
    
    # Créer une nouvelle partie
    game_id = str(uuid.uuid4())
    games[game_id] = ChessGame(game_id, mode)
    session['game_id'] = game_id
    
    return render_template('game.html', mode=mode, game_id=game_id)

@app.route('/api/game/state')
def get_game_state():
    game_id = session.get('game_id')
    if not game_id or game_id not in games:
        return jsonify({'error': 'Partie non trouvée'}), 404
    
    game = games[game_id]
    return jsonify(game.get_board_state())

@app.route('/api/game/move', methods=['POST'])
def make_move():
    game_id = session.get('game_id')
    if not game_id or game_id not in games:
        return jsonify({'error': 'Partie non trouvée'}), 404
    
    data = request.json
    move = data.get('move')
    
    if not move:
        return jsonify({'error': 'Coup manquant'}), 400
    
    game = games[game_id]
    result = game.make_move(move)
    
    return jsonify(result)

@app.route('/api/game/ai-move', methods=['POST'])
def get_ai_move():
    game_id = session.get('game_id')
    if not game_id or game_id not in games:
        return jsonify({'error': 'Partie non trouvée'}), 404
    
    game = games[game_id]
    
    if game.mode != 'ai':
        return jsonify({'error': 'Mode IA non activé'}), 400
    
    if game.current_player != 'black':  # IA joue les noirs
        return jsonify({'error': 'Ce n\'est pas le tour de l\'IA'}), 400
    
    ai_move = game.get_ai_move()
    if not ai_move:
        return jsonify({'error': 'IA ne peut pas jouer'}), 500
    
    # Effectuer le coup de l'IA
    result = game.make_move(ai_move)
    result['ai_move'] = True
    
    return jsonify(result)

@app.route('/api/game/reset', methods=['POST'])
def reset_game():
    game_id = session.get('game_id')
    if not game_id or game_id not in games:
        return jsonify({'error': 'Partie non trouvée'}), 404
    
    game = games[game_id]
    # Réinitialiser la partie
    games[game_id] = ChessGame(game_id, game.mode)
    
    return jsonify({'success': True, 'message': 'Partie réinitialisée'})

@app.route('/api/game/legal-moves')
def get_legal_moves():
    game_id = session.get('game_id')
    if not game_id or game_id not in games:
        return jsonify({'error': 'Partie non trouvée'}), 404
    
    data = request.args
    square = data.get('square')
    
    if not square:
        return jsonify({'error': 'Case manquante'}), 400
    
    game = games[game_id]
    legal_moves = []
    
    for move in game.board.legal_moves:
        if move.from_square == chess.parse_square(square):
            legal_moves.append(chess.square_name(move.to_square))
    
    return jsonify({'legal_moves': legal_moves})

if __name__ == '__main__':
    app.run(debug=True)