dojo任务的标准板机制
board的Python项目详细描述
简介
通常,当运行python dojo时,我们会遇到一个挑战 以某种木板或瓷砖为基础的景观。在这些 在这种情况下,花很多时间建立 为了支持更有趣的 游戏算法。
这个模块实现了一个通用的板结构 具有一系列用途所需的功能,并且 为了满足这些特殊的需要。
依赖关系
无-仅限STDLIB
测试
相当不错的覆盖率(实际上没有用coverage.py检查):test.py
开始
使用pip安装:
pip install board
绝对基本用法:
import board # # Produce a 3x3 board # b = board.Board((3, 3)) b[0, 0] = "X" b[1, 0] = "O"
用法
电路板是一个n维电路板,任何一个维度都可以是 无限大。(所以如果你有,比如说,3个无限维,你有 雷艇布局的基础)。维度是基于零的。
电路板上的单元通过项目访问访问,例如电路板[1,2]或 横向[1,1,10]。
可以复制电路板,也可以通过 。复制方法。或者一块板的一部分可以链接到原始的 通过切片原始板来制作板:
b1 = board.Board((9, 9)) b1[1, 1] = 1 b2 = b1.copy() b3 = b1[:3, :3]
请注意,切片必须包含原始的所有尺寸 板,但这些子尺寸中的任何一个子尺寸的长度都可以是1:
b1 = board.Board((9, 9, 9)) b2 = b1[:3, :3, :1]
sentinel值为空表示未填充的位置 因为它从未有过值,或者因为它的值已被删除:
b1 = board.Board((3, 3)) assert b1[1, 1] is board.Empty b1.populate("abcdefghi") assert b1[1, 1] == "e" del b1[1, 1] assert b1[1, 1] is board.Empty
在电路板上迭代得到它的坐标:
b1 = board.Board((2, 2)) for coord in b1: print(coord) # # => (0, 0), (0, 1) etc. #
在具有一个或多个无限维的板上迭代将起作用 通过分块迭代:
b1 = board.Board((3, 3, board.Infinity)) for coord in b1: print(b1)
要查看坐标及其数据项,请使用iterData:
b1 = board.Board((2, 2)) b1.populate("abcd") for coord, data in b1.iterdata(): print(coord, "=>", data)
在板位置读取、写入和清空数据,使用索引:
b1 = board.Board((3, 3)) b1.populate("abcdef") print(b1[0, 0]) # "a" b1[0, 0] = "*" print(b1[0, 0]) # "*" del b1[0, 0] print(b1[0, 0]) # <Empty>
要测试坐标是否包含在局部坐标空间中,请使用in:
b1 = board.Board((3, 3)) (1, 1) in b1 # True (4, 4) in b1 # False (1, 1, 1) in b1 # InvalidDimensionsError
如果一块板具有相同的维度和 每个数据项相等:
b1 = board.Board((3, 3)) b1.populate("abcdef") b2 = b1.copy() b1 == b2 # True b2[0, 0] = "*" b1 == b2 # False b2 = board.Board((2, 2)) b2.populate("abcdef") b1 == b2 # False
要粗略查看电路板的内容,请使用.dump:
b1 = board.Board((3, 3)) b1.populate("abcdef") b1.dump()
要获得二维电路板的网格视图,请使用.draw:
b1 = board.Board((3, 3)) b1.populate("OX XXOO ") b1.draw()
要从任意迭代器填充电路板,请使用.populate:
def random_letters(): import random, string while True: yield random.choice(string.ascii_uppercase) b1 = board.Board((4, 4)) b1.populate(random_letters())
要清除电路板,请使用.clear:
b1 = board.Board((3, 3)) b1.populate(range(10)) b1.clear() list(b1.iterdata()) # []
电路板有数据时为真,没有数据时为假:
b1 = board.Board((2, 2)) b1.populate("abcd") bool(b1) # True b1.clear() bool(b1) # False
板的长度是其尺寸长度的乘积。如果有的话 尺寸是无限的,板长是无限的。NB找到 板上的数据量,使用lendata:
b1 = board.Board((4, 4)) len(b1) # 16 b1.populate("abcd") len(b1) # 16 b1.lendata() # 4 b2 = board.Board((2, board.Infinity)) len(b2) # Infinity
要确定包含数据的电路板的边界框,请使用.占用:
b1 = board.Board((3, 3)) b1.populate("abcd") list(c for (c, d) in b1.iterdata()) # [(0, 0), (0, 1), (0, 2), (1, 0)] b1.occupied() # ((0, 0), (1, 2))
要测试某个位置是否位于板的任何边缘上,请使用.is_edge:
b1 = board.Board((3, 3)) b1.is_edge((0, 0)) # True b1.is_edge((1, 1)) # False b1.is_edge((2, 0)) # True
要查找所有维度上某个位置的直接车载邻居:
b1 = board.Board((3, 3, 3)) list(b1.neighbours((0, 0, 0))) # [(0, 1, 1), (1, 1, 0), ..., (1, 0, 1), (0, 1, 0)]
实验:在 两个角,使用.itercoords:
b1 = board.Board((3, 3)) list(b1.itercoords((0, 0), (1, 1))) # [(0, 0), (0, 1), (1, 0), (1, 1)]
实验性的:从一个点迭代所有的车载位置 特定方向,使用.iterline:
b1 = board.Board((4, 4)) start_from = 1, 1 direction = 1, 1 list(b1.iterline(start_from, direction)) # [(1, 1), (2, 2), (3, 3)] direction = 0, 2 list(b1.iterline(start_from, direction)) # [(1, 1), (1, 3)]
属性
要确定一块电路板是否与另一块电路板偏移(即切片的结果):
b1 = board.Board((3, 3)) b1.is_offset # False b2 = b1[:1, :1] b2.is_offset # True
确定电路板是否具有任何无限或有限尺寸:
b1 = board.Board((3, board.Infinity)) b1.has_finite_dimensions # True b1.has_infinite_dimensions # True b2 = board.Board((3, 3)) b1.has_infinite_dimensions # False b3 = board.Board((board.Infinity, board.Infinity)) b3.has_finite_dimensions # False
局部和全局坐标
因为一块板可以代表另一块板的一部分,所以有两个级别 坐标:局部坐标和全局坐标。传递或返回的坐标 任何公共api方法对于该板都是本地的。他们 表示板的自然坐标空间。在内部, 模块将使用全局坐标,根据需要进行转换。
说你是法力在基于平铺的地牢游戏中 主副本板是100 x 100,但可见板是10 x 10。 您的视区板当前表示主视图的切片 董事会从(5,5)至(14,14)。在上的位置(2,2)更改项目 视区板将在主视图上的位置(7,7)更改项目 董事会(反之亦然)。
作为api的用户,除了理解 板片本质上是其父级的视图。如果你愿意 若要子类化或以其他方式扩展董事会,您需要注意 坐标转换是必要的。