跳到正文
DEV Community· hinezi·· 4 小時前AI 評分33

開發 TicketKST K-pop 搶票遊戲,修正一分評分錯誤

Building a K-pop ticketing game — and fixing a one-point scoring bug

AI 導讀

TicketKST 開發者修正了瀏覽器遊戲與排行榜之間的一分評分差異,讓 Python 伺服器對非負分數採用與 JavaScript 一致的四捨五入方式。遊戲改為傳送座位操作及時間戳記,由伺服器重建遊戲狀態並驗證座位選擇、分數和連擊。45 輪測試比對 JavaScript 模擬與 Python 重播的結果。

正文

I built TicketKST, a browser game that recreates the pressure of booking K-pop concert tickets.

Players wait for the sale to open, click into a queue, type a captcha, and then have 30 seconds to select seats. Requests include adjacent seats, aisle seats, and seats within a budget. Other simulated fans keep buying seats while you choose.

The game uses a fictional venue and does not book real tickets.

You can try it here: https://ticketkst.com

The frontend is vanilla JavaScript, HTML, and CSS. The backend uses Flask and SQLite.

One surprisingly small implementation detail caused the score shown in the browser to disagree with the leaderboard.

JavaScript and Python don't always round the same way

Each completed seat request earns points based on seat quality and a combo multiplier.

Consider a request worth 645 base points with a 2.5× multiplier:

Math.round(645 * 2.5)
// 1613

The original Python calculation used:

round(645 * 2.5)
# 1612

Python's built-in round() uses ties-to-even rounding, while JavaScript's Math.round() resolves this positive halfway value upward.

Both calculations looked reasonable on their own. Together, they produced a one-point discrepancy.

For the game's nonnegative point values, the server now uses:

import math

def round_points(value):
    return math.floor(value + 0.5)

The result screen also uses the server's saved score once the response arrives.

Recalculating a score isn't enough

Another issue was what the server trusted.

Recalculating a total from client-reported success counts and seat-quality values still lets the client invent those inputs.

The updated version sends seat actions and their timestamps instead. The server reconstructs the daily hall and checks:

  • Whether the selected seats were available
  • Whether they matched the current request
  • Whether adjacent seats were actually together
  • How scheduled sell-outs affected availability
  • What score and combo followed from those actions

This validates the game state. It does not prove that a human made every move or eliminate automated play.

Testing both implementations together

The daily challenge gives everyone the same initial hall and requests for the same Korean date.

That makes consistency between the JavaScript simulation and Python replay important.

An offline test harness runs the actual JavaScript controller with a lightweight DOM and clock test double. It generates action transcripts, which are then replayed by Python.

Across 45 test rounds, the checks compare the initial hall, request sequence, outcomes, score, seat count, and best combo. The scenarios include delayed frames and the game's three surprise events.

These tests helped check the boundary between the two implementations, rather than testing each scoring function in isolation.

I'd be interested to hear how other developers handle this: do you replay browser-game actions on the server, share simulation code between environments, or make the server authoritative for every move?

Disclosure: AI tools assisted with implementation and drafting this article.

來源:DEV Community · dev.to