Compare commits

..

13 Commits

13 changed files with 390 additions and 87 deletions

View File

@ -1,5 +1,5 @@
parcel: parcel:
npm run parcel src/player.html src/*.ts npm run parcel src/player.html src/*.ts imgs/*.jpg
uncrash: uncrash:
pkill -9 node pkill -9 node

7
bootstrap.min.css vendored

File diff suppressed because one or more lines are too long

BIN
imgs/carcasonne.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

BIN
imgs/castle12.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
imgs/green.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
imgs/init.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
imgs/turn.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
imgs/xroad.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -1,4 +1,4 @@
import {resetVar} from "./moooove"; import {resetVar, resideBoardScreenSize} from "./moooove";
/** /**
* return the WebBoard information * return the WebBoard information
@ -177,6 +177,8 @@ function clearBoard() {
grid.append(line0); grid.append(line0);
resizeBoard(); resizeBoard();
resetVar(); resetVar();
resideBoardScreenSize();
} }
export { export {

View File

@ -53,6 +53,12 @@ type Game = {
crashReport?: CrashReport; crashReport?: CrashReport;
}; };
function invertBorder() {
showBorders(bordersShown);
bordersShown = !bordersShown;
switchMessage(<HTMLElement>document.getElementById("showTeams"), "les équipes");
}
let games: Game[] = []; let games: Game[] = [];
function main() { function main() {
@ -73,11 +79,103 @@ function main() {
console.log(crashes); console.log(crashes);
} }
function switchMessage(elm: HTMLElement, txt: string) {
if (elm.innerText.includes("Afficher"))
elm.innerText = "Cacher " + txt;
else
elm.innerText = "Afficher " + txt;
}
function changeDisplayed(className: string) {
}
function showBorders(visible: boolean) {
function f(name: string) {
const elms = document.getElementsByClassName(name);
const elmsp = document.getElementsByClassName(name + "-hidden");
function g(elms1: any) {
for (let i = elms1.length; i > 0; i--) { // this loop must be reverted as getElementsByClassName identify elements via CSSselector (?) and it does change during the loop
const elm = <HTMLElement>(elms1[i - 1]);
if (visible) {
elm.classList.remove(name);
elm.classList.add(name + "-hidden");
} else {
elm.classList.remove(name + "-hidden");
elm.classList.add(name);
}
}
}
g(elms);
g(elmsp);
}
f("player1");
f("player0");
f("player-1");
}
let IsImgsDisplayed = true;
function switchToGraph() {
console.log("switching to " + (IsImgsDisplayed ? "GRAPH" : "IMAGES") + " vue");
IsImgsDisplayed = !IsImgsDisplayed;
const imgElms = document.getElementsByClassName("tileImg");
for (let i = 0; i < imgElms.length; i++) {
const elm = <HTMLElement>(imgElms[i]);
if (IsImgsDisplayed)
elm.classList.remove("hidden");
else
elm.classList.add("hidden");
}
const tileElms = document.getElementsByClassName("subTile");
for (let i = 0; i < tileElms.length; i++) {
const elm = <HTMLElement>(tileElms[i]);
if (!IsImgsDisplayed)
elm.classList.remove("hidden");
else
elm.classList.add("hidden");
}
}
let bordersShown = false;
const showDataButton = (<HTMLElement>document.getElementById('showData'));
showDataButton.addEventListener(
'click',
() => {
(<HTMLElement>document.getElementById('jsonData')).classList.toggle("closed");
switchMessage(showDataButton, "les données de parties");
});
const showImgsButton = <HTMLElement>document.getElementById("showImages");
showImgsButton.addEventListener("click", () => {
switchToGraph();
switchMessage(showImgsButton, "le graphe");
}
);
const showTeamsButton = <HTMLElement>document.getElementById("showTeams");
showTeamsButton.addEventListener("click", () => {
invertBorder();
}
);
window.onload = ((e) => { window.onload = ((e) => {
main(); main();
clearBoard(); clearBoard();
setGameInfo(); setGameInfo();
resizeBoard(); resizeBoard();
// src: https://stackoverflow.com/a/8916697
window.addEventListener("keydown", function (e) {
if (["Space", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].indexOf(e.code) > -1) {
e.preventDefault();
}
}, false);
}); });
export {games, Move}; export {games, Move, IsImgsDisplayed, switchToGraph, showBorders, bordersShown, invertBorder};

View File

@ -1,4 +1,4 @@
import {games, Move} from "./index"; import {bordersShown, games, invertBorder, IsImgsDisplayed, Move, showBorders, switchToGraph} from "./index";
import {addColumnLeft, addColumnRight, addRowAbove, addRowUnder, clearBoard, resizeBoard} from "./Board"; import {addColumnLeft, addColumnRight, addRowAbove, addRowUnder, clearBoard, resizeBoard} from "./Board";
let min_x = 0; let min_x = 0;
@ -8,7 +8,7 @@ let max_y = 0;
let gameIndex = 0; let gameIndex = 0;
let gameMoveId = 0; let gameMoveId = 0;
const playerColors = ["green", "blue", "purple"]; const playerColors = ["blue", "yellow", "purple"];
function resetVar() { function resetVar() {
min_y = 0; min_y = 0;
@ -25,14 +25,18 @@ function switchPrevGame() {
clearBoard(); clearBoard();
if (gameIndex > 0) if (gameIndex > 0)
gameIndex--; gameIndex--;
setGameInfo(); //setGameInfo();
(<HTMLElement>document.getElementById("gameIDdisp")).innerText = gameIndex + "";
setTimeout(setGameInfo, 1); // prevent the big flash before the board is fully resized
} }
function switchNextGame() { function switchNextGame() {
clearBoard(); clearBoard();
if (gameIndex < games.length - 1) if (gameIndex < games.length - 1)
gameIndex++; gameIndex++;
setGameInfo(); setTimeout(setGameInfo, 1);
(<HTMLElement>document.getElementById("gameIDdisp")).innerText = gameIndex + "";
//setGameInfo();
} }
/** /**
@ -41,9 +45,7 @@ function switchNextGame() {
function setGameInfo() { function setGameInfo() {
(<HTMLElement>document.getElementById("seed_disp")).innerText = games[gameIndex].seed + ""; (<HTMLElement>document.getElementById("seed_disp")).innerText = games[gameIndex].seed + "";
(<HTMLElement>document.getElementById("player0_disp")).innerText = games[gameIndex].player0 + ""; (<HTMLElement>document.getElementById("player0_disp")).innerText = games[gameIndex].player0 + "";
(<HTMLElement>document.getElementById("player0_disp")).style.color = playerColors[0];
(<HTMLElement>document.getElementById("player1_disp")).innerText = games[gameIndex].player1 + ""; (<HTMLElement>document.getElementById("player1_disp")).innerText = games[gameIndex].player1 + "";
(<HTMLElement>document.getElementById("player1_disp")).style.color = playerColors[1];
(<HTMLElement>document.getElementById("winner_disp")).innerText = games[gameIndex].winner + ""; (<HTMLElement>document.getElementById("winner_disp")).innerText = games[gameIndex].winner + "";
(<HTMLElement>document.getElementById("cause_disp")).innerText = games[gameIndex].cause + ""; (<HTMLElement>document.getElementById("cause_disp")).innerText = games[gameIndex].cause + "";
addMove(games[gameIndex]["moves"][0]); addMove(games[gameIndex]["moves"][0]);
@ -120,35 +122,83 @@ function addMove(move: Move) {
placeMove(move); placeMove(move);
} }
function resideBoardScreenSize() {
const nb_lines = (window.innerHeight - 200) / 200;
const nb_cols = (window.innerWidth - 200) / 200;
let side = false;
for (let i = 0; i < nb_lines; i++) {
if (side) {
max_y++;
addRowUnder();
side = !side;
} else {
side = !side;
min_y--;
addRowAbove();
}
}
for (let i = 0; i < nb_cols; i++) {
if (side) {
side = !side;
max_x++;
addColumnRight();
} else {
side = !side;
min_x--;
addColumnLeft();
}
}
}
function setInnerTile(elm: HTMLElement, tile: number[], angle: string) {
function setInnerTile(elm: HTMLElement, tile: number[]) {
const idx_to_cord = [[1, 0], [2, 0], [3, 0], [4, 1], [4, 2], [4, 3], [3, 4], [2, 4], [1, 4], [0, 3], [0, 2], [0, 1], [2, 2]]; const idx_to_cord = [[1, 0], [2, 0], [3, 0], [4, 1], [4, 2], [4, 3], [3, 4], [2, 4], [1, 4], [0, 3], [0, 2], [0, 1], [2, 2]];
const nb_to_color = ["green", "gray", "blue", "#964B00", "purple", "gold", "#069AF3", "#420D08", "white", "none"]; const nb_to_color = ["green", "gray", "blue", "#964B00", "purple", "gold", "#069AF3", "#420D08", "white", "none"];
elm.children[0].children[0].innerHTML = gameMoveId + "";
if (tile[0] !== 9)
(<HTMLElement>elm.children[0].children[0]).style.opacity = "1";
else
(<HTMLElement>elm.children[0].children[0]).style.opacity = "0";
// console.log("Adding a new " + (IsImgsDisplayed ? "HIDDEN" : "VISIBLE") + " graph tile");
for (let i = 0; i < 13; i++) { for (let i = 0; i < 13; i++) {
const subLine = elm.children[idx_to_cord[i][1]]; const subLine = elm.children[idx_to_cord[i][1]];
(<HTMLElement>subLine.children[idx_to_cord[i][0]]).style.background = nb_to_color[tile[i]]; (<HTMLElement>subLine.children[idx_to_cord[i][0]]).style.background = nb_to_color[tile[i]];
if (IsImgsDisplayed)
(<HTMLElement>subLine.children[idx_to_cord[i][0]]).classList.add("hidden");
} }
} }
/** /**
* there is the real adding part * there is thesubTiledding part
* @param move * @param move
*/ */
function placeMove(move: Move) { function placeMove(move: Move) {
const line = <HTMLElement>document.getElementById("line" + (-move.y - min_y)); const line = <HTMLElement>document.getElementById("line" + (-move.y - min_y));
const box = <HTMLElement>line.children[move.x - min_x]; const box = <HTMLElement>line.children[move.x - min_x];
box.style.border = "dotted 2px " + (inInterval(move.id, 0, 1) === 0 ? playerColors[move.id] : playerColors[2]); box.classList.add("player" + move.id + (bordersShown ? "" : "-hidden"));
setInnerTile(box, move.tile.c); const img = document.createElement("img");
box.style.rotate = move.tile.angle + "deg"; img.src = './imgs/' + move.tile.name + ".jpg";
img.className = "tileImg";
if (!IsImgsDisplayed)
img.className += " hidden";
box.append(img);
img.style.rotate = '-' + move.tile.angle + "deg";
setInnerTile(box, move.tile.c, move.tile.angle);
} }
function removeMove(move: Move) { function removeMove(move: Move) {
console.log(move.y);
console.log(move.y - min_y);
const line = <HTMLElement>document.getElementById("line" + (-move.y - min_y)); const line = <HTMLElement>document.getElementById("line" + (-move.y - min_y));
const box = <HTMLElement>line.children[move.x - min_x]; const box = <HTMLElement>line.children[move.x - min_x];
setInnerTile(box, Array(13).fill(9)); setInnerTile(box, Array(13).fill(9), "0");
box.style.border = "none"; box.removeChild(box.getElementsByTagName('img')[0]);
const t = ["player0", "player0-hidden", "player1", "player1-hidden", "player-1", "player-1-hidden"];
for (let i = 0; i < 6; i++) {
box.classList.remove(t[i]);
}
box.style.rotate = "0"; box.style.rotate = "0";
} }
@ -172,6 +222,7 @@ lastMoveButton.addEventListener("click", tolastMove);
firstMoveButton.addEventListener("click", toFirstMove); firstMoveButton.addEventListener("click", toFirstMove);
function keyShortcut(e: { keyCode: number, ctrlKey: boolean, shiftKey: boolean }) { function keyShortcut(e: { keyCode: number, ctrlKey: boolean, shiftKey: boolean }) {
// console.log(`key ${e.keyCode} pressed`);
switch (e.keyCode) { switch (e.keyCode) {
case 37: case 37:
if (e.shiftKey) { if (e.shiftKey) {
@ -195,13 +246,19 @@ function keyShortcut(e: { keyCode: number, ctrlKey: boolean, shiftKey: boolean }
} }
nextMove(); nextMove();
break; break;
case 71:
switchToGraph();
break;
case 84:
invertBorder();
break;
} }
} }
document.addEventListener("keydown", keyShortcut); document.addEventListener("keydown", keyShortcut);
export {setGameInfo, switchPrevGame, resetVar}; export {setGameInfo, switchPrevGame, resetVar, resideBoardScreenSize};

View File

@ -3,8 +3,6 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!--<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">-->
<link rel="stylesheet" href="../bootstrap.min.css">
<link rel="stylesheet" href="./style.css"> <link rel="stylesheet" href="./style.css">
<script src="index.ts" type="module"></script> <script src="index.ts" type="module"></script>
<script src="moooove.ts" type="module"></script> <script src="moooove.ts" type="module"></script>
@ -13,65 +11,50 @@
</head> </head>
<body> <body>
<div class="container-fluid bg-light header">
<h1 id="title">Carcassonne viewer</h1>
<div class="row">
<div class="col-lg-3 sidebar">
<ul class="list-group" id="games_list">
</ul>
</div>
<div class="col-lg-9"> <img src="../imgs/carcasonne.jpg" alt="GameTable" class="background">
<div id="game_container" class="row"> <div class="header">
</div> <div class="left">
<div class="button interactable" id="prevGameButton">|&lt;<&lt;</div>
<div class="row viewer_controls"> <div class="button interactable" id="firstMoveButton">|&lt;&lt;</div>
<div class="col-lg-2"></div> <div class="button interactable" id="prevMoveButton">&lt;</div>
<div class="btn-group col-lg-8" role="group" aria-label="Basic example">
<button type="button" class="btn btn-secondary" id="prevGameButton">|&lt;<&lt;</button>
<button type="button" class="btn btn-secondary" id="firstMoveButton">|&lt;&lt;</button>
<button type="button" class="btn btn-secondary" id="prevMoveButton">&lt;</button>
<button type="button" class="btn btn-secondary" id="nextMoveButton">&gt;</button>
<button type="button" class="btn btn-secondary" id="lastMoveButton">&gt;&gt;|</button>
<button type="button" class="btn btn-secondary" id="nextGameButton">>>>|</button>
</div>
<div class="col-lg-2"></div>
</div>
<table class="table table-striped table-sm" style="text-align: left; width: 100%">
<tbody>
<tr>
<th scope="row" style="width: 15%">Player 0</th>
<td id="player0_disp">player0</td>
</tr>
<tr>
<th scope="row">Player 1</th>
<td id="player1_disp">player1</td>
</tr>
<tr>
<th scope="row">Seed</th>
<td id="seed_disp">uéuéuéu</td>
</tr>
<tr>
<th scope="row">Winner</th>
<td id="winner_disp">winner</td>
</tr>
<tr>
<th scope="row">Cause</th>
<td id="cause_disp">cause</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
<div class="center">
🏆
<div id="winner_disp"> winner</div>
🏆
<div class="spacer">-></div>
<div id="cause_disp">cause</div>
</div>
<div class="right">
<div class="button interactable" id="nextMoveButton">&gt;</div>
<div class="button interactable" id="lastMoveButton">&gt;&gt;|</div>
<div class="button interactable" id="nextGameButton">>>>|</div>
</div>
</div> </div>
<div class="left_player" id="player0_disp">player0</div>
<div class="right_player" id="player1_disp">player1</div>
<div id="games"> <div id="games">
<div id="board" class="board"> <div id="board" class="board">
</div> </div>
</div> </div>
<div id="jsonData"> <div class="footer">
<div style=" width: 100%">Seed: <span id="seed_disp"></span>&nbsp; Partie: <span id="gameIDdisp">0</span></div>
<div style="display: flex; width: 200%; justify-content: right">
<div class="button interactable" id="showData">Afficher les données de parties</div>
<div class="button interactable" id="showImages">Afficher le graphe</div>
<div class="button interactable" id="showTeams">Afficher les équipes</div>
</div>
</div>
<div class="closed" id="jsonData">
<pre> <pre>
[ [
{ {
@ -494,14 +477,14 @@
"cause": "Victory on points for player Pierre Du Caillou" "cause": "Victory on points for player Pierre Du Caillou"
} }
] ]
</pre> </pre>
</div> </div>
<div id="error_box" style="display: none"> <div id="error_box" style="display: none">
</div> </div>
<div id="errors" style="background-color: #fee; display: visible"> <div id="errors" style="display: none;background-color: #fee">
<pre style="white-space: break-spaces">[ <pre style="white-space: break-spaces">[
]</pre> ]</pre>

View File

@ -1,21 +1,138 @@
body { body {
height: 100em; height: 100vh;
overflow: hidden; /*overflow: hidden;*/
overflow-x: hidden;
align-items: center; align-items: center;
justify-content: center;
margin: 0;
}
.background {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: -1;
}
.container {
display: flex;
flex-direction: row;
}
#games {
display: flex;
align-items: center;
justify-content: center;
} }
.header { .header {
height: 20vh; display: flex;
overflow: hidden; align-items: center;
justify-content: center;
}
.footer {
margin-top: -5px;
display: flex;
align-items: center;
color: white;
height: 5vh;
} }
.board { .board {
width: 80vw; width: 90vw;
height: 80vh; height: 90vh;
background: black; margin: 1vh;
} }
.header {
display: flex;
flex-direction: row;
width: 100%;
height: 4vh;
margin: 0;
justify-content: center;
}
.left {
justify-content: flex-start;
width: 10%;
align-items: center;
display: inherit;
}
.right {
justify-content: flex-end;
align-items: center;
width: 10%;
display: flex;
}
.right2 {
justify-content: flex-end;
align-items: center;
width: 50vw;
display: flex;
}
.center {
justify-content: center;
align-items: center;
width: 80%;
display: flex;
color: white;
}
.spacer {
margin-left: 3vw;
margin-right: 3vw;
}
.left_player {
color: white;
writing-mode: vertical-lr;
position: absolute;
left: 0;
top: 35vh;
width: 3vw;
display: flex;
align-items: center;
}
.right_player {
color: white;
writing-mode: vertical-lr;
position: absolute;
right: 0;
top: 25vh;
width: 3vw;
display: flex;
align-items: center;
}
.player0 {
border: solid 3px blue;
}
.player1 {
border: solid 3px yellow;
}
.player-1 {
border: solid 3px black;
}
.viewer_controls {
margin: 0 -0.3vw 0 -0.3vw;
width: 101%;
}
.gridTile { .gridTile {
box-sizing: border-box;
color: white; color: white;
font-size: 1em; font-size: 1em;
} }
@ -31,6 +148,7 @@ body {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center;
} }
.column { .column {
@ -41,4 +159,56 @@ body {
.subTile { .subTile {
width: 20%; width: 20%;
height: 100%; height: 100%;
z-index: 1;
} }
.button {
font-size: 1em;
width: fit-content;
padding: 5px;
margin: 3px 5px 3px 5px;
border: 1px solid #ececec;
border-radius: 10px;
color: white;
}
.button:hover {
background: #ececec;
color: black;
}
.interactable {
cursor: pointer;
}
#jsonData {
font-size: 1em;
overflow-y: hidden;
overflow-x: scroll;
transition: font-size 500ms cubic-bezier(1, 1, 1, 1);
margin: 0.1vw;
border: 1px solid rgba(169, 169, 169, 0.67);
padding: 0.2vw;
}
.closed#jsonData {
font-size: 0 !important;
margin: 0;
padding: 0;
}
.tileImg {
width: 100%;
height: 100%;
z-index: 0;
margin-top: -100%;
}
.hidden {
opacity: 0;
}
/*#jsonData {*/
/* position: absolute;*/
/* top: 100vh;*/
/*}*/