How to draw map objects next to each other and stack on top of each other in terminal

I am doing twenty one games. I have a card class and a Deck class, the deck consists of card objects. When the player shows his hand, I call the to_s method on the card object, which I represent in ascii characters. This all works great, except that the players deal one card on top of the other. I wonder how I will print the whole hand side by side. I've searched the web and can't find anything other than using print instead of puts, but that doesn't fix my problem. Thank you in advance for any advice you may have.

    class Card
  attr_reader :value
  def initialize(suit, value)
    @suit = suit
    @value = value
  end

  def to_s
    """
    +-----+
    |#{@value}    |
    |     |
    |  #{@suit}  |
    |     |
    |    #{@value}|
    +-----+
    """
  end
end

      

Output example:

Your Hand:

    +-----+
    |Q    |
    |     |
    |  C  |
    |     |
    |    Q|
    +-----+

    +-----+
    |K    |
    |     |
    |  S  |
    |     |
    |    K|
    +-----+
    Your total is 20

      

+3


source to share


1 answer


Let me start by saying that there is no easy solution to what you are trying to do. Terminals are designed to print text line by line, not column. And once something is printed to the console, you usually cannot go back and change it. With this in mind, you have two options:

1) Use ncurses (or similar library) : ncurses is a library for building "gui" applications in the terminal. The library treats the terminal as a grid of cells, allowing the developer to specify every character in every cell at any time. This gives developers a lot of energy, but it also forces you to manually add "traditional" terminal functionality (ie, receive input and print lines of output).

2) Buffer your line and print it right away : even though the terminal can only print lines line by line, there is nothing stopping you from taking a bunch of cards and reordering their lines manually so that they can be printed correctly. It seemed like an interesting programming task, so I went ahead and took a picture:



def display_hand cards
  strings = cards.map { |c| c.to_s.each_line.to_a }
  first, *rest = *strings
  side_by_side = first.zip *rest
  side_by_side.each do |row|
    row.each { |s| print s.chomp }
    print "\n"
  end
end

display_hand [Card.new("A", 1), Card.new("B", 2), Card.new("C", 3)]

      

This code takes an array of maps, assembles their string representations into arrays, and then uses them zip

to group by string . So instead of printing card 1, card 2, card 3, etc., it prints line 1 of all cards, line 2 of all cards, etc.

Hope this helps!

+3


source







All Articles