fully working ruby/ncurses version

This commit is contained in:
Gwenhael Le Moine 2022-09-14 15:59:19 +02:00
parent a84cd71053
commit c86a191aa7
No known key found for this signature in database
GPG key ID: FDFE3669426707A7

126
myhunt.rb
View file

@ -1,5 +1,7 @@
#!/usr/bin/env ruby
require 'curses'
module MyHunt
class Cell
attr_accessor :mine,
@ -33,7 +35,6 @@ module MyHunt
@width.times do |x|
@height.times do |y|
puts "(#{x}, #{y})"
@field[[x, y]] = Cell.new( open: x.zero? && y.zero? )
end
end
@ -49,24 +50,6 @@ module MyHunt
end
end
def display
puts "nearby: #{count_nearby_mines}"
@height.times do |y|
@width.times do |x|
if [@explorer_x, @explorer_y] == [x, y]
putc 'o'
elsif [@width, @height] == [x + 1, y + 1]
putc '_'
elsif @field[[x, y]].open
putc @field[[x, y]].mine ? '*' : ' '
else
putc '█'
end
end
putc "\n"
end
end
def update_explorer_location( direction )
case direction
when 'up'
@ -103,15 +86,13 @@ module MyHunt
def move( direction )
update_explorer_location( direction )
if @explorer_x == (@width - 1) && @explorer_y == (@height - 1)
puts 'Victory'
elsif @field[[@explorer_x, @explorer_y]].explore
puts 'Blown up'
end
{ dead: @field[[@explorer_x, @explorer_y]].explore,
victory: @explorer_x == (@width - 1) && @explorer_y == (@height - 1) }
end
def count_nearby_mines
counter = 0
[@explorer_x - 1, @explorer_x, @explorer_x + 1].each do |x|
[@explorer_y - 1, @explorer_y, @explorer_y + 1].each do |y|
next if x.negative?
@ -120,25 +101,100 @@ module MyHunt
next if y == @height
next if x == @explorer_x && y == @explorer_y
puts "(#{x}, #{y})"
counter += 1 if @field[[x, y]].mine
end
end
counter
end
def debug
@height.times { move('down-right') }
move( 'right' )
@height.times { move('up-right') }
end
end
end
field = MyHunt::Board.new
field.display
field.debug
field.display
def display_curses( field, state = { dead: false, victory: false } )
Curses.setpos 0, 0
if state[:dead]
Curses.addstr 'You died! :('
elsif state[:victory]
Curses.addstr 'You won!! :)'
else
Curses.addstr "nearby: #{field.count_nearby_mines}"
end
field.height.times do |y|
field.width.times do |x|
Curses.setpos y + 2, x
if [field.explorer_x, field.explorer_y] == [x, y]
Curses.addch 'o'
elsif [field.width, field.height] == [x + 1, y + 1]
Curses.addch '_'
elsif field.field[[x, y]].open
Curses.addch field.field[[x, y]].mine ? '*' : ' '
else
Curses.addch 'H'
end
end
end
Curses.refresh
end
Curses.init_screen
Curses.cbreak
Curses.noecho
Curses.stdscr.keypad = true
at_exit do
Curses.close_screen
end
finished = false
display_curses( field )
loop do
direction = ''
ch = Curses.getch
if finished
begin
case ch
when 'r'
field = MyHunt::Board.new
finished = false
else
break
end
rescue Curses::RequestDeniedError
'prout'
end
else
begin
case ch
when '1'
direction = 'down-left'
when '2', Curses::KEY_DOWN
direction = 'down'
when '3'
direction = 'down-right'
when '4', Curses::KEY_LEFT
direction = 'left'
when '6', Curses::KEY_RIGHT
direction = 'right'
when '7'
direction = 'up-left'
when '8', Curses::KEY_UP
direction = 'up'
when '9'
direction = 'up-right'
when 'q'
break
end
rescue Curses::RequestDeniedError
'prout'
end
end
state = field.move( direction )
finished = state[:dead] || state[:victory]
display_curses( field, state )
end