Class: Xudoku::Cli::Screens::Puzzle
- Defined in:
- lib/xudoku/cli/screens/puzzle.rb
Overview
:nodoc:
Constant Summary collapse
- CELL_WIDTH =
7- CELL_HEIGHT =
3- BOX_GAP =
1- BOX_GAP_R =
1- TITLE_HEIGHT =
3- MENU_HEIGHT =
4- MENU_ITEMS =
[ ["↑↓←→ / HJKL / WASD", "Move"], ["1–9", "Enter digit"], ["⌫ Backspace", "Erase cell"], ["U", "Undo"], ["Q", "Quit"], ["B", "Main menu"], ["R", "Restart"] ].freeze
Constants inherited from Base
Instance Attribute Summary collapse
-
#game ⇒ Object
readonly
Returns the value of attribute game.
Attributes inherited from Base
#app, #first_render, #io, #reader
Instance Method Summary collapse
- #board_left ⇒ Object
- #board_px_width ⇒ Object
- #board_top ⇒ Object
- #cell_origin(x, y) ⇒ Object
- #cell_style(x, y) ⇒ Object
- #clear_board ⇒ Object
- #handle_event(event) ⇒ Object
- #paint_screen(event = nil) ⇒ Object
- #render_board ⇒ Object
- #render_box_separators ⇒ Object
- #render_cell(x, y, num) ⇒ Object
- #render_menu ⇒ Object
- #render_solved_overlay ⇒ Object
- #setup ⇒ Object
- #strip_ansi(str) ⇒ Object
Methods inherited from Base
#initialize, #redraw!, #render
Constructor Details
This class inherits a constructor from Xudoku::Cli::Screens::Base
Instance Attribute Details
#game ⇒ Object (readonly)
Returns the value of attribute game.
8 9 10 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 8 def game @game end |
Instance Method Details
#board_left ⇒ Object
58 59 60 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 58 def board_left [(width - board_px_width) / 2, 0].max end |
#board_px_width ⇒ Object
54 55 56 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 54 def board_px_width 9 * CELL_WIDTH + 2 * BOX_GAP # 2 gaps between 3 groups of 3 cols end |
#board_top ⇒ Object
62 63 64 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 62 def board_top TITLE_HEIGHT + 1 end |
#cell_origin(x, y) ⇒ Object
66 67 68 69 70 71 72 73 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 66 def cell_origin(x, y) extra_col = (y / 3) * BOX_GAP # 0, 1, or 2 extra cols for box gaps extra_row = (x / 3) * BOX_GAP_R col = board_left + y * CELL_WIDTH + extra_col row = board_top + x * CELL_HEIGHT + extra_row [col, row] end |
#cell_style(x, y) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 75 def cell_style(x, y) if game.error?(x, y) { style: { bg: :red, fg: :bright_white, border: { fg: :bright_white, bg: :red } } } elsif game.selected?(x, y) { style: { bg: :green, fg: :bright_white, border: { fg: :bright_white, bg: :green } } } elsif game.same_row?(x, y) || game.same_col?(x, y) || game.same_grid?(x, y) { style: { bg: :white, fg: :black, border: { fg: :bright_black, bg: :white } } } elsif game.clue?(x, y) { style: { bg: :bright_black, fg: :bright_white, border: { fg: :bright_black, bg: :bright_black } } } else { style: { border: { fg: :bright_black, bg: :black } } } end end |
#clear_board ⇒ Object
133 134 135 136 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 133 def clear_board write cursor.move_to(*cell_origin(0, 0)) write cursor.clear_lines (CELL_HEIGHT * 10), :down end |
#handle_event(event) ⇒ Object
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 43 def handle_event(event) handle(:quit) if event.quit? handle(:menu) if event. game.set(event.value) if event.digit? %w[up down left right delete undo restart].each do |method| game.send(method) if event.send("#{method}?") end end |
#paint_screen(event = nil) ⇒ Object
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 32 def paint_screen(event = nil) handle_event(event) unless event.nil? if first_render? render_title render_board else render_board end end |
#render_board ⇒ Object
138 139 140 141 142 143 144 145 146 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 138 def render_board clear_board game.each_cell do |x, y, value| render_cell(x, y, value) end render_box_separators end |
#render_box_separators ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 107 def render_box_separators 3.times do |group_row| 3.times do |group_col| next if group_col == 2 # Draw a one-char-wide dim bar in the gap column gap_col = board_left + (group_col + 1) * 3 * CELL_WIDTH + group_col * BOX_GAP 3.times do |cell_row| _, row = cell_origin(group_row * 3 + cell_row, 0) write cursor.move_to(gap_col, row) CELL_HEIGHT.times do |r| write cursor.move_to(gap_col, row + r) write @pastel.dim("┃") end end end end 2.times do |sep| row = board_top + (sep + 1) * 3 * CELL_HEIGHT + sep * BOX_GAP_R = @pastel.dim("━" * board_px_width) write cursor.move_to(board_left, row) write end end |
#render_cell(x, y, num) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 93 def render_cell(x, y, num) col, row = cell_origin(x, y) label = num.to_s.match?(/\A[1-9]\z/) ? num.to_s : "" box = TTY::Box.frame( top: row, left: col, width: CELL_WIDTH, height: CELL_HEIGHT, align: :center, **cell_style(x, y) ) { label } write box end |
#render_menu ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 148 def = board_top + 9 * CELL_HEIGHT + 2 * BOX_GAP_R + 1 separator = @pastel.dim("─" * width) write cursor.move_to(0, ) write separator items_str = MENU_ITEMS.map do |key, desc| "#{@pastel.bright_yellow(key)} #{@pastel.dim(desc)}" end.join(@pastel.dim(" │ ")) # Centre the menu line padding = [(width - strip_ansi(items_str).length) / 2, 0].max write cursor.move_to(0, + 1) write(" " * padding + items_str) end |
#render_solved_overlay ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 165 def = "Puzzle Solved! Press Q to quit. " w = .size + 4 h = 5 left = (width - w) / 2 top = (height - h) / 2 box = TTY::Box.frame( top: top, left: left, width: w, height: h, align: :center, padding: [1, 2], style: { fg: :bright_white, bg: :green, border: { fg: :bright_white, bg: :green } } ) { msg } write box end |
#setup ⇒ Object
27 28 29 30 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 27 def setup @game = Game.new @pastel = Pastel.new end |
#strip_ansi(str) ⇒ Object
184 185 186 |
# File 'lib/xudoku/cli/screens/puzzle.rb', line 184 def strip_ansi(str) str.gsub(/\e\[[0-9;]*m/, "") end |