15浏览
查看: 15|回复: 3

[项目] 【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛

[复制链接]
Kitronik ARCADE 是一款由英国教育科技公司 Kitronik 精心打造的可编程游戏机开发板,专为编程教学与创客实践而设计。该设备原生支持微软的 MakeCode Arcade 平台,用户可通过图形化或 JavaScript 编程方式,轻松创建、下载并运行复古风格的街机游戏。

它集成了彩色 LCD 显示屏、方向控制键、功能按键、蜂鸣器和震动马达等交互组件,提供完整的游戏输入输出体验。无论是初学者进行编程启蒙,还是创客群体开发交互式作品,Kitronik ARCADE 都能作为理想的硬件载体,助力创意实现。

凭借其开源友好、易于上手、兼容性强等特点,该开发板广泛应用于中小学编程课程、创客工作坊、游戏开发教学以及个人项目原型设计,深受教育者与技术爱好者的喜爱。

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛图1

驴友花雕  中级技神
 楼主|

发表于 12 小时前

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛

作为学习、练习与尝试,这里创建一个Pi 蒙特卡洛的小游戏。
打开网页版:https://arcade.makecode.com/,设置项目名称:Pi 蒙特卡洛

MicroPython实验代码

  1. @namespace
  2. class SpriteKind:
  3.     Square = SpriteKind.create()
  4.     Circle = SpriteKind.create()
  5. def on_on_destroyed(sprite):
  6.     game.reset()
  7. sprites.on_destroyed(SpriteKind.Square, on_on_destroyed)
  8. def on_b_pressed():
  9.     game.show_long_text("Pi: " + ("" + str(4 * circleDots / squareDots)) + " using " + ("" + str(circleDots)) + " dots",
  10.         DialogLayout.BOTTOM)
  11. controller.B.on_event(ControllerButtonEvent.PRESSED, on_b_pressed)
  12. def on_life_zero():
  13.     info.set_score(circleDots)
  14.     game.show_long_text("Pi: " + ("" + str(4 * circleDots / squareDots)),
  15.         DialogLayout.BOTTOM)
  16.     mCircle.say("Bye..")
  17.     mCircle.vx = 1000
  18.     mSquare.say("..we have Pi")
  19.     mSquare.ax = 50
  20. info.on_life_zero(on_life_zero)
  21. def drawCircle():
  22.     global xx, yy
  23.     # draw a circle outline using random dots!
  24.     for index in range(dots):
  25.         xx = randint(0, 2 * r) - r
  26.         yy = randint(0, 2 * r) - r
  27.         # test if the point will draw the circle
  28.         if xx * xx + yy * yy >= r ** 2 and xx * xx + yy * yy < (r + 1) ** 2:
  29.             cirImage.set_pixel(xx + r, yy + r, 1)
  30. delay2 = 0
  31. simulate = False
  32. j = 0
  33. yy = 0
  34. xx = 0
  35. squareDots = 0
  36. circleDots = 0
  37. mCircle: Sprite = None
  38. mSquare: Sprite = None
  39. cirImage: Image = None
  40. dots = 0
  41. r = 0
  42. # set the radius and side length for the shapes
  43. r = scene.screen_height() / 4
  44. l = r * 2 + 1
  45. # total dots (sample count)
  46. dots = 1000000
  47. # virtual radius length
  48. r2 = 5000
  49. # scale the actual radius from the virtual radius
  50. scale = (r + 1) / r2
  51. sqImage = image.create(l, l)
  52. sqImage.fill(0)
  53. sqImage.draw_rect(0, 0, l, l, 1)
  54. cirImage = image.create(l, l)
  55. cirImage.fill(0)
  56. game.splash("Approximate Pi", "Monte Carlo Method")
  57. mSquare = sprites.create(sqImage, SpriteKind.Square)
  58. mSquare.set_flag(SpriteFlag.AUTO_DESTROY, True)
  59. drawCircle()
  60. mCircle = sprites.create(cirImage, SpriteKind.Circle)
  61. def on_forever():
  62.     global xx, yy, squareDots, circleDots, j
  63.     # A simple Monte Carlo simulation to approximate Pi
  64.     while j < dots and simulate:
  65.         # generate a point within the square
  66.         xx = randint(0, 2 * r2) - r2
  67.         yy = randint(0, 2 * r2) - r2
  68.         sqImage.set_pixel(xx * scale + r, yy * scale + r, 7)
  69.         squareDots += 1
  70.         # test if the point is within the circle
  71.         # sqrt(x**2 + y**2) < r ==> x**2 + y**2 < r**2
  72.         if xx * xx + yy * yy <= r2 ** 2:
  73.             circleDots += 1
  74.             # scale to screen coordinates
  75.             xx = xx * scale
  76.             yy = yy * scale
  77.             # shift over the x or y == 0 position
  78.             if xx < 0:
  79.                 xx += 1
  80.             if yy < 0:
  81.                 yy += 1
  82.             cirImage.set_pixel(xx + r, yy + r, 2)
  83.         # after a little while just quickly finish the simulation
  84.         if squareDots < dots / 50 and squareDots % 100 == 0:
  85.             info.set_score(circleDots)
  86.             pause(100)
  87.         j += 1
  88.         if j >= dots:
  89.             info.set_score(circleDots)
  90.             info.set_life(0)
  91. forever(on_forever)
  92. def on_update_interval():
  93.     global simulate, delay2
  94.     if delay2 > 10:
  95.         # start simulation
  96.         simulate = True
  97.     if delay2 > 20:
  98.         # slide shape apart
  99.         if mCircle.x < scene.screen_width() - 3 * r / 2:
  100.             mSquare.x += -1
  101.             mCircle.x += 1
  102.     delay2 += 1
  103. game.on_update_interval(100, on_update_interval)
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 12 小时前

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛

