-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathapp.py
275 lines (224 loc) · 7.72 KB
/
app.py
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#!/usr/bin/python
''' TEMP '''
import os
import json
import cgitb
import logging
from flask import Flask, request, redirect, abort, render_template
from flask import session
from game import Game
cgitb.enable()
APP = Flask(__name__)
# Generate a random key for user sessions
APP.secret_key = os.urandom(24)
class MetaData():
''' Contains all of the metadata about each match'''
def __init__(self):
'''
Sets testing, debug mode, and initializes games
'''
# TEST_MODE will disable session checking so that games can be started
# with 1 user
self.test_mode = True
# Debug mode will display useful data
self.debug_mode = False
self.num_starting_games = 5
# 2 for ongoing games, 1 for games with 1 person waiting, 0 otherwise
self.games = [0] * self.num_starting_games
self.player_ids = [0]
self.store_games = {}
# Store the user IDs for each game
self.game_players = [[0, 0] for i in range(self.num_starting_games)]
def is_debug(self):
''' Return true if in debug mode '''
return self.debug_mode
def get_games(self):
''' Get all ongoing games '''
return self.store_games
MD = MetaData()
@APP.route('/chess-app', methods=["POST", "GET"])
def main_page():
'''
Handles the main page for the chess web application
'''
# If the user requests to join a new game, get the next game available
# and redirect to URL
if request.method == "POST":
next_available_game = get_next_game()
if next_available_game == -1:
return json.dumps("error")
return json.dumps("game\\" + str(next_available_game))
# Display available games to the user
# If DEBUG MODE is ON, display the raw data without any styling
if MD.debug_mode:
return display_games_available_raw()
return render_template('index.html', games=MD.games,
numberOfGames=len(MD.games))
def display_games_available_raw():
''' Displays a list of the games currently available in raw text format
'''
display = ""
for game_index, game_on in enumerate(MD.games):
display += f"Game {game_index+1}, Available: {bool(not game_on)} <br>"
return display
def get_next_game():
'''
Loops through the list of ongoing games and finds the next game available
'''
for game_id, game_value in enumerate(MD.games):
if game_value < 2:
return game_id
return -1
def get_db():
'''
Implementing SQL to store usernames and passwords
'''
@APP.route('/chess-app/create_game', methods=["POST"])
def create_game():
'''
Creates a new empty game that users can join
'''
MD.games.append(0)
MD.game_players.append([0, 0])
@APP.route('/chess-app/about_us')
def about_us_page():
'''
Renders the "About Us" page
'''
return render_template('about_us.html')
@APP.route('/chess-app/get_games', methods=["POST"])
def get_open_games():
'''
Gets called every x seconds to check which games are currently open.
'''
return json.dumps(MD.games)
@APP.route('/chess-app/make_move', methods=["POST"])
def get_move():
''' Get movedata from AJAX request and make the move for the player
Request is sent when player clicks on a valid square on the board
'''
req_json = request.get_json()
game_num = req_json[34:]
move = req_json[0] + req_json[2] + req_json[4] + req_json[6]
return json.dumps(MD.store_games[int(game_num)].make_move(move))
@APP.route('/chess-app/get_piece_move', methods=["POST"])
def get_piece_move():
''' Runs when the user submits a requests to move a piece.
Obtains movedata as JSON from AJAX request and makes the corresponding move
'''
move_data = request.get_json()
starting_coord = move_data[0] + move_data[2]
game_num = move_data[30:]
allowed_moves = MD.store_games[int(game_num)].get_allowed_moves(starting_coord)
return json.dumps(allowed_moves)
@APP.route('/chess-app/ajax', methods=["POST"])
def get_data():
'''
Test this
'''
try:
# TODO: test this to make sure it's working with the game number
request_data = request.get_json()
print(request_data)
move_data = request_data # TODO
return json.dumps(MD.store_games[0].make_move(move_data))
except KeyError:
pass
@APP.route('/')
def quick_join():
'''
Allows user to join the next available game
'''
game_value = get_next_game()
if game_value == -1:
return "Games in progress...please wait..."
return redirect("game\\" + str(get_next_game()))
@APP.route('/chess-app/show_game', methods=["POST"])
def show_game():
'''
Used for spectating a particular game
'''
return json.dumps('abc')
@APP.route('/chess-app/login', methods=["POST"])
def login(data):
''' Allows the user to log in '''
return json.dumps(data)
@APP.route('/chess-app/spectate/<int:game_num>')
def spectate_game(game_num):
'''
Allows the user to spectate a given game
'''
print(game_num)
return render_template("spectate_game.html")
def get_next_id():
'''
Gets the next ID not currently begin used
'''
MD.player_ids[0] += 1
return MD.player_ids[0]
@APP.route('/chess-app/forgot_password')
def forgot_pw():
'''
Display page for "forgot password" from login screen
'''
return render_template('forgot_password.html')
@APP.route('/chess-app/game/<int:game_num>', methods=["POST", "GET"])
def get_game(game_num):
'''
Handles ongoing chess matches
'''
if request.method == "POST":
try:
# Use JS to create an AJAX request
var = request.form['movedata']
return MD.store_games[game_num].make_move(str(var))
except KeyError:
return "Doing a 404<br>Your last move was: " + \
str(request.form['movedata'])
# abort(404)
if request.method == "GET" and game_num < len(MD.games):
if MD.games[game_num] <= 2:
if not MD.test_mode:
if "player_id" in session:
# make sure that you are not already in the `
if session["player_id"] not in MD.game_players[game_num]:
add_new_player(game_num, session["player_id"])
else:
# create a new session for the user
session["player_id"] = get_next_id()
add_new_player(game_num, session["player_id"])
else:
MD.games[game_num] += 1
if MD.games[game_num] == 2:
# TODO: check session here?
new_game = Game()
MD.store_games[game_num] = new_game
board_data = MD.store_games[game_num].board.get_raw()
board_disp = str(MD.store_games[game_num].board)
return render_template('get_move.html',
board_repr=str(MD.store_games[game_num]),
board_disp=board_disp,
game_num=game_num,
board_data=board_data)
return render_template('waiting.html', game_num=game_num)
if request.method == "GET":
abort(404)
return None
def add_new_player(game_num, play_id):
'''
Checks if the current user is a new player in the game
'''
if MD.game_players[game_num][0] == 0:
MD.game_players[game_num][0] = play_id
else:
MD.game_players[game_num][1] = play_id
MD.games[game_num] += 1
@APP.errorhandler(404)
def page_not_found(err):
'''
Actions to take on a 404 error
'''
logging.info(err)
return render_template("404.html")
if __name__ == "__main__":
APP.run(host='0.0.0.0')