Compare commits

..

No commits in common. "bd224094c7d9b3e4a02a217b7c60720a7086bdc9" and "0924b4ee45fbf7dedcebbbb212be604c00b7966c" have entirely different histories.

7 changed files with 170 additions and 6198 deletions

View File

@ -22,12 +22,6 @@ def home():
def background(): def background():
#return the background image #return the background image
return app.send_static_file('azul.webp') return app.send_static_file('azul.webp')
@app.route('/socket.io.js')
def socketio_js():
#return the background image
return app.send_static_file('socket.io.js')
@app.route('/azul-flake.png') @app.route('/azul-flake.png')
def logo(): def logo():
#return the background image #return the background image

File diff suppressed because it is too large Load Diff

View File

@ -10,49 +10,40 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-left: 10vw; margin-left: 20vw;
width: 80vw; width: 60vw;
background-color: #000; /* removed due to low visibility */
color: #fff; /* background: url({{ url_for('static', filename='azul.webp') }}) no-repeat center center fixed;
color-scheme: dark; -webkit-background-size: cover;
} -moz-background-size: cover;
-o-background-size: cover;
div { background-size: cover; */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-wrap: wrap; /* Allow the flex items to wrap onto the next line */
width: 100%;
} }
form { form {
margin-top: 20vh; margin-top: 20px;
max-width: 40em; width: 300px;
min-width: 300px;
margin: 0 auto; margin: 0 auto;
} }
input[type="text"] { input[type="text"] {
padding: 1em; padding: 10px;
margin-top: 1em; margin-top: 10px;
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
border: 0.5em solid #000; border: 2px solid #000;
border-radius: 1em; border-radius: 4px;
} }
input[type="submit"] { input[type="submit"] {
padding: 1em; padding: 10px;
margin-top: 3em; margin-top: 10px;
width: 100%; width: 100%;
background-color: #0000FF; background-color: #0000FF;
color: #fff; color: #fff;
border: none; border: none;
border-radius: 1em; border-radius: 4px;
cursor: pointer; cursor: pointer;
box-shadow: 0px 0.1em 0.5em rgba(255, 255, 255, 0.333); /* Add some shadow for depth */
transition: background-color 0.3s ease;
} }
input[type="submit"]:hover { input[type="submit"]:hover {
@ -60,12 +51,12 @@
} }
button { button {
padding: 1em; padding: 10px;
margin-top: 1em; margin-top: 10px;
background-color: #0000FF; background-color: #0000FF;
color: #fff; color: #fff;
border: none; border: none;
border-radius: 0.5em; border-radius: 4px;
cursor: pointer; cursor: pointer;
} }
@ -76,16 +67,13 @@
</head> </head>
<body> <body>
{% if not game_id %} {% if not game_id %}
<div>
<h1>Create Game</h1>
<h2>Fill in playernames for wanted players</h2>
<h3>Leave empty for no player ...</h3>
</div>
<form method="POST" action="/create"> <form method="POST" action="/create">
<div>Fill inn playernames for wanted players ...</div>
<div>Leave empty for no player ...</div>
<input type="text" name="player1" placeholder="Player 1" required> <input type="text" name="player1" placeholder="Player 1" required>
<input type="text" name="player2" placeholder="Player 2" required> <input type="text" name="player2" placeholder="Player 2" required>
<input type="text" name="player3" placeholder="Player 3" style="background-color: #2a2929;"> <input type="text" name="player3" placeholder="Player 3" style="background-color: #D3D3D3;">
<input type="text" name="player4" placeholder="Player 4" style="background-color: #2a2929;"> <input type="text" name="player4" placeholder="Player 4" style="background-color: #D3D3D3;">
<!-- Add more input fields for more players --> <!-- Add more input fields for more players -->
<input type="submit" value="Create Game"> <input type="submit" value="Create Game">
</form> </form>

View File

