-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
115 lines (88 loc) · 5.05 KB
/
main.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
from flask import *
from colour import Color
from catan.board.terrain_hexes import terrain_hex_distribution, TerrainType
from catan.generation.generate_board import generate_balanced_board, generate_unbalanced_board
# How many random boards to test in generate_balanced_board and generate_unbalanced_board:
# The higher this value is, the better and more consistent the results will be (at the expense of generation time)
num_random = 10 ** 4
# How many hexes and how many number tokens should be on a Catan board. See render_generated_board() for usage and more.
num_hexes = sum(list(terrain_hex_distribution.values()))
num_number_tokens = num_hexes - terrain_hex_distribution['DESERT']
# A dictionary with keys equal to TerrainType values and values corresponding to the appropriate class to add to the
# <g> tag in static/img/catan_board.svg for a TerrainHex of this TerrainType
svg_class_conversions = {terrain_type.value: terrain_type.name.lower() for terrain_type in TerrainType}
# Use the Colour library to generate a range of colors between green and red, with 101 steps in between. This will be
# used to give a color to the calculated balance value, in increments of 0.01 (green = 0, red = 1)
balance_color_range = list(Color('#228b22').range_to(Color('#ff0000'), 101))
app = Flask(__name__)
# Render home page
@app.route('/')
def render_home_page():
return render_template('index.html')
# Render generated board, if the right GET parameters are provided
@app.route('/view-board', methods=['GET'])
def render_generated_board():
# Read get parameters
hexes = request.args.get('hexes')
numbers = request.args.get('numbers')
score = request.args.get('score')
# If one of the parameters is missing, send the user back to the home page
if hexes is None or numbers is None or score is None:
return redirect('/', code=307, Response=None)
# Split into arrays of strings
hexes_arr = hexes.split(',')
numbers_arr = numbers.split(',')
# Check if the lengths of these arrays are correct:
# There should be as many items in hexes_arr as there are TerrainHexes in the game
# There should be len(hexes_arr) - the number of deserts in the game items in numbers_arr, as deserts have no
# NumberTokens on them.
#
# The number of TerrainHexes in the game and the number of deserts were pulled from terrain_hex_distribution
#
# If either length is incorrect, redirect to the home page
if len(hexes_arr) != num_hexes or len(numbers_arr) != num_number_tokens:
return redirect('/', code=307, Response=None)
# Convert to integers and floats
try:
converted_hexes_arr = list(map(int, hexes_arr))
converted_numbers_arr = list(map(int, numbers_arr))
converted_score = float(score)
# Check if the converted score is in the proper generated range. If not, redirect to the home page
if converted_score < 0 or converted_score > 1:
return redirect('/', code=307, Response=None)
# Check if every resource type is valid
for enum_value in converted_hexes_arr:
if TerrainType(enum_value) is None:
return redirect('/', code=307, Response=None)
# Check if every number token value is valid
for number_token_value in converted_numbers_arr:
if not 2 <= number_token_value <= 12:
return redirect('/', code=307, Response=None)
# If we have reached this point, everything is valid! Render the page with the parsed data
return render_template('view_board.html', terrain_hex_arr=converted_hexes_arr,
number_token_arr=converted_numbers_arr, score=converted_score,
svg_class_conversions=json.dumps(svg_class_conversions),
balance_color=balance_color_range[round(round(converted_score, 2) / 0.01)].hex)
except ValueError:
# One of the values is not a number, thus the parameters are invalid and the user should be redirected home
return redirect('/', code=307, Response=None)
# Listen and comply to board generation requests
@app.route('/generate-board', methods=['POST'])
def api_generate_board():
req_json = request.get_json(silent=True)
generating_balanced = req_json['isBalanced']
generated_board, board_balance_score = generate_balanced_board(
num_random) if generating_balanced else generate_unbalanced_board(num_random)
terrain_hexes, number_tokens = generated_board.get_board_arrays()
# Build the URL to redirect to the board-viewing page with the board's data passed into the GET parameters
redirect_url = '/view-board?hexes={0}&numbers={1}&score={2}'.format(','.join(map(str, terrain_hexes)),
','.join(map(str, number_tokens)),
board_balance_score)
return_data = {
'status': 'ok',
'code': 200,
'redirect_url': redirect_url
}
return jsonify(return_data)
if __name__ == "__main__":
app.run()