2

I am looking to update a construct on screen as the input changes. The construct will look like so:

puts "    |    |    "
puts "    |    |    "
puts "----+----+----"
puts "make an input (1/2/3/4/5/6)"
selection = gets.chomp
#process selection, returns value, value to be updated in construct.

I defined the spaces for the values as a 2x3 array. The value returned, for example, can be '2' to be stored in space [0][1] (row 1, col 2). The output should then look like:

    |  2 |
    |    |    
----+----+----

This needs to happen without re-printing the construct. When the user is prompted (in a loop) to make another selection, again the construct should be updated without re-printing.

ndnenkov
  • 35,425
  • 9
  • 72
  • 104
  • What is your question? – sawa Aug 15 '15 at 13:25
  • Not exactly a duplicate of this [question](http://stackoverflow.com/questions/4762843/writing-over-previously-output-lines-in-the-command-prompt-with-ruby) since that is just modifying the output of one line but may be a good place to start. – frostmatthew Aug 15 '15 at 13:25
  • Thanks @Exupery, but the \r only moves cursor back one line, in this case the rewrite has to happen at a specific location (of a 2D array). – codescribble Aug 15 '15 at 14:09

2 Answers2

3

May I interest you, fine gentleman, in the battle between good and evil? Heavily inspired by TTT:

require 'dispel'

class Lucky6
  BOARD = <<-BOARD.gsub /^\s+/, ''
    | X | X | X |
    | X | X | X |
    ----+---+----
  BOARD

  attr_reader :position

  def initialize
    @fields   = Array.new(6) { ' ' }
    @position = 0
  end

  def board
    index = -1
    BOARD.gsub(" X ") do
      index += 1
      field = @fields[index]
      @position == index ? "[#{field}]" : " #{field} "
    end
  end

  def set(position)
    @position = position.pred
    @fields[@position] = position
  end
end

def draw(l6)
  [l6.board, "1..6=Set r=Reset q=Quit"].join("\n")
end

Dispel::Screen.open do |screen|
  l6 = Lucky6.new
  screen.draw draw(l6)

  Dispel::Keyboard.output do |key|
    case key
    when ('1'..'6') then l6.set(key.to_i)
    when "r" then l6 = Lucky6.new
    when "q" then break
    end
    screen.draw draw(l6)
  end
end
ndnenkov
  • 35,425
  • 9
  • 72
  • 104
  • Good stuff! but may I ask for a non OOP approach and with the constraints I have shown .. :) – codescribble Aug 15 '15 at 15:35
  • @codescribble, what do you mean? Change `"1..6=Set"` to `"make an input (1/2/3/4/5/6)"`? Changing from `Lucky6` to regular `Array` and methods is somewhat trivial. Also why do you not like the *"OOP approach"*? – ndnenkov Aug 15 '15 at 15:39
0

What you are asking is not possible using technique of \r, but you can use a trick of clearing the screen as shown below

matrix = [ ["", "", ""], ["", "", ""]]
pos_to_index = [[0, 0], [0, 1], [0, 2], [1,0], [1,1], [1,2]]

system("cls")

begin
    print "make an input (1/2/3/4/5/6)\n"
    selection = gets.chomp
    system("cls")

    if (selection.to_i <= pos_to_index.size)

        pos = pos_to_index[selection.to_i - 1]
        matrix[pos[0]][pos[1]] = selection

        matrix.each { |a| a.each { |i| print " #{i.empty? ? ' ' : i} |" }; puts }
        puts "---+---+----"
    end 

end while (not selection.empty?)

PS: system("cls") works on windows, if it does not work for you, try system("clear") as explained here

Community
  • 1
  • 1
Wand Maker
  • 18,476
  • 8
  • 53
  • 87
  • thanks, in this case for each selection the construct is reprinted out to the output. So if I make 3 selections, I see 3 constructs. What I am looking to do is to have just one construct for any number of selections made, however, the selection is dynamically updated within the construct without printing out the construct for every input selection. The construct should remain static on the screen, only the values should change based on input selection. – codescribble Aug 15 '15 at 14:30
  • hi! `system 'clear'` helps! Thanks. – codescribble Aug 15 '15 at 15:43