@ -5,56 +5,19 @@
<title>Ozai:game</title> <title>Ozai:game</title>
<link rel="icon" type="image/png" href="/azul-flake.png"> <link rel="icon" type="image/png" href="/azul-flake.png">
<style> <style>
* {
--border-color: rgb(172, 172, 172);
--bg-transparency: 0.5;
--tile-size: 2em;
}
body {
background-color: #383737;
color: white;
color-scheme: dark;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
a { a {
padding: 1em;
display: inline-block; display: inline-block;
text-decoration: none; text-decoration: none;
color: #aba4f6; color: black;
background-color: #1919a7; background-color: #c3bfbf;
border-radius: 1em; border-radius: 5px;
font-weight: bold; font-weight: bold;
font-size: 1.5em; /* increase font size */ font-size: 1.5em; /* increase font size */
} }
a:hover { a:hover {
background-color: #204ac8; background-color: #868787;
} }
input[type="submit"] {
border: none;
border-radius: 1em;
background-color: #3232d1;
padding: 1em;
}
input[type="submit"]:hover {
background-color: #3f3ff2;
}
select {
font-size: 1.5em;
}
.move_select {
display: flex;
justify-content: space-around;
flex-direction: row;
align-items: baseline;
}
/* flexbox class */ /* flexbox class */
.flex-row { .flex-row {
display: flex; display: flex;
@ -62,17 +25,10 @@
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
align-items:baseline; align-items:baseline;
}
@media (max-width: 400px) {
.flex-row {
flex-direction: column;
justify-content: center;
align-items: center;
}
} }
.flex-row > * { .flex-row > * {
margin-right: 1em; margin-right: 5px;
} }
.flex-col { .flex-col {
display: flex; display: flex;
@ -82,7 +38,7 @@
.factory { .factory {
overflow: hidden; overflow: hidden;
border: 2px solid var(--border-color); border: 2px solid black;
border-radius: 30%; border-radius: 30%;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -91,13 +47,13 @@
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
height: calc(var(--tile-size) * 3); height: 5em;
width: calc(var(--tile-size) * 3); width: 5em;
} }
#market { #market {
height: calc(var(--tile-size) * 6); height: 10em;
width: calc(var(--tile-size) * 6); width: 10em;
} }
/* put the first element in the corner of the factory */ /* put the first element in the corner of the factory */
.factory-name { .factory-name {
@ -107,7 +63,7 @@
position: relative; position: relative;
top: 0; top: 0;
left: 0; left: 0;
border: 2px solid var(--border-color); border: 2px solid black;
text-align: center; text-align: center;
margin: 0.1em; margin: 0.1em;
width: 1.5em; width: 1.5em;
@ -119,23 +75,16 @@
.factory > * { .factory > * {
border-radius: 10%; border-radius: 10%;
border: 1px solid var(--border-color); border: 1px solid black;
text-align: center; text-align: center;
margin: 0.1em; margin: 0.1em;
width: var(--tile-size); width: 1.5em;
height: var(--tile-size); height: 1.5em;
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
} }
.player_area {
border: 2px solid var(--border-color);
border-radius: 20px;
padding: 10px;
margin: 10px;
}
.wall { .wall {
/* 5*5 grid */ /* 5*5 grid */
display: grid; display: grid;
@ -144,9 +93,9 @@
gap: 0.1em; gap: 0.1em;
} }
.wall > * { .wall > * {
border: 1px solid var(--border-color); border: 1px solid black;
width: var(--tile-size); width: 1.5em;
height: var(--tile-size); height: 1.5em;
text-align: center; text-align: center;
margin-top: 0.1em; margin-top: 0.1em;
} }
@ -163,85 +112,69 @@
align-items:baseline; align-items:baseline;
} }
.pattern_line > * { .pattern_line > * {
border: 1px solid var(--border-color); border: 1px solid black;
text-align: center; text-align: center;
margin: 0.1em; margin: 0.1em;
width: var(--tile-size); width: 1.5em;
height: var(--tile-size); height: 1.5em;
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
} }
.floor_container { .floor {
display: flex; display: flex;
justify-content: left; justify-content: left;
flex-direction: row; flex-direction: row;
align-items:baseline; align-items:baseline;
} }
.floor { .floor > * {
border: 1px solid var(--border-color); border: 1px solid black;
text-align: center; text-align: center;
width: var(--tile-size); width: 1.5em;
height: var(--tile-size); height: 1.5em;
} }
.floor_value {
text-align: center;
width: var(--tile-size);
}
.blue_bg { .blue_bg {
background-color: rgb(49, 157, 245, var(--bg-transparency)); background-color: rgb(49, 157, 245, 0.5);
} }
.yellow_bg { .yellow_bg {
background-color: rgb(247, 148, 62, var(--bg-transparency)); background-color: rgb(245, 245, 10, 0.5);
} }
.red_bg { .red_bg {
background-color: rgb(200, 50, 50, var(--bg-transparency)); background-color: rgb(255, 0, 0, 0.5);
} }
.black_bg { .black_bg {
background-color: rgb(30, 30, 30, var(--bg-transparency)); background-color: rgb(93, 93, 93, 0.5);
} }
.white_bg { .white_bg {
background-color:rgb(130, 130, 130, var(--bg-transparency)); background-color:rgb(208, 202, 195, 0.5);
} }
.blue { .blue {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(49, 157, 245); background-color: rgb(49, 157, 245);
} }
.yellow { .yellow {
border-radius: calc(var(--tile-size) * 0.2); background-color: yellow;
background-color: rgb(247, 148, 62);
} }
.red { .red {
border-radius: calc(var(--tile-size) * 0.2); background-color: red;
background-color: rgb(200, 50, 50);
} }
.black { .black {
border-radius: calc(var(--tile-size) * 0.2); background-color: rgb(93, 93, 93);
background-color: rgb(30, 30, 30);
} }
.white { .white {
border-radius: calc(var(--tile-size) * 0.2); background-color:rgb(208, 202, 195);
background-color:rgb(130, 130, 130);
} }
.start { .start {
border-radius: calc(var(--tile-size) * 0.2); background-color: rgb(255, 1, 238);
background-color: rgb(165, 1, 155);
} }
</style> </style>
</head> </head>
<body> <body>
<div class="flex-row"> <div class="flex-row">
<p>Number of Players: {{ gamestate.n_players }}</p> <p>Number of Players: {{ gamestate.n_players }}</p>
<p>Current Player: {{ gamestate.current_player }}</p> <p>Current Player: {{ gamestate.current_player }}</p>
<p>Playing as: {{ player_name }}</p>
<p>Game Status: {% if gamestate.game_end %}Ended{% else %}Active{% endif %}</p> <p>Game Status: {% if gamestate.game_end %}Ended{% else %}Active{% endif %}</p>
<p>Rounds: {{ gamestate.rounds }}</p> <p>Rounds: {{ gamestate.rounds }}</p>
<p>Days: {{ gamestate.days }}</p> <p>Days: {{ gamestate.days }}</p>
@ -278,19 +211,18 @@
{% endfor %} {% endfor %}
</div> </div>
<div class="flex-row"> <div class="flex-row">
{% for name, player_data in gamestate.players.items() %} {% for name, player_data in gamestate.players.items() %}
<div class="flex-col player_area"> <div class="flex-col">
<div class="flex-row"> <div class="flex-row">
{% if gamestate.current_player == name %}
<p></p>
{% else %}
<p></p>
{% endif %}
{% if player_name == name %} {% if player_name == name %}
<div><strong>{{ name }}</strong></div> <h2>{{ player_name }} (You)</h2>
{% else %} {% else %}
<div>{{ name }}</div> <h2>{{ name }}</h2>
{% endif %}
{% if gamestate.current_player == name %}
<p>(current)</p>
{% endif %} {% endif %}
{% if player_data.ready %} {% if player_data.ready %}
<p>Ready</p> <p>Ready</p>
@ -329,75 +261,32 @@
</div> </div>
</div> </div>
<div class="floor_container" onclick="selectPatternLine(this)" value="floor"> <div class="flex-row">
<div style="width: 0.7em;">1</div>
<div style="width: 0.7em;">1</div>
<div style="width: 0.7em;">2</div>
<div style="width: 0.7em;">2</div>
<div style="width: 0.7em;">2</div>
<div style="width: 0.7em;">3</div>
<div style="width: 0.7em;">3</div>
</div>
<div class="floor" onclick="selectPatternLine(this)" value="floor">
{% set floor_count = 0 %} {% set floor_count = 0 %}
{% set floor_negative_values = [1,1,2,2,2,3,3] %}
{% for color, number in player_data.floor.items() %} {% for color, number in player_data.floor.items() %}
{% if number > 0 %} {% if number > 0 %}
{% set floor_count = floor_count + number %} {% set floor_count = floor_count + number %}
{% for i in range(0, number) %} {% for i in range(0, number) %}
<!-- get index of item and set value to te value of floor_neg.. --> <div class="{{ color }}">{{ color[:1] }}</div>
<div class="flex-col">
<div class="floor_value">-{{ floor_negative_values[i] }}</div>
<div class="{{ color }} floor">{{ color[:1] }}</div>
</div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% if floor_count < 7 %} {% if floor_count < 7 %}
{% set floor_blank_tiles = 7 - floor_count %} {% set floor_blank_tiles = 7 - floor_count %}
{% for i in range(0, floor_blank_tiles) %} {% for i in range(0, floor_blank_tiles) %}
<div class="flex-col"> <div>_</div>
<div class="floor_value">-{{ floor_negative_values[i] }}</div>
<div class="floor">_</div>
</div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</div> </div>
{% if player_name == name %}
<form id='moveForm'</form>>
<div class="flex-col">
<div class="flex-row move_select">
<div>
<label for="source">from:</label>
<select id="source" name="source">
<option value="market">Market</option>
{% for factory in gamestate.factories %}
<option value="{{ loop.index }}">Factory {{ loop.index }}</option>
{% endfor %}
</select>
</div>
<div>
<label for="color">Color:</label>
<select id="color" name="color">
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="yellow">Yellow</option>
<option value="black">Black</option>
<option value="white">White</option>
</select>
</div>
<div>
<label for="destination">to:</label>
<select id="destination" name="destination">
<option value="1">Line 1</option>
<option value="2">Line 2</option>
<option value="3">Line 3</option>
<option value="4">Line 4</option>
<option value="5">Line 5</option>
<option value="floor">Floor</option>
</select>
</div>
</div>
<input type="submit" value="Submit Move" style="margin-top: 1em;">
</div>
</form>
{% endif %}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
@ -407,8 +296,39 @@
{% if player_name %} {% if player_name %}
<h1>Play area</h1>
<p>Playing as: {{ player_name }}</p>
<!-- form for submitting a move, a move is a selection of marcet or factory, what color, and what patternline or floor it goes to. --> <!-- form for submitting a move, a move is a selection of marcet or factory, what color, and what patternline or floor it goes to. -->
<form id='moveForm'</form>>
<label for="source">Source:</label>
<select id="source" name="source">
<option value="market">Market</option>
{% for factory in gamestate.factories %}
<option value="{{ loop.index }}">Factory {{ loop.index }}</option>
{% endfor %}
</select>
<label for="color">Color:</label>
<select id="color" name="color">
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="yellow">Yellow</option>
<option value="black">Black</option>
<option value="white">White</option>
</select>
<label for="destination">Destination:</label>
<select id="destination" name="destination">
<option value="1">Pattern Line 1</option>
<option value="2">Pattern Line 2</option>
<option value="3">Pattern Line 3</option>
<option value="4">Pattern Line 4</option>
<option value="5">Pattern Line 5</option>
<option value="floor">Floor</option>
</select>
<input type="submit" value="Submit Move">
</form>
<!-- button to go to next player --> <!-- button to go to next player -->
{% set current_index = gamestate.player_names.index(player_name) %} {% set current_index = gamestate.player_names.index(player_name) %}
{% set next_index = current_index + 1 if current_index + 1 < gamestate.player_names|length else 0 %} {% set next_index = current_index + 1 if current_index + 1 < gamestate.player_names|length else 0 %}
@ -419,7 +339,7 @@
<script src="/socket.io.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.3/socket.io.js"></script>
<script> <script>
console.log('Game ID: {{ game_id }}'); console.log('Game ID: {{ game_id }}');
console.log('Player Name: {{ player_name }}'); console.log('Player Name: {{ player_name }}');

