🎮ArcadeLab

攻破 ambiguous

by AtomicWizard88
363 lines35.3 KB
▶ Play
你提了两个关键问题:

1. 搭配题的问号提示暴露了正确答案——只有真实搭配有"?"按钮,玩家一眼就知道选哪个
2. 应该点击单词本身就能看到解释,而不是额外搞一个"?"按钮

我来重新设计:去掉所有"?"按钮,直接点击选项里的单词就能弹出详情卡片。同时搭配题的假选项也做成可点击的(但显示的是"这不是习惯搭配")。

```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>攻破 ambiguous</title>
    <style>
        body {
            background: #faf8f5; color: #2c2416;
            font-family: Georgia, '楷体', serif;
            max-width: 560px; margin: 0 auto; padding: 16px; line-height: 1.9;
        }
        .card { background: #fff; padding: 20px 18px; margin-bottom: 10px; }
        .word-big { font-size: 1.5em; color: #6b4c3b; text-align: center; }
        .cn { color: #8b7355; text-align: center; margin-bottom: 4px; }
        .label { color: #b0a090; font-size: 0.75em; }
        .info { color: #4a3a2a; margin: 2px 0; }
        .highlight { color: #6b4c3b; font-weight: bold; }
        .nuance { color: #8b7355; font-size: 0.8em; margin-left: 4px; }
        .clickable { cursor: pointer; border-bottom: 1px dashed #b0a090; padding: 1px 2px; }
        .clickable:hover { background: #fdf5eb; }
        button {
            padding: 8px 18px; background: #6b4c3b; color: #fff;
            border: none; cursor: pointer; font-family: inherit; font-size: 0.9em; margin: 3px 4px;
        }
        button:disabled { opacity: 0.4; cursor: default; }
        button.outline { background: none; border: 1px solid #6b4c3b; color: #6b4c3b; }
        button.back-btn { background: none; border: 1px solid #b0a090; color: #8b7355; font-size: 0.8em; padding: 4px 12px; }
        .msg { margin: 8px 0; min-height: 20px; }
        .msg.ok { color: #2d6a4f; } .msg.no { color: #c0392b; } .msg.show { color: #b0883a; }
        input { padding: 7px; border: 1px solid #c0b0a0; font-family: inherit; font-size: 1em; text-align: center; background: #faf8f5; }
        .row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 6px 0; }
        .center { text-align: center; }
        hr { border: none; border-top: 1px solid #e8e0d8; margin: 10px 0; }
        .piece-btn { display: inline-block; padding: 8px 14px; background: #f5ede3; border: 1px solid #d4c4b0; cursor: pointer; user-select: none; margin: 3px; font-size: 0.9em; }
        .piece-btn.selected { background: #6b4c3b; color: #fff; border-color: #6b4c3b; }
        .piece-btn.used { opacity: 0.3; pointer-events: none; }
        .slot { display: inline-block; min-width: 60px; padding: 8px 14px; border: 2px dashed #d4c4b0; margin: 3px; text-align: center; font-size: 0.9em; color: #b0a090; cursor: pointer; user-select: none; }
        .slot.filled { border-style: solid; border-color: #6b4c3b; color: #4a3a2a; background: #fdf9f5; }
        .slot.highlight { border-color: #b0883a; background: #fef9f0; }
        .match-left { font-weight: bold; padding: 6px 10px; background: #f5ede3; text-align: center; cursor: pointer; user-select: none; display: inline-block; min-width: 60px; margin: 2px; }
        .match-left.selected { background: #6b4c3b; color: #fff; }
        .match-right { padding: 6px 10px; border: 1px solid #d4c4b0; text-align: center; cursor: pointer; display: inline-block; margin: 2px; }
        .match-right.selected { border-color: #6b4c3b; background: #fdf9f5; }

        .option-row { display: flex; align-items: center; gap: 10px; margin: 6px 0; padding: 10px 14px; background: #faf8f5; border: 1px solid #e8e0d8; }
        .option-row .radio-area { flex-shrink: 0; cursor: pointer; }
        .option-row .word-area { flex: 1; cursor: pointer; }
        .option-row .word-area .highlight { cursor: pointer; border-bottom: 1px dashed #b0a090; }
        .option-row .word-area .highlight:hover { background: #fdf5eb; }
        .option-row:hover { background: #f5f0ea; }
        .option-row.chosen { background: #6b4c3b; color: #fff; border-color: #6b4c3b; }
        .option-row.chosen .highlight { color: #fff; border-bottom-color: #d4c4b0; }
        .option-row.right { background: #d4edda; color: #2d6a4f; border-color: #2d6a4f; }
        .option-row.right .highlight { color: #2d6a4f; }
        .option-row.wrong { background: #f8d7da; color: #a04040; border-color: #c0392b; }
        .option-row.wrong .highlight { color: #a04040; }
        .option-radio { width: 18px; height: 18px; border-radius: 50%; border: 2px solid #b0a090; display: inline-block; flex-shrink: 0; }
        .option-row.chosen .option-radio { border-color: #fff; background: #fff; box-shadow: inset 0 0 0 4px #6b4c3b; }

        .letter-box { display: inline-block; width: 32px; height: 38px; line-height: 38px; text-align: center; border-bottom: 2px solid #6b4c3b; margin: 0 1px; font-size: 1em; color: #6b4c3b; cursor: pointer; }
        .letter-box.given { color: #b0a090; border-bottom-color: #b0a090; cursor: default; }
        .letter-box.empty { color: #c0b0a0; }
        .letter-pool { display: inline-block; padding: 6px 12px; margin: 3px; background: #f5ede3; border: 1px solid #d4c4b0; cursor: pointer; user-select: none; font-size: 1em; }
        .letter-pool.used { opacity: 0.25; pointer-events: none; }
        .letter-pool.selected { background: #6b4c3b; color: #fff; }
        .dots { text-align: center; margin: 8px 0; }
        .dot { display: inline-block; width: 26px; height: 26px; line-height: 26px; font-size: 0.7em; margin: 0 3px; background: #e8e0d8; color: #a09080; }
        .dot.done { background: #6b4c3b; color: #fff; }
        .dot.now { background: #fff; color: #6b4c3b; outline: 2px solid #6b4c3b; font-weight: bold; }
        .detail-card { background: #fdf9f5; border: 1px solid #e0d5c8; padding: 16px; margin-top: 8px; }
        .detail-word { font-size: 1.2em; color: #6b4c3b; } .detail-cn { color: #8b7355; }
        .detail-label { color: #b0a090; font-size: 0.7em; margin-top: 8px; } .detail-info { color: #4a3a2a; font-size: 0.9em; }
        .detail-example { color: #6b5b4b; font-style: italic; margin: 4px 0; } .detail-example-cn { color: #b0a090; font-size: 0.8em; }
        .fake-note { color: #c0392b; font-size: 0.85em; }
    </style>
</head>
<body>
<div id="app"></div>
<script>
const data = {
    word: 'ambiguous', cn: '模糊的;含糊的',
    family: {
        noun: { en:'ambiguity', cn:'模糊性', example:'There is some ambiguity in the contract.', exampleCN:'合同中有一些模糊之处。', note:'不可数名词,常与 there is 连用。' },
        adv: { en:'ambiguously', cn:'模糊地', example:'He answered ambiguously.', exampleCN:'他回答得模棱两可。', note:'修饰动词,描述动作的方式含糊不清。' }
    },
    rootParts: ['ambi-', 'gu-', '-ous'],
    rootMeanings: ['两边;周围', '引导', '形容词后缀'],
    rootFull: '往两边引导 → 不明确 → 模糊的',
    synonyms: [
        { en:'vague', cn:'模糊的', nuance:'指缺乏细节、不具体', example:'a vague memory of childhood', exampleCN:'对童年的模糊记忆', diff:'vague 侧重"轮廓不清",ambiguous 侧重"可多重解读"。' },
        { en:'unclear', cn:'不清楚的', nuance:'指难以理解、不明确', example:'The instructions are unclear.', exampleCN:'指示不清楚。', diff:'unclear 最口语化,ambiguous 更正式。' },
        { en:'obscure', cn:'晦涩的', nuance:'指深奥难懂、鲜为人知', example:'an obscure reference to Greek myth', exampleCN:'对希腊神话的晦涩引用', diff:'obscure 强调"因深奥而难懂",ambiguous 强调"因歧义而模糊"。' },
        { en:'equivocal', cn:'模棱两可的', nuance:'指故意含糊其辞', example:'an equivocal response', exampleCN:'模棱两可的回应', diff:'equivocal 更强调"有意为之"的含糊。' }
    ],
    antonyms: [
        { en:'clear', cn:'清晰的', nuance:'一目了然,没有歧义', example:'a clear explanation', exampleCN:'清晰的解释', diff:'clear 最通用。' },
        { en:'explicit', cn:'明确的', nuance:'直截了当、毫不含糊', example:'explicit instructions', exampleCN:'明确的指示', diff:'explicit 强调公开直接说出来。' },
        { en:'definite', cn:'确定的', nuance:'有明确边界、不会变动', example:'a definite answer', exampleCN:'确定的答案', diff:'definite 强调有定论不变。' },
        { en:'unequivocal', cn:'不含糊的', nuance:'语气最强,毫无歧义空间', example:'an unequivocal denial', exampleCN:'毫不含糊的否认', diff:'unequivocal 是 ambiguous 的最强反义词。' }
    ],
    collocations: [
        { en:'deliberately ambiguous', cn:'故意模棱两可', example:'His statement was deliberately ambiguous.', exampleCN:'他的声明故意模棱两可。', note:'用于描述有意为之的含糊。' },
        { en:'remain ambiguous', cn:'仍然模糊', example:'The details remain ambiguous.', exampleCN:'细节仍然模糊。', note:'用于某事尚未明朗的状态。' },
        { en:'an ambiguous statement', cn:'含糊的声明', example:'The company issued an ambiguous statement.', exampleCN:'公司发布了一份含糊的声明。', note:'最常见搭配之一。' },
        { en:'morally ambiguous', cn:'道德上模糊的', example:'a morally ambiguous character', exampleCN:'道德上模棱两可的角色', note:'用于文学影视评论。' }
    ],
    distractors: [
        { en:'brilliant', cn:'杰出的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'fragile', cn:'脆弱的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'humble', cn:'谦虚的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'eager', cn:'渴望的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'harsh', cn:'严厉的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'fierce', cn:'凶猛的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'absurd', cn:'荒谬的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'subtle', cn:'微妙的', fake:'subtle 和 ambiguous 容易混淆,但 subtle 指"细微难察",ambiguous 指"可多重解读"。' },
        { en:'solemn', cn:'庄严的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'gloomy', cn:'阴郁的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'steady', cn:'稳定的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' },
        { en:'hollow', cn:'空洞的', fake:'这是一个普通形容词,不是 ambiguous 的近义词或反义词。' }
    ],
    fakeCollocations: [
        { en:'strongly ambiguous', cn:'强烈模糊', note:'语法上没错,但不是英语的习惯搭配。' },
        { en:'deeply ambiguous', cn:'深度模糊', note:'语法上没错,但不是英语的习惯搭配。' },
        { en:'highly ambiguous', cn:'高度模糊', note:'语法上没错,但不是英语的习惯搭配。' },
        { en:'completely ambiguous', cn:'完全模糊', note:'语法上没错,但不是英语的习惯搭配。' },
        { en:'rather ambiguous', cn:'相当模糊', note:'语法上没错,但不是英语的习惯搭配。' },
        { en:'slightly ambiguous', cn:'稍微模糊', note:'语法上没错,但不是英语的习惯搭配。' },
        { en:'ambiguously unclear', cn:'模糊地不清楚', note:'这个表达不自然,英语中不会这样搭配。' }
    ],
    sentence: 'His answer was deliberately ambiguous, leaving everyone confused.',
    sentenceCN: '他的回答故意模棱两可,让所有人都感到困惑。'
};

const quizStages = [
    { id:0, name:'词根拼图', desc:'把词根放到正确位置' },
    { id:1, name:'词根含义', desc:'把词根和含义连起来' },
    { id:2, name:'家族词形', desc:'用给出的字母拼出单词' },
    { id:3, name:'近义词辨析', desc:'点击单词查看意思,选中正确答案' },
    { id:4, name:'反义词辨析', desc:'点击单词查看意思,选中正确答案' },
    { id:5, name:'搭配选择', desc:'点击搭配查看详情,选出真正的常用搭配' },
    { id:6, name:'实战翻译', desc:'根据中文补全句子' }
];

let phase = 'learn', quizIndex = 0, quizDone = [], detailView = null;
let _slots, _selPiece, _selIdx, _pairs, _selLeft;
let _q2words, _q2current, _q2filled, _selQ2letter, _selQ2idx;
let _q3opts, _q3ans, _q3chosen, _q4opts, _q4ans, _q4chosen, _q5opts, _q5ans, _q5chosen;
let _quizLocked = false;

function render() {
    const app = document.getElementById('app');
    if (detailView) { renderDetail(app); return; }
    if (phase === 'learn') renderLearn(app);
    else renderQuiz(app);
}

function showDetail(item) { detailView = { item: item }; render(); }
function backToLearn() { detailView = null; render(); }

function renderDetail(app) {
    const item = detailView.item;
    if (item.fake) {
        app.innerHTML = '<div class="detail-card"><div class="detail-word">'+item.en+'</div><div class="detail-cn">'+item.cn+'</div><div class="detail-label">说明</div><div class="detail-info fake-note">'+item.fake+'</div></div><div style="margin-top:8px;"><button class="back-btn" onclick="backToLearn()">← 返回</button></div>';
        return;
    }
    if (item.note && !item.example) {
        app.innerHTML = '<div class="detail-card"><div class="detail-word">'+item.en+'</div><div class="detail-cn">'+item.cn+'</div><div class="detail-label">说明</div><div class="detail-info fake-note">'+item.note+'</div></div><div style="margin-top:8px;"><button class="back-btn" onclick="backToLearn()">← 返回</button></div>';
        return;
    }
    let html = '<div class="detail-card"><div class="detail-word">'+item.en+'</div><div class="detail-cn">'+item.cn+'</div>';
    if (item.nuance) { html += '<div class="detail-label">使用场景</div><div class="detail-info">'+item.nuance+'</div>'; }
    if (item.diff) { html += '<div class="detail-label">与 ambiguous 的区别</div><div class="detail-info">'+item.diff+'</div>'; }
    if (item.note) { html += '<div class="detail-label">说明</div><div class="detail-info">'+item.note+'</div>'; }
    html += '<div class="detail-label">例句</div><div class="detail-example">"'+item.example+'"</div><div class="detail-example-cn">'+item.exampleCN+'</div></div>';
    html += '<div style="margin-top:8px;"><button class="back-btn" onclick="backToLearn()">← 返回</button></div>';
    app.innerHTML = html;
}

function renderLearn(app) {
    let synHtml = '', antHtml = '', colHtml = '';
    for (let i=0; i<data.synonyms.length; i++) synHtml += '<div style="margin:4px 0;"><span class="highlight clickable" onclick="showDetail(data.synonyms['+i+'])">'+data.synonyms[i].en+'</span>('+data.synonyms[i].cn+')<span class="nuance">→ '+data.synonyms[i].nuance+'</span></div>';
    for (let i=0; i<data.antonyms.length; i++) antHtml += '<div style="margin:4px 0;"><span class="highlight clickable" onclick="showDetail(data.antonyms['+i+'])">'+data.antonyms[i].en+'</span>('+data.antonyms[i].cn+')<span class="nuance">→ '+data.antonyms[i].nuance+'</span></div>';
    for (let i=0; i<data.collocations.length; i++) colHtml += '<span class="highlight clickable" onclick="showDetail(data.collocations['+i+'])">'+data.collocations[i].en+'</span>('+data.collocations[i].cn+')<br>';
    let rootHtml = '';
    for (let i=0; i<data.rootParts.length; i++) { rootHtml += '<span class="highlight">'+data.rootParts[i]+'</span>('+data.rootMeanings[i]+')'; if (i<2) rootHtml += ' + '; }
    app.innerHTML = '<div class="card"><div class="word-big">'+data.word+'</div><div class="cn">'+data.cn+'</div><hr><div class="label">词根拆解</div><div class="info">'+rootHtml+'</div><div class="info" style="color:#b0a090;">'+data.rootFull+'</div><hr><div class="label">家族词形</div><div class="info">名词:<span class="highlight clickable" onclick="showDetail(data.family.noun)">'+data.family.noun.en+'</span>('+data.family.noun.cn+')</div><div class="info">副词:<span class="highlight clickable" onclick="showDetail(data.family.adv)">'+data.family.adv.en+'</span>('+data.family.adv.cn+')</div><hr><div class="label">近义词(点击单词查看详情)</div><div class="info">'+synHtml+'</div><hr><div class="label">反义词(点击单词查看详情)</div><div class="info">'+antHtml+'</div><hr><div class="label">常用搭配(点击查看详情)</div><div class="info">'+colHtml+'</div><hr><div class="label">例句</div><div class="info">'+data.sentence+'</div><div class="info" style="color:#b0a090;">'+data.sentenceCN+'</div></div><div class="center"><button onclick="startQuiz()">学好了,开始闯关</button></div>';
}

function startQuiz() { phase = 'quiz'; quizIndex = 0; quizDone = []; detailView = null; render(); }

function renderQuiz(app) {
    if (quizIndex >= quizStages.length) { endQuiz(app); return; }
    const s = quizStages[quizIndex];
    let dotsHtml = '';
    for (let i=0; i<quizStages.length; i++) {
        let cls = 'dot';
        if (quizDone.includes(i)) cls += ' done';
        else if (i === quizIndex) cls += ' now';
        dotsHtml += '<span class="'+cls+'">'+(quizDone.includes(i)?'✓':i+1)+'</span>';
    }
    _quizLocked = false;
    app.innerHTML = '<div class="dots">'+dotsHtml+'</div><div class="card"><div style="font-weight:bold;color:#6b4c3b;margin-bottom:4px;">第'+(quizIndex+1)+'关:'+s.name+'</div><div style="color:#8b7355;font-size:0.85em;margin-bottom:8px;">'+s.desc+'</div><div id="quizContent"></div><div class="msg" id="msg"></div><div class="row" style="margin-top:10px;" id="btnRow"><button id="submitBtn" onclick="checkAnswer()">提交</button><button class="outline" id="showBtn" onclick="showAnswer()">不会</button></div></div>';
    loadQuiz();
}

function loadQuiz() { [q0,q1,q2,q3,q4,q5,q6][quizIndex](); }

function enableButtons() { const sb=document.getElementById('submitBtn'); const shb=document.getElementById('showBtn'); if(sb)sb.disabled=false; if(shb)shb.disabled=false; }

function lockAndNext() {
    _quizLocked = true;
    const sb=document.getElementById('submitBtn'); const shb=document.getElementById('showBtn');
    if(sb)sb.disabled=true; if(shb)shb.disabled=true;
    if(!document.getElementById('nextBtn')){
        const row=document.getElementById('btnRow');
        if(row){const btn=document.createElement('button');btn.id='nextBtn';btn.textContent=quizIndex<quizStages.length-1?'下一关 →':'查看结果';btn.style.background='#2d6a4f';btn.onclick=function(){if(!quizDone.includes(quizIndex))quizDone.push(quizIndex);quizIndex++;render();};row.appendChild(btn);}
    }
}

function q0() {
    const correct = data.rootParts;
    let shuffled = correct.slice().sort(function(){return Math.random()-0.5;});
    let html = '<div style="color:#b0a090;font-size:0.8em;margin-bottom:8px;">先点词根块,再点目标位置放入</div><div style="margin:10px 0;"><span class="slot" id="slot0" onclick="clickSlot(0)">?</span><span class="slot" id="slot1" onclick="clickSlot(1)">?</span><span class="slot" id="slot2" onclick="clickSlot(2)">?</span></div><div class="row" id="pieces">';
    for (let i=0; i<shuffled.length; i++) html += '<span class="piece-btn" id="pb'+i+'" onclick="clickPiece(\''+shuffled[i]+'\','+i+')">'+shuffled[i]+'</span>';
    html += '</div>'; document.getElementById('quizContent').innerHTML = html;
    _slots=[null,null,null]; _selPiece=null; _selIdx=null; enableButtons();
}
function clickPiece(part,idx){const allP=document.querySelectorAll('.piece-btn'),allS=document.querySelectorAll('.slot');for(let i=0;i<allP.length;i++)allP[i].classList.remove('selected');for(let i=0;i<allS.length;i++)allS[i].classList.remove('highlight');if(_selPiece===part&&_selIdx===idx){_selPiece=null;_selIdx=null;return;}_selPiece=part;_selIdx=idx;document.getElementById('pb'+idx).classList.add('selected');for(let i=0;i<allS.length;i++){if(!allS[i].classList.contains('filled'))allS[i].classList.add('highlight');}}
function clickSlot(idx){if(_quizLocked)return;if(_slots[idx]){const old=_slots[idx];_slots[idx]=null;document.getElementById('slot'+idx).textContent='?';document.getElementById('slot'+idx).classList.remove('filled');const allP=document.querySelectorAll('.piece-btn');for(let i=0;i<allP.length;i++){if(allP[i].textContent===old)allP[i].classList.remove('used');}return;}if(!_selPiece)return;let exist=-1;for(let i=0;i<_slots.length;i++){if(_slots[i]===_selPiece)exist=i;}if(exist!==-1){_slots[exist]=null;document.getElementById('slot'+exist).textContent='?';document.getElementById('slot'+exist).classList.remove('filled');}_slots[idx]=_selPiece;document.getElementById('slot'+idx).textContent=_selPiece;document.getElementById('slot'+idx).classList.add('filled');document.getElementById('pb'+_selIdx).classList.add('used');_selPiece=null;_selIdx=null;const allP=document.querySelectorAll('.piece-btn'),allS=document.querySelectorAll('.slot');for(let i=0;i<allP.length;i++)allP[i].classList.remove('selected');for(let i=0;i<allS.length;i++)allS[i].classList.remove('highlight');}
function check0(){return _slots[0]===data.rootParts[0]&&_slots[1]===data.rootParts[1]&&_slots[2]===data.rootParts[2];}
function show0(){for(let i=0;i<3;i++){document.getElementById('slot'+i).textContent=data.rootParts[i];document.getElementById('slot'+i).classList.add('filled');}const allP=document.querySelectorAll('.piece-btn');for(let i=0;i<allP.length;i++)allP[i].classList.add('used');document.getElementById('msg').className='msg show';document.getElementById('msg').innerHTML='正确:'+data.rootParts.join(' + ')+' → '+data.rootFull;}

function q1() {
    let html = '<div style="color:#b0a090;font-size:0.8em;margin-bottom:8px;">先点左边词根,再点右边含义</div><div style="display:flex;gap:20px;flex-wrap:wrap;"><div>';
    for(let i=0;i<data.rootParts.length;i++)html+='<div class="match-left" id="left'+i+'" onclick="selLeft('+i+')">'+data.rootParts[i]+'</div>';
    html+='</div><div>';let meanings=data.rootMeanings.slice().sort(function(){return Math.random()-0.5;});
    for(let i=0;i<meanings.length;i++)html+='<div class="match-right" onclick="selRight(\''+meanings[i]+'\')">'+meanings[i]+'</div>';
    html+='</div></div><div id="matchResult" style="margin-top:8px;color:#b0a090;font-size:0.8em;"></div>';
    document.getElementById('quizContent').innerHTML=html;_pairs={};_selLeft=null;enableButtons();
}
function selLeft(idx){const all=document.querySelectorAll('.match-left');for(let i=0;i<all.length;i++)all[i].classList.remove('selected');document.getElementById('left'+idx).classList.add('selected');_selLeft=idx;}
function selRight(meaning){if(_selLeft===null)return;const li=_selLeft;for(let k in _pairs){if(_pairs[k]===meaning&&parseInt(k)!==li)delete _pairs[k];}_pairs[li]=meaning;let result='';for(let i=0;i<data.rootParts.length;i++){let m=_pairs[i]||'___';result+=data.rootParts[i]+' → '+m+' | ';}document.getElementById('matchResult').innerHTML=result.slice(0,-3);document.getElementById('left'+li).classList.remove('selected');_selLeft=null;}
function check1(){if(Object.keys(_pairs).length!==3)return false;for(let i=0;i<data.rootParts.length;i++){if(_pairs[i]!==data.rootMeanings[i])return false;}return true;}
function show1(){for(let i=0;i<data.rootParts.length;i++)_pairs[i]=data.rootMeanings[i];let result='';for(let i=0;i<data.rootParts.length;i++)result+=data.rootParts[i]+' → '+data.rootMeanings[i]+' | ';document.getElementById('matchResult').innerHTML=result.slice(0,-3);document.getElementById('msg').className='msg show';document.getElementById('msg').innerHTML='ambi- = 两边/周围,gu- = 引导,-ous = 形容词后缀';}

function q2(){_q2words=[{word:data.family.noun.en,cn:data.family.noun.cn,label:'名词'},{word:data.family.adv.en,cn:data.family.adv.cn,label:'副词'}];_q2current=0;_q2filled=[{},{}];_selQ2letter=null;_selQ2idx=null;enableButtons();renderQ2();}
function renderQ2(){const idx=_q2current;const w=_q2words[idx];const filled=_q2filled[idx];const word=w.word;let boxesHtml='';let neededSet={};for(let i=0;i<word.length;i++){if(i===0||i===word.length-1){boxesHtml+='<span class="letter-box given">'+word[i]+'</span>';}else{neededSet[word[i]]=true;let val=filled[i]||'';boxesHtml+='<span class="letter-box'+(val?'':' empty')+'" id="box'+idx+'_'+i+'" onclick="clickBox('+idx+','+i+')">'+(val||'_')+'</span>';}}let needed=Object.keys(neededSet);let distractors=['x','z','k','w'];let poolArr=[];for(let i=0;i<needed.length;i++)poolArr.push(needed[i]);for(let i=0;i<distractors.length&&poolArr.length<6;i++){if(!neededSet[distractors[i]])poolArr.push(distractors[i]);}poolArr.sort(function(){return Math.random()-0.5;});function countInWord(l){let c=0;for(let i=1;i<word.length-1;i++){if(word[i]===l)c++;}return c;}function countInFilled(l){let c=0;let vals=Object.values(filled);for(let i=0;i<vals.length;i++){if(vals[i]===l)c++;}return c;}let poolHtml='';for(let i=0;i<poolArr.length;i++){let l=poolArr[i];let used=countInFilled(l)>=countInWord(l);poolHtml+='<span class="letter-pool'+(used?' used':'')+'" id="lp_'+idx+'_'+i+'" onclick="clickPool(\''+l+'\','+idx+','+i+')">'+l+'</span>';}document.getElementById('quizContent').innerHTML='<div style="color:#b0a090;font-size:0.8em;margin-bottom:8px;">当前:<strong>'+w.label+'</strong>('+w.cn+')—— 点字母再点空格填入</div><div style="margin:10px 0;letter-spacing:2px;">'+boxesHtml+'</div><div style="color:#b0a090;font-size:0.75em;margin:4px 0;">可选字母:</div><div class="row">'+poolHtml+'</div><div style="margin-top:10px;"><button class="outline" onclick="switchQ2word()">切换到'+_q2words[1-idx].label+'</button><button class="outline" onclick="clearQ2current()">清空当前</button></div>';enableButtons();}
function clickPool(letter,idx,poolIdx){if(_quizLocked)return;const el=document.getElementById('lp_'+idx+'_'+poolIdx);if(!el||el.classList.contains('used'))return;const all=document.querySelectorAll('.letter-pool');for(let i=0;i<all.length;i++)all[i].classList.remove('selected');el.classList.add('selected');_selQ2letter=letter;_selQ2idx=idx;}
function clickBox(idx,pos){if(_quizLocked)return;if(!_selQ2letter||_selQ2idx!==idx)return;_q2filled[idx][pos]=_selQ2letter;_selQ2letter=null;renderQ2();}
function switchQ2word(){_q2current=_q2current===0?1:0;_selQ2letter=null;renderQ2();}
function clearQ2current(){_q2filled[_q2current]={};_selQ2letter=null;renderQ2();}
function getFilledWord(idx){const w=_q2words[idx];const filled=_q2filled[idx];let r='';for(let i=0;i<w.word.length;i++){if(i===0||i===w.word.length-1)r+=w.word[i];else r+=(filled[i]||'');}return r;}
function check2(){return getFilledWord(0)===data.family.noun.en&&getFilledWord(1)===data.family.adv.en;}
function show2(){const n=data.family.noun.en,a=data.family.adv.en;_q2filled[0]={};_q2filled[1]={};for(let j=1;j<n.length-1;j++)_q2filled[0][j]=n[j];for(let j=1;j<a.length-1;j++)_q2filled[1][j]=a[j];renderQ2();document.getElementById('msg').className='msg show';document.getElementById('msg').innerHTML='名词:'+n+'('+data.family.noun.cn+')/ 副词:'+a+'('+data.family.adv.cn+')';}

function q3(){
    const correct=data.synonyms[Math.floor(Math.random()*data.synonyms.length)];
    let dis=data.distractors.slice().sort(function(){return Math.random()-0.5;});
    _q3opts=[correct].concat(dis.slice(0,3));
    _q3opts.sort(function(){return Math.random()-0.5;});_q3ans=correct;_q3chosen=null;
    let html='<div style="color:#b0a090;font-size:0.8em;margin-bottom:8px;">哪个是 ambiguous 的<strong>近义词</strong>?(点击单词可查看解释)</div>';
    for(let i=0;i<_q3opts.length;i++){
        let item=_q3opts[i];
        html+='<div class="option-row" id="opt3row_'+i+'"><span class="radio-area" onclick="selOpt3('+i+')"><span class="option-radio"></span></span><span class="word-area" onclick="event.stopPropagation();showDetail(_q3opts['+i+'])"><span class="highlight">'+item.en+'</span></span></div>';
    }
    document.getElementById('quizContent').innerHTML=html;enableButtons();
}
function selOpt3(idx){if(_quizLocked)return;if(_q3chosen===idx){_q3chosen=null;document.getElementById('opt3row_'+idx).classList.remove('chosen');return;}const all=document.querySelectorAll('.option-row');for(let i=0;i<all.length;i++)all[i].classList.remove('chosen');document.getElementById('opt3row_'+idx).classList.add('chosen');_q3chosen=idx;}
function check3(){return _q3chosen!==null&&_q3opts[_q3chosen].en===_q3ans.en;}
function show3(){const all=document.querySelectorAll('.option-row');for(let i=0;i<all.length;i++){all[i].style.pointerEvents='none';if(_q3opts[i].en===_q3ans.en)all[i].classList.add('right');else if(i===_q3chosen)all[i].classList.add('wrong');}document.getElementById('msg').className='msg show';document.getElementById('msg').innerHTML='<strong>'+_q3ans.en+'</strong>('+_q3ans.cn+')—— '+_q3ans.nuance+'<br><span style="font-size:0.8em;">与 ambiguous 的区别:'+_q3ans.diff+'</span>';}

function q4(){
    const correct=data.antonyms[Math.floor(Math.random()*data.antonyms.length)];
    let dis=data.distractors.slice().sort(function(){return Math.random()-0.5;});
    _q4opts=[correct].concat(dis.slice(0,3));
    _q4opts.sort(function(){return Math.random()-0.5;});_q4ans=correct;_q4chosen=null;
    let html='<div style="color:#b0a090;font-size:0.8em;margin-bottom:8px;">哪个是 ambiguous 的<strong>反义词</strong>?(点击单词可查看解释)</div>';
    for(let i=0;i<_q4opts.length;i++){
        let item=_q4opts[i];
        html+='<div class="option-row" id="opt4row_'+i+'"><span class="radio-area" onclick="selOpt4('+i+')"><span class="option-radio"></span></span><span class="word-area" onclick="event.stopPropagation();showDetail(_q4opts['+i+'])"><span class="highlight">'+item.en+'</span></span></div>';
    }
    document.getElementById('quizContent').innerHTML=html;enableButtons();
}
function selOpt4(idx){if(_quizLocked)return;if(_q4chosen===idx){_q4chosen=null;document.getElementById('opt4row_'+idx).classList.remove('chosen');return;}const all=document.querySelectorAll('.option-row');for(let i=0;i<all.length;i++)all[i].classList.remove('chosen');document.getElementById('opt4row_'+idx).classList.add('chosen');_q4chosen=idx;}
function check4(){return _q4chosen!==null&&_q4opts[_q4chosen].en===_q4ans.en;}
function show4(){const all=document.querySelectorAll('.option-row');for(let i=0;i<all.length;i++){all[i].style.pointerEvents='none';if(_q4opts[i].en===_q4ans.en)all[i].classList.add('right');else if(i===_q4chosen)all[i].classList.add('wrong');}document.getElementById('msg').className='msg show';document.getElementById('msg').innerHTML='<strong>'+_q4ans.en+'</strong>('+_q4ans.cn+')—— '+_q4ans.nuance+'<br><span style="font-size:0.8em;">与 ambiguous 的区别:'+_q4ans.diff+'</span>';}

function q5(){
    const correct=data.collocations[Math.floor(Math.random()*data.collocations.length)];
    let fakes=data.fakeCollocations.slice().sort(function(){return Math.random()-0.5;});
    _q5opts=[correct].concat(fakes.slice(0,3));
    _q5opts.sort(function(){return Math.random()-0.5;});_q5ans=correct;_q5chosen=null;
    let html='<div style="color:#b0a090;font-size:0.8em;margin-bottom:8px;">哪个是 ambiguous 真正的<strong>常用搭配</strong>?(点击搭配可查看详情)</div>';
    for(let i=0;i<_q5opts.length;i++){
        let item=_q5opts[i];
        html+='<div class="option-row" id="opt5row_'+i+'"><span class="radio-area" onclick="selOpt5('+i+')"><span class="option-radio"></span></span><span class="word-area" onclick="event.stopPropagation();showDetail(_q5opts['+i+'])"><span class="highlight">'+item.en+'</span></span></div>';
    }
    document.getElementById('quizContent').innerHTML=html;enableButtons();
}
function selOpt5(idx){if(_quizLocked)return;if(_q5chosen===idx){_q5chosen=null;document.getElementById('opt5row_'+idx).classList.remove('chosen');return;}const all=document.querySelectorAll('.option-row');for(let i=0;i<all.length;i++)all[i].classList.remove('chosen');document.getElementById('opt5row_'+idx).classList.add('chosen');_q5chosen=idx;}
function check5(){return _q5chosen!==null&&_q5opts[_q5chosen].en===_q5ans.en;}
function show5(){const all=document.querySelectorAll('.option-row');for(let i=0;i<all.length;i++){all[i].style.pointerEvents='none';if(_q5opts[i].en===_q5ans.en)all[i].classList.add('right');else if(i===_q5chosen)all[i].classList.add('wrong');}document.getElementById('msg').className='msg show';document.getElementById('msg').innerHTML='<strong>'+_q5ans.en+'</strong>('+_q5ans.cn+')—— '+_q5ans.note;}

function q6(){const s=data.sentence.replace('ambiguous','______');document.getElementById('quizContent').innerHTML='<div style="color:#b0a090;font-size:0.8em;margin-bottom:8px;">中文:'+data.sentenceCN+'</div><p>'+s+'</p><input id="inp" placeholder="填入缺失单词" style="width:180px;">';enableButtons();}
function check6(){return document.getElementById('inp').value.trim().toLowerCase()==='ambiguous';}
function show6(){document.getElementById('inp').value='ambiguous';document.getElementById('msg').className='msg show';document.getElementById('msg').innerHTML=data.sentence;}

function checkAnswer(){
    if(_quizLocked)return;
    const checks=[check0,check1,check2,check3,check4,check5,check6];
    const msg=document.getElementById('msg');
    if(checks[quizIndex]()){
        msg.className='msg ok';msg.innerHTML='✅ 正确!';
        if(quizIndex===3||quizIndex===4||quizIndex===5){showAnswer();}
        lockAndNext();
    }else{
        msg.className='msg.no';
        msg.innerHTML='❌ 不对。点"不会"查看答案,或点击单词本身了解含义。';
    }
}

function showAnswer(){
    const shows=[show0,show1,show2,show3,show4,show5,show6];
    shows[quizIndex]();
    lockAndNext();
}

function endQuiz(app){
    let synEnd='',antEnd='';
    for(let i=0;i<data.synonyms.length;i++)synEnd+=data.synonyms[i].en+'('+data.synonyms[i].cn+')→ '+data.synonyms[i].nuance+'<br>';
    for(let i=0;i<data.antonyms.length;i++)antEnd+=data.antonyms[i].en+'('+data.antonyms[i].cn+')→ '+data.antonyms[i].nuance+'<br>';
    app.innerHTML='<div class="card center"><div class="word-big">🏆 通关</div><p><strong>'+data.word+'</strong> —— '+data.cn+'</p><p>闯过 <strong>'+quizDone.length+'</strong> / '+quizStages.length+' 关</p><hr><p>词根:'+data.rootFull+'</p><p>家族:'+data.family.noun.en+'('+data.family.noun.cn+')/ '+data.family.adv.en+'('+data.family.adv.cn+')</p><p style="font-size:0.85em;">近义:<br>'+synEnd+'</p><p style="font-size:0.85em;">反义:<br>'+antEnd+'</p><p>"'+data.sentence+'"</p><p style="color:#b0a090;">'+data.sentenceCN+'</p><hr><button onclick="phase=\'learn\';render();">📖 重新学习</button><button class="outline" onclick="startQuiz();">🔄 重新闯关</button></div>';
}

render();
</script>
</body>
</html>
```

现在的设计:

每个选项行分成两个独立区域:

· 左侧圆圈(radio-area):点击选中/取消答案
· 右侧单词(word-area):点击弹出详情卡片(不影响选择状态)

所有选项的单词都可以点击查看,不管是正确答案还是干扰项:

· 近义词/反义词的干扰项点开会显示"这是一个普通形容词,不是近/反义词"(subtle 有特殊说明因为它容易混淆)
· 搭配题的假搭配点开会显示"语法上没错,但不是英语的习惯搭配"
· 没有任何"?"按钮暴露答案

这样玩家想了解每个词的意思就点单词,想选答案就点圆圈,两个操作完全独立。

Game Source: 攻破 ambiguous

Creator: AtomicWizard88

Libraries: none

Complexity: complex (363 lines, 35.3 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: ambiguous-atomicwizard88" to link back to the original. Then publish at arcadelab.ai/publish.