ARCADE MakeCode Pi 蒙特卡洛游戏代码解读
这是一个使用蒙特卡洛方法估算π值的游戏程序。代码结构分析:

1. 自定义精灵类型
python
  1. class SpriteKind:
  2.     Square = SpriteKind.create()
  3.     Circle = SpriteKind.create()
复制代码

定义两种精灵类型:方形和圆形,用于表示蒙特卡洛模拟中的方形区域和圆形区域。

2. 全局变量初始化
python
  1. # 各种变量初始化
  2. delay2 = 0
  3. simulate = False
  4. j = 0
  5. yy = 0
  6. xx = 0
  7. squareDots = 0  # 方形内的点数
  8. circleDots = 0  # 圆形内的点数
  9. mCircle: Sprite = None
  10. mSquare: Sprite = None
  11. cirImage: Image = None
  12. dots = 0
  13. r = 0
  14. # 设置形状的半径和边长
  15. r = scene.screen_height() / 4  # 半径为屏幕高度的1/4
  16. l = r * 2 + 1  # 方形边长
  17. # 总点数(样本数量)
  18. dots = 1000000
  19. # 虚拟半径长度(用于计算)
  20. r2 = 5000
  21. # 实际半径与虚拟半径的比例
  22. scale = (r + 1) / r2
复制代码

3. 图像和精灵创建
python
  1. # 创建方形图像
  2. sqImage = image.create(l, l)
  3. sqImage.fill(0)
  4. sqImage.draw_rect(0, 0, l, l, 1)
  5. # 创建圆形图像
  6. cirImage = image.create(l, l)
  7. cirImage.fill(0)
  8. # 显示游戏介绍
  9. game.splash("Approximate Pi", "Monte Carlo Method")
  10. # 创建方形精灵
  11. mSquare = sprites.create(sqImage, SpriteKind.Square)
  12. mSquare.set_flag(SpriteFlag.AUTO_DESTROY, True)
  13. # 绘制圆形轮廓
  14. drawCircle()
  15. # 创建圆形精灵
  16. mCircle = sprites.create(cirImage, SpriteKind.Circle)
复制代码

