feat(ttt): added draw status in ttt match history
This commit is contained in:
parent
830f251537
commit
f87a991441
7 changed files with 36 additions and 17 deletions
|
|
@ -66,7 +66,8 @@ export interface TttHistory200ResponsePayloadDataInner {
|
||||||
export const TttHistory200ResponsePayloadDataInnerOutcomeEnum = {
|
export const TttHistory200ResponsePayloadDataInnerOutcomeEnum = {
|
||||||
WinX: 'winX',
|
WinX: 'winX',
|
||||||
WinO: 'winO',
|
WinO: 'winO',
|
||||||
Other: 'other'
|
Other: 'other',
|
||||||
|
Draw: 'draw'
|
||||||
} as const;
|
} as const;
|
||||||
export type TttHistory200ResponsePayloadDataInnerOutcomeEnum = typeof TttHistory200ResponsePayloadDataInnerOutcomeEnum[keyof typeof TttHistory200ResponsePayloadDataInnerOutcomeEnum];
|
export type TttHistory200ResponsePayloadDataInnerOutcomeEnum = typeof TttHistory200ResponsePayloadDataInnerOutcomeEnum[keyof typeof TttHistory200ResponsePayloadDataInnerOutcomeEnum];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,18 @@ function getHHMM(d: Date): string {
|
||||||
return `${h < 9 ? '0' : ''}${h}:${m < 9 ? '0' : ''}${m}`
|
return `${h < 9 ? '0' : ''}${h}:${m < 9 ? '0' : ''}${m}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function statusText(side:'X'|'O',status: string): string {
|
||||||
|
if (status === `win${side}`) return 'WIN';
|
||||||
|
if (status === `win${side === 'X'? 'O' : 'X'}`) return 'LOSE';
|
||||||
|
return 'DRAW'
|
||||||
|
}
|
||||||
|
|
||||||
|
function statusColor(side:'X'|'O',status: string): string {
|
||||||
|
if (status === `win${side}`) return 'text-green-600';
|
||||||
|
if (status === `win${side === 'X'? 'O' : 'X'}`) return 'text-red-600';
|
||||||
|
return 'text-yellow-600'
|
||||||
|
}
|
||||||
|
|
||||||
async function tttHistory(_url: string, args: RouteHandlerParams): Promise<RouteHandlerReturn> {
|
async function tttHistory(_url: string, args: RouteHandlerParams): Promise<RouteHandlerReturn> {
|
||||||
if (isNullish(args.userid))
|
if (isNullish(args.userid))
|
||||||
args.userid = 'me';
|
args.userid = 'me';
|
||||||
|
|
@ -42,32 +54,36 @@ async function tttHistory(_url: string, args: RouteHandlerParams): Promise<Route
|
||||||
// maybe we do want local games ? then put the check here :D
|
// maybe we do want local games ? then put the check here :D
|
||||||
// if (!g.local) {
|
// if (!g.local) {
|
||||||
if (true) {
|
if (true) {
|
||||||
let youwin = false;
|
let state: 'win'|'lose'|'draw' = 'lose';
|
||||||
|
|
||||||
if (g.playerX.id === user.id && g.outcome === 'winX')
|
if (g.outcome === 'draw')
|
||||||
youwin = true;
|
state = 'draw';
|
||||||
|
else if (g.playerX.id === user.id && g.outcome === 'winX')
|
||||||
|
state = 'win';
|
||||||
else if (g.playerO.id === user.id && g.outcome === 'winO')
|
else if (g.playerO.id === user.id && g.outcome === 'winO')
|
||||||
youwin = true;
|
state = 'win';
|
||||||
|
|
||||||
if (youwin)
|
if (state === 'win')
|
||||||
color = 'bg-green-300';
|
color = 'bg-green-300';
|
||||||
else
|
else if (state === 'lose')
|
||||||
color = 'bg-red-300';
|
color = 'bg-red-300';
|
||||||
|
else
|
||||||
|
color = 'bg-amber-200';
|
||||||
}
|
}
|
||||||
e.className =
|
e.className =
|
||||||
'grid grid-cols-[1fr_auto_1fr] items-center rounded-lg px-4 py-3 ' + color;
|
'grid grid-cols-[1fr_auto_1fr] items-center rounded-lg px-4 py-3 ' + color;
|
||||||
|
|
||||||
e.innerHTML = `
|
e.innerHTML = `
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<div class="font-semibold ${g.outcome === 'winX' ? 'text-green-600' : 'text-red-600'}">${g.playerX.name}</div>
|
<div class="font-semibold ${statusColor('X', g.outcome)}">${g.playerX.name}</div>
|
||||||
<div class="text-lg ${g.outcome === 'winX' ? 'text-green-600' : 'text-red-600'}">${g.outcome === 'winX' ? 'WON' : 'LOST'}</div>
|
<div class="text-lg ${statusColor('X', g.outcome)}">${statusText('X', g.outcome)}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center text-sm text-gray-800 px-4 whitespace-nowrap">${date.toDateString()}<br />${getHHMM(date)}</div>
|
<div class="text-center text-sm text-gray-800 px-4 whitespace-nowrap">${date.toDateString()}<br />${getHHMM(date)}</div>
|
||||||
|
|
||||||
<div class="text-left">
|
<div class="text-left">
|
||||||
<div class="font-semibold ${g.outcome === 'winO' ? 'text-green-600' : 'text-red-600'}">${g.playerO.name}</div>
|
<div class="font-semibold ${statusColor('O', g.outcome)}">${g.playerO.name}</div>
|
||||||
<div class="text-lg ${g.outcome === 'winO' ? 'text-green-600' : 'text-red-600'}">${g.outcome === 'winO' ? 'WON' : 'LOST'}</div>
|
<div class="text-lg ${statusColor('O', g.outcome)}">${statusText('O', g.outcome)}</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
return e;
|
return e;
|
||||||
}).filter(v => !isNullish(v));
|
}).filter(v => !isNullish(v));
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import type { Database } from './_base';
|
||||||
import { UserId } from './user';
|
import { UserId } from './user';
|
||||||
import { isNullish } from '@shared/utils';
|
import { isNullish } from '@shared/utils';
|
||||||
|
|
||||||
export type TicTacToeOutcome = 'winX' | 'winO' | 'other';
|
export type TicTacToeOutcome = 'winX' | 'winO' | 'draw' | 'other';
|
||||||
// describe every function in the object
|
// describe every function in the object
|
||||||
export interface ITicTacToeDb extends Database {
|
export interface ITicTacToeDb extends Database {
|
||||||
setTTTGameOutcome(this: ITicTacToeDb, id: TTTGameId, player1: UserId, player2: UserId, outcome: TicTacToeOutcome): void,
|
setTTTGameOutcome(this: ITicTacToeDb, id: TTTGameId, player1: UserId, player2: UserId, outcome: TicTacToeOutcome): void,
|
||||||
|
|
@ -82,7 +82,7 @@ function TicTacToeGameFromRow(r: Partial<TicTacToeGameTable> | undefined): TicTa
|
||||||
if (isNullish(r.outcome)) return undefined;
|
if (isNullish(r.outcome)) return undefined;
|
||||||
if (isNullish(r.time)) return undefined;
|
if (isNullish(r.time)) return undefined;
|
||||||
|
|
||||||
if (r.outcome !== 'winX' && r.outcome !== 'winO' && r.outcome !== 'other') return undefined;
|
if (r.outcome !== 'winX' && r.outcome !== 'winO' && r.outcome !== 'other' && r.outcome !== 'draw') return undefined;
|
||||||
const date = Date.parse(r.time);
|
const date = Date.parse(r.time);
|
||||||
if (Number.isNaN(date)) return undefined;
|
if (Number.isNaN(date)) return undefined;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2013,7 +2013,8 @@
|
||||||
"enum": [
|
"enum": [
|
||||||
"winX",
|
"winX",
|
||||||
"winO",
|
"winO",
|
||||||
"other"
|
"other",
|
||||||
|
"draw"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,8 @@
|
||||||
"enum": [
|
"enum": [
|
||||||
"winX",
|
"winX",
|
||||||
"winO",
|
"winO",
|
||||||
"other"
|
"other",
|
||||||
|
"draw"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const TTTHistoryResponse = {
|
||||||
playerX: Type.Object({ id: Type.String(), name: Type.String() }),
|
playerX: Type.Object({ id: Type.String(), name: Type.String() }),
|
||||||
playerO: Type.Object({ id: Type.String(), name: Type.String() }),
|
playerO: Type.Object({ id: Type.String(), name: Type.String() }),
|
||||||
date: Type.String(),
|
date: Type.String(),
|
||||||
outcome: Type.Enum(['winX', 'winO', 'other']),
|
outcome: Type.Enum(['winX', 'winO', 'other', 'draw']),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export type GameUpdate = {
|
||||||
|
|
||||||
boardState: CellState[];
|
boardState: CellState[];
|
||||||
currentPlayer: 'X' | 'O';
|
currentPlayer: 'X' | 'O';
|
||||||
gameState: 'winX' | 'winO' | 'concededX' | 'concededO' | 'draw' | 'ongoing';
|
gameState: 'winX' | 'winO' | 'draw' | 'ongoing';
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GameMove = {
|
export type GameMove = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue