tomtom
tomtom

Reputation: 1190

Ruby print hash in grid format

I'm working on coding a chess board. The structure of my board will be like this:

#   a b c d e f g h 
# 1 * * * * * * * *     # <= Black pieces on top
# 2 * * * * * * * *
# 3 * * * * * * * *
# 4 * * * * * * * *
# 5 * * * * * * * *
# 6 * * * * * * * *
# 7 * * * * * * * *
# 8 * * * * * * * *     # <= White pieces on bottom

I created an @board hash, which stores the value of any item in the grid (i.e. pieces or blank space).

How can I take my hash, which maps a grid location to a "*" currently (i.e. @board['a8']=> '*', etc), and output that hash in the grid-like format?

Here's my @board variable:

def drawBoard
    @board = Hash.new   
    letter='a'
    while letter <= 'h'
            i=1
            while i<9
                @board["#{letter}#{i}"] = "*"
                i+=1
            end
        letter=letter.next
    end     
    @board  
end

Current output is just the hash itself. i.e.,

{"a1"=>"*", "a2"=>"*", "a3"=>"*", "a4"=>"*", "a5"=>"*", "a6"=>"*", "a7"=>"*", "a8"=>"*", "b1"=>"*", "b2"=>"*", "b3"=>"*", "b4"=>"*", "b5"=>"*", "b6"=>"*", "b7"=>"*", "b8"=>"*", "c1"=>"*", "c2"=>"*", "c3"=>"*", "c4"=>"*", "c5"=>"*", "c6"=>"*", "c7"=>"*", "c8"=>"*", "d1"=>"*", "d2"=>"*", "d3"=>"*", "d4"=>"*", "d5"=>"*", "d6"=>"*", "d7"=>"*", "d8"=>"*", "e1"=>"*", "e2"=>"*", "e3"=>"*", "e4"=>"*", "e5"=>"*", "e6"=>"*", "e7"=>"*", "e8"=>"*", "f1"=>"*", "f2"=>"*", "f3"=>"*", "f4"=>"*", "f5"=>"*", "f6"=>"*", "f7"=>"*", "f8"=>"*", "g1"=>"*", "g2"=>"*", "g3"=>"*", "g4"=>"*", "g5"=>"*", "g6"=>"*", "g7"=>"*", "g8"=>"*", "h1"=>"*", "h2"=>"*", "h3"=>"*", "h4"=>"*", "h5"=>"*", "h6"=>"*", "h7"=>"*", "h8"=>"*"}

Edit: Thanks to David's answer, he led me toward a much more compact hash generation method as well. The updated (and working) code:

def drawBoard
        @board = Hash.new   
        ('a'..'h').each do |letter|
            (1..9).each do |i|
                @board["#{letter}#{i}"] = "*"
                print @board["#{letter}#{i}"]
            end
            puts
        end
end

Upvotes: 0

Views: 1886

Answers (2)

David Grayson
David Grayson

Reputation: 87396

Here is a starting point you can use. You would need to add the row and column labels yourself, and add spaces, but this should get you going in the right direction:

('a'..'h').each do |letter|
  (1..8).each do |i|
     print @board["#{letter}#{i}"]
  end
  puts  # end the line
end

Upvotes: 1

sawa
sawa

Reputation: 168101

Provided that you can use symbols for the keys in @board instead of strings:

@board = {:"a1" => "*", ...}

I think the easiest would be to prepare a fixed template string, and do string format to rewrite the grids.

Template = <<_
 a b c d e f g h 
1 %{a1} %{b1} %{c1} %{d1} %{e1} %{f1} %{g1} %{h1}
2 %{a2} %{b2} %{c2} %{d2} %{e2} %{f2} %{g2} %{h2}
3 %{a3} %{b3} %{c3} %{d3} %{e3} %{f3} %{g3} %{h3}
4 %{a4} %{b4} %{c4} %{d4} %{e4} %{f4} %{g4} %{h4}
5 %{a5} %{b5} %{c5} %{d5} %{e5} %{f5} %{g5} %{h5}
6 %{a6} %{b6} %{c6} %{d6} %{e6} %{f6} %{g6} %{h6}
7 %{a7} %{b7} %{c7} %{d7} %{e7} %{f7} %{g7} %{h7}
8 %{a8} %{b8} %{c8} %{d8} %{e8} %{f8} %{g8} %{h8}
_

Template % @board

If you let @board be a flat array instead (which can be handled by using modulo operations), then replace the %{..} above with %s, and it will work the same way.

Upvotes: 3

Related Questions