View File

@ -5,50 +5,38 @@
<link rel="icon" type="image/png" href="/azul-flake.png"> <link rel="icon" type="image/png" href="/azul-flake.png">
<style> <style>
body { body {
background-color: black;
}
div {
display: flex; display: flex;
flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-wrap: wrap; /* Allow the flex items to wrap onto the next line */ height: 100vh;
width: 90%; padding: 10px;
position: relative; background: url({{ url_for('static', filename='azul.webp') }}) no-repeat center center fixed;
left: 5%; -webkit-background-size: cover;
} -moz-background-size: cover;
-o-background-size: cover;
img { background-size: cover;
position: relative;
left: 40%;
width: 20%;
} }
a { a {
display: inline-block; display: inline-block;
margin: 5%; margin-right: 10vh;
padding: 5vh 5vw; /* increase padding to make buttons larger */ margin-left: 10vh;
padding: 10vh 20vh; /* increase padding to make buttons larger */
text-decoration: none; text-decoration: none;
color: white; color: white;
background-color: rgb(0, 120, 247); /* Semi-transparent blue color to mimic the tiles */ background-color: rgba(0, 123, 255, 0.7); /* Semi-transparent blue color to mimic the tiles */
border-radius: 1em; border-radius: 5px;
font-weight: bold; font-weight: bold;
font-size: 3em; /* increase font size */ font-size: 3em; /* increase font size */
box-shadow: 0px 0.5em 1em rgba(255, 255, 255, 0.333); /* Add some shadow for depth */ box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.1); /* Add some shadow for depth */
transition: background-color 0.3s ease; /* Smooth transition for hover and focus */
} }
a:hover {
a:hover, a:focus { background-color: rgba(0, 86, 179, 0.7); /* Darker blue on hover */
background-color: rgba(0, 120, 247, 0.7); /* Darker blue on hover and focus */
outline: none; /* Remove default focus outline */
} }
</style> </style>
</head> </head>
<body> <body>
<img src="azul-flake.png" alt="">
<div>
<a href="/create">Create Game</a> <a href="/create">Create Game</a>
<a href="/join">Join Game</a> <a href="/join">Join Game</a>
</div>
</body> </body>
</html> </html>

