使用Python制作钻石ASCII艺术

4

我在制作这个菱形图案时遇到了困难。每当我让字符数量为偶数时,都能成功制作出来。然而,当字符数量为奇数时,只有菱形的底部会出现问题。我已经花费了几个小时在这上面,现在已经快完成了。提前感谢您的帮助。

chars = 'ABCDEF'
length = len(chars)
string = ''
dots = (length*2 - 1)*2 - 1
for i in range(length):
    string1 = ''
    string += chars[i]
    length1 = len(string)
    for j in range(0, length1):
        if j % 2 != 0:
            string1 += chars[length -1 - j].center(3, '.')
        else:
            string1 += chars[length - 1 - j]
    for k in range(i - 1, -1, -1):
        if k % 2 != 0:
            string1 += chars[length - 1 - k].center(3, '.')
        else:
            string1 += chars[length - 1 - k]
    string1 = string1.center(dots, '.')
    print(string1)

string=''
for i in range(length - 1):
    string1 = ''
    string += chars[i]
    length1 = len(string)
    for j in range(length - 1 - i):
        if j % 2 != 0:
            string1 += chars[length - 1 - j]
        else:
            string1 += chars[length -1 - j].center(3, '.')
    for k in range(i + 2, length):
        if k % 2 != 0:
            string1 += chars[k].center(3, '.')
        else:
            string1 += chars[k]
    string1 = string1.center(dots, '.')     
    print(string1)

当字符长度为奇数时

当字符长度为偶数时

2个回答

12

这是Python。您可以使用许多有用的字符串函数,在几行代码中创建创新的ASCII艺术。

其中一些最重要的函数包括str.joinstr.Xjust。我们还会利用chrord来迭代字符范围。

首先,定义一个处理填充的函数。

def pad(c1, c2, sep='.', field_width=10):
    out = sep.join(chr(x) for x in range(c2, c1, -1)).rjust(field_width, sep) # build the first part 
    return sep.join([out, chr(c1), out[::-1]])

第一行代码将构建钻石线的上半部分。第二行将上半部分与中心字母和上半部分的反转版本连接起来。

接下来,确定范围 - 您的钻石将有多大。

start = 'A'
end = ...
field_width = (ord(end) - ord('A')) * 2 - 1

现在,你需要两个不同的循环-一个用于上部分的菱形,另一个用于下部分。两个循环在每次迭代时都调用pad

for e in range(ord(end), ord(start), -1):
    print(pad(e, ord(end), '.', field_width))

for e in range(ord(start), ord(end) + 1):
    print(pad(e, ord(end), '.', field_width))

end = 'E'

........E........
......E.D.E......
....E.D.C.D.E....
..E.D.C.B.C.D.E..
E.D.C.B.A.B.C.D.E
..E.D.C.B.C.D.E..
....E.D.C.D.E....
......E.D.E......
........E........

end = 'F':

end = 'F'

..........F..........
........F.E.F........
......F.E.D.E.F......
....F.E.D.C.D.E.F....
..F.E.D.C.B.C.D.E.F..
F.E.D.C.B.A.B.C.D.E.F
..F.E.D.C.B.C.D.E.F..
....F.E.D.C.D.E.F....
......F.E.D.E.F......
........F.E.F........
..........F..........

Seth Difley的回答 探讨了一种替代方法,其中涉及构建钻石的前半部分并将其反转以获得后半部分。确实,可以采用这种方法来解决问题,大致步骤如下:


lines = []
for e in range(ord(end), ord(start) - 1, -1):
    lines.append(pad(e, ord(end), '.', field_width))

for x in lines + lines[-2::-1]:
    print(x)

这也导致相同的输出,并且速度更快。


3

策略:由于现有程序已正确生成了菱形的上半部分,因此先生成上半部分,然后通过反转上半部分的行来生成下半部分。 build_diamond 返回一个包含上半部分字符串的列表。 print('\n'.join(string_list)) 打印上半部分。 bottom_of_diamond_string_list = list(reversed(string_list))[1:] 反转上半部分的字符串并使用 [1:] 删除中间的字符串,以获取下半部分的字符串。 print('\n'.join(bottom_of_diamond_string_list)) 打印下半部分。已测试并适用于长度为 5 和 6(偶数和奇数)的 chars。如果需要,可以进行更多的代码清理。

chars = 'ABCDEF'
length = len(chars)

def build_diamond(length):
    dots = (length*2 - 1)*2 - 1
    string = ''
    string_list = []
    for i in range(length):
        string1 = ''
        string += chars[i]
        length1 = len(string)
        for j in range(0, length1):
            if j % 2 != 0:
                string1 += chars[length -1 - j].center(3, '.')
            else:
                string1 += chars[length - 1 - j]
        for k in range(i - 1, -1, -1):
            if k % 2 != 0:
                string1 += chars[length - 1 - k].center(3, '.')
            else:
                string1 += chars[length - 1 - k]
        string1 = string1.center(dots, '.')
        string_list.append(string1)
    return string_list

if __name__ == '__main__':
    string_list = build_diamond(length)
    print('\n'.join(string_list))
    bottom_of_diamond_string_list = list(reversed(string_list))[1:]
    print('\n'.join(bottom_of_diamond_string_list))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接