Geek7 commited on
Commit
ac3c79b
·
verified ·
1 Parent(s): 0d7f062

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +159 -0
  2. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import socketio
3
+ from flask import Flask, render_template, jsonify
4
+ import eventlet
5
+
6
+ eventlet.monkey_patch()
7
+
8
+ sio = socketio.Server(cors_allowed_origins='*')
9
+ app = Flask(__name__)
10
+ app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)
11
+
12
+ WAITING_PLAYERS = []
13
+ PLAYER_DATA = {}
14
+ GAME_STATES = {}
15
+
16
+ def init_board():
17
+ board = [[None for _ in range(8)] for _ in range(8)]
18
+ for row in range(3):
19
+ for col in range(8):
20
+ if (row + col) % 2 == 1:
21
+ board[row][col] = 'b'
22
+ for row in range(5, 8):
23
+ for col in range(8):
24
+ if (row + col) % 2 == 1:
25
+ board[row][col] = 'r'
26
+ return board
27
+
28
+ def get_valid_moves(board, row, col, color, is_king):
29
+ directions = [(-1, -1), (-1, 1)] if color == 'red' else [(1, -1), (1, 1)]
30
+ if is_king:
31
+ directions += [(-d[0], -d[1]) for d in directions]
32
+
33
+ moves, captures = [], []
34
+ for dr, dc in directions:
35
+ r, c = row + dr, col + dc
36
+ if 0 <= r < 8 and 0 <= c < 8 and board[r][c] is None:
37
+ moves.append((r, c))
38
+ elif 0 <= r < 8 and 0 <= c < 8:
39
+ mid_piece = board[r][c]
40
+ if mid_piece and mid_piece[0].lower() != color[0]:
41
+ r2, c2 = r + dr, c + dc
42
+ if 0 <= r2 < 8 and 0 <= c2 < 8 and board[r2][c2] is None:
43
+ captures.append(((r2, c2), (r, c)))
44
+ return moves, captures
45
+
46
+ @app.route('/')
47
+ def index():
48
+ return render_template('client.html') # Ensure 'templates/client.html' exists
49
+
50
+ @app.route('/state')
51
+ def game_state():
52
+ return jsonify({'status': 'OK'}) # Avoid accessing PLAYER_DATA here
53
+
54
+ @sio.event
55
+ def connect(sid, environ):
56
+ print(f"{sid} connected")
57
+
58
+ @sio.event
59
+ def set_name(sid, data):
60
+ name = data.get('name', 'Player')
61
+ PLAYER_DATA[sid] = {'name': name}
62
+
63
+ if WAITING_PLAYERS:
64
+ opponent_sid = WAITING_PLAYERS.pop(0)
65
+ room = f"room_{sid[:4]}_{opponent_sid[:4]}"
66
+ for psid in [sid, opponent_sid]:
67
+ pdata = PLAYER_DATA[psid]
68
+ pdata['room'] = room
69
+ sio.enter_room(psid, room)
70
+
71
+ players = [(sid, 'red'), (opponent_sid, 'black')]
72
+ random.shuffle(players)
73
+ for psid, color in players:
74
+ PLAYER_DATA[psid]['color'] = color
75
+ opp_sid = opponent_sid if psid == sid else sid
76
+ opp_name = PLAYER_DATA[opp_sid]['name']
77
+ sio.emit("match_found", {'color': color, 'opponent': opp_name}, to=psid)
78
+
79
+ GAME_STATES[room] = {'board': init_board(), 'turn': 'red'}
80
+ else:
81
+ WAITING_PLAYERS.append(sid)
82
+
83
+ @sio.event
84
+ def move(sid, data):
85
+ pdata = PLAYER_DATA.get(sid)
86
+ if not pdata:
87
+ return
88
+ room = pdata.get('room')
89
+ state = GAME_STATES.get(room)
90
+ if not state:
91
+ return
92
+ board = state['board']
93
+ turn = state['turn']
94
+ color = pdata['color']
95
+
96
+ if color != turn:
97
+ return
98
+
99
+ from_row, from_col = data['from']
100
+ to_row, to_col = data['to']
101
+ piece = board[from_row][from_col]
102
+ if not piece or piece[0].lower() != color[0]:
103
+ return
104
+
105
+ is_king = piece.isupper()
106
+ _, captures = get_valid_moves(board, from_row, from_col, color, is_king)
107
+ move_is_capture = abs(to_row - from_row) == 2
108
+ if captures and not move_is_capture:
109
+ return
110
+
111
+ board[to_row][to_col] = piece
112
+ board[from_row][from_col] = None
113
+
114
+ if move_is_capture:
115
+ cap_row = (from_row + to_row) // 2
116
+ cap_col = (from_col + to_col) // 2
117
+ board[cap_row][cap_col] = None
118
+ _, new_captures = get_valid_moves(board, to_row, to_col, color, is_king or to_row in (0, 7))
119
+ if new_captures:
120
+ state['board'] = board
121
+ GAME_STATES[room] = state
122
+ sio.emit('multi_jump', {'from': [to_row, to_col]}, to=sid)
123
+ return
124
+
125
+ if (color == 'red' and to_row == 0) or (color == 'black' and to_row == 7):
126
+ board[to_row][to_col] = piece.upper()
127
+
128
+ flat = sum(board, [])
129
+ if all(p not in flat for p in ['r', 'R']):
130
+ sio.emit('game_over', {'winner': 'black', 'room': room}, room=room)
131
+ del GAME_STATES[room]
132
+ return
133
+ if all(p not in flat for p in ['b', 'B']):
134
+ sio.emit('game_over', {'winner': 'red', 'room': room}, room=room)
135
+ del GAME_STATES[room]
136
+ return
137
+
138
+ state['board'] = board
139
+ state['turn'] = 'black' if turn == 'red' else 'red'
140
+ GAME_STATES[room] = state
141
+ sio.emit('opponent_move', {'move': data, 'room': room, 'sid': sid}, room=room, skip_sid=sid)
142
+
143
+ @sio.event
144
+ def disconnect(sid):
145
+ print(f"{sid} disconnected")
146
+ if sid in WAITING_PLAYERS:
147
+ WAITING_PLAYERS.remove(sid)
148
+ pdata = PLAYER_DATA.pop(sid, None)
149
+ if pdata and 'room' in pdata:
150
+ room = pdata['room']
151
+ for psid in list(PLAYER_DATA.keys()):
152
+ if PLAYER_DATA[psid].get('room') == room:
153
+ del PLAYER_DATA[psid]
154
+ if room in GAME_STATES:
155
+ del GAME_STATES[room]
156
+ sio.emit('opponent_disconnected', room=room)
157
+
158
+ if __name__ == '__main__':
159
+ eventlet.wsgi.server(eventlet.listen(('0.0.0.0', 5000)), app)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ flask
2
+ python-socketio[asyncio_client,client,eventlet]
3
+ eventlet
4
+ asyncpg
5
+ nats-py