ChingCL commited on
Commit
803aa94
·
verified ·
1 Parent(s): 253fa7c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -102
app.py CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect } from 'react';
2
 
3
  // 成語資料庫
4
  const idiomDatabase = [
@@ -6,65 +6,31 @@ const idiomDatabase = [
6
  { mainIdiom: '一葉知秋', synonyms: ['見微知著', '月暈而風'], meaning: '從小徵兆可以預見未來的發展' },
7
  { mainIdiom: '一丘之貉', synonyms: ['沆瀣一氣', '狐群狗黨'], meaning: '形容品性相同的壞人' },
8
  { mainIdiom: '一蹴可幾', synonyms: ['一步登天', '唾手可得'], meaning: '一下子就能達到目的' },
9
- { mainIdiom: '一暴十寒', synonyms: ['兩天打魚,三天曬網', '虎頭蛇尾'], meaning: '形容學習或做事不能持之以恆' },
10
- { mainIdiom: '環堵蕭然', synonyms: ['一貧如洗', '家徒四壁'], meaning: '形容生活很貧困' },
11
- { mainIdiom: '一字千金', synonyms: ['字字珠璣', '文不加點'], meaning: '形容文章寫得好,文字珍貴' },
12
- { mainIdiom: '一擲千金', synonyms: ['揮金如土', '揮霍無度'], meaning: '形容揮霍錢財' },
13
- { mainIdiom: '生靈塗炭', synonyms: ['民不聊生', '民生凋敝'], meaning: '形容人民生活困苦' },
14
- { mainIdiom: '瓜熟蒂落', synonyms: ['水到渠成', '順理成章'], meaning: '形容事情自然成功' }
15
  ];
16
 
17
  function ChineseIdiomGame() {
18
- const [currentQuestion, setCurrentQuestion] = useState(null);
19
- const [options, setOptions] = useState([]);
20
  const [selectedAnswers, setSelectedAnswers] = useState([]);
21
  const [score, setScore] = useState(0);
22
- const [message, setMessage] = useState('');
23
  const [gameComplete, setGameComplete] = useState(false);
24
- const [usedQuestions, setUsedQuestions] = useState([]);
25
 
26
- // 打亂陣列順序的函數
27
- const shuffleArray = (array) => {
28
- return [...array].sort(() => Math.random() - 0.5);
29
- };
30
-
31
- // 開始新的題目
32
- const startNewQuestion = () => {
33
- // 過濾掉已使用的題目
34
- const availableQuestions = idiomDatabase.filter(
35
- q => !usedQuestions.includes(q.mainIdiom)
36
- );
37
-
38
- // 如果所有題目都用完了,重置使用記錄
39
- if (availableQuestions.length === 0) {
40
- setUsedQuestions([]);
41
- return startNewQuestion();
42
- }
43
 
44
- // 隨機選擇一個新題目
45
- const newQuestion = availableQuestions[Math.floor(Math.random() * availableQuestions.length)];
46
-
47
- // 生成選項
48
  const otherOptions = idiomDatabase
49
- .filter(item => item.mainIdiom !== newQuestion.mainIdiom)
50
  .flatMap(item => item.synonyms)
51
- .filter(opt => !newQuestion.synonyms.includes(opt));
52
 
53
- const shuffledOtherOptions = shuffleArray(otherOptions).slice(0, 8);
54
- const allOptions = shuffleArray([...newQuestion.synonyms, ...shuffledOtherOptions]);
55
-
56
- setCurrentQuestion(newQuestion);
57
- setOptions(allOptions);
58
- setSelectedAnswers([]);
59
- setMessage('');
60
- setUsedQuestions([...usedQuestions, newQuestion.mainIdiom]);
61
  };
62
 
63
- // 初始化遊戲
64
- useEffect(() => {
65
- startNewQuestion();
66
- }, []);
67
-
68
  // 處理選項點擊
69
  const handleOptionSelect = (option) => {
70
  if (selectedAnswers.includes(option)) return;
@@ -74,13 +40,16 @@ function ChineseIdiomGame() {
74
  setSelectedAnswers(newSelected);
75
 
76
  if (newSelected.length === 2) {
77
- const newScore = score + 10;
78
  setScore(newScore);
79
 
80
  if (newScore >= 100) {
81
  setGameComplete(true);
82
  } else {
83
- setTimeout(startNewQuestion, 1000);
 
 
 
84
  }
85
  }
86
  }
@@ -90,71 +59,120 @@ function ChineseIdiomGame() {
90
  const restartGame = () => {
91
  setScore(0);
92
  setGameComplete(false);
93
- setUsedQuestions([]);
94
- startNewQuestion();
95
  };
96
 
97
  if (gameComplete) {
98
  return (
99
- <div className="min-h-screen bg-gray-100 flex items-center justify-center p-4">
100
- <div className="bg-white rounded-lg p-8 text-center max-w-md w-full">
101
- <h2 className="text-2xl font-bold text-green-600 mb-6">
102
- 太棒了!你是成語小天才!
103
- </h2>
104
- <button
105
- onClick={restartGame}
106
- className="bg-green-500 text-white px-6 py-2 rounded-lg hover:bg-green-600"
107
- >
108
- 再玩一次
109
- </button>
110
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  </div>
112
  );
113
  }
114
 
115
  return (
116
- <div className="min-h-screen bg-gray-100 p-4">
117
- <div className="max-w-2xl mx-auto bg-white rounded-lg shadow p-6">
118
- <h1 className="text-2xl font-bold text-center mb-6">成語對對碰</h1>
119
-
120
- {currentQuestion && (
121
- <>
122
- <div className="bg-blue-100 p-4 rounded-lg mb-6">
123
- <h2 className="text-xl font-bold text-center mb-2">
124
- {currentQuestion.mainIdiom}
125
- </h2>
126
- <p className="text-gray-600 text-center">
127
- {currentQuestion.meaning}
128
- </p>
129
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
- <div className="grid grid-cols-2 sm:grid-cols-3 gap-4 mb-6">
132
- {options.map((option, index) => (
133
- <button
134
- key={index}
135
- onClick={() => handleOptionSelect(option)}
136
- className={`
137
- p-3 rounded-lg text-center
138
- ${selectedAnswers.includes(option) ? 'bg-green-500 text-white' : 'bg-gray-100'}
139
- hover:bg-gray-200
140
- `}
141
- disabled={selectedAnswers.includes(option)}
142
- >
143
- {option}
144
- </button>
145
- ))}
146
- </div>
 
 
 
 
 
 
 
 
147
 
148
- <div className="bg-gray-200 rounded-full h-4 mb-4">
149
- <div
150
- className="bg-green-500 h-full rounded-full transition-all duration-500"
151
- style={{ width: `${score}%` }}
152
- />
153
- </div>
154
- <p className="text-center text-gray-600">分數:{score}/100</p>
155
- </>
156
- )}
 
 
 
 
 
157
  </div>
 
 
 
158
  </div>
159
  );
160
  }
 
1
+ import React, { useState } from 'react';
2
 
3
  // 成語資料庫
4
  const idiomDatabase = [
 
6
  { mainIdiom: '一葉知秋', synonyms: ['見微知著', '月暈而風'], meaning: '從小徵兆可以預見未來的發展' },
7
  { mainIdiom: '一丘之貉', synonyms: ['沆瀣一氣', '狐群狗黨'], meaning: '形容品性相同的壞人' },
8
  { mainIdiom: '一蹴可幾', synonyms: ['一步登天', '唾手可得'], meaning: '一下子就能達到目的' },
9
+ { mainIdiom: '一暴十寒', synonyms: ['兩天打魚,三天曬網', '虎頭蛇尾'], meaning: '形容學習或做事不能持之以恆' }
 
 
 
 
 
10
  ];
11
 
12
  function ChineseIdiomGame() {
13
+ // 狀態管理
14
+ const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
15
  const [selectedAnswers, setSelectedAnswers] = useState([]);
16
  const [score, setScore] = useState(0);
 
17
  const [gameComplete, setGameComplete] = useState(false);
 
18
 
19
+ // 當前題目
20
+ const currentQuestion = idiomDatabase[currentQuestionIndex];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ // 生成選項
23
+ const generateOptions = () => {
24
+ const correctAnswers = currentQuestion.synonyms;
 
25
  const otherOptions = idiomDatabase
26
+ .filter((_, index) => index !== currentQuestionIndex)
27
  .flatMap(item => item.synonyms)
28
+ .slice(0, 8);
29
 
30
+ return [...correctAnswers, ...otherOptions]
31
+ .sort(() => Math.random() - 0.5);
 
 
 
 
 
 
32
  };
33
 
 
 
 
 
 
34
  // 處理選項點擊
35
  const handleOptionSelect = (option) => {
36
  if (selectedAnswers.includes(option)) return;
 
40
  setSelectedAnswers(newSelected);
41
 
42
  if (newSelected.length === 2) {
43
+ const newScore = score + 20;
44
  setScore(newScore);
45
 
46
  if (newScore >= 100) {
47
  setGameComplete(true);
48
  } else {
49
+ setTimeout(() => {
50
+ setCurrentQuestionIndex((prev) => (prev + 1) % idiomDatabase.length);
51
+ setSelectedAnswers([]);
52
+ }, 1000);
53
  }
54
  }
55
  }
 
59
  const restartGame = () => {
60
  setScore(0);
61
  setGameComplete(false);
62
+ setCurrentQuestionIndex(0);
63
+ setSelectedAnswers([]);
64
  };
65
 
66
  if (gameComplete) {
67
  return (
68
+ <div style={{
69
+ padding: '20px',
70
+ textAlign: 'center',
71
+ maxWidth: '600px',
72
+ margin: '0 auto'
73
+ }}>
74
+ <h2 style={{
75
+ fontSize: '24px',
76
+ color: '#16a34a',
77
+ marginBottom: '20px'
78
+ }}>
79
+ 太棒了!你是成語小天才!
80
+ </h2>
81
+ <button
82
+ onClick={restartGame}
83
+ style={{
84
+ backgroundColor: '#16a34a',
85
+ color: 'white',
86
+ padding: '10px 20px',
87
+ borderRadius: '8px',
88
+ border: 'none',
89
+ cursor: 'pointer'
90
+ }}
91
+ >
92
+ 再玩一次
93
+ </button>
94
  </div>
95
  );
96
  }
97
 
98
  return (
99
+ <div style={{
100
+ padding: '20px',
101
+ maxWidth: '800px',
102
+ margin: '0 auto'
103
+ }}>
104
+ <h1 style={{
105
+ fontSize: '24px',
106
+ textAlign: 'center',
107
+ marginBottom: '20px'
108
+ }}>
109
+ 成語對對碰
110
+ </h1>
111
+
112
+ <div style={{
113
+ backgroundColor: '#f0f9ff',
114
+ padding: '20px',
115
+ borderRadius: '8px',
116
+ marginBottom: '20px'
117
+ }}>
118
+ <h2 style={{
119
+ fontSize: '20px',
120
+ textAlign: 'center',
121
+ marginBottom: '10px'
122
+ }}>
123
+ {currentQuestion.mainIdiom}
124
+ </h2>
125
+ <p style={{
126
+ textAlign: 'center',
127
+ color: '#4b5563'
128
+ }}>
129
+ {currentQuestion.meaning}
130
+ </p>
131
+ </div>
132
 
133
+ <div style={{
134
+ display: 'grid',
135
+ gridTemplateColumns: 'repeat(auto-fill, minmax(150px, 1fr))',
136
+ gap: '10px',
137
+ marginBottom: '20px'
138
+ }}>
139
+ {generateOptions().map((option, index) => (
140
+ <button
141
+ key={index}
142
+ onClick={() => handleOptionSelect(option)}
143
+ style={{
144
+ padding: '10px',
145
+ borderRadius: '8px',
146
+ border: '1px solid #e5e7eb',
147
+ backgroundColor: selectedAnswers.includes(option) ? '#16a34a' : 'white',
148
+ color: selectedAnswers.includes(option) ? 'white' : 'black',
149
+ cursor: 'pointer'
150
+ }}
151
+ disabled={selectedAnswers.includes(option)}
152
+ >
153
+ {option}
154
+ </button>
155
+ ))}
156
+ </div>
157
 
158
+ <div style={{
159
+ backgroundColor: '#e5e7eb',
160
+ borderRadius: '9999px',
161
+ height: '20px',
162
+ overflow: 'hidden'
163
+ }}>
164
+ <div
165
+ style={{
166
+ backgroundColor: '#16a34a',
167
+ height: '100%',
168
+ width: `${score}%`,
169
+ transition: 'width 0.5s ease-in-out'
170
+ }}
171
+ />
172
  </div>
173
+ <p style={{ textAlign: 'center', marginTop: '10px' }}>
174
+ 分數:{score}/100
175
+ </p>
176
  </div>
177
  );
178
  }