feat: added new features, refactored code

This commit is contained in:
2025-11-21 16:15:33 +01:00
parent 3b0c00ab5f
commit b446190abe
4 changed files with 155 additions and 56 deletions

83
ui.ts
View File

@@ -58,19 +58,25 @@ export async function selectGameMode(): Promise<GameMode> {
message: "Select difficulty mode:",
options: [
{
name: `${colors.green("Easy")} - Letters (A-Z)`,
name: `${colors.green("Easy")} - Letters (A-Z)`,
value: "letters",
},
{
name: `${colors.yellow("Medium")} - Numbers (0-9)`,
value: "numbers",
name: `${colors.yellow("Medium")} - Letters + Numbers (A-Z, 0-9)`,
value: "alphanumeric",
},
{
name: `${colors.magenta("Hard")} - Words`,
name: `${colors.magenta(
"Hard"
)} - Letters + Numbers + Punctuation (🔥) `,
value: "full",
},
{
name: `${colors.cyan("Challenge")} - Words`,
value: "words",
},
{
name: `${colors.red("Expert")} - Phrases`,
name: `${colors.red("Expert")} - Phrases`,
value: "phrases",
},
],
@@ -83,8 +89,26 @@ export async function selectGameMode(): Promise<GameMode> {
* Configure game settings
*/
export async function configureGame(
_mode: GameMode
): Promise<{ rounds: number; timePerRound: number }> {
mode: GameMode
): Promise<{ rounds: number; timePerRound: number; dynamicTime: boolean }> {
// Set default time based on mode
let defaultTime: string;
switch (mode) {
case "letters":
defaultTime = "3";
break;
case "alphanumeric":
defaultTime = "5";
break;
case "full":
defaultTime = "7";
break;
case "words":
case "phrases":
defaultTime = "5";
break;
}
const roundsInput = await Input.prompt({
message: "How many rounds? (5-50)",
default: "10",
@@ -97,13 +121,24 @@ export async function configureGame(
},
});
// Ask about dynamic time for words/phrases
let dynamicTime = false;
if (mode === "words" || mode === "phrases") {
dynamicTime = await Confirm.prompt({
message: "Use dynamic time? (time multiplied by character count)",
default: true,
});
}
const timeInput = await Input.prompt({
message: "Seconds per round? (10-60)",
default: "30",
message: dynamicTime
? "Base seconds per character? (3-60)"
: "Seconds per round? (3-60)",
default: defaultTime,
validate: (value) => {
const num = parseInt(value);
if (isNaN(num) || num < 10 || num > 60) {
return "Please enter a number between 10 and 60";
if (isNaN(num) || num < 3 || num > 60) {
return "Please enter a number between 3 and 60";
}
return true;
},
@@ -112,6 +147,7 @@ export async function configureGame(
return {
rounds: parseInt(roundsInput),
timePerRound: parseInt(timeInput),
dynamicTime,
};
}
@@ -123,6 +159,17 @@ export async function playRound(
roundNumber: number
): Promise<RoundResult> {
const challenge = getChallenge(session.config.mode);
// Calculate dynamic time limit for words and phrases if enabled
let timeLimit = session.config.timePerRound;
if (
session.config.dynamicTime &&
(session.config.mode === "words" || session.config.mode === "phrases")
) {
// Use configured time as multiplier per character
timeLimit = challenge.length * session.config.timePerRound;
}
const startTime = Date.now();
clearScreen();
@@ -132,7 +179,7 @@ export async function playRound(
);
console.log(
colors.gray(
`Time limit: ${session.config.timePerRound}s | Current streak: ${session.currentStreak}\n`
`Time limit: ${timeLimit}s | Current streak: ${session.currentStreak}\n`
)
);
@@ -148,7 +195,7 @@ export async function playRound(
const timeoutPromise = new Promise<string>((_, reject) => {
setTimeout(() => {
reject(new Error("Time's up!"));
}, session.config.timePerRound * 1000);
}, timeLimit * 1000);
});
// Get user input with timeout
@@ -194,8 +241,16 @@ export async function playRound(
}
}
// Longer wait time for words and phrases
let waitTime = 2000; // Default: 2 seconds
if (session.config.mode === "words") {
waitTime = 4000; // 4 seconds for words
} else if (session.config.mode === "phrases") {
waitTime = 6000; // 6 seconds for phrases
}
// Wait for user to continue
await new Promise((resolve) => setTimeout(resolve, 2000));
await new Promise((resolve) => setTimeout(resolve, waitTime));
return result;
}