Skip to content

Commit

Permalink
Hashed Option for towns&roads to indicate Premove is Planned!
Browse files Browse the repository at this point in the history
  • Loading branch information
berg44 committed Sep 15, 2023
1 parent 17a11e2 commit f60cdfa
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 74 deletions.
2 changes: 1 addition & 1 deletion soos-client/src/components/hex/Hex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { hexCoordsToPixels } from '../../utils';
import './Hex.scss';

// Debug thing to show the HexCoords of every hex on the board.
const showAllCoords = false;
const showAllCoords =true;

function getTerrainClass(terrainType: TerrainType, resourceType?: ResourceType): string {
let terrainClass = '';
Expand Down
27 changes: 17 additions & 10 deletions soos-client/src/components/road/Road.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ import './Road.scss';
export type RoadProps = {
gameRoad: GameRoad;
highlighted: boolean;
premove: boolean;
makingPremoves: boolean;
premoveQueued: boolean;
onClick: () => void;
};

export const Road = (props: RoadProps) => {
const { gameRoad, onClick, premove, highlighted } = props;
const { gameRoad, onClick, makingPremoves, premoveQueued, highlighted } = props;
const coords = gameRoad.coords;
const { x, y } = edgeCoordsToPixels(coords);
const playerIdx = gameRoad.playerIdx ?? -1;
const shouldDisplay = premove || highlighted || playerIdx !== -1;
const shouldDisplay = makingPremoves || highlighted || playerIdx !== -1|| premoveQueued;

// don't display anything at all
if (!shouldDisplay) {
Expand All @@ -31,20 +32,20 @@ export const Road = (props: RoadProps) => {
top: y + 'px',
}}
onClick={() => {
console.log("road Clicked");
onClick()
console.log('road Clicked');
onClick();
}}
>
{makeSVG(
coords.direction,
Variables.PlayerColors[playerIdx],
props.premove || (playerIdx === -1 && props.highlighted),
props.makingPremoves || (playerIdx === -1 && props.highlighted), premoveQueued,
)}
</div>
);
};

