File size: 4,993 Bytes
ee84822 ac3c79b 21b0446 ac3c79b eb4f09a |
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 |
import eventlet
eventlet.monkey_patch()
import random
import socketio
from flask import Flask, render_template, jsonify
sio = socketio.Server(cors_allowed_origins='*')
app = Flask(__name__)
app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)
WAITING_PLAYERS = []
PLAYER_DATA = {}
GAME_STATES = {}
def init_board():
board = [[None for _ in range(8)] for _ in range(8)]
for row in range(3):
for col in range(8):
if (row + col) % 2 == 1:
board[row][col] = 'b'
for row in range(5, 8):
for col in range(8):
if (row + col) % 2 == 1:
board[row][col] = 'r'
return board
def get_valid_moves(board, row, col, color, is_king):
directions = [(-1, -1), (-1, 1)] if color == 'red' else [(1, -1), (1, 1)]
if is_king:
directions += [(-d[0], -d[1]) for d in directions]
moves, captures = [], []
for dr, dc in directions:
r, c = row + dr, col + dc
if 0 <= r < 8 and 0 <= c < 8 and board[r][c] is None:
moves.append((r, c))
elif 0 <= r < 8 and 0 <= c < 8:
mid_piece = board[r][c]
if mid_piece and mid_piece[0].lower() != color[0]:
r2, c2 = r + dr, c + dc
if 0 <= r2 < 8 and 0 <= c2 < 8 and board[r2][c2] is None:
captures.append(((r2, c2), (r, c)))
return moves, captures
@app.route('/')
def index():
return "Hi" # Ensure 'templates/client.html' exists
@app.route('/state')
def game_state():
return jsonify({'status': 'OK'}) # Avoid accessing PLAYER_DATA here
@sio.event
def connect(sid, environ):
print(f"{sid} connected")
@sio.event
def set_name(sid, data):
name = data.get('name', 'Player')
PLAYER_DATA[sid] = {'name': name}
if WAITING_PLAYERS:
opponent_sid = WAITING_PLAYERS.pop(0)
room = f"room_{sid[:4]}_{opponent_sid[:4]}"
for psid in [sid, opponent_sid]:
pdata = PLAYER_DATA[psid]
pdata['room'] = room
sio.enter_room(psid, room)
players = [(sid, 'red'), (opponent_sid, 'black')]
random.shuffle(players)
for psid, color in players:
PLAYER_DATA[psid]['color'] = color
opp_sid = opponent_sid if psid == sid else sid
opp_name = PLAYER_DATA[opp_sid]['name']
sio.emit("match_found", {'color': color, 'opponent': opp_name}, to=psid)
GAME_STATES[room] = {'board': init_board(), 'turn': 'red'}
else:
WAITING_PLAYERS.append(sid)
@sio.event
def move(sid, data):
pdata = PLAYER_DATA.get(sid)
if not pdata:
return
room = pdata.get('room')
state = GAME_STATES.get(room)
if not state:
return
board = state['board']
turn = state['turn']
color = pdata['color']
if color != turn:
return
from_row, from_col = data['from']
to_row, to_col = data['to']
piece = board[from_row][from_col]
if not piece or piece[0].lower() != color[0]:
return
is_king = piece.isupper()
_, captures = get_valid_moves(board, from_row, from_col, color, is_king)
move_is_capture = abs(to_row - from_row) == 2
if captures and not move_is_capture:
return
board[to_row][to_col] = piece
board[from_row][from_col] = None
if move_is_capture:
cap_row = (from_row + to_row) // 2
cap_col = (from_col + to_col) // 2
board[cap_row][cap_col] = None
_, new_captures = get_valid_moves(board, to_row, to_col, color, is_king or to_row in (0, 7))
if new_captures:
state['board'] = board
GAME_STATES[room] = state
sio.emit('multi_jump', {'from': [to_row, to_col]}, to=sid)
return
if (color == 'red' and to_row == 0) or (color == 'black' and to_row == 7):
board[to_row][to_col] = piece.upper()
flat = sum(board, [])
if all(p not in flat for p in ['r', 'R']):
sio.emit('game_over', {'winner': 'black', 'room': room}, room=room)
del GAME_STATES[room]
return
if all(p not in flat for p in ['b', 'B']):
sio.emit('game_over', {'winner': 'red', 'room': room}, room=room)
del GAME_STATES[room]
return
state['board'] = board
state['turn'] = 'black' if turn == 'red' else 'red'
GAME_STATES[room] = state
sio.emit('opponent_move', {'move': data, 'room': room, 'sid': sid}, room=room, skip_sid=sid)
@sio.event
def disconnect(sid):
print(f"{sid} disconnected")
if sid in WAITING_PLAYERS:
WAITING_PLAYERS.remove(sid)
pdata = PLAYER_DATA.pop(sid, None)
if pdata and 'room' in pdata:
room = pdata['room']
for psid in list(PLAYER_DATA.keys()):
if PLAYER_DATA[psid].get('room') == room:
del PLAYER_DATA[psid]
if room in GAME_STATES:
del GAME_STATES[room]
sio.emit('opponent_disconnected', room=room)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860) |