ozai-webui/templates/game.html

506 lines
18 KiB
HTML

<!-- HTML for game.html -->
<!DOCTYPE html>
<html>
<head>
<title>Ozai:game</title>
<link rel="icon" type="image/png" href="/azul-flake.png">
<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 {
padding: 1em;
display: inline-block;
text-decoration: none;
color: #aba4f6;
background-color: #1919a7;
border-radius: 1em;
font-weight: bold;
font-size: 1.5em; /* increase font size */
}
a:hover {
background-color: #204ac8;
}
input[type="submit"] {
border: none;
border-radius: 1em;
background-color: #3232d1;
padding: 1em;
}
input[type="submit"]:hover {
background-color: #3f3ff2;
}
select {
font-size: 1.2em;
}
.move_select {
margin-top: 0.5em;
display: flex;
justify-content: space-around;
flex-direction: row;
align-items: baseline;
}
/* flexbox class */
.flex-row {
display: flex;
justify-content: left;
flex-direction: row;
flex-wrap: wrap;
align-items: baseline;
}
@media (max-width: 40em) {
.flex-row {
flex-direction: column;
justify-content: center;
align-items: center;
}
}
.flex-row > * {
margin-right: 1em;
}
.flex-col {
display: flex;
justify-content:space-around;
flex-direction: column;
}
.factory {
overflow: hidden;
border: 0.2em solid var(--border-color);
border-radius: 30%;
display: flex;
justify-content: center;
align-items: center;
/* flex wrap */
flex-direction: row;
flex-wrap: wrap;
height: calc(var(--tile-size) * 3);
width: calc(var(--tile-size) * 3);
}
#market {
height: calc(var(--tile-size) * 7);
width: calc(var(--tile-size) * 7);
}
/* put the first element in the corner of the factory */
.factory-name {
border-radius: 20%;
margin-top: 0;
margin-left: 0;
position: relative;
top: 0;
left: 0;
border: 0.2em solid var(--border-color);
text-align: center;
margin: 0.1em;
width: 1.5em;
height: 1.5em;
overflow: hidden;
text-align: center;
vertical-align: middle;
}
.factory > * {
border-radius: 10%;
border: 0.15em solid var(--border-color);
text-align: center;
margin: 0.1em;
width: var(--tile-size);
height: var(--tile-size);
overflow: hidden;
text-align: center;
vertical-align: middle;
}
.player_area {
border: 0.2em solid var(--border-color);
border-radius: 2em;
padding: 1em;
margin: 1em;
}
.wall {
/* 5*5 grid */
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
gap: 0.1em;
}
.wall > * {
border: 0.15em solid var(--border-color);
width: var(--tile-size);
height: var(--tile-size);
text-align: center;
margin-top: 0.1em;
}
.pattern_lines {
display: flex;
justify-content: space-around;
flex-direction: column;
align-items: start;
}
.pattern_line {
display: flex;
justify-content: right;
flex-direction:row-reverse;
align-items:baseline;
}
.pattern_line > * {
border: 0.15em solid var(--border-color);
text-align: center;
margin: 0.1em;
width: var(--tile-size);
height: var(--tile-size);
overflow: hidden;
text-align: center;
vertical-align: middle;
}
.floor_container {
display: flex;
justify-content: left;
flex-direction: row;
align-items:baseline;
}
.floor {
border: 0.15em solid var(--border-color);
text-align: center;
width: var(--tile-size);
height: var(--tile-size);
}
.floor_value {
text-align: center;
width: var(--tile-size);
}
.blue_bg {
background-color: rgb(49, 157, 245, var(--bg-transparency));
}
.yellow_bg {
background-color: rgb(247, 148, 62, var(--bg-transparency));
}
.red_bg {
background-color: rgb(200, 50, 50, var(--bg-transparency));
}
.black_bg {
background-color: rgb(30, 30, 30, var(--bg-transparency));
}
.white_bg {
background-color:rgb(130, 130, 130, var(--bg-transparency));
}
.blue {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(49, 157, 245);
}
.yellow {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(247, 148, 62);
}
.red {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(200, 50, 50);
}
.black {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(30, 30, 30);
}
.white {
border-radius: calc(var(--tile-size) * 0.2);
background-color:rgb(130, 130, 130);
}
.start {
border-radius: calc(var(--tile-size) * 0.2);
background-color: rgb(165, 1, 155);
}
</style>
</head>
<body>
<div class="flex-row">
<p>Number of Players: {{ gamestate.n_players }}</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>Rounds: {{ gamestate.rounds }}</p>
<p>Days: {{ gamestate.days }}</p>
</div>
<div class="flex-row">
<!-- market -->
<div class="flex-col">
<div class="factory-name">M</div>
<div class="factory" id="market">
{% for color, number in gamestate.market.items() %}
{% if number > 0 %}
{% for i in range(0, number) %}
<div onclick="selectTile(this)" class="{{ color }}">{{ color[:1] }}</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
<!-- factories -->
{% for factory in gamestate.factories %}
<div class="flex col">
<div class="factory-name">{{ loop.index }}</div>
<div class="factory" id="factory{{ loop.index }}">
{% for color, number in factory.items() %}
{% if number > 0 %}
{% for i in range(0, number) %}
<div onclick="selectTile(this)" class="{{ color }}">{{ color[:1] }}</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
</div>
<div class="flex-row">
{% for name, player_data in gamestate.players.items() %}
<div class="flex-col player_area">
<div class="flex-row">
{% if gamestate.current_player == name %}
<p></p>
{% else %}
<p></p>
{% endif %}
{% if player_name == name %}
<div><strong>{{ name }}</strong></div>
{% else %}
<div>{{ name }}</div>
{% endif %}
{% if player_data.ready %}
<p>Ready</p>
{% endif %}
<p>Points: {{ player_data.points }}</p>
</div>
<div class="flex-row">
<div class="flex-col">
<!-- <h3>Pattern Lines</h3> -->
{% for line in player_data.pattern_lines %}
<div class="pattern_line" onclick="selectPatternLine(this)" value="{{loop.index}}">
<!-- TODO: Fix this to not fill empty spaces. -->
{% for i in range(0, loop.index) %}
{% if line.number > i %}
<div class="{{ line.color }}" >{{ line.color[:1] }}</div>
{% else %}
<div >_</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
</div>
<div class="flex-col">
<!-- <h3>Wall</h3> -->
<div class="wall">
{% set colors_base = ['blue', 'yellow', 'red', 'black', 'white'] %}
{% for row in player_data.wall %}
{% set colors = colors_base[-loop.index0:] + colors_base[:-loop.index0] %}
{% for cell in row %}
{% set color = colors[loop.index0] + "_bg" %}
<div class="{{ color }}">{% if cell %}{{ color[:1] }}{% else %}{{ '_' }}{% endif %}</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
<div class="floor_container" onclick="selectPatternLine(this)" value="floor">
{% set floor_count = 0 %}
{% set floor_negative_values = [1,1,2,2,2,3,3] %}
{% for color, number in player_data.floor.items() %}
{% if number > 0 %}
{% set floor_count = floor_count + number %}
{% for i in range(0, number) %}
<!-- get index of item and set value to te value of floor_neg.. -->
<div class="flex-col">
<div class="floor_value">-{{ floor_negative_values[i] }}</div>
<div class="{{ color }} floor">{{ color[:1] }}</div>
</div>
{% endfor %}
{% endif %}
{% endfor %}
{% if floor_count < 7 %}
{% set floor_blank_tiles = 7 - floor_count %}
{% for i in range(0, floor_blank_tiles) %}
<div class="flex-col">
<div class="floor_value">-{{ floor_negative_values[i] }}</div>
<div class="floor">_</div>
</div>
{% endfor %}
{% endif %}
</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>
{% endfor %}
</div>
{% if player_name %}
<!-- form for submitting a move, a move is a selection of marcet or factory, what color, and what patternline or floor it goes to. -->
<!-- button to go to next player -->
{% if local_game %}
{% 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 %}
<a href="/game/{{ game_id }}/player/{{ gamestate.player_names[next_index] }}">Next Player</a>
{% endif %}
{% endif %}
<script src="/socket.io.js"></script>
<script>
console.log('Game ID: {{ game_id }}');
console.log('Player Name: {{ player_name }}');
console.log('Gamestate: {{ gamestate }}');
function selectTile(tile) {
var source = tile.parentElement.id;
if (source == 'market') {
source = 'market';
}else {
source = source.replace('factory', '');
}
var color = tile.getAttribute('class');
console.log('Selected tile: ' + color + ' from ' + source);
//get elements of the form
var sourceElement = document.getElementById('source');
var colorElement = document.getElementById('color');
//select the selected source and color
console.log(sourceElement);
console.log(colorElement);
//find the element in the dropdowns with the same value as the source and color
var sourceOption = sourceElement.querySelector('option[value="' + source + '"]');
var colorOption = colorElement.querySelector('option[value="' + color + '"]');
console.log(sourceOption);
console.log(colorOption);
//set the selected attribute to true
sourceOption.selected = true;
colorOption.selected = true;
}
function selectPatternLine(pattern_line) {
//get the value of the pattern line element
value = pattern_line.getAttribute('value');
console.log('Selected pattern line: ' + pattern_line + ' with value: ' + value);
var destinationElement = document.getElementById('destination');
var destinationOption = destinationElement.querySelector('option[value="' + value + '"]');
destinationOption.selected = true;
}
// refresh the page by listening to websocket events
game_id = '{{ game_id }}';
player_name = '{{ player_name }}';
var socket = io();
// send a message to the server in the message name space
socket.emit('join', {game_id: game_id});
socket.addEventListener('move', function (event) {
console.log('Game update received: ' + event);
window.location.reload();
});
// if we wana go over to using websocket entirely to send the move
let form = document.querySelector('#moveForm');
form.addEventListener('submit', function(event) {
// Prevent the form from being submitted normally
event.preventDefault();
// Create a FormData object from the form
let formData = new FormData(form);
// Convert the FormData to a plain object
let data = {};
formData.forEach((value, key) => data[key] = value);
console.log(data);
socket.emit('move', {game_id: game_id, player_name, move: data});
// if local_game is tru change player
//{% if local_game %}
let nextPlayer = '{{ gamestate.player_names[gamestate.player_names.index(player_name) + 1 if gamestate.player_names.index(player_name) + 1 < gamestate.player_names|length else 0] }}';
window.location.href = '/game/{{ game_id }}/player/' + nextPlayer;
//{% endif %}
});
</script>
</body>
</html>