Skip to content

Commit

Permalink
feat(*): add 8 players support
Browse files Browse the repository at this point in the history
  • Loading branch information
guilhermebkel committed Nov 9, 2022
1 parent d51de70 commit dcba1b2
Show file tree
Hide file tree
Showing 9 changed files with 47,126 additions and 6,743 deletions.
4 changes: 1 addition & 3 deletions .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{
"*.{ts,tsx}": [
"eslint --fix"
]
"*.{ts,tsx}": []
}
53,656 changes: 46,982 additions & 6,674 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"scripts": {
"dev:resources": "docker-compose up",
"setup": "npm run setup:app && npm run setup:env",
"setup:app": "npm install && npm run install:unapy && npm run install:unoenty && npm run bootstrap",
"setup:app": "npm install && npm run bootstrap",
"setup:env": "npm run env:unapy && npm run env:unoenty",
"bootstrap": "lerna bootstrap --use-workspaces --hoist && lerna link",
"list": "lerna ls",
Expand Down
2 changes: 1 addition & 1 deletion packages/unapy/src/Services/GameService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class GameService {
const playerData = await PlayerService.getPlayerData(playerId)

const game: Game = {
maxPlayers: 6,
maxPlayers: 8,
type: "public",
status: "waiting",
round: 0,
Expand Down
70 changes: 38 additions & 32 deletions packages/unoenty/src/hooks/useSocket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import {
GameStartedEventData,
NewMessageEventData,
} from "@uno-game/protocols"
import { GameDeckLayoutPosition } from "@/utils/game"
import { getSanitizedValueWithBoundaries } from "@/utils/number"

type UseSocketResponse = {
currentPlayer: PlayerData
winner: PlayerData | null
otherPlayers: PlayerData[]
layoutedOtherPlayers: Record<GameDeckLayoutPosition, PlayerData>
currentRoundPlayer: PlayerData
getWinner: (game?: Game) => PlayerData | null
getCurrentPlayer: (players?: PlayerData[] | undefined) => PlayerData
Expand Down Expand Up @@ -83,45 +85,49 @@ const useSocket = (): UseSocketResponse => {
return player as PlayerData
}

const getOtherPlayers = (): PlayerData[] => {
const totalPlayers = socketStore?.game?.players?.length as number
const getLayoutedOtherPlayers = (): Record<GameDeckLayoutPosition, PlayerData> => {
const positionsIndexMap: Record<number, GameDeckLayoutPosition> = {
0: "topLeft",
1: "top",
2: "topRight",
3: "right",
4: "bottomRight",
5: "bottom",
6: "bottomLeft",
7: "left"
}

const layoutedOtherPlayers = {} as Record<GameDeckLayoutPosition, PlayerData>

const players = socketStore?.game?.players || []
const playerId = socketStore.player?.id

let currentPlayerIndex = socketStore?.game?.players?.
findIndex(player => player.id === playerId) as number
const currentPlayerIndex = players?.findIndex(player => player.id === playerId) as number
const isThereAnyCurrentPlayer = currentPlayerIndex === -1

if (currentPlayerIndex === -1) {
currentPlayerIndex = totalPlayers
}
if (isThereAnyCurrentPlayer) {
players.forEach((player, index) => {
layoutedOtherPlayers[positionsIndexMap[index]] = player
})
} else {
const currentPlayerPositionIndex = 5 // bottom

const otherPlayersBeforeCurrentPlayer = socketStore?.game?.players?.
slice(0, currentPlayerIndex)
const otherPlayersBeforeCurrentPlayer = players?.slice(0, currentPlayerIndex)

const otherPlayersAfterCurrentPlayer = socketStore?.game?.players?.
slice(currentPlayerIndex + 1, socketStore?.game?.players?.length)
otherPlayersBeforeCurrentPlayer?.reverse()?.forEach((player, index) => {
const otherPlayerIndex = getSanitizedValueWithBoundaries(currentPlayerPositionIndex - (index + 1), players.length, 0)
layoutedOtherPlayers[positionsIndexMap[otherPlayerIndex]] = player
})

let otherPlayers = [
...otherPlayersAfterCurrentPlayer || [],
...otherPlayersBeforeCurrentPlayer || [],
]
const otherPlayersAfterCurrentPlayer = players?.slice(currentPlayerIndex + 1, players?.length)

/**
* Improves layout location
*/
if (totalPlayers <= 4) {
otherPlayers = [
otherPlayers[0],
{} as PlayerData,
otherPlayers[1],
{} as PlayerData,
otherPlayers[2],
{} as PlayerData,
otherPlayers[3],
]
otherPlayersAfterCurrentPlayer?.forEach((player, index) => {
const otherPlayerIndex = getSanitizedValueWithBoundaries(currentPlayerPositionIndex + (index + 1), players.length, 0)
layoutedOtherPlayers[positionsIndexMap[otherPlayerIndex]] = player
})
}

return (otherPlayers || []) as PlayerData[]
return layoutedOtherPlayers
}

const joinGame = async (gameId: string): Promise<Game> => {
Expand Down Expand Up @@ -302,8 +308,8 @@ const useSocket = (): UseSocketResponse => {
get currentPlayer (): PlayerData {
return getCurrentPlayer()
},
get otherPlayers (): PlayerData[] {
return getOtherPlayers()
get layoutedOtherPlayers (): Record<GameDeckLayoutPosition, PlayerData> {
return getLayoutedOtherPlayers()
},
get currentRoundPlayer (): PlayerData {
return getCurrentRoundPlayer()
Expand Down
58 changes: 39 additions & 19 deletions packages/unoenty/src/pages/Table/CardDeckPlaceholder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react"
import {
Grid,
Typography,
Tooltip
} from "@material-ui/core"

import { PlayerData } from "@uno-game/protocols"
Expand All @@ -20,12 +21,13 @@ import PlayerEffect from "@/pages/Table/PlayerEffect"

import { getCardPosition } from "@/utils/card"
import { buildPercentage } from "@/utils/number"
import { GameDeckLayoutPosition } from "@/utils/game"

const MAX_CARDS = 7

type CardDeckPlaceholderProps = {
player: PlayerData
position: "left" | "top" | "topLeft" | "topRight" | "right" | "bottom"
position: GameDeckLayoutPosition
}

type CardDeckPlaceholderPositionStylesMap = {
Expand All @@ -34,6 +36,7 @@ type CardDeckPlaceholderPositionStylesMap = {
cardContainer?: React.CSSProperties
remainingCardsText?: React.CSSProperties
container?: React.CSSProperties
avatarContainer?: React.CSSProperties
}
}

Expand Down Expand Up @@ -71,8 +74,22 @@ const cardDeckPlaceholderPositionStylesMap: CardDeckPlaceholderPositionStylesMap
cardCounterContainer: { alignItems: "flex-end" },
cardContainer: { top: 50, left: -10, transform: "rotate(330deg)" },
remainingCardsText: { width: 55, height: 50, transform: "rotate(-90deg)" },
container: { flexDirection: "row-reverse", top: 40, left: 64 },
},
bottomLeft: {
cardCounterContainer: { alignItems: "flex-end", position: "relative", bottom: -30 },
cardContainer: { top: 80, left: 8, transform: "rotate(366deg)" },
remainingCardsText: { width: 55, height: 50, transform: "rotate(-90deg)" },
container: { flexDirection: "row-reverse" },
avatarContainer: { flexDirection: "column-reverse", position: "relative", bottom: -60, height: 88, justifyContent: "space-between" }
},
bottomRight: {
cardCounterContainer: { alignItems: "flex-end", position: "relative", bottom: -36 },
cardContainer: { top: 36, left: 40, transform: "rotate(280deg)" },
remainingCardsText: { width: 55, height: 50, transform: "rotate(-90deg)" },
container: { flexDirection: "row", width: "auto", justifyContent: "flex-end" },
avatarContainer: { flexDirection: "column-reverse", position: "relative", bottom: -60, height: 98, justifyContent: "space-between" }
}
}

const CardDeckPlaceholder: React.FC<CardDeckPlaceholderProps> = (props) => {
Expand Down Expand Up @@ -137,25 +154,28 @@ const CardDeckPlaceholder: React.FC<CardDeckPlaceholderProps> = (props) => {

<Divider orientation="vertical" size={2} />

<Grid
container
direction="column"
alignItems="center"
className={classes.avatarContainer}
>
<Typography
variant="h3"
className={`${classes.playerName} ${customClasses.limitedName}`}
<Tooltip title={player.name}>
<Grid
container
direction="column"
alignItems="center"
className={classes.avatarContainer}
style={positionStyles.avatarContainer}
>
{player.name}
</Typography>

<Avatar
name={player.name}
size="small"
className={player.isCurrentRoundPlayer ? customClasses.avatarTimer : ""}
/>
</Grid>
<Typography
variant="h3"
className={`${classes.playerName} ${customClasses.limitedName}`}
>
{player.name}
</Typography>

<Avatar
name={player.name}
size="small"
className={player.isCurrentRoundPlayer ? customClasses.avatarTimer : ""}
/>
</Grid>
</Tooltip>

<Divider orientation="vertical" size={2} />

Expand Down
61 changes: 48 additions & 13 deletions packages/unoenty/src/pages/Table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const Table: React.FC = () => {
>
<CardDeckPlaceholder
position="topLeft"
player={socket.otherPlayers?.[1]}
player={socket.layoutedOtherPlayers.topLeft}
/>
</Grid>
<Grid
Expand All @@ -175,7 +175,7 @@ const Table: React.FC = () => {
<Grid container justify="center" alignItems="center">
<CardDeckPlaceholder
position="top"
player={socket.otherPlayers?.[2]}
player={socket.layoutedOtherPlayers.top}
/>
</Grid>
</Grid>
Expand All @@ -186,7 +186,7 @@ const Table: React.FC = () => {
>
<CardDeckPlaceholder
position="topRight"
player={socket.otherPlayers?.[3]}
player={socket.layoutedOtherPlayers.topRight}
/>
</Grid>
</Grid>
Expand All @@ -203,7 +203,7 @@ const Table: React.FC = () => {
<Grid container justify="flex-start">
<CardDeckPlaceholder
position="left"
player={socket.otherPlayers?.[0]}
player={socket.layoutedOtherPlayers.left}
/>
</Grid>
</Grid>
Expand All @@ -223,28 +223,63 @@ const Table: React.FC = () => {
<Grid container justify="flex-end">
<CardDeckPlaceholder
position="right"
player={socket.otherPlayers?.[4]}
player={socket.layoutedOtherPlayers.right}
/>
</Grid>
</Grid>
</Grid>
<Grid container alignItems="center">
<Grid container justify="center" style={{ height: "100%" }}>
{socket?.currentPlayer ? (
<>
<Grid container justify="space-between">
<Grid
item
xs={2}
className={classes.cardDeckPlaceholder}
>
<CardDeckPlaceholder
position="bottomLeft"
player={socket.layoutedOtherPlayers.bottomLeft}
/>
</Grid>

{socket?.currentPlayer ? (
<Grid
container
alignItems="center"
justify="center"
style={{ position: "absolute", bottom: 16, height: 240, left: 0 }}
>
<Grid
style={{ height: "100%" }}
>
<CustomCardDragPreview />

<CardDeck
cards={socket.currentPlayer?.handCards}
player={socket.currentPlayer}
/>
</>
) : (
</Grid>
</Grid>
) : (
<Grid
item
xs={2}
className={classes.cardDeckPlaceholder}
>
<CardDeckPlaceholder
position="bottom"
player={socket.otherPlayers?.[5]}
player={socket.layoutedOtherPlayers.bottom}
/>
)}
</Grid>
)}

<Grid
item
xs={2}
className={classes.cardDeckPlaceholder}
>
<CardDeckPlaceholder
position="bottomRight"
player={socket.layoutedOtherPlayers.bottomRight}
/>
</Grid>
</Grid>
</Grid>
Expand Down
2 changes: 2 additions & 0 deletions packages/unoenty/src/utils/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ export const statusColorMap: StatusMap<string> = {
waiting: colors.palette.yellow1,
}

export type GameDeckLayoutPosition = "left" | "top" | "topLeft" | "topRight" | "right" | "bottom" | "bottomLeft" | "bottomRight"

// eslint-disable-next-line
export const orderByCreatedAtDesc = (a: any, b: any) => b.createdAt - a.createdAt
14 changes: 14 additions & 0 deletions packages/unoenty/src/utils/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,17 @@ export const buildPercentage = (used: number, total: number): number => {

return percentage
}

export const getSanitizedValueWithBoundaries = (value: number, max: number, min: number) => {
let sanitizedValue: number

if (value >= max) {
sanitizedValue = value % max
} else if (value <= min) {
sanitizedValue = Math.abs(max - Math.abs(value)) % max
} else {
return value
}

return sanitizedValue
}

0 comments on commit dcba1b2

Please sign in to comment.