Skip to content

Commit 3ba62fc

Browse files
committed
feat: measure the time to type for each key
Take into account the number of modifier keys needed to type a character. fixes #115
1 parent 88054c3 commit 3ba62fc

File tree

23 files changed

+1168
-1193
lines changed

23 files changed

+1168
-1193
lines changed

packages/keybr-multiplayer-server/lib/room.ts

+5-12
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
type PlayerState,
2121
type ServerMessage,
2222
} from "@keybr/multiplayer-shared";
23-
import { computeSpeed } from "@keybr/textinput";
23+
import { computeSpeed, countErrors } from "@keybr/textinput";
2424
import { type Task, Tasks, Timer } from "@keybr/timer";
2525
import { type Game } from "./game.ts";
2626
import { type Player, ReadyState } from "./player.ts";
@@ -182,9 +182,9 @@ export class Room {
182182
if (this.#gameState === GameState.RUNNING) {
183183
if (!player.spectator && !player.finished) {
184184
player.lastInput = now;
185-
player.textInput.appendChar(message.codePoint, now);
185+
player.textInput.appendChar(now, message.codePoint, 0);
186186
updatePlayer(player, this.#started);
187-
if (player.offset === this.#text.length) {
187+
if (player.textInput.completed) {
188188
player.finished = true;
189189
player.position = this.#finishOrder++;
190190
}
@@ -416,15 +416,8 @@ function updatePlayer(player: Player, started: number): void {
416416
player.offset = pos;
417417
if (pos > 0) {
418418
const time = steps[pos - 1].timeStamp - started;
419-
const speed = Math.round(computeSpeed(pos, time));
420-
let errors = 0;
421-
for (const step of steps) {
422-
if (step.typo) {
423-
errors += 1;
424-
}
425-
}
426-
player.speed = speed;
427-
player.errors = errors;
419+
player.speed = Math.round(computeSpeed(pos, time));
420+
player.errors = countErrors(steps);
428421
} else {
429422
player.speed = 0;
430423
player.errors = 0;

packages/keybr-multiplayer-shared/lib/worldstate.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,21 @@ import {
2424
} from "./types.ts";
2525
import { positionName } from "./util.ts";
2626

27-
export const NOBODY = Object.freeze<Player>({
27+
export const NOBODY = Object.freeze({
2828
id: 0,
29-
user: Object.freeze<AnyUser>({
29+
user: Object.freeze({
3030
id: null,
3131
name: "nobody",
3232
imageUrl: null,
33-
}),
33+
} satisfies AnyUser),
3434
spectator: false,
3535
finished: false,
3636
position: 0,
3737
offset: 0,
3838
speed: 0,
3939
errors: 0,
4040
progress: 0,
41-
});
41+
} satisfies Player);
4242

4343
export function makeTextInput(text: string): TextInput {
4444
return new TextInput(text, {
@@ -77,7 +77,7 @@ export function handleTextInput(
7777
const { gameState, players, textInput, timer } = worldState;
7878
if (!players.me.spectator && gameState === GameState.RUNNING) {
7979
const elapsed = timer.elapsed();
80-
textInput.appendChar(codePoint, elapsed);
80+
textInput.appendChar(elapsed, codePoint, 0);
8181
const { lines } = textInput;
8282
return { worldState: { ...worldState, lines }, elapsed };
8383
} else {

0 commit comments

Comments
 (0)