Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| def create_idiom_game(): | |
| # 建立 Gradio 介面 | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# 成語對對碰") | |
| # 嵌入 HTML 和 JavaScript | |
| gr.HTML(""" | |
| <div id="game-root"></div> | |
| <script src="https://unpkg.com/react@17/umd/react.production.min.js"></script> | |
| <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script> | |
| <script> | |
| const idiomDatabase = [ | |
| { mainIdiom: '急如星火', synonyms: ['迫在眉睫', '刻不容緩'], meaning: '形容事情非常緊急' }, | |
| { mainIdiom: '一葉知秋', synonyms: ['見微知著', '月暈而風'], meaning: '從小徵兆可以預見未來的發展' }, | |
| { mainIdiom: '一丘之貉', synonyms: ['沆瀣一氣', '狐群狗黨'], meaning: '形容品性相同的壞人' }, | |
| { mainIdiom: '一蹴可幾', synonyms: ['一步登天', '唾手可得'], meaning: '一下子就能達到目的' }, | |
| { mainIdiom: '一暴十寒', synonyms: ['兩天打魚,三天曬網', '虎頭蛇尾'], meaning: '形容學習或做事不能持之以恆' }, | |
| { mainIdiom: '環堵蕭然', synonyms: ['一貧如洗', '家徒四壁'], meaning: '形容生活很貧困' }, | |
| { mainIdiom: '一字千金', synonyms: ['字字珠璣', '文不加點'], meaning: '形容文章寫得好,文字珍貴' }, | |
| { mainIdiom: '一擲千金', synonyms: ['揮金如土', '揮霍無度'], meaning: '形容揮霍錢財' }, | |
| { mainIdiom: '生靈塗炭', synonyms: ['民不聊生', '民生凋敝'], meaning: '形容人民生活困苦' }, | |
| { mainIdiom: '瓜熟蒂落', synonyms: ['水到渠成', '順理成章'], meaning: '形容事情自然成功' } | |
| ]; | |
| function IdiomGame() { | |
| const [currentIndex, setCurrentIndex] = React.useState(0); | |
| const [score, setScore] = React.useState(0); | |
| const [selected, setSelected] = React.useState([]); | |
| const current = idiomDatabase[currentIndex]; | |
| const handleSelect = (answer) => { | |
| if (selected.includes(answer)) return; | |
| if (current.synonyms.includes(answer)) { | |
| const newSelected = [...selected, answer]; | |
| setSelected(newSelected); | |
| if (newSelected.length === 2) { | |
| setScore(score + 10); | |
| setTimeout(() => { | |
| setCurrentIndex((currentIndex + 1) % idiomDatabase.length); | |
| setSelected([]); | |
| }, 1000); | |
| } | |
| } | |
| }; | |
| const options = [...current.synonyms, '望穿秋水', '守株待兔', '揮金如土'].sort(() => Math.random() - 0.5); | |
| return React.createElement('div', { style: { padding: '20px' } }, | |
| React.createElement('div', { style: { backgroundColor: '#f0f0f0', padding: '20px', marginBottom: '20px' } }, | |
| React.createElement('h2', null, current.mainIdiom), | |
| React.createElement('p', null, current.meaning) | |
| ), | |
| React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '10px' } }, | |
| options.map((option, index) => | |
| React.createElement('button', { | |
| key: index, | |
| onClick: () => handleSelect(option), | |
| style: { | |
| padding: '10px', | |
| backgroundColor: selected.includes(option) ? '#4CAF50' : 'white', | |
| color: selected.includes(option) ? 'white' : 'black', | |
| border: '1px solid #ddd' | |
| } | |
| }, option) | |
| ) | |
| ), | |
| React.createElement('div', { style: { marginTop: '20px' } }, | |
| `分數: ${score}` | |
| ) | |
| ); | |
| } | |
| ReactDOM.render( | |
| React.createElement(IdiomGame), | |
| document.getElementById('game-root') | |
| ); | |
| </script> | |
| """) | |
| return demo | |
| if __name__ == "__main__": | |
| demo = create_idiom_game() | |
| demo.launch() |