4. 绘制圆形函数
python
  1. def drawCircle():
  2.     global xx, yy
  3.     # 使用随机点绘制圆形轮廓
  4.     for index in range(dots):
  5.         xx = randint(0, 2 * r) - r
  6.         yy = randint(0, 2 * r) - r
  7.         # 测试点是否在圆形轮廓上
  8.         if xx * xx + yy * yy >= r ** 2 and xx * xx + yy * yy < (r + 1) ** 2:
  9.             cirImage.set_pixel(xx + r, yy + r, 1)
复制代码

5. 蒙特卡洛模拟主循环
python
  1. def on_forever():
  2.     global xx, yy, squareDots, circleDots, j
  3.     # 简单的蒙特卡洛模拟来估算π值
  4.     while j < dots and simulate:
  5.         # 在方形内生成随机点
  6.         xx = randint(0, 2 * r2) - r2
  7.         yy = randint(0, 2 * r2) - r2
  8.         sqImage.set_pixel(xx * scale + r, yy * scale + r, 7)
  9.         squareDots += 1
  10.         
  11.         # 测试点是否在圆形内
  12.         if xx * xx + yy * yy <= r2 ** 2:
  13.             circleDots += 1
  14.             # 缩放到屏幕坐标
  15.             xx = xx * scale
  16.             yy = yy * scale
  17.             # 调整x或y为0的位置
  18.             if xx < 0:
  19.                 xx += 1
  20.             if yy < 0:
  21.                 yy += 1
  22.             cirImage.set_pixel(xx + r, yy + r, 2)
  23.         
  24.         # 定期更新显示
  25.         if squareDots < dots / 50 and squareDots % 100 == 0:
  26.             info.set_score(circleDots)
  27.             pause(100)
  28.         
  29.         j += 1
  30.         
  31.         # 完成模拟
  32.         if j >= dots:
  33.             info.set_score(circleDots)
  34.             info.set_life(0)
复制代码

6. 更新间隔函数
python
  1. def on_update_interval():
  2.     global simulate, delay2
  3.     if delay2 > 10:
  4.         # 开始模拟
  5.         simulate = True
  6.     if delay2 > 20:
  7.         # 将形状分开
  8.         if mCircle.x < scene.screen_width() - 3 * r / 2:
  9.             mSquare.x += -1
  10.             mCircle.x += 1
  11.     delay2 += 1
复制代码

7. 事件处理函数
python
  1. # B按钮按下事件:显示π值估算结果
  2. def on_b_pressed():
  3.     game.show_long_text("Pi: " + ("" + str(4 * circleDots / squareDots)) + " using " + ("" + str(circleDots)) + " dots",
  4.         DialogLayout.BOTTOM)
  5. controller.B.on_event(ControllerButtonEvent.PRESSED, on_b_pressed)
  6. # 生命值为零事件:显示最终结果
  7. def on_life_zero():
  8.     info.set_score(circleDots)
  9.     game.show_long_text("Pi: " + ("" + str(4 * circleDots / squareDots)),
  10.         DialogLayout.BOTTOM)
  11.     mCircle.say("Bye..")
  12.     mCircle.vx = 1000
  13.     mSquare.say("..we have Pi")
  14.     mSquare.ax = 50
  15. info.on_life_zero(on_life_zero)
  16. # 方形精灵销毁事件:重置游戏
  17. def on_on_destroyed(sprite):
  18.     game.reset()
  19. sprites.on_destroyed(SpriteKind.Square, on_on_destroyed)
复制代码


蒙特卡洛方法原理
这个程序使用蒙特卡洛方法估算π值,原理如下:

在一个正方形内随机生成大量点

统计落在内切圆内的点的数量

根据公式 π ≈ 4 × (圆内点数 / 总点数) 估算π值

这种方法通过随机抽样和概率统计来近似计算数学常数,是蒙特卡洛方法的经典应用。

这个程序通过可视化方式展示了这一过程,使抽象的数学概念变得更加直观和有趣。

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 12 小时前

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛

图形编程参考实验程序

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛图1

通过模拟器,调试与模拟运行

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛图5

实验场景记录

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛图4

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛图2

【花雕动手做】基于Kitronik可编程开发板之 Pi 蒙特卡洛图3

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail