Implement board view based on board builder

pull/6/head
MiguelMLorente 2024-11-24 15:07:10 +01:00
parent e9305893cb
commit 0945336463
5 changed files with 141 additions and 123 deletions

View File

@ -60,14 +60,19 @@ function createBoard(): Cell[][] {
function connectAdjacentCells(board: Cell[][]) { function connectAdjacentCells(board: Cell[][]) {
const indexes = Array.from(Array(boardSize).keys()); const indexes = Array.from(Array(boardSize).keys());
for (const rowIndex of indexes.slice(0, -1)) { 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 cell = board[rowIndex][colIndex];
const rightCell = board[rowIndex][colIndex + 1];
const bottomCell = board[rowIndex + 1][colIndex]; const bottomCell = board[rowIndex + 1][colIndex];
cell cell
.getNodeAt(Direction.SOUTH) .getNodeAt(Direction.SOUTH)
.linkToNode(bottomCell.getNodeAt(Direction.NORTH)); .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 cell
.getNodeAt(Direction.EAST) .getNodeAt(Direction.EAST)
.linkToNode(rightCell.getNodeAt(Direction.WEST)); .linkToNode(rightCell.getNodeAt(Direction.WEST));

View File

@ -4,3 +4,10 @@ export enum Direction {
EAST = "EAST", EAST = "EAST",
WEST = "WEST", WEST = "WEST",
} }
export const directions: Direction[] = [
Direction.NORTH,
Direction.SOUTH,
Direction.EAST,
Direction.WEST,
];

View File

@ -15,10 +15,15 @@ export class ExternalNode extends Node {
public linkToNode(other: ExternalNode | Exit) { public linkToNode(other: ExternalNode | Exit) {
this.border = new Border(this, other); this.border = new Border(this, other);
if (other instanceof ExternalNode) {
other.border = this.border;
}
} }
public traverseBorder(): ExternalNode | Exit { 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); return (this.border as Border).traverseFrom(this);
} }
} }

View File

@ -1,79 +1,125 @@
.game-board { .game-board {
height: 700px; height: 850px;
width: 700px; width: 850px;
display: grid; display: grid;
grid-template-columns: repeat(11, auto); grid-template-columns: repeat(7, auto);
gap: auto; gap: auto;
padding: 10px; padding: 50px;
.cell { .cell {
width: 60px; width: 100px;
height: 60px; height: 100px;
border: 2px solid black; border: 2px solid black;
border-radius: 10%; border-radius: 10%;
}
.v-exit { &.house {
width: 60px; background-color: blue;
height: 30px; }
> div { &.university {
width: 20px; background-color: orange;
height: 100%; }
margin: auto;
&.factory {
background-color: grey;
}
.exit:has(.exit-road) {
border: solid black; border: solid black;
border-width: 0 1px; border-width: 0 1px;
.dotted { .exit-road {
margin: auto; margin: auto;
width: 0;
height: 100%;
border: dashed black; border: dashed black;
border-width: 0 1px; 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; width: 0;
height: 100%;
border: dashed black;
border-width: 0 1px;
transform: translate(calc(50% - 1px));
} }
} }
&:has(.v-exit-up) { .exit:has(.exit-rail) {
margin-bottom: -9px; 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) { .exit:has(.exit-ambivalent) {
margin-top: -9px; 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 { &:has(.exit-north), &:has(.exit-south) {
height: 60px; + .exit:has(.exit-west) {
width: 30px;
> div {
height: 20px;
width: 100%;
margin: auto;
border: solid black;
border-width: 1px 0;
position: relative;
top: 50%; top: 50%;
transform: translateY(-50%); transform: rotate(90deg) translate(-150%, 100%);
.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;
} }
} }
} }

View File

@ -1,76 +1,31 @@
import { buildBoard, Cell, directions, Exit } from "interface";
const GameBoard = () => { const GameBoard = () => {
const range = (n: number) => Array.from(Array(n).keys()); const board: Cell[][] = buildBoard();
const cells = range(11).flatMap((rowIndex) => {
return range(11).map((colIndex) => {
return { rowIndex, colIndex };
});
});
return ( return (
<div className="game-board"> <div className="game-board">
{cells.map(({ rowIndex, colIndex }) => { {board.flatMap((row) =>
if ( row.map((cell) => (
(rowIndex === 0 || rowIndex === 10) && <div className={"cell " + cell.cellType.toLowerCase()}>
(colIndex === 0 || colIndex === 10) {directions.map((direction) => {
) { const traversedNode = cell.getNodeAt(direction).traverseBorder();
return <div className="corner" />; const isExit = traversedNode instanceof Exit;
} if (!isExit) return;
if (rowIndex === 0) { const className =
return ( `exit-${direction.toLowerCase()}` +
<div className="v-exit"> ` exit-${(traversedNode as Exit).type.toLowerCase()}`;
<div className="v-exit-up"> return (
<div className="dotted" /> <div className="exit">
</div> <div className={className} />
</div> </div>
); );
} })}
if (rowIndex === 10) { </div>
return ( )),
<div className="v-exit"> )}
<div className="v-exit-down">
<div className="dotted" />
</div>
</div>
);
}
if (colIndex === 0) {
return (
<div className="h-exit">
<div className="h-exit-left">
<div className="dotted" />
</div>
</div>
);
}
if (colIndex === 10) {
return (
<div className="h-exit">
<div className="h-exit-right">
<div className="dotted" />
</div>
</div>
);
}
return <div className="cell"></div>;
})}
</div> </div>
); );
/*
{range(9).map(() => (
<div className="v-exit v-exit-up">
<div className="dotted"></div>
</div>
))}
{range(81).map(() => (
<div className="cell"></div>
))}
{range(9).map(() => (
<div className="v-exit v-exit-down">
<div className="dotted"></div>
</div>
))}
*/
}; };
export default GameBoard; export default GameBoard;