2017-09-03 99 views
1

我在制作这颗钻石时遇到了麻烦。每当我使字符等于一个均匀的长度,结果很好。然而,当它很奇怪时,只有钻石的底部会变得混乱。我一直在这个工作时间,差不多完成了。先谢谢您的帮助。用Python制作钻石ASCII艺术

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) 

当炭化长度为奇数

当炭化长度为偶数

回答

9

这是蟒。有许多有用的字符串函数可用于在少量代码中创建创造性的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'

..........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's answer探索一种替代方法涉及构建直径的前半部分并反转它以获得下半场。事实上,这种方法也可以用于这个解决方案,沿线的东西:

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) 

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

+1

漂亮的代码。 – Dark

2

策略:由于现有程序正确渲染钻石的上半部分,生成上半部分,然后通过颠倒上半部分的线条生成下半部分。 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))