Skip to content

Commit b03415f

Browse files
Merge pull request #53 from jinwandalaohu66/submission/script_mnadv3th
2 parents 4d5e71e + 6995556 commit b03415f

2 files changed

Lines changed: 212 additions & 2 deletions

File tree

script_library/index.json

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"format_version": 1,
3-
"data_version": 34,
4-
"updated": "2026-03-28T11:28:25.065Z",
3+
"data_version": 35,
4+
"updated": "2026-03-28T13:45:54.582Z",
55
"announcement": null,
66
"categories": [
77
{
@@ -867,6 +867,29 @@
867867
"updated": null,
868868
"status": "active",
869869
"lines": 113
870+
},
871+
{
872+
"id": "script_mnadv3th",
873+
"name": "猜数字",
874+
"name_en": "猜数字",
875+
"desc": "iOS风格",
876+
"desc_en": "iOS风格",
877+
"category": "games",
878+
"file": "scripts/games/script_mnadv3th.py",
879+
"thumbnail": null,
880+
"version": 1,
881+
"file_type": "py",
882+
"author": "Yahoo",
883+
"author_en": "Yahoo",
884+
"tags": [
885+
"community"
886+
],
887+
"requires": [],
888+
"min_app_version": "1.5.0",
889+
"added": "2026-03-28",
890+
"updated": null,
891+
"status": "active",
892+
"lines": 188
870893
}
871894
]
872895
}
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import ui
2+
import random
3+
import traceback
4+
5+
class GuessNumberView(ui.View):
6+
def __init__(self):
7+
super().__init__()
8+
9+
# 基础视图设置
10+
self.name = '猜数字游戏'
11+
self.background_color = '#F2F2F7'
12+
13+
# 游戏配置常量
14+
self.LOWER_LIMIT = 1
15+
self.UPPER_LIMIT = 100
16+
17+
# 声明状态变量
18+
self.target_number = 0
19+
self.attempts = 0
20+
self.current_min = 0
21+
self.current_max = 0
22+
23+
self.setup_ui()
24+
# 仅初始化逻辑状态,避免在 __init__ 中调起键盘导致崩溃
25+
self._init_game_state()
26+
27+
def setup_ui(self):
28+
content_width = 280
29+
30+
self.title_label = ui.Label(
31+
text='猜数字',
32+
font=('<system-bold>', 36),
33+
alignment=ui.ALIGN_CENTER,
34+
flex='LR'
35+
)
36+
self.title_label.width, self.title_label.height = content_width, 50
37+
38+
self.range_label = ui.Label(
39+
font=('<system-medium>', 18),
40+
text_color='#007AFF',
41+
alignment=ui.ALIGN_CENTER,
42+
flex='LR'
43+
)
44+
self.range_label.width, self.range_label.height = content_width, 30
45+
46+
self.input_field = ui.TextField(
47+
placeholder='输入数字...',
48+
font=('<system>', 24),
49+
alignment=ui.ALIGN_CENTER,
50+
keyboard_type=ui.KEYBOARD_NUMBER_PAD,
51+
background_color='white',
52+
corner_radius=12,
53+
flex='LR'
54+
)
55+
self.input_field.width, self.input_field.height = content_width, 50
56+
57+
self.guess_button = ui.Button(
58+
title='确 认',
59+
font=('<system-bold>', 20),
60+
background_color='#007AFF',
61+
tint_color='white',
62+
corner_radius=12,
63+
action=self.check_guess,
64+
flex='LR'
65+
)
66+
self.guess_button.width, self.guess_button.height = content_width, 50
67+
68+
self.feedback_label = ui.Label(
69+
font=('<system-medium>', 18),
70+
alignment=ui.ALIGN_CENTER,
71+
number_of_lines=0,
72+
flex='LR'
73+
)
74+
self.feedback_label.width, self.feedback_label.height = content_width, 80
75+
76+
self.reset_button = ui.Button(
77+
title='🔄 重新开始',
78+
font=('<system-bold>', 18),
79+
tint_color='#FF3B30',
80+
action=self.reset_game,
81+
flex='LR'
82+
)
83+
self.reset_button.width, self.reset_button.height = content_width, 50
84+
85+
for subview in [self.title_label, self.range_label, self.input_field,
86+
self.guess_button, self.feedback_label, self.reset_button]:
87+
self.add_subview(subview)
88+
89+
def layout(self):
90+
"""覆盖底层布局方法,确保设备旋转时自动完美居中"""
91+
center_x = self.width / 2
92+
self.title_label.center = (center_x, 100)
93+
self.range_label.center = (center_x, 150)
94+
self.input_field.center = (center_x, 220)
95+
self.guess_button.center = (center_x, 290)
96+
self.feedback_label.center = (center_x, 380)
97+
self.reset_button.center = (center_x, 480)
98+
99+
def update_range_label(self):
100+
self.range_label.text = f'目标范围: {self.current_min} - {self.current_max}'
101+
102+
def show_feedback(self, text, color):
103+
self.feedback_label.text = text
104+
self.feedback_label.text_color = color
105+
106+
def _init_game_state(self):
107+
"""防御性初始化:只管理数据,不涉及任何阻塞式的 UI 动作"""
108+
self.target_number = random.randint(self.LOWER_LIMIT, self.UPPER_LIMIT)
109+
self.attempts = 0
110+
self.current_min = self.LOWER_LIMIT
111+
self.current_max = self.UPPER_LIMIT
112+
113+
self.update_range_label()
114+
self.show_feedback('游戏已准备好,请输入数字', '#8E8E93')
115+
116+
self.guess_button.enabled = True
117+
self.input_field.enabled = True
118+
self.reset_button.hidden = True
119+
self.input_field.text = ''
120+
121+
def check_guess(self, sender):
122+
"""事件回调函数,利用异常捕获构筑防护网"""
123+
try:
124+
input_text = self.input_field.text.strip()
125+
126+
# 基础输入校验
127+
if not input_text:
128+
self.show_feedback('请输入数字!', '#FF3B30')
129+
return
130+
131+
if not input_text.isdigit():
132+
self.show_feedback('请输入有效的整数!', '#FF3B30')
133+
self.input_field.text = ''
134+
return
135+
136+
guess = int(input_text)
137+
138+
# 范围越界校验
139+
if guess < self.LOWER_LIMIT or guess > self.UPPER_LIMIT:
140+
self.show_feedback(f'超出范围!请输入 {self.LOWER_LIMIT}-{self.UPPER_LIMIT}', '#FF3B30')
141+
self.input_field.text = ''
142+
return
143+
144+
self.attempts += 1
145+
146+
# 核心算法:区间单向收窄
147+
if guess < self.target_number:
148+
self.current_min = max(self.current_min, guess + 1)
149+
self.show_feedback(f'太小了!(已猜 {self.attempts} 次)', '#FF9500')
150+
self.update_range_label()
151+
self.input_field.text = ''
152+
# 延迟调用 begin_editing,避免可能的UI冲突
153+
ui.delay(0.1, lambda: self.input_field.begin_editing())
154+
155+
elif guess > self.target_number:
156+
self.current_max = min(self.current_max, guess - 1)
157+
self.show_feedback(f'太大了!(已猜 {self.attempts} 次)', '#FF9500')
158+
self.update_range_label()
159+
self.input_field.text = ''
160+
# 延迟调用 begin_editing,避免可能的UI冲突
161+
ui.delay(0.1, lambda: self.input_field.begin_editing())
162+
163+
else:
164+
# 猜中时的特殊处理
165+
self.show_feedback(f'🎉 恭喜猜中!答案是 {self.target_number}\n总共猜了 {self.attempts} 次。', '#34C759')
166+
self.range_label.text = f'正确答案: {self.target_number}'
167+
168+
# 锁定交互并释放键盘
169+
self.guess_button.enabled = False
170+
self.input_field.enabled = False
171+
self.reset_button.hidden = False
172+
# 延迟调用 end_editing,避免可能的UI冲突
173+
ui.delay(0.1, lambda: self.input_field.end_editing())
174+
175+
except Exception as e:
176+
# 简化异常处理,避免显示技术性错误信息
177+
self.show_feedback('输入有误,请重试', '#FF3B30')
178+
self.input_field.text = ''
179+
180+
def reset_game(self, sender):
181+
self._init_game_state()
182+
# 延迟调用 begin_editing,避免可能的UI冲突
183+
ui.delay(0.1, lambda: self.input_field.begin_editing())
184+
185+
if __name__ == '__main__':
186+
view = GuessNumberView()
187+
view.present('fullscreen')

0 commit comments

Comments
 (0)