Ruby 2d阵列颜色印刷垃圾

时间:2017-09-08 20:44:07

标签: arrays ruby multidimensional-array colors console

我有一个非常具体的错误,我似乎无法解决。我已尝试过插件和

中的扩展字符串类

Colorized Ruby output

现在发生的事情就是当我想要颜色时,它会对一个角色起作用。但是,如果再次写入该字符,或者有时只是旁边的字符用颜色写入,则2d数组会因着色字符串文本而损坏。

请注意,上面的堆栈溢出链接中的colorize gem会出现此问题,并且当我不使用它并且只是自己扩展字符串类时。

提供了一些示例代码,以便您可以自己复制它。请注意,在着色文本之后,您永远不能使用Ruby的漂亮打印来打印2d数组,因为它总是看起来已损坏。如果您不希望安装gem来自己测试它,您可以像上面链接显示的响应之一那样扩展字符串类。选择哪个版本并不重要,它不会以任何方式影响结果。我还会在底部链接该代码。

编辑:每条水平线都有一种颜色是允许的。除此之外的任何事情都会导致腐败。

此版本运行正常。

private def color(screen_object, i, j, k)

  #Creates 2d
  screen2 = Array.new(25) { Array.new(25, 0) }
  for i in 0...25 do
    if i == 0 || i == 24
      screen2[i] = '$-----------------------$'
    else
      screen2[i] = '|                       |'
    end
  end

  screen2[0][0] = '~'.colorize(:red)

  for i in 0..25
    puts "#{screen2[i]}"
  end

end

当使用相同的char和相同颜色覆盖相同位置时,此版本会导致损坏。

private def color(screen_object, i, j, k)
  #Creates 2d
  screen2 = Array.new(25) { Array.new(25, 0) }
  for i in 0...25 do
    if i == 0 || i == 24
      screen2[i] = '$-----------------------$'
    else
      screen2[i] = '|                       |'
    end
  end

  screen2[0][0] = '~'.colorize(:red)
  screen2[0][0] = '~'.colorize(:red)

  for i in 0..25
    puts "#{screen2[i]}"
  end
end

此版本不会覆盖任何字符,但是将颜色化的彼此相邻的字符会导致损坏。

private def color(screen_object, i, j, k)
  #Creates 2d
  screen2 = Array.new(25) { Array.new(25, 0) }
  for i in 0...25 do
    if i == 0 || i == 24
      screen2[i] = '$-----------------------$'
    else
      screen2[i] = '|                       |'
    end
  end

  screen2[0][0] = '~'.colorize(:red)
  screen2[0][1] = '~'.colorize(:red)

  for i in 0..25
    puts "#{screen2[i]}"
  end
end

但有时候把对方写在一起很好。彼此相邻的角色似乎不会受到太大影响。

private def color(screen_object, i, j, k)
  #Creates 2d
  screen2 = Array.new(25) { Array.new(25, 0) }
  for i in 0...25 do
    if i == 0 || i == 24
      screen2[i] = '$-----------------------$'
    else
     screen2[i] = '|                       |'
    end
  end

  screen2[0][0] = '~'.colorize(:red)
  screen2[1][0] = '~'.colorize(:red)

  for i in 0..25
    puts "#{screen2[i]}"
  end
end

最后,许多字符只要不相互网络就可以有颜色。

private def color(screen_object, i, j, k)
  #Creates 2d
   screen2 = Array.new(25) { Array.new(25, 0) }
  for i in 0...25 do
    if i == 0 || i == 24
      screen2[i] = '$-----------------------$'
    else
      screen2[i] = '|                       |'
    end
 end

  screen2[0][0] = '~'.colorize(:red)
 screen2[14][22] = '~'.colorize(:red)
  screen2[7][22] = '~'.colorize(:red)
  screen2[2][14] = '~'.colorize(:red)
  screen2[24][24] = '~'.colorize(:red)
  screen2[9][11] = '~'.colorize(:red)

  for i in 0..25
    puts "#{screen2[i]}"
  end
end

如果您不想安装gem,这是字符串扩展名。从另一篇文章中获得用户Ivan Black的信用。

class String
def black;          "\e[30m#{self}\e[0m" end
def red;            "\e[31m#{self}\e[0m" end
def green;          "\e[32m#{self}\e[0m" end
def brown;          "\e[33m#{self}\e[0m" end
def blue;           "\e[34m#{self}\e[0m" end
def magenta;        "\e[35m#{self}\e[0m" end
def cyan;           "\e[36m#{self}\e[0m" end
def gray;           "\e[37m#{self}\e[0m" end

def bg_black;       "\e[40m#{self}\e[0m" end
def bg_red;         "\e[41m#{self}\e[0m" end
def bg_green;       "\e[42m#{self}\e[0m" end
def bg_brown;       "\e[43m#{self}\e[0m" end
def bg_blue;        "\e[44m#{self}\e[0m" end
def bg_magenta;     "\e[45m#{self}\e[0m" end
def bg_cyan;        "\e[46m#{self}\e[0m" end
def bg_gray;        "\e[47m#{self}\e[0m" end
def bold;           "\e[1m#{self}\e[22m" end
def italic;         "\e[3m#{self}\e[23m" end
def underline;      "\e[4m#{self}\e[24m" end
def blink;          "\e[5m#{self}\e[25m" end
def reverse_color;  "\e[7m#{self}\e[27m" end
end

1 个答案:

答案 0 :(得分:2)

发生这种情况的原因是因为您将单个字符更改为多个字符的字符串。例如,让我们考虑一个更简单的例子(使用提供的String类):

string = "1"
puts [string.length, string[0], string.inspect, string]
puts '---'
string[0] = "1".red
puts [string.length, string[0], string.inspect, string]

这个输出是:

1
1
"1"
1
---
10
  # nothing output, but string[0] = "\e"
\e[31m1\e[0m
1 # (this line is red)

运行此功能时,更容易看到,字符串的长度从1更改为10,因此string[0]会相应更改,从数字"1"更改为字符{{1 }}。所以现在,如果我们通过重新运行该脚本的最后几行来再次更改第一个字符:

"\e"

此部分的输出是:

puts '---'
string[0] = "1".red
puts [string.length, string[0], string.inspect, string]

此字符串现已损坏&#39;因为我们已将字符--- 19 \e[31m1\e[0m[31m1\e[0m 1[31m1 # (first character is red, but then we have the random string) 替换为字符串"\e",然后我们仍然在其末尾包含原始字符串"\e[31m1\e[0m"的其余部分。< / p>

可以每行添加多种颜色,您必须确保在执行此操作后重新考虑字符串的新长度,例如:

"[31m1\e[0m"

这个有效,因为我们确保不要踩到颜色代码&#39;脚趾,通过定位字符串的第一个字符,然后定位最后一个字符,这不会通过在第一个字符周围添加颜色转义而受到影响。如果您想要字符串中的第二个字符,则必须检查着色字符串的长度:

string = "12"
string[0] = "1".red
string[-1] = "2".blue
puts string
# outputs "12" with the "1" red and the "2" blue.

重新阅读你的例子,你可能只是因为你认为你的数组而感到困惑,string = "123" string[0] = "1".red string["1".red.length] = "2".blue puts string # '123' with '1' being red, '2' being blue and '3' being unaffected. 是一个数组数组,当它以这种方式开始时,它不会这样结束:

screen2

希望这一切都有意义并且有所帮助