2024-02-14 21:52:29 +01:00
|
|
|
<!-- HTML for game.html -->
|
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
2024-02-25 20:41:38 +01:00
|
|
|
<title>Ozai:game</title>
|
|
|
|
<link rel="icon" type="image/png" href="/azul-flake.png">
|
2024-02-15 12:58:18 +01:00
|
|
|
<style>
|
2024-02-24 21:33:28 +01:00
|
|
|
a {
|
|
|
|
display: inline-block;
|
|
|
|
text-decoration: none;
|
|
|
|
color: black;
|
|
|
|
background-color: #c3bfbf;
|
|
|
|
border-radius: 5px;
|
|
|
|
font-weight: bold;
|
|
|
|
font-size: 1.5em; /* increase font size */
|
|
|
|
|
|
|
|
}
|
|
|
|
a:hover {
|
|
|
|
background-color: #868787;
|
|
|
|
}
|
2024-02-15 12:58:18 +01:00
|
|
|
/* flexbox class */
|
|
|
|
.flex-row {
|
|
|
|
display: flex;
|
|
|
|
justify-content: left;
|
|
|
|
flex-direction: row;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
align-items:baseline;
|
|
|
|
|
|
|
|
}
|
|
|
|
.flex-row > * {
|
|
|
|
margin-right: 5px;
|
|
|
|
}
|
|
|
|
.flex-col {
|
|
|
|
display: flex;
|
|
|
|
justify-content:space-around;
|
|
|
|
flex-direction: column;
|
|
|
|
}
|
2024-02-24 21:33:28 +01:00
|
|
|
|
|
|
|
.factory {
|
|
|
|
overflow: hidden;
|
|
|
|
border: 2px solid black;
|
|
|
|
border-radius: 30%;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
/* flex wrap */
|
|
|
|
flex-direction: row;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
|
|
height: 5em;
|
|
|
|
width: 5em;
|
|
|
|
|
|
|
|
}
|
|
|
|
#market {
|
|
|
|
height: 10em;
|
|
|
|
width: 10em;
|
|
|
|
}
|
|
|
|
/* 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: 2px solid black;
|
|
|
|
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: 1px solid black;
|
|
|
|
text-align: center;
|
|
|
|
margin: 0.1em;
|
|
|
|
width: 1.5em;
|
|
|
|
height: 1.5em;
|
|
|
|
overflow: hidden;
|
|
|
|
text-align: center;
|
|
|
|
vertical-align: middle;
|
|
|
|
}
|
|
|
|
|
2024-02-15 12:58:18 +01:00
|
|
|
.wall {
|
|
|
|
/* 5*5 grid */
|
|
|
|
display: grid;
|
|
|
|
grid-template-columns: repeat(5, 1fr);
|
|
|
|
grid-template-rows: repeat(5, 1fr);
|
|
|
|
gap: 0.1em;
|
|
|
|
}
|
|
|
|
.wall > * {
|
|
|
|
border: 1px solid black;
|
2024-02-24 21:33:28 +01:00
|
|
|
width: 1.5em;
|
|
|
|
height: 1.5em;
|
2024-02-15 12:58:18 +01:00
|
|
|
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;
|
2024-02-24 21:33:28 +01:00
|
|
|
flex-direction:row-reverse;
|
2024-02-15 12:58:18 +01:00
|
|
|
align-items:baseline;
|
|
|
|
}
|
|
|
|
.pattern_line > * {
|
|
|
|
border: 1px solid black;
|
|
|
|
text-align: center;
|
|
|
|
margin: 0.1em;
|
2024-02-24 21:33:28 +01:00
|
|
|
width: 1.5em;
|
|
|
|
height: 1.5em;
|
|
|
|
overflow: hidden;
|
|
|
|
text-align: center;
|
|
|
|
vertical-align: middle;
|
2024-02-15 12:58:18 +01:00
|
|
|
}
|
|
|
|
.floor {
|
|
|
|
display: flex;
|
|
|
|
justify-content: left;
|
|
|
|
flex-direction: row;
|
|
|
|
align-items:baseline;
|
|
|
|
}
|
|
|
|
.floor > * {
|
|
|
|
border: 1px solid black;
|
|
|
|
text-align: center;
|
2024-02-24 21:33:28 +01:00
|
|
|
width: 1.5em;
|
|
|
|
height: 1.5em;
|
2024-02-15 12:58:18 +01:00
|
|
|
}
|
|
|
|
|
2024-02-24 22:55:26 +01:00
|
|
|
.blue_bg {
|
|
|
|
background-color: rgb(49, 157, 245, 0.5);
|
|
|
|
}
|
|
|
|
.yellow_bg {
|
|
|
|
background-color: rgb(245, 245, 10, 0.5);
|
|
|
|
}
|
|
|
|
.red_bg {
|
|
|
|
background-color: rgb(255, 0, 0, 0.5);
|
|
|
|
}
|
|
|
|
.black_bg {
|
|
|
|
background-color: rgb(93, 93, 93, 0.5);
|
|
|
|
}
|
|
|
|
.white_bg {
|
|
|
|
background-color:rgb(208, 202, 195, 0.5);
|
|
|
|
}
|
|
|
|
|
2024-02-15 12:58:18 +01:00
|
|
|
.blue {
|
|
|
|
background-color: rgb(49, 157, 245);
|
|
|
|
}
|
|
|
|
.yellow {
|
|
|
|
background-color: yellow;
|
|
|
|
}
|
|
|
|
.red {
|
|
|
|
background-color: red;
|
|
|
|
}
|
|
|
|
.black {
|
|
|
|
background-color: rgb(93, 93, 93);
|
|
|
|
}
|
|
|
|
.white {
|
2024-02-24 21:33:28 +01:00
|
|
|
background-color:rgb(208, 202, 195);
|
2024-02-15 12:58:18 +01:00
|
|
|
}
|
|
|
|
.start {
|
|
|
|
background-color: rgb(255, 1, 238);
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|
2024-02-14 21:52:29 +01:00
|
|
|
</head>
|
|
|
|
<body>
|
2024-02-15 12:58:18 +01:00
|
|
|
<div class="flex-row">
|
|
|
|
<p>Number of Players: {{ gamestate.n_players }}</p>
|
|
|
|
<p>Current Player: {{ gamestate.current_player }}</p>
|
|
|
|
<p>Game Status: {% if gamestate.game_end %}Ended{% else %}Active{% endif %}</p>
|
|
|
|
<p>Rounds: {{ gamestate.rounds }}</p>
|
|
|
|
<p>Days: {{ gamestate.days }}</p>
|
|
|
|
</div>
|
2024-02-14 21:52:29 +01:00
|
|
|
|
2024-02-15 12:58:18 +01:00
|
|
|
<div class="flex-row">
|
2024-02-24 21:33:28 +01:00
|
|
|
<!-- 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>
|
2024-02-15 12:58:18 +01:00
|
|
|
</div>
|
2024-02-24 21:33:28 +01:00
|
|
|
<!-- 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>
|
2024-02-15 12:58:18 +01:00
|
|
|
{% endfor %}
|
|
|
|
</div>
|
|
|
|
|
2024-02-24 21:33:28 +01:00
|
|
|
|
2024-02-15 12:58:18 +01:00
|
|
|
<div class="flex-row">
|
2024-02-14 21:52:29 +01:00
|
|
|
{% for name, player_data in gamestate.players.items() %}
|
2024-02-15 12:58:18 +01:00
|
|
|
<div class="flex-col">
|
|
|
|
<div class="flex-row">
|
|
|
|
{% if player_name == name %}
|
|
|
|
<h2>{{ player_name }} (You)</h2>
|
|
|
|
{% else %}
|
|
|
|
<h2>{{ name }}</h2>
|
|
|
|
{% endif %}
|
2024-02-24 21:33:28 +01:00
|
|
|
{% if gamestate.current_player == name %}
|
|
|
|
<p>(current)</p>
|
|
|
|
{% endif %}
|
2024-02-15 12:58:18 +01:00
|
|
|
{% if player_data.ready %}
|
2024-02-24 21:33:28 +01:00
|
|
|
<p>Ready</p>
|
2024-02-15 12:58:18 +01:00
|
|
|
{% 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 %}
|
2024-02-25 20:41:38 +01:00
|
|
|
<div class="pattern_line" onclick="selectPatternLine(this)" value="{{loop.index}}">
|
2024-02-24 21:33:28 +01:00
|
|
|
<!-- TODO: Fix this to not fill empty spaces. -->
|
2024-02-15 12:58:18 +01:00
|
|
|
{% for i in range(0, loop.index) %}
|
2024-02-24 21:33:28 +01:00
|
|
|
{% if line.number > i %}
|
2024-02-25 20:41:38 +01:00
|
|
|
<div class="{{ line.color }}" >{{ line.color[:1] }}</div>
|
2024-02-24 21:33:28 +01:00
|
|
|
{% else %}
|
2024-02-25 20:41:38 +01:00
|
|
|
<div >_</div>
|
2024-02-24 21:33:28 +01:00
|
|
|
{% endif %}
|
2024-02-15 12:58:18 +01:00
|
|
|
{% endfor %}
|
|
|
|
</div>
|
2024-02-24 21:33:28 +01:00
|
|
|
{% endfor %}
|
|
|
|
</div>
|
2024-02-15 12:58:18 +01:00
|
|
|
<div class="flex-col">
|
|
|
|
<!-- <h3>Wall</h3> -->
|
2024-02-24 22:55:26 +01:00
|
|
|
<div class="wall">
|
|
|
|
{% set colors_base = ['blue', 'yellow', 'red', 'black', 'white'] %}
|
2024-02-15 12:58:18 +01:00
|
|
|
{% for row in player_data.wall %}
|
2024-02-24 22:55:26 +01:00
|
|
|
{% 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 %}
|
2024-02-15 12:58:18 +01:00
|
|
|
{% endfor %}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2024-02-14 21:52:29 +01:00
|
|
|
|
2024-02-24 21:33:28 +01:00
|
|
|
<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>
|
2024-02-25 20:41:38 +01:00
|
|
|
<div class="floor" onclick="selectPatternLine(this)" value="floor">
|
2024-02-24 21:33:28 +01:00
|
|
|
{% set floor_count = 0 %}
|
2024-02-15 12:58:18 +01:00
|
|
|
{% for color, number in player_data.floor.items() %}
|
2024-02-24 21:33:28 +01:00
|
|
|
{% if number > 0 %}
|
|
|
|
{% set floor_count = floor_count + number %}
|
|
|
|
{% for i in range(0, number) %}
|
|
|
|
<div class="{{ color }}">{{ color[:1] }}</div>
|
|
|
|
{% endfor %}
|
|
|
|
{% endif %}
|
|
|
|
{% endfor %}
|
|
|
|
{% if floor_count < 7 %}
|
|
|
|
{% set floor_blank_tiles = 7 - floor_count %}
|
|
|
|
{% for i in range(0, floor_blank_tiles) %}
|
|
|
|
<div>_</div>
|
2024-02-15 12:58:18 +01:00
|
|
|
{% endfor %}
|
2024-02-24 21:33:28 +01:00
|
|
|
{% endif %}
|
2024-02-15 12:58:18 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{% endfor %}
|
|
|
|
</div>
|
|
|
|
|
2024-02-24 21:33:28 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2024-02-15 12:58:18 +01:00
|
|
|
|
2024-02-14 21:52:29 +01:00
|
|
|
{% if player_name %}
|
|
|
|
<h1>Play area</h1>
|
|
|
|
<p>Playing as: {{ player_name }}</p>
|
2024-02-15 12:58:18 +01:00
|
|
|
<!-- form for submitting a move, a move is a selection of marcet or factory, what color, and what patternline or floor it goes to. -->
|
2024-02-25 20:41:38 +01:00
|
|
|
<form id='moveForm'</form>>
|
2024-02-15 12:58:18 +01:00
|
|
|
<label for="source">Source:</label>
|
|
|
|
<select id="source" name="source">
|
2024-02-25 20:41:38 +01:00
|
|
|
<option value="market">Market</option>
|
2024-02-15 12:58:18 +01:00
|
|
|
{% for factory in gamestate.factories %}
|
2024-02-25 20:41:38 +01:00
|
|
|
<option value="{{ loop.index }}">Factory {{ loop.index }}</option>
|
2024-02-15 12:58:18 +01:00
|
|
|
{% 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">
|
2024-02-24 21:33:28 +01:00
|
|
|
<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>
|
2024-02-15 12:58:18 +01:00
|
|
|
<option value="floor">Floor</option>
|
|
|
|
</select>
|
|
|
|
|
|
|
|
<input type="submit" value="Submit Move">
|
|
|
|
</form>
|
2024-02-24 21:33:28 +01:00
|
|
|
<!-- button to go to next player -->
|
|
|
|
{% 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>
|
2024-02-15 12:58:18 +01:00
|
|
|
|
|
|
|
|
2024-02-14 21:52:29 +01:00
|
|
|
{% endif %}
|
2024-02-15 12:58:18 +01:00
|
|
|
|
|
|
|
|
2024-02-25 20:41:38 +01:00
|
|
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.3/socket.io.js"></script>
|
2024-02-15 12:58:18 +01:00
|
|
|
<script>
|
|
|
|
console.log('Game ID: {{ game_id }}');
|
|
|
|
console.log('Player Name: {{ player_name }}');
|
|
|
|
console.log('Gamestate: {{ gamestate }}');
|
2024-02-24 21:33:28 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-02-25 20:41:38 +01:00
|
|
|
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);
|
2024-02-24 21:33:28 +01:00
|
|
|
var destinationElement = document.getElementById('destination');
|
2024-02-25 20:41:38 +01:00
|
|
|
var destinationOption = destinationElement.querySelector('option[value="' + value + '"]');
|
2024-02-24 21:33:28 +01:00
|
|
|
destinationOption.selected = true;
|
|
|
|
}
|
|
|
|
|
2024-02-25 20:41:38 +01:00
|
|
|
// 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});
|
|
|
|
});
|
|
|
|
|
2024-02-15 12:58:18 +01:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
2024-02-14 21:52:29 +01:00
|
|
|
</body>
|
|
|
|
</html>
|