Skip to content

Commit

Permalink
feat(ui): add leaderboard in replay
Browse files Browse the repository at this point in the history
  • Loading branch information
Molmin committed Jun 6, 2024
1 parent b14412f commit dca30e2
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 22 deletions.
2 changes: 2 additions & 0 deletions frontend/component/alert.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { } from '../lib/jquery'

const clickEvents: ((ev: JQuery.ClickEvent) => void)[] = []

export class Alert {
Expand Down
3 changes: 3 additions & 0 deletions frontend/component/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './alert'
export * from './game_table'
export * as LeaderBoard from './leaderboard'
20 changes: 20 additions & 0 deletions frontend/component/leaderboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { PLAYER_STATUS, PlayerInfo } from '../lib/game'

export function update(players: Array<PlayerInfo>) {
$('.game-leaderboard > tbody').html(`
<tr>
<td><span style="white-space: nowrap;"><span style="color: gold;">★ </span></span></td>
<td>Player</td>
<td>Army</td>
<td>Land</td>
</tr>
${players.map((player) => `
<tr class="${player.status === PLAYER_STATUS.DEAD ? 'dead' : player.status === PLAYER_STATUS.SURRENDERED ? 'surrendered' : ''}">
<td><span style="white-space: nowrap;"><span style="color: gold;">★ </span>0</span></td>
<td class="leaderboard-name owner--${player.id}">${player.name}</td>
<td>${player.army}</td>
<td>${player.land}</td>
</tr>
`).join('')}
`)
}
2 changes: 1 addition & 1 deletion frontend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as pageGamePlay from './pages/game_play'
import * as pageGameReplay from './pages/game_replay'
import { gotoPage, registerPage } from './lib/page'
import { UserService } from './lib/user'
import { registerAlertEvent } from './component/alert'
import { registerAlertEvent } from './component'
import { getPathName, redirectTo } from './lib/path'

registerPage('home', pageHome.init)
Expand Down
27 changes: 25 additions & 2 deletions frontend/lib/replay.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { GeneralsGame } from './game'
import { LeaderBoard } from '../component'
import { GeneralsGame, PLAYER_STATUS, PlayerInfo } from './game'

export interface GeneralsReplay {
replayVersion: number
Expand All @@ -14,10 +15,11 @@ export class GeneralsGameReplay extends GeneralsGame {
isHalf = false

constructor(
public replay: GeneralsReplay
public replay: GeneralsReplay,
) {
super()
this.updateMap(this.replay.initial.join(';'))
this.updateLeaderboard()
}

gotoTurn(turn: number, isHalf: boolean) {
Expand All @@ -41,9 +43,30 @@ export class GeneralsGameReplay extends GeneralsGame {
for (const d of diffs) if (d) this.updateDiffMap(d)
}
}
this.updateLeaderboard()
this.nowTurn = turn, this.isHalf = isHalf
}

updateLeaderboard() {
const playerArmy: Record<number, number> = {}
const playerLand: Record<number, number> = {}
for (let i = 0; i < this.now.length; i++)
for (let j = 0; j < this.now[0].length; j++) {
const { owner, army } = this.now[i][j]
playerLand[owner] = (playerLand[owner] || 0) + 1
playerArmy[owner] = (playerArmy[owner] || 0) + army
}
const players = Object.entries(this.replay.idToPlayer).map(([id, uid]) => ({
id: +id,
uid,
name: uid.toString(),
army: playerArmy[+id] || 0,
land: playerLand[+id] || 0,
status: (playerLand[+id] || 0) === 0 ? PLAYER_STATUS.DEAD : PLAYER_STATUS.PLAYING,
})).sort((x, y) => x.army === y.army ? y.land - x.land : y.army - x.army)
LeaderBoard.update(players)
}

updateDiffMap(diff: string) {
const cellId = +diff.replace(/[a-z]\d+/, '')
const x = Math.floor(cellId / this.now[0].length)
Expand Down
21 changes: 3 additions & 18 deletions frontend/pages/game_play.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import superagent from 'superagent'
import { io as SocketIO } from 'socket.io-client'
import { } from '../lib/jquery'
import { UserService } from '../lib/user'
import { GeneralsGame, PLAYER_STATUS, PlayerInfo } from '../lib/game'
import { Alert } from '../component/alert'
import { GeneralsGame, PlayerInfo } from '../lib/game'
import { Alert, LeaderBoard } from '../component'
import { getPathName, redirectTo } from '../lib/path'
import { registerGameTableComponent } from '../component/game_table'

Expand Down Expand Up @@ -42,22 +42,7 @@ export async function init() {
game.markStepsAsDone(data.doneSteps)
game.updatePlayers(data.players)
game.updateMap(data.map)
$('.game-leaderboard > tbody').html(`
<tr>
<td><span style="white-space: nowrap;"><span style="color: gold;">★ </span></span></td>
<td>Player</td>
<td>Army</td>
<td>Land</td>
</tr>
${data.players.map((player) => `
<tr class="${player.status === PLAYER_STATUS.DEAD ? 'dead' : player.status === PLAYER_STATUS.SURRENDERED ? 'surrendered' : ''}">
<td><span style="white-space: nowrap;"><span style="color: gold;">★ </span>0</span></td>
<td class="leaderboard-name owner--${player.id}">${player.name}</td>
<td>${player.army}</td>
<td>${player.land}</td>
</tr>
`).join('')}
`)
LeaderBoard.update(data.players)
$('.page--game_play > .turn-counter').text(
Date.now() >= info.startAt ? `Turn ${data.turn}${data.isHalf ? '.' : ''}` : `Game will start after ${Math.ceil((info.startAt - Date.now()) / 1000)} s`
)
Expand Down
2 changes: 1 addition & 1 deletion frontend/pages/game_replay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { } from '../lib/jquery'
import { UserService } from '../lib/user'
import { GeneralsGameReplay, GeneralsReplay } from '../lib/replay'
import { getPathName, redirectTo } from '../lib/path'
import { registerGameTableComponent } from '../component/game_table'
import { registerGameTableComponent } from '../component'

async function getReplay() {
if (window['site_prefix'] !== '') {
Expand Down

0 comments on commit dca30e2

Please sign in to comment.