diff --git a/README.md b/README.md index ff4f538cb1714527b5d58ebc7894696da9f7a0dd..4695a112fb7054b7b07888c627e760ccbd7a9e8e 100644 --- a/README.md +++ b/README.md @@ -23,4 +23,14 @@ $ 木兰 基本.ul 第15步:狼:11;羊:73;草:11909; 第16步:狼:11;羊:99;草:23766; 第17步:狼:12;羊:117;草:23746; -``` \ No newline at end of file +``` + +## 待做 + +- 暂停运行后观察个体 + - 控制台快速切换输入 上下历史 +- 根据条件暂停运行 + +## 参考 + +https://stackoverflow.com/questions/11552320/correct-way-to-pause-a-python-program diff --git "a/\344\272\244\344\272\222.ul" "b/\344\272\244\344\272\222.ul" new file mode 100644 index 0000000000000000000000000000000000000000..aeee94e375a88bec58c0ee320da3072cd54542d1 --- /dev/null +++ "b/\344\272\244\344\272\222.ul" @@ -0,0 +1,32 @@ +using * in 生物种类 + +type 交互 { + + func $交互() { + super() + $某狼 = nil + } + + func $进行(所有生物表) { + while true { + 输入 = input("请问:") + if 输入 == "能狼" { + for $某狼 in 所有生物表[狼.__name__] { + println($某狼.观察()) if $某狼.能量 > 0 + } + } elif 输入 == "某狼" { + $某狼 = 所有生物表[狼.__name__][0] if #所有生物表[狼.__name__] > 0 and !$某狼 + println($某狼.观察()) + } elif 输入 == "狼距目标" { + println($某狼.目标 ? $某狼.距离($某狼.目标) : "无目标") if $某狼 + } elif 输入 == "狼速加倍" { + if $某狼 { + $某狼.dx = $某狼.dx * 2 + $某狼.dy = $某狼.dy * 2 + } + } elif 输入 == "" { + break + } + } + } +} \ No newline at end of file diff --git "a/\345\237\272\346\234\254.ul" "b/\345\237\272\346\234\254.ul" index 8494af54ccda8e3fe2993356871d1c540afd1c58..12e95d2f33dde61db8aa5ec6b504f4821149d0ec 100644 --- "a/\345\237\272\346\234\254.ul" +++ "b/\345\237\272\346\234\254.ul" @@ -1,134 +1,13 @@ -using math -using random -using datetime in datetime -random.seed(datetime.now().timestamp()) -地图宽度, 地图高度 = 1440, 900 -终了 = 18 -初始能量 = 0 - -type 生物 { - - func $繁衍 { - if $能量 >= $繁衍需能 { - $能量 = 初始能量 - 后代 = $__new__($__class__) - 后代.__init__($x + random.randint(-20, 20), $y + random.randint(-20, 20)) - return 后代 - } - } - - func $生物(x=nil, y=nil) { - super() - $速度上限 = 0.0 - // 位置 - $x = x ? x : random.randint(0, 地图宽度) - $y = y ? y : random.randint(0, 地图高度) - // 两方向速度 - $dx, $dy = 0, 0 - $活着 = true - $目标 = nil - $能量 = 初始能量 - $繁衍需能 = 0 - $食物种类 = nil - } +using 交互 in 交互 +using * in 生物种类 +using * in 显示 - func $代谢(所有生物表) { - 食物 = 所有生物表.__contains__($食物种类) ? 所有生物表[$食物种类] : [] - if ($__class__ == 草) { - $能量 = $能量 + 1 - return - } - if ($目标 and (!$目标.活着)) { - $目标 = nil - } - if $目标 { - 直线距离 = ($x - $目标.x) ^ 2 + ($y - $目标.y) ^ 2 - if (直线距离 < 400) { - $目标.活着 = false - $能量 = $能量 + 1 - } - } else { - $选取目标(食物) - } - $更新位置() - } - - func $选取目标(食物) { - 最小距离 = 9999999 - 最近目标 = nil - for 目标 in 食物 { - if ((目标 !== self) and 目标.活着) { - 目标距离 = ($x - 目标.x) ^ 2 + ($y - 目标.y) ^ 2 - if (目标距离 < 最小距离) { - 最小距离 = 目标距离 - 最近目标 = 目标 - } - } - } - if (最小距离 < 100000) { - $目标 = 最近目标 - } - } - - func $更新位置 { - fx = 0 - fy = 0 - if $目标 { - fx += 0.1 * ($目标.x - $x) - fy += 0.1 * ($目标.y - $y) - } - $dx = $dx + 0.05 * fx - $dy = $dy + 0.05 * fy - 速度 = math.sqrt($dx ^ 2 + $dy ^ 2) - if (速度 > $速度上限) { - $dx = $dx / 速度 * $速度上限 - $dy = $dy / 速度 * $速度上限 - } - $x = $x + $dx - $y = $y + $dy - - $x = max($x, 0) - $x = min($x, 地图宽度) - $y = max($y, 0) - $y = min($y, 地图高度) - } -} - - -type 狼 : 生物 { - - func $狼(x=nil, y=nil) { - super() - $食物种类 = 羊 - $速度上限 = 2.5 - $繁衍需能 = 1 - } -} - - -type 羊 : 生物 { - - func $羊(x=nil, y=nil) { - super() - $食物种类 = 草 - $速度上限 = 2 - $繁衍需能 = 1 - } -} - - -type 草 : 生物 { - - func $草(x=nil, y=nil) { - super() - $繁衍需能 = 2 - } -} +终了 = 18 func 按类整理(所有生物) { 所有生物表 = {:} for 生物 in 所有生物 { - 类型 = 生物.__class__ + 类型 = 生物.__class__.__name__ if 所有生物表.__contains__(类型) { 所有生物表[类型].append(生物) } else { @@ -138,22 +17,41 @@ func 按类整理(所有生物) { return 所有生物表 } +显示 = true + func main() { - 所有生物 = list(map(i -> 狼(), range(10))) + list(map(i -> 羊(), range(40))) + list(map(i -> 草(), range(100))) + 屏幕 = 生物显示.初始化(地图宽度, 地图高度) if 显示 + 所有生物 = list(map(i -> 狼(), range(10))) + + list(map(i -> 羊(), range(40))) + + list(map(i -> 草(), range(100))) + 交互平台 = 交互() 时间 = 0 - while (时间 < 终了) { + 运行 = true + while 时间 < 终了 and 运行 { 所有生物表 = 按类整理(所有生物) - print("第`时间`步:"); print("`类型.__name__`:`#所有生物表[类型]`;") for 类型 in 所有生物表; println() + print("第`时间`步:"); print("`类型`:`#所有生物表[类型]`;") for 类型 in 所有生物表; println() a.代谢(所有生物表) for a in 所有生物 + if 显示 { + 运行 = 生物显示.探测退出事件() + 屏幕.fill(tuple(11, 11, 11)) + + 生物显示(a).显示(屏幕) for a in 所有生物 + 生物显示.刷新() + } else { + 交互平台.进行(所有生物表) + } + 所有生物 = list(filter(某物 -> 某物.活着, 所有生物)) for p in 所有生物 { 后代 = p.繁衍() 所有生物.append(后代) if 后代 } + 时间 = 时间 + 1 } + 生物显示.结束() if 显示 } if (__name__ == '__main__') { main() diff --git "a/\346\230\276\347\244\272.ul" "b/\346\230\276\347\244\272.ul" new file mode 100644 index 0000000000000000000000000000000000000000..5d45889c8b774403d6e37a782cc1df77468b532e --- /dev/null +++ "b/\346\230\276\347\244\272.ul" @@ -0,0 +1,67 @@ +using pygame +using K_ESCAPE, KEYDOWN in pygame.locals + +type 生物显示 : pygame.sprite.Sprite { + + { + pygame.init() + clock = pygame.time.Clock() + } + + func 初始化(地图宽度, 地图高度) { + return pygame.display.set_mode(tuple(地图宽度, 地图高度)) + } + + func 探测退出事件 { + for 事件 in pygame.event.get() { + return false if (事件.__getattribute__('type') == pygame.QUIT) + + if (事件.__getattribute__('type') == KEYDOWN) { + return false if 事件.key == K_ESCAPE + } + } + return true + } + + func 刷新 { + pygame.display.flip() + 生物显示.clock.tick(24) + } + + func 结束 { + pygame.quit() + } + + func $生物显示(生物) { + super() + $生物 = 生物 + 种类 = 生物.__class__.__name__ + if 种类 == '狼' { + 个头 = 4 + 颜色 = tuple(255, 0, 0) + } elif 种类 == '羊' { + 个头 = 3 + 颜色 = tuple(255, 255, 255) + } elif 种类 == '草' { + 个头 = 2 + 颜色 = tuple(0, 128, 0) + } + + $surf = pygame.Surface(tuple(2 * 个头, 2 * 个头), pygame.SRCALPHA, 32) + pygame.draw.circle($surf, 颜色, tuple(个头, 个头), 个头) + $rect = $surf.get_rect() + $rect.centerx = int(生物.x) + $rect.centery = int(生物.y) + } + + func $显示(screen) { + if ($生物.__class__.__name__ == '草') { + screen.blit($surf, $rect) + } else { + $rect.centerx = int($生物.x) + $rect.centery = int($生物.y) + screen.blit($surf, $rect) + } + } + +} \ No newline at end of file diff --git "a/\347\224\237\347\211\251\347\247\215\347\261\273.ul" "b/\347\224\237\347\211\251\347\247\215\347\261\273.ul" new file mode 100644 index 0000000000000000000000000000000000000000..d5e0958968c684c2dd27daee4ddea1c65ba53819 --- /dev/null +++ "b/\347\224\237\347\211\251\347\247\215\347\261\273.ul" @@ -0,0 +1,146 @@ +using datetime in datetime +using math +using random +random.seed(datetime.now().timestamp()) + +地图宽度, 地图高度 = 1440, 900 +初始能量 = 0 + +type 生物 { + + func $生物(x=nil, y=nil) { + super() + $速度上限 = 0.0 + // 位置 + $x = x ? x : random.randint(0, 地图宽度) + $y = y ? y : random.randint(0, 地图高度) + // 两方向速度 + $dx, $dy = 0, 0 + $活着 = true + $目标 = nil + $能量 = 初始能量 + $繁衍需能 = 0 + $食物种类 = nil + } + + func $观察 { + 情况 = {:} + 情况['种类'] = $__class__.__name__ + 情况['活着'] = $活着 + 情况['速度'] = math.sqrt($dx ^ 2 + $dy ^ 2) + 情况['能量'] = $能量 + 情况['目标'] = $目标.观察() if $目标 + return 情况 + } + + func $繁衍 { + if $能量 >= $繁衍需能 { + $能量 = 初始能量 + 后代 = $__new__($__class__) + 后代.__init__($x + random.randint(-20, 20), $y + random.randint(-20, 20)) + return 后代 + } + } + + func $所有潜在食物(所有生物表) { + return [] if !$食物种类 + 食物种类名 = $食物种类.__name__ + return 所有生物表.__contains__(食物种类名) ? 所有生物表[食物种类名] : [] + } + + func $代谢(所有生物表) { + 食物 = $所有潜在食物(所有生物表) + if ($__class__ == 草) { + $能量 = $能量 + 1 + return + } + if ($目标 and (!$目标.活着)) { + $目标 = nil + } + if $目标 { + 直线距离 = $距离($目标) + if (直线距离 < 400) { + $目标.活着 = false + $能量 = $能量 + 1 + } + } else { + $选取目标(食物) + } + $更新位置() + } + + func $选取目标(食物) { + 最小距离 = 9999999 + 最近目标 = nil + for 目标 in 食物 { + if ((目标 !== self) and 目标.活着) { + 目标距离 = $距离(目标) + if (目标距离 < 最小距离) { + 最小距离 = 目标距离 + 最近目标 = 目标 + } + } + } + if (最小距离 < 100000) { + $目标 = 最近目标 + } + } + + func $距离(目标) { + return ($x - 目标.x) ^ 2 + ($y - 目标.y) ^ 2 + } + + func $更新位置 { + fx = 0 + fy = 0 + if $目标 { + fx += 0.1 * ($目标.x - $x) + fy += 0.1 * ($目标.y - $y) + } + $dx = $dx + 0.05 * fx + $dy = $dy + 0.05 * fy + 速度 = math.sqrt($dx ^ 2 + $dy ^ 2) + if (速度 > $速度上限) { + $dx = $dx / 速度 * $速度上限 + $dy = $dy / 速度 * $速度上限 + } + $x = $x + $dx + $y = $y + $dy + + $x = max($x, 0) + $x = min($x, 地图宽度) + $y = max($y, 0) + $y = min($y, 地图高度) + } +} + + +type 狼 : 生物 { + + func $狼(x=nil, y=nil) { + super() + $食物种类 = 羊 + $速度上限 = 10 + $繁衍需能 = 1 + } +} + + +type 羊 : 生物 { + + func $羊(x=nil, y=nil) { + super() + $食物种类 = 草 + $速度上限 = 2 + $繁衍需能 = 1 + } +} + + +type 草 : 生物 { + + func $草(x=nil, y=nil) { + super() + $繁衍需能 = 3 + } +} \ No newline at end of file diff --git "a/\351\227\256\351\242\230.md" "b/\351\227\256\351\242\230.md" new file mode 100644 index 0000000000000000000000000000000000000000..67c98d8d5a2b76f93cf9d0b08a8b651ee5b4f8ff --- /dev/null +++ "b/\351\227\256\351\242\230.md" @@ -0,0 +1,63 @@ +## 语言工具局限 + +` 😰 字典中不存在此键:` +应该由此导致:https://zhuanlan.zhihu.com/p/350337192 + +## 报错信息改进 + +### 错误的类方法调用 + + func $进行(所有生物表) { + + + 交互平台 = 交互() +。。。 + 交互.进行(所有生物表) + +类调用 - 应该实例调用 + + 😰 类型错误:进行() missing 1 required positional argument: '所有生物表' + +### + +```python +print("`类型.__name__`:`#所有生物表[类型]`;") for 类型 in 所有生物表 +``` + +`类型` 已为字符串: + +``` +第0步:Traceback (most recent call last): + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/中.py", line 190, in 中 + exec(可执行码, 环境变量) + File "基本.ul", line 45, in + main() + File "基本.ul", line 1, in main + using 交互 in 交互 +AttributeError: 'str' object has no attribute '__name__' + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "/Users/xuanwu/opt/anaconda3/bin/木兰", line 8, in + sys.exit(中()) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/中.py", line 199, in 中 + sys.stderr.write('%s\n' % 反馈信息(e, 源码文件)) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/功用/反馈信息.py", line 28, in 反馈信息 + return 提神符 + "\n".join(中文化(例外, 源码文件)) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/功用/反馈信息.py", line 40, in 中文化 + 关键 = 取关键信息(提示(类型, 原信息), 行信息[0]) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/功用/反馈信息.py", line 81, in 取关键信息 + 问题变量 = 诊断无属性问题(节点, 问题属性) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/功用/反馈信息.py", line 130, in 诊断无属性问题 + 所有变量 += 诊断无属性问题(属性[1], 问题属性) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/功用/反馈信息.py", line 115, in 诊断无属性问题 + 所有变量 += 诊断无属性问题(子节点, 问题属性) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/功用/反馈信息.py", line 130, in 诊断无属性问题 + 所有变量 += 诊断无属性问题(属性[1], 问题属性) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/功用/反馈信息.py", line 115, in 诊断无属性问题 + 所有变量 += 诊断无属性问题(子节点, 问题属性) + File "/Users/xuanwu/opt/anaconda3/lib/python3.8/site-packages/木兰/功用/反馈信息.py", line 130, in 诊断无属性问题 + 所有变量 += 诊断无属性问题(属性[1], 问题属性) +TypeError: 'NoneType' object is not iterable +``` \ No newline at end of file