From d90942624b3efcf953ae27e0f625ab8648a1e5cb Mon Sep 17 00:00:00 2001 From: MiguelMLorente Date: Sun, 24 Nov 2024 15:07:10 +0100 Subject: [PATCH] Implement board view based on board builder --- interface/BoardBuilder.ts | 11 +- interface/constants/Direction.ts | 7 + interface/types/ExternalNode.ts | 7 +- web/src/pages/game/components/GameBoard.scss | 150 ++++++++++++------- web/src/pages/game/components/GameBoard.tsx | 89 +++-------- 5 files changed, 141 insertions(+), 123 deletions(-) diff --git a/interface/BoardBuilder.ts b/interface/BoardBuilder.ts index c4ed092..e2e79c7 100644 --- a/interface/BoardBuilder.ts +++ b/interface/BoardBuilder.ts @@ -60,14 +60,19 @@ function createBoard(): Cell[][] { function connectAdjacentCells(board: Cell[][]) { const indexes = Array.from(Array(boardSize).keys()); for (const rowIndex of indexes.slice(0, -1)) { - for (const colIndex of indexes.slice(0, -1)) { + for (const colIndex of indexes) { const cell = board[rowIndex][colIndex]; - const rightCell = board[rowIndex][colIndex + 1]; const bottomCell = board[rowIndex + 1][colIndex]; - cell .getNodeAt(Direction.SOUTH) .linkToNode(bottomCell.getNodeAt(Direction.NORTH)); + } + } + + for (const rowIndex of indexes) { + for (const colIndex of indexes.slice(0, -1)) { + const cell = board[rowIndex][colIndex]; + const rightCell = board[rowIndex][colIndex + 1]; cell .getNodeAt(Direction.EAST) .linkToNode(rightCell.getNodeAt(Direction.WEST)); diff --git a/interface/constants/Direction.ts b/interface/constants/Direction.ts index 1f54f0c..6bc4347 100644 --- a/interface/constants/Direction.ts +++ b/interface/constants/Direction.ts @@ -4,3 +4,10 @@ export enum Direction { EAST = "EAST", WEST = "WEST", } + +export const directions: Direction[] = [ + Direction.NORTH, + Direction.SOUTH, + Direction.EAST, + Direction.WEST, +]; diff --git a/interface/types/ExternalNode.ts b/interface/types/ExternalNode.ts index c951c54..14dcbbe 100644 --- a/interface/types/ExternalNode.ts +++ b/interface/types/ExternalNode.ts @@ -15,10 +15,15 @@ export class ExternalNode extends Node { public linkToNode(other: ExternalNode | Exit) { this.border = new Border(this, other); + if (other instanceof ExternalNode) { + other.border = this.border; + } } public traverseBorder(): ExternalNode | Exit { - if (!this.border) throw Error(`Missing border for node`); + if (!this.border) { + throw Error(`Missing border for node`); + } return (this.border as Border).traverseFrom(this); } } diff --git a/web/src/pages/game/components/GameBoard.scss b/web/src/pages/game/components/GameBoard.scss index 477f4cc..fca4d47 100644 --- a/web/src/pages/game/components/GameBoard.scss +++ b/web/src/pages/game/components/GameBoard.scss @@ -1,79 +1,125 @@ .game-board { - height: 700px; - width: 700px; + height: 850px; + width: 850px; display: grid; - grid-template-columns: repeat(11, auto); + grid-template-columns: repeat(7, auto); gap: auto; - padding: 10px; + padding: 50px; .cell { - width: 60px; - height: 60px; + width: 100px; + height: 100px; border: 2px solid black; border-radius: 10%; - } - .v-exit { - width: 60px; - height: 30px; - - > div { - width: 20px; - height: 100%; - margin: auto; + &.house { + background-color: blue; + } + + &.university { + background-color: orange; + } + + &.factory { + background-color: grey; + } + + .exit:has(.exit-road) { border: solid black; border-width: 0 1px; - .dotted { + .exit-road { margin: auto; + width: 0; + height: 100%; border: dashed black; border-width: 0 1px; - height: 100%; + transform: translate(calc(50% - 1px)); + } + } + + .exit:has(.exit-road) { + border: solid black; + border-width: 0 1px; + + .exit-road { + margin: auto; width: 0; + height: 100%; + border: dashed black; + border-width: 0 1px; + transform: translate(calc(50% - 1px)); } } - &:has(.v-exit-up) { - margin-bottom: -9px; + .exit:has(.exit-rail) { + border-width: 0 1px; + + .exit-rail { + margin: auto; + width: 0; + height: 100%; + border: solid black; + border-width: 0 1px; + transform: translate(calc(50% - 1px)); + } } - &:has(.v-exit-down) { - margin-top: -9px; + .exit:has(.exit-ambivalent) { + border-width: 0 1px; + border-style: dotted; + + .exit-ambivalent { + margin: auto; + width: 0; + height: 100%; + border: dotted black; + border-width: 0 1px 0 0; + transform: translate(calc(50%)); + } + } + } +} + +.exit { + position: relative; + width: 20px; + height: 20px; + + &:has(.exit-north) { + left: 50%; + transform: translate(calc(-50% - 1px), -100%); + } + + &:has(.exit-south) { + left: 50%; + top: 100%; + transform: translate(calc(-50% - 1px), 0%); + } + + &:has(.exit-east) { + left: 100%; + top: 50%; + transform: rotate(90deg) translate(-50%, 0); + } + + &:has(.exit-west) { + left: 0%; + top: 50%; + transform: rotate(90deg) translate(-50%, 100%); + } + + &:has(.exit-north), &:has(.exit-south) { + + .exit:has(.exit-east) { + left: 100%; + transform: rotate(90deg) translate(-150%, 0); } } - .h-exit { - height: 60px; - width: 30px; - - > div { - height: 20px; - width: 100%; - margin: auto; - border: solid black; - border-width: 1px 0; - position: relative; + &:has(.exit-north), &:has(.exit-south) { + + .exit:has(.exit-west) { top: 50%; - transform: translateY(-50%); - - .dotted { - margin: auto; - border: dashed black; - border-width: 1px 0; - width: 100%; - height: 0; - position: relative; - top: 50%; - transform: translateY(-50%); - } - } - - &:has(.h-exit-left) { - margin-right: -9px; - } - - &:has(.h-exit-right) { - margin-left: -9px; + transform: rotate(90deg) translate(-150%, 100%); } } } \ No newline at end of file diff --git a/web/src/pages/game/components/GameBoard.tsx b/web/src/pages/game/components/GameBoard.tsx index 31078b1..bfacbe7 100644 --- a/web/src/pages/game/components/GameBoard.tsx +++ b/web/src/pages/game/components/GameBoard.tsx @@ -1,76 +1,31 @@ +import { buildBoard, Cell, directions, Exit } from "interface"; + const GameBoard = () => { - const range = (n: number) => Array.from(Array(n).keys()); - const cells = range(11).flatMap((rowIndex) => { - return range(11).map((colIndex) => { - return { rowIndex, colIndex }; - }); - }); + const board: Cell[][] = buildBoard(); return (
- {cells.map(({ rowIndex, colIndex }) => { - if ( - (rowIndex === 0 || rowIndex === 10) && - (colIndex === 0 || colIndex === 10) - ) { - return
; - } - if (rowIndex === 0) { - return ( -
-
-
-
-
- ); - } - if (rowIndex === 10) { - return ( -
-
-
-
-
- ); - } - if (colIndex === 0) { - return ( -
-
-
-
-
- ); - } - if (colIndex === 10) { - return ( -
-
-
-
-
- ); - } - return
; - })} + {board.flatMap((row) => + row.map((cell) => ( +
+ {directions.map((direction) => { + const traversedNode = cell.getNodeAt(direction).traverseBorder(); + const isExit = traversedNode instanceof Exit; + if (!isExit) return; + const className = + `exit-${direction.toLowerCase()}` + + ` exit-${(traversedNode as Exit).type.toLowerCase()}`; + return ( +
+
+
+ ); + })} +
+ )), + )}
); - - /* - {range(9).map(() => ( -
-
-
- ))} - {range(81).map(() => ( -
- ))} - {range(9).map(() => ( -
-
-
- ))} - */ }; export default GameBoard;