View File

@ -7,62 +7,26 @@
<style> <style>
body { body {
display: flex; display: flex;
flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: black; height: 100vh;
color: white; padding: 10px;
color-scheme: dark; background: url({{ url_for('static', filename='azul.webp') }}) no-repeat center center fixed;
} -webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
form { background-size: cover;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 5vh;
width: 80%;
max-width: 500px;
}
button, input[type="submit"] {
background-color: #0000FF;
cursor: pointer;
box-shadow: 0px 0.1em 0.5em rgba(255, 255, 255, 0.333);
margin-top: 2em;
}
button, input[type="submit"], input[type="text"] {
margin-top: 5vh;
padding: 1em;
margin-top: 1em;
color: #fff;
border: none;
border-radius: 1em;
width: 100%;
}
@media (max-width: 768px) {
input[type="text"], input[type="submit"], button {
font-size: 1.5em;
}
} }
</style> </style>
</head> </head>
<body> <body>
<img src="azul-flake.png" alt="">
<!-- a field to add a game id --> <!-- a field to add a game id -->
<form id="joinGameForm" method="POST" action="/join" onsubmit="submitForm(event)"> <form id="joinGameForm" method="POST" action="/join" onsubmit="submitForm(event)">
<input type="text" name="game_id" placeholder="Game ID" required value="{{ game_id }}"> <input type="text" name="game_id" placeholder="Game ID" required value="{{ game_id }}">
<input type="submit" value="Join Game"> <input type="submit" value="Join Game">
<button onclick="window.history.back();">Back</button>
</form> </form>
<button onclick="window.history.back();">Back</button>
<!-- script to get from localstorage and prefill join game -->
</body>
<script> <script>
function submitForm(e) { function submitForm(e) {
e.preventDefault(); e.preventDefault();
@ -84,5 +48,15 @@
//redirect to join game //redirect to join game
window.location.href = '/join_game/' + game_id; window.location.href = '/join_game/' + game_id;
</script> </script>
<noscript>
<p>manual redirect</p>
<a href="/join_game/+{{ game_id }}">Go to player selection</a>
</noscript>
{% endif %} {% endif %}
<noscript>
<p>JavaScript is not enabled. Some convenience migth not work.</p>
</noscript>
</body>
</html> </html>

View File

@ -4,6 +4,10 @@
<head> <head>
<title>Ozai webui:Join Game</title> <title>Ozai webui:Join Game</title>
<style> <style>
* {
box-sizing: border-box;
margin-left: 3em;
}
body { body {
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
margin: 0; margin: 0;
@ -12,61 +16,36 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: black;
color: white;
color-scheme: dark;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
div{
margin-top: 20vh;
}
div,form {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-wrap: wrap; /* Allow the flex items to wrap onto the next line */
width: 90vw;
} }
ul { ul {
list-style-type: none; list-style-type: none;
padding: 0; padding: 0;
} }
li { li {
margin-bottom: 1em; margin-bottom: 10px;
}
form {
margin-top: 20px;
} }
select, input[type="submit"] { select, input[type="submit"] {
padding: 1em; padding: 10px;
margin-top: 1em; margin-top: 10px;
width: 40%;
min-width: 30em;
max-width: 50em;
height: 8vh;
} }
input[type="submit"] { input[type="submit"] {
background-color: #3779fd; background-color: #3779fd;
border: none; border: none;
border-radius: 1em;
text-decoration: none; text-decoration: none;
margin: 6em 1em; margin: 4px 2px;
cursor: pointer; cursor: pointer;
} }
</style> </style>
</head> </head>
<body> <body>
<div>
{% if game_id %} {% if game_id %}
<p>Selected game to join is: <strong>{{ game_id }}</strong></p> <p>Selected game to join is: <strong>{{ game_id }}</strong></p>
{% endif %} {% endif %}
@ -88,26 +67,25 @@
</select> </select>
<input type="submit" value="Join Game"> <input type="submit" value="Join Game">
</form> </form>
{% else %} {% else %}
<p>No players found in game, please recreate the game.</p> <p>No players found in game, please recreate the game.</p>
{% endif %} {% endif %}
{% if player_name %} {% if player_name %}
<noscript>
<p>Selected player to join as: {{ player_name }}</p> <p>Selected player to join as: {{ player_name }}</p>
<p>manual redirect</p>
<a href="/game/{{ game_id }}/player/{{ player_name }}">Go to game</a>
</noscript>
<script> <script>
// Save player name in browser session for auto fill in game page // Save player name in browser session for auto fill in game page
sessionStorage.setItem('player_name', '{{ player_name }}'); sessionStorage.setItem('player_name', '{{ player_name }}');
//redirect to game //redirect to game
window.location.href = '/game/{{ game_id }}/player/{{ player_name }}'; window.location.href = '/game/{{ game_id }}/player/{{ player_name }}';
</script> </script>
<noscript>
<p>manual redirect</p>
<a href="/game/{{ game_id }}/player/{{ player_name }}">Go to game</a>
</noscript>
{% endif %} {% endif %}
</div>
</body> </body>
</html> </html>