Versions

  • v14

    10/25/2024
    Open: Version
    Changes from v13 to v14
    +77
    -18
    ⦚ 17 unchanged lines ⦚
    },
    ]);
    const [visibleValidators, setVisibleValidators] = useState<Set<number>>(new Set());
    const [loading, setLoading] = useState(false);
    const [failedRequirements, setFailedRequirements] = useState<string[]>([]);
    ⦚ 5 unchanged lines ⦚

    for (let i = 0; i < level; i++) {
    const requirement = requirements[i];
    try {
    ⦚ 21 unchanged lines ⦚
    const response = await fetch("/", {
    method: "POST",
    body: JSON.stringify({ level, password }),
    headers: { "Content-Type": "application/json" },
    });
    ⦚ 11 unchanged lines ⦚

    validatePassword();
    }, [password, level, requirements]);

    return (
    ⦚ 18 unchanged lines ⦚
    const requirement = JSON.parse(error);
    const isValidatorVisible = visibleValidators.has(i);
    return (
    <div
    key={i}
    className="error"
    onClick={() => {
    ⦚ 17 unchanged lines ⦚
    },
    ]);
    const [dismissedRequirements, setDismissedRequirements] = useState<Set<number>>(new Set());
    const [visibleValidators, setVisibleValidators] = useState<Set<number>>(new Set());
    const [loading, setLoading] = useState(false);
    const [failedRequirements, setFailedRequirements] = useState<string[]>([]);
    ⦚ 5 unchanged lines ⦚

    for (let i = 0; i < level; i++) {
    if (dismissedRequirements.has(i)) continue;
    const requirement = requirements[i];
    try {
    ⦚ 21 unchanged lines ⦚
    const response = await fetch("/", {
    method: "POST",
    body: JSON.stringify({ level, password, requirements }),
    headers: { "Content-Type": "application/json" },
    });
    ⦚ 11 unchanged lines ⦚

    validatePassword();
    }, [password, level, requirements, dismissedRequirements]);

    return (
    ⦚ 18 unchanged lines ⦚
    const requirement = JSON.parse(error);
    const isValidatorVisible = visibleValidators.has(i);
    if (dismissedRequirements.has(i)) return null;
    return (
  • v13

    10/25/2024
    Open: Version
    Changes from v12 to v13
    +16
    -18
    ⦚ 93 unchanged lines ⦚
    return (
    <div
    key={i}
    className="error"
    onClick={() => {
    setVisibleValidators(prev => {
    const next = new Set(prev);
    isValidatorVisible ? next.delete(i) : next.add(i);
    return next;
    });
    }}
    >
    <div className="error-description">{requirement.description} {isValidatorVisible ? '🔽' : '🔼'}</div>
    {isValidatorVisible && <code className="validator-code">{requirement.validator}</code>}
    </div>
    ))}
    </div>
    )}
    ⦚ 164 unchanged lines ⦚
    border-radius: 4px;
    text-align: left;
    }
    .error {
    cursor: pointer;
    }
    ⦚ 10 unchanged lines ⦚
    ⦚ 93 unchanged lines ⦚
    return (
    <div
    key={i}
    className="error"
    onClick={() => {
    setVisibleValidators(prev => {
    const next = new Set(prev);
    isValidatorVisible ? next.delete(i) : next.add(i);
    return next;
    });
    }}
    >
    <div className="error-description">{requirement.description} {isValidatorVisible ? '🔽' : '🔼'}</div>
    {isValidatorVisible && <code className="validator-code">{requirement.validator}</code>}
    </div>
    );
    })}
    </div>
    )}
    ⦚ 164 unchanged lines ⦚
    border-radius: 4px;
    text-align: left;
    cursor: pointer;
    }
    ⦚ 10 unchanged lines ⦚
  • v12

    10/25/2024
    Open: Version
    Changes from v11 to v12
    +33
    -4
    ⦚ 17 unchanged lines ⦚
    },
    ]);
    const [loading, setLoading] = useState(false);
    const [failedRequirements, setFailedRequirements] = useState<string[]>([]);

    ⦚ 9 unchanged lines ⦚
    const isValid = new Function("password", `return ${requirement.validator}`)(password);
    if (!isValid) {
    failed.push(requirement.description);
    allValid = false;
    }
    ⦚ 51 unchanged lines ⦚
    {failedRequirements.length > 0 && (
    <div className="errors">
    {failedRequirements.map((error, i) => (
    <div key={i} className="error">
    {error}
    </div>
    ))}
    ⦚ 166 unchanged lines ⦚
    border-radius: 4px;
    text-align: left;
    }
    `;
    ⦚ 17 unchanged lines ⦚
    },
    ]);
    const [visibleValidators, setVisibleValidators] = useState<Set<number>>(new Set());
    const [loading, setLoading] = useState(false);
    const [failedRequirements, setFailedRequirements] = useState<string[]>([]);

    ⦚ 9 unchanged lines ⦚
    const isValid = new Function("password", `return ${requirement.validator}`)(password);
    if (!isValid) {
    failed.push(JSON.stringify(requirement));
    allValid = false;
    }
    ⦚ 51 unchanged lines ⦚
    {failedRequirements.length > 0 && (
    <div className="errors">
    {failedRequirements.map((error, i) => {
    const requirement = JSON.parse(error);
    const isValidatorVisible = visibleValidators.has(i);
    return (
    <div
    key={i}
    className="error"
    onClick={() => {
    setVisibleValidators(prev => {
    const next = new Set(prev);
    isValidatorVisible ? next.delete(i) : next.add(i);
    return next;
    });
    }}
    >
    <div className="error-description">{requirement.description} {isValidatorVisible ? '🔽' : '🔼'}</div>
  • v11

    10/25/2024
    Open: Version
    Changes from v10 to v11
    +13
    -13
    ⦚ 115 unchanged lines ⦚
    {
    role: "system",
    content: "You are a creative game master. Make each password requirement more challenging and entertaining than the last.",
    },
    {
    ⦚ 21 unchanged lines ⦚
    }
    {
    "description": "The numbers in your password must add up to 25",
    "validator": "password.match(/\\d/g)?.reduce((sum, n) => sum + parseInt(n), 0) === 25"
    }
    {
    "description": "Password must contain the word 'cerebras'",
    "validator": "password.toLowerCase().includes('cerebras')"
    }
    Be creative! Ideas:
    - Mathematical operations with numbers in the password
    - Special character patterns
    - Word puzzles or riddles
    - ASCII art requirements
    - Chess notation
    - Chemical elements
    - Emoji requirements`,
    parameters: {
    type: "object",
    properties: {
    description: {
    type: "string",
    description: "Clear English description of what the password must contain",
    },
    validator: {
    ⦚ 97 unchanged lines ⦚
    ⦚ 115 unchanged lines ⦚
    {
    role: "system",
    content: "You are a hilarious game show host. Make each password requirement funnier and more ridiculous than the last. Focus on humor, not difficulty. Think dad jokes and silly requirements.",
    },
    {
    ⦚ 21 unchanged lines ⦚
    }
    {
    "description": "Password must contain a dad joke (Example: 'Why don't eggs tell jokes? They'd crack up!')",
    "validator": "password.toLowerCase().includes('joke')"
    }
    {
    "description": "Password must include at least one 🦄 unicorn emoji because who doesn't love unicorns?",
    "validator": "password.includes('🦄')"
    }
    Be creative! Ideas:
    - Silly emoji combinations
    - Dad jokes or puns
    - Animal sounds
    - Food combinations
    - Internet memes
    - Funny character patterns
    - Pop culture references`,
    parameters: {
    type: "object",
    properties: {
    description: {
    type: "string",
    description: "A funny description of what the password must contain, including the reason why (make it silly!)",
    },
    validator: {
    ⦚ 97 unchanged lines ⦚
  • v10

    10/25/2024
    Open: Version
    Changes from v9 to v10
    +34
    -18
    ⦚ 115 unchanged lines ⦚
    {
    role: "system",
    content:
    `You are a creative game master for "The Password Game". Generate increasingly challenging and creative password requirements. Return only JSON in the specified format.`,
    },
    {
    role: "system",
    content: `Requirements must be returned as a JSON object with two fields:
    1. "description": A clear English description of the requirement
    2. "validator": A JavaScript expression that returns true/false when evaluated with the password variable
    Example:
    {
    "description": "Password must contain at least one uppercase letter",
    "validator": "password.match(/[A-Z]/) !== null"
    }`,
    },
    {
    role: "user",
    content: `Generate the next requirement for level ${level + 1}. Current password: ${password}`,
    },
    ],
    ⦚ 3 unchanged lines ⦚
    function: {
    name: "generateRequirement",
    description: "Generate a new password requirement",
    parameters: {
    type: "object",
    properties: {
    description: {
    type: "string",
    description: "The human-readable description of the requirement",
    },
    ⦚ 115 unchanged lines ⦚
    {
    role: "system",
    content: "You are a creative game master. Make each password requirement more challenging and entertaining than the last.",
    },
    {
    role: "user",
    content: `Generate the next password requirement for level ${level + 1}.`,
    },
    ],
    ⦚ 3 unchanged lines ⦚
    function: {
    name: "generateRequirement",
    description: `Generate a creative password requirement with two fields:
    1. A clear description of what the password must contain
    2. A JavaScript expression that validates the requirement

    Examples of increasing difficulty:
    {
    "description": "Password must contain at least one number",
    "validator": "password.match(/\\d/) !== null"
    }
    {
    "description": "Password must contain an uppercase letter",
    "validator": "password.match(/[A-Z]/) !== null"
    }
    {
    "description": "The numbers in your password must add up to 25",
    "validator": "password.match(/\\d/g)?.reduce((sum, n) => sum + parseInt(n), 0) === 25"
    }
    {
    "description": "Password must contain the word 'cerebras'",
    "validator": "password.toLowerCase().includes('cerebras')"
    }
  • v9

    10/25/2024
    Open: Version
    Changes from v8 to v9
    +2
    -2
    ⦚ 161 unchanged lines ⦚
    console.log(completion);

    const functionCall = completion.choices?.at(0)?.message?.tool_calls?.at(0)?.function_call;
    if (functionCall.name === "generateRequirement") {
    return new Response(functionCall.arguments, {
    headers: { "Content-Type": "application/json" },
    ⦚ 81 unchanged lines ⦚
    ⦚ 161 unchanged lines ⦚
    console.log(completion);

    const functionCall = completion.choices?.at(0)?.message?.tool_calls?.at(0)?.function;
    if (functionCall?.name === "generateRequirement") {
    return new Response(functionCall.arguments, {
    headers: { "Content-Type": "application/json" },
    ⦚ 81 unchanged lines ⦚
  • v8

    10/25/2024
    Open: Version
    Changes from v7 to v8
    +5
    -8
    ⦚ 159 unchanged lines ⦚
    });

    let requirement;
    const choice = completion.choices[0].message;

    const functionCall = choice.tool_calls[0].function;
    if (functionCall.name === "generateRequirement") {
    requirement = JSON.parse(functionCall.arguments);
    } else {
    console.log(completion);
    throw new Error("Unexpected function call");
    }

    return new Response(JSON.stringify(requirement), {
    headers: { "Content-Type": "application/json" },
    });
    }

    ⦚ 74 unchanged lines ⦚
    ⦚ 159 unchanged lines ⦚
    });

    console.log(completion);

    const functionCall = completion.choices?.at(0)?.message?.tool_calls?.at(0)?.function_call;
    if (functionCall.name === "generateRequirement") {
    return new Response(functionCall.arguments, {
    headers: { "Content-Type": "application/json" },
    });
    } else {
    console.log(completion);
    throw new Error("Unexpected function call");
    }
    }

    ⦚ 74 unchanged lines ⦚
  • v7

    10/25/2024
    Open: Version
    Changes from v6 to v7
    +0
    -0
    ⦚ 251 unchanged lines ⦚
    ⦚ 251 unchanged lines ⦚
  • v6

    10/25/2024
    Open: Version
    +251
    -0

    /** @jsxImportSource https://esm.sh/react */
    import Cerebras from "https://esm.sh/@cerebras/cerebras_cloud_sdk";
    import React, { useEffect, useState } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";

    interface Requirement {
    description: string;
    validator: string;
    }

    function App() {
    const [password, setPassword] = useState("");
    const [level, setLevel] = useState(1);
    const [requirements, setRequirements] = useState<Requirement[]>([
    {
    description: "Password must contain at least one number",
    validator: "password.match(/\\d/) !== null",
    },
    ]);
    const [loading, setLoading] = useState(false);
    const [failedRequirements, setFailedRequirements] = useState<string[]>([]);

    useEffect(() => {
    const validatePassword = async () => {
    const failed: string[] = [];
    let allValid = true;

    for (let i = 0; i < level; i++) {
    const requirement = requirements[i];
    try {
    // eslint-disable-next-line no-new-func
    const isValid = new Function("password", `return ${requirement.validator}`)(password);
    if (!isValid) {
    failed.push(requirement.description);
    allValid = false;
    }
stevekrouse-passwordgame.web.val.run
Updated: October 25, 2024