Barista Guru

Serve 50 correct drinks in a single session of challenge mode
奖杯心得
  • #8312 fredomhunter
    <!DOCTYPE html>
    <html>

    <head>
    <meta charset=utf-8>
    <title>coffeetalk</title>
    <style>
    .table {
    display: table;
    width: 99%;
    border-collapse: collapse;
    margin: 5px;
    }

    .table-row {
    display: table-row;
    }

    .table-header,
    .table-cell {
    display: table-cell;
    border: 1px solid #000;
    padding: 8px;
    text-align: left;
    }

    .table-header {
    background-color: #f2f2f2;
    }

    /* 新增样式使 target 和 result 平行显示 */
    .container {
    display: flex;
    justify-content: space-around;
    }

    .container>div {
    flex: 1;
    }

    .square {
    width: 15px;
    height: 15px;
    margin: 1px;
    display: inline-block;
    }



    .hollow {
    border: 1px solid #000;
    }

    .solid {
    border: 1px solid #000;
    background-color: #000;
    }
    </style>
    </head>

    <body>
    <h1>coffeetalk</h1>
    <br />
    <form name=myForm>
    温暖:<input type=radio name=warm value=0,0 id=a1><label for=a1>不要</label>
    <input type=radio name=warm value=1,3 id=a2><label for=a2>少一点</label>
    <input type=radio name=warm value=4,5 id=a3><label for=a3>有</label>
    <input type=radio name=warm value=6,8 id=a4><label for=a4>多一点</label><br /><br />
    清爽:<input type=radio name=cool value=0,0 id=a5><label for=a5>不要</label>
    <input type=radio name=cool value=1,3 id=a6><label for=a6>少一点</label>
    <input type=radio name=cool value=4,5 id=a7><label for=a7>有</label>
    <input type=radio name=cool value=6,8 id=a8><label for=a8>多一点</label><br /><br />
    甜味:<input type=radio name=sweet value=0,0 id=b1><label for=b1>不要</label>
    <input type=radio name=sweet value=1,3 id=b2><label for=b2>少一点</label>
    <input type=radio name=sweet value=4,5 id=b3><label for=b3>有</label>
    <input type=radio name=sweet value=6,8 id=b4><label for=b4>多一点</label><br /><br />
    苦味:<input type=radio name=bitter value=0,0 id=b5><label for=b5>不要</label>
    <input type=radio name=bitter value=1,3 id=b6><label for=b6>少一点</label>
    <input type=radio name=bitter value=4,5 id=b7><label for=b7>有</label>
    <input type=radio name=bitter value=6,8 id=b8><label for=b8>多一点</label><br /><br />
    <input type=button onclick=myclick() value=确定>
    <input type=reset value=重置>
    <input type=button onclick=location.reload() value=刷新>
    <input type=button onclick=showDrinks() value=显示配方>
    <br />
    <br />
    蝶豆花,洛神花为2代
    <br />
    <br />
    </form>

    配方:
    <div class=container>
    <div id=target></div>
    <div id=result></div>
    </div>

    <script>
    const drinks = [
    { name: 黑色柠檬, ingredients: [咖啡, 咖啡, 柠檬] },
    { name: 黑魔法, ingredients: [咖啡, 薄荷, 蜂蜜] },
    { name: 拿铁咖啡, ingredients: [咖啡, 牛奶, 牛奶] },
    { name: 卡布奇诺, ingredients: [咖啡, 咖啡, 牛奶] },
    { name: 意式浓缩, ingredients: [咖啡, 咖啡, 咖啡] },
    { name: 姜饼咖啡, ingredients: [咖啡, 姜, 肉桂] },
    { name: 姜味拿铁, ingredients: [咖啡, 姜, 牛奶] },
    { name: 印尼姜汁咖啡, ingredients: [咖啡, 咖啡, 姜] },
    { name: 糖与香料, ingredients: [咖啡, 蜂蜜, 肉桂] },
    { name: 蜂舞, ingredients: [咖啡, 蜂蜜, 牛奶] },
    { name: 肉桂拿铁, ingredients: [咖啡, 牛奶, 肉桂] },
    { name: 甜咖啡, ingredients: [咖啡, 咖啡, 蜂蜜] },
    { name: 凯马达, ingredients: [咖啡, 蜂蜜, 柠檬] },
    { name: 豆儿响叮当, ingredients: [咖啡, 咖啡, 肉桂] },
    { name: 加拉喝的, ingredients: [红茶, 牛奶, 姜] },
    { name: 印度奶茶, ingredients: [红茶, 姜, 肉桂] },
    { name: 仲夏夜之梦, ingredients: [红茶, 柠檬, 蜂蜜] },
    { name: 俄罗斯红茶, ingredients: [红茶, 柠檬, 肉桂] },
    { name: 也门亚丁奶茶, ingredients: [红茶, 牛奶, 肉桂] },
    { name: 拉茶, ingredients: [红茶, 红茶, 牛奶] },
    { name: 咳嗽糖浆, ingredients: [绿茶, 柠檬, 蜂蜜] },
    { name: 绿茶拿铁, ingredients: [绿茶, 牛奶, 牛奶] },
    { name: 马拉喀什, ingredients: [绿茶, 薄荷, 薄荷] },
    { name: 生姜玄米茶, ingredients: [绿茶, 绿茶, 姜] },
    { name: 绿毛怪格林奇, ingredients: [绿茶, 姜, 肉桂] },
    { name: 抹茶, ingredients: [绿茶, 绿茶, 绿茶] },
    { name: 解酒茶, ingredients: [绿茶, 姜, 柠檬] },
    { name: 五星!, ingredients: [绿茶, 蜂蜜, 牛奶] },
    { name: 苦涩之心, ingredients: [巧克力, 姜, 肉桂] },
    { name: 巧克力蜂蜜牛奶, ingredients: [巧克力, 蜂蜜, 牛奶] },
    { name: 黑巧克力, ingredients: [巧克力, 巧克力, 巧克力] },
    { name: 西班牙撒哈拉, ingredients: [巧克力, 牛奶, 姜] },
    { name: 辣妹, ingredients: [巧克力, 牛奶, 肉桂] },
    { name: 299.792.458, ingredients: [巧克力, 蜂蜜, 姜] },
    { name: 午夜之后, ingredients: [巧克力, 蜂蜜, 薄荷] },
    { name: 温柔乡, ingredients: [牛奶, 肉桂, 蜂蜜] },
    { name: 薄荷醇香, ingredients: [牛奶, 薄荷, 柠檬] },
    { name: 柠檬尼·斯尼科特, ingredients: [牛奶, 蜂蜜, 柠檬] },
    { name: 银河, ingredients: [牛奶, 蜂蜜, 薄荷] },
    { name: STMJ, ingredients: [牛奶, 姜, 蜂蜜] },
    { name: 蝶豆花茶, ingredients: [蝶豆花, 蝶豆花, 蝶豆花] },
    { name: 星河薄荷茶, ingredients: [蝶豆花, 薄荷, 柠檬] },
    { name: 梦中蓝, ingredients: [蝶豆花, 牛奶, 蜂蜜] },
    { name: 阿库娅的安神茶, ingredients: [蝶豆花, 薄荷, 薄荷] },
    { name: 蓝色闪电, ingredients: [蝶豆花, 姜, 姜] },
    { name: 花房, ingredients: [蝶豆花, 蜂蜜, 薄荷] },
    { name: 加拉的茶, ingredients: [蝶豆花, 牛奶, 姜] },
    { name: 蓝色棉花糖, ingredients: [蝶豆花, 蜂蜜, 牛奶] },
    { name: 洛神花茶, ingredients: [洛神花, 洛神花, 洛神花] },
    { name: 比萨普, ingredients: [洛神花, 姜, 柠檬] },
    { name: 忒贾黑罗塞拉, ingredients: [洛神花, 姜, 蜂蜜] },
    { name: 甜心拿铁, ingredients: [洛神花, 牛奶, 蜂蜜] },
    { name: 胭脂香, ingredients: [洛神花, 牛奶, 肉桂] },
    { name: 佐波, ingredients: [洛神花, 姜, 姜] },
    { name: 蓝莓洛神花馅饼, ingredients: [洛神花, 蜂蜜, 薄荷] }
    ]

    // 原料数据
    const ingredientData = {
    base: [
    [咖啡, [3, 0, 0, 4]],
    [绿茶, [2, 0, 0, 4]],
    [红茶, [4, 2, 0, 3]],
    [巧克力, [0, 2, 2, 4]],
    [蝶豆花, [2, 2, 1, 3]],
    [洛神花, [0, 3, 2, 2]],
    [牛奶, [2, 3, 1, 0]]
    ],
    primary: [
    [姜, [3, 0, 0, 3]],
    [薄荷, [0, 4, 1, 2]],
    [柠檬, [0, 2, 0, 3]],
    [蜂蜜, [0, 0, 4, 0]],
    [肉桂, [3, 0, 3, 0]],
    [牛奶, [1, 2, 0, 0]]
    ],
    secondary: [
    [姜, [2, 0, 0, 1]],
    [薄荷, [0, 3, 0, 0]],
    [柠檬, [0, 1, 0, 2]],
    [蜂蜜, [0, 0, 3, 0]],
    [肉桂, [1, 0, 2, 0]],
    [牛奶, [0, 1, 0, 0]]
    ],
    otherPrimary: [
    [咖啡, [2, 0, 0, 3]],
    [绿茶, [1, 0, 0, 3]],
    [红茶, [3, 1, 0, 2]],
    [巧克力, [1, 1, 0, 3]],
    [蝶豆花, [1, 1, 0, 2]],
    [洛神花, [0, 2, 2, 1]]
    ],
    otherSecondary: [
    [咖啡, [1, 0, 0, 2]],
    [绿茶, [0, 0, 0, 2]],
    [红茶, [2, 0, 0, 1]],
    [巧克力, [0, 0, 0, 2]],
    [蝶豆花, [0, 0, 0, 1]],
    [洛神花, [0, 1, 0, 0]]
    ]
    };

    // 过滤掉牛奶基底
    const basesWithoutMilk = ingredientData.base.filter(([name]) => name !== '牛奶');

    // 将原料分成名称和参数两个数组
    const splitIngredients = (ingredients) => {
    const names = [];
    const params = [];
    for (let i = 0; i < ingredients.length; i++) {
    names.push(ingredients[0]);
    params.push(ingredients[1]);
    }
    return [names, params];
    };

    // 限制值在0-8之间
    const limitValue = (value) => Math.min(value, 8);

    // 获取默认值
    const getDefaultValue = (value) => value === ? 0,9 : value;

    // 生成混合配方
    const generateMixRecipes = () => {
    const [baseNames, baseParams] = splitIngredients(ingredientData.base);
    const [primaryNames, primaryParams] = splitIngredients(ingredientData.primary);
    const [secondaryNames, secondaryParams] = splitIngredients(ingredientData.secondary);
    const [nonMilkBaseNames, nonMilkBaseParams] = splitIngredients(basesWithoutMilk);
    const [otherPrimaryNames, otherPrimaryParams] = splitIngredients(ingredientData.otherPrimary);
    const [otherSecondaryNames, otherSecondaryParams] = splitIngredients(ingredientData.otherSecondary);

    const combos = [
    [baseNames, baseParams, primaryNames, primaryParams, secondaryNames, secondaryParams],
    [nonMilkBaseNames, nonMilkBaseParams, otherPrimaryNames, otherPrimaryParams, secondaryNames, secondaryParams],
    [nonMilkBaseNames, nonMilkBaseParams, primaryNames, primaryParams, otherSecondaryNames, otherSecondaryParams],
    [nonMilkBaseNames, nonMilkBaseParams, otherPrimaryNames, otherPrimaryParams, otherSecondaryNames, otherSecondaryParams]
    ];

    let allNames = [];
    let allParams = [];

    // 生成所有可能的配方组合
    for (const [bNames, bParams, pNames, pParams, sNames, sParams] of combos) {
    for (let i = 0; i < bNames.length; i++) {
    for (let j = 0; j < pNames.length; j++) {
    for (let k = 0; k < sNames.length; k++) {
    allNames.push(`${bNames},${pNames[j]},${sNames[k]}`);
    allParams.push([
    limitValue(bParams[0] + pParams[j][0] + sParams[k][0]),
    limitValue(bParams[1] + pParams[j][1] + sParams[k][1]),
    limitValue(bParams[2] + pParams[j][2] + sParams[k][2]),
    limitValue(bParams[3] + pParams[j][3] + sParams[k][3])
    ]);
    }
    }
    }
    }

    return [allNames, allParams];
    };

    // 配方参数条件判断
    const isRecipeValid = (recipeParams, targetParams) => {
    for (let i = 0; i < targetParams.length; i++) {
    const [min, max] = targetParams;
    const value = recipeParams;
    if (value < parseInt(min) || value > parseInt(max)) {
    return false;
    }
    }
    return true;
    };

    // 点击事件处理函数
    const myclick = () => {
    const targetParams = [];
    const paramNames = ['warm', 'cool', 'sweet', 'bitter'];
    for (let i = 0; i < paramNames.length; i++) {
    const value = document.myForm[paramNames].value;
    targetParams.push(getDefaultValue(value).split(','));
    }

    const [mixNames, mixParams] = generateMixRecipes();
    let validRecipes = '<div class=table>';
    validRecipes += '<div class=table-row><div class=table-header>配方名称</div><div class=table-header>参数</div></div>';

    // 生成有效的配方
    for (let i = 0; i < mixNames.length; i++) {
    if (isRecipeValid(mixParams, targetParams)) {
    validRecipes += `<div class=table-row><div class=table-cell>${mixNames}</div><div class=table-cell>${renderSquares(mixParams)}</div></div>`;
    }
    }

    validRecipes += '</div>';
    document.getElementById(target).innerHTML = validRecipes || 没有合适的配方;
    };

    // 显示所有饮品
    const showDrinks = () => {
    let drinksList = '<div class=table>';
    drinksList += '<div class=table-row><div class=table-header>配方名称</div><div class=table-header>原料</div><div class=table-header>参数</div></div>';
    for (let i = 0; i < drinks.length; i++) {
    // 获取配方的参数
    const baseIngredient = drinks.ingredients[0];
    const baseParams = ingredientData.base.find(([name]) => name === baseIngredient)?.[1] || [];
    drinksList += `<div class=table-row><div class=table-cell>${drinks.name}</div><div class=table-cell>${drinks.ingredients.join(',')}</div><div class=table-cell>${renderSquares(baseParams)}</div></div>`;
    }
    drinksList += '</div>';
    document.getElementById(result).innerHTML = drinksList;
    };

    // 渲染方格
    const renderSquares = (params) => {
    let squares = '';
    for (let i = 0; i < params.length; i++) {
    squares += `${i === 0 ? '温暖' : i === 1 ? '清爽' : i === 2 ? '甜味' : '苦味'}:`;
    for (let j = 0; j < 8; j++) {
    squares += `<div class=square ${j < params ? 'solid' : 'hollow'} style=width:${6 + j * 2}px; height:${6 + j * 2}px;></div>`;
    }
    squares += '<br>';
    }
    return squares;
    };
    </script>
    </body>

    </html>
    ----------分割线----------


    以上内容复制到txt,改后缀为.html后打开即可,这个求解器2代也可以用,而且增加了重置和列表功能,比其他的好用很多。实测完成2代的奖杯不需要用到新增的两种材料。
    搬运https://gitee.com/fft9/coffetalk/blob/master/coffetalk.html的内容
发表评论,请先 登录