function makeSVG(direction: HexDirection, color: string, dotted: boolean) {
function makeSVG(direction: HexDirection, color: string, dotted: boolean, hashed:boolean) {
let rotation = 0, translateX = 0, translateY = 0;
if (direction === HexDirection.NW || direction === HexDirection.SE) {
rotation = -33;
Expand All @@ -61,13 +62,13 @@ function makeSVG(direction: HexDirection, color: string, dotted: boolean) {
}

let fillOpacity, strokeDasharray, strokeWidth = 0;
if (dotted) {
if (dotted && !hashed) {
// dotted line
fillOpacity = '0';
strokeDasharray = '3 2';
strokeWidth = 3;
}

const checkerSize = 3;
return (
<svg
width={40}
Expand All @@ -78,14 +79,20 @@ function makeSVG(direction: HexDirection, color: string, dotted: boolean) {
transformOrigin: '16px 8px',
}}
>
<defs>
<pattern id="checkers" x={checkerSize} y={checkerSize} width={2*checkerSize} height={2*checkerSize} patternUnits="userSpaceOnUse">
<rect x={0} y={0} width={checkerSize} height={checkerSize} style={{ stroke: 'none', fill: color }}/>
<rect x={checkerSize} y={checkerSize} width={checkerSize} height={checkerSize} style={{ stroke: 'none', fill: color }}/>
</pattern>
</defs>
<rect
x={4}
y={4}
width={26}
height={10}
stroke={color}
strokeWidth={strokeWidth}
fill={color}
fill={(hashed? 'url(#checkers)': color)}
fillOpacity={fillOpacity}
strokeDasharray={strokeDasharray}
/>
Expand Down
2 changes: 1 addition & 1 deletion soos-client/src/components/town/Town.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
height: 20px;

position: absolute;
z-index: 10;
z-index: 11;
font-size: 15px;
text-align: center;
}
Expand Down
41 changes: 25 additions & 16 deletions soos-client/src/components/town/Town.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type TownProps = {
gameTown: GameTown;
highlighted: boolean;
makingPremove: boolean;
premoveQueued:boolean;
onClick: (vertexCoords: VertexCoords) => void;
};

Expand Down Expand Up @@ -35,11 +36,11 @@ const suburbSize = 28;
const suburbPolygonPoints = townPoints(suburbSize, [[ 0, .25 ], [ 0, 1 ], [ 1, 1 ], [ 1, .5 ], [ .5, .5 ], [ .5, .25 ], [ .25, 0 ]]);

export const Town = (props: TownProps) => {
const { boardPlayerIdx, gameTown, onClick, makingPremove, highlighted } = props;
const { boardPlayerIdx, gameTown, onClick, makingPremove, highlighted, premoveQueued } = props;

const playerIdx = gameTown.playerIdx ?? -1;
const playerColor = Variables.PlayerColors[playerIdx];
const playerClass = gameTown.isUnclaimed() ? 'unclaimed' : '';
const playerClass = gameTown.isUnclaimed() && !premoveQueued ? 'unclaimed' : '';
let highlightedClass = '';
if (highlighted) {
highlightedClass = 'highlight';
Expand Down Expand Up @@ -73,16 +74,24 @@ export const Town = (props: TownProps) => {
break;
}

svg = makeTownSVG(townSize, points, playerColor,
highlighted || (makingPremove && activePlayersTown), highlighted);
let townColor = playerColor;
let townColorId = playerIdx.toString();
if(boardPlayerIdx!==undefined && premoveQueued){
townColor=Variables.PlayerColors[boardPlayerIdx];
townColorId = boardPlayerIdx.toString();
console.log('prepping premove on town for ' + townColor);
}

svg = makeTownSVG(townSize, points, townColor,
highlighted || (makingPremove && activePlayersTown), premoveQueued, townColorId);

const { x, y } = vertexCoordsToPixels(gameTown.coords!);

const shouldDisplay = highlighted || playerIdx !== -1;
const shouldDisplay = highlighted || playerIdx !== -1 || premoveQueued;
if (!shouldDisplay) {
return null;
}

highlightedClass= '';
return (
<div className={'Town ' + playerClass + ' ' + highlightedClass}
key={`t:${gameTown.coords!.hexCoords.x},${gameTown.coords!.hexCoords.y},${gameTown.coords!.direction}`}
Expand All @@ -98,35 +107,35 @@ export const Town = (props: TownProps) => {
);
};

function makeTownSVG(townSize:number, points:string, playerColor:string, dotted:boolean,
hashed:boolean ){
function makeTownSVG(townSize:number, points:string, townColor:string, dotted:boolean,
hashed:boolean, playerId:string ){

let fillOpacity, strokeDasharray, strokeWidth = 0;
if (dotted) {
if (dotted && !hashed) {
// dotted line
fillOpacity = '0';
strokeDasharray = '3 2';
strokeWidth = 3;
}

const checkersName = 'checkers'+playerId;
const checkersURL = 'url(#'+checkersName+')';
const checkerSize = 3;
return (

<svg
width={townSize + 5}
height={townSize + 5}
style={{ transform: `translate(${-baseOffset}px, ${-baseOffset}px)` }}>
<defs>
<pattern id="checkers" x={checkerSize} y={checkerSize} width={2*checkerSize} height={2*checkerSize} patternUnits="userSpaceOnUse">
<rect x={0} y={0} width={checkerSize} height={checkerSize} style={{ stroke: 'none', fill: playerColor }}/>
<rect x={checkerSize} y={checkerSize} width={checkerSize} height={checkerSize} style={{ stroke: 'none', fill: playerColor }}/>
<pattern id={checkersName} x={checkerSize} y={checkerSize} width={2*checkerSize} height={2*checkerSize} patternUnits="userSpaceOnUse">
<rect x={0} y={0} width={checkerSize} height={checkerSize} style={{ stroke: 'none', fill: townColor }}/>
<rect x={checkerSize} y={checkerSize} width={checkerSize} height={checkerSize} style={{ stroke: 'none', fill: townColor }}/>
</pattern>
</defs>
<polygon
points={points}
fill= {(hashed? 'url(#checkers)':playerColor)}
fill= {(hashed? checkersURL:townColor)}
fillOpacity={fillOpacity}
stroke={playerColor}
stroke={townColor}
strokeWidth={strokeWidth}
strokeDasharray={strokeDasharray}
/>
Expand Down
10 changes: 5 additions & 5 deletions soos-client/src/features/gameView/GameView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import {
import { Player } from '~/src/components';
import { Board, ResourceBar, TradeWindow } from './components';

let premoves: BuildAction[] = [];

type GameViewProps = {
socket: Socket;
game: Game;
Expand All @@ -30,9 +28,8 @@ export const GameView = (props: GameViewProps) => {
const [ playerId, setPlayerId ] = React.useState<number | undefined>(undefined);
const [ isTradeWindowShowing, setIsTradeWindowShowing ] = React.useState<boolean>(false);
const [ makingPremoves, setMakingPremoves ] = React.useState<boolean>(false);

const [ possibleBuildActions, setPossibleBuildActions ] = React.useState<BuildAction[]>([]);

const [ queuedPremoves, setQueuedPremoves ] = React.useState<BuildAction[]>([]);
// Set up force update function
const [ count, setCount ] = React.useState<number>(0);
game.forceUpdate = () => {
Expand All @@ -59,15 +56,17 @@ export const GameView = (props: GameViewProps) => {
setPossibleBuildActions([]);
console.log('pba: ' + possibleBuildActions.length);
console.log('got new game state');
socket.emit('getPremoves');
}

function setPremoves(serverPremoves: BuildAction[]) {
console.log('got premoves: ');
console.log(serverPremoves);
premoves = [];
const premoves:BuildAction[] = [];
for (const serverMove of serverPremoves) {
premoves.push(hydrateBuildAction(serverMove));
}
setQueuedPremoves(premoves);
game.forceUpdate();
}

Expand Down Expand Up @@ -132,6 +131,7 @@ export const GameView = (props: GameViewProps) => {
makingPremoves={makingPremoves}
playerId={playerId}
possibleBuildActions={possibleBuildActions}
queuedPremoves = {queuedPremoves}
/>

{/* List of players' resource count & victory points */}
Expand Down
40 changes: 25 additions & 15 deletions soos-client/src/features/gameView/components/board/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ type BoardProps = {
makingPremoves: boolean;
playerId?: number;
possibleBuildActions: BuildAction[];
queuedPremoves: BuildAction[];
};

const premoves: BuildAction[] = [];

export const Board = (props: BoardProps) => {
const { game, socket, makingPremoves, playerId, possibleBuildActions } = props;
const { game, socket, makingPremoves, playerId, possibleBuildActions, queuedPremoves } = props;

function sendGameStateToServer() {
socket.emit('newGameState', game.toString());
Expand Down Expand Up @@ -53,31 +54,36 @@ export const Board = (props: BoardProps) => {
const townBuildActions = possibleBuildActions.filter(pba => pba.type === BuildActionType.Settlement || pba.type === BuildActionType.City);
console.log('town build actions: ' + townBuildActions.length);
const isSettlementSetup = game.setupPhase() && game.currPlayerIdx === playerId && !game.claimedSettlement;

const townQdActions = queuedPremoves.filter(pba => pba.type === BuildActionType.Settlement || pba.type === BuildActionType.City);
const towns = [];
console.log('Building towns for player '+ playerId);
for (const town of game.map.towns) {
if (!town || !town.coords) {
continue;
}
const townCoords = town.coords;

let queued = false;
let buildAction: BuildAction | undefined;
if (isSettlementSetup) {
buildAction = new BuildSettlementAction(playerId, townCoords);
} else {
// TODO optimize
buildAction = townBuildActions.find(pba => townCoords.equals(pba.location));
queued = townQdActions.find(pba => townCoords.equals(pba.location))!==undefined;
if(buildAction!==undefined) {
console.log('Found build action for location: ' + townCoords.toString());
}
if(queued){
console.log('Premove found for town! ' + townCoords.toString());
}
}

towns.push(
<Town
boardPlayerIdx={playerId}
gameTown={town}
highlighted={!!buildAction}
makingPremove={makingPremoves}
premoveQueued = {queued}
onClick={() => {
if (buildAction) {
if(makingPremoves){
Expand All @@ -93,31 +99,29 @@ export const Board = (props: BoardProps) => {
}

let roadBuildActions = possibleBuildActions.filter(pba => pba.type === BuildActionType.Road);

const roadQdActions = queuedPremoves.filter(pba=>pba.type===BuildActionType.Road);
if (playerId!==undefined && ((game.gamePhase === GamePhase.PlaceSettlement1 || game.gamePhase === GamePhase.PlaceSettlement2)
&& game.currPlayerIdx === playerId
&& game.claimedSettlement) || makingPremoves) {
// custom roadBuildActions for setup phase
roadBuildActions = game.getValidBuildActions(playerId!, BuildActionType.Road);
}
for (const premoveAction of premoves){
if(premoveAction.type===BuildActionType.Road) {
roadBuildActions.push(premoveAction);
}
}

const roads = [];
let queued = false;
for (const road of game.map.roads) {
const roadCoords = road.coords;

// TODO optimize
const buildAction = roadBuildActions.find(pba => road.coords.equals(pba.location));

queued = false;
queued = roadQdActions.find(pba => roadCoords.equals(pba.location))!==undefined;
roads.push(
<Road
gameRoad={road}
highlighted={!!buildAction}
premove={false && makingPremoves && road.playerIdx === playerId}
makingPremoves={false && makingPremoves && road.playerIdx === playerId}
premoveQueued = {queued}
onClick={() => {
if (buildAction) {
if(makingPremoves){
Expand All @@ -144,9 +148,15 @@ export const Board = (props: BoardProps) => {

return (
<div className="Board__body">
{hexes}
{towns}
{roads}
<div className="Hexes">
{hexes}
</div>
<div className="Towns">
{towns}
</div>
<div>
{roads}
</div>
{robber}
</div>
);
Expand Down
Loading

0 comments on commit f60cdfa

Please sign in to comment.