From c86a191aa7672d72364161d2ad8f73350a35092d Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Wed, 14 Sep 2022 15:59:19 +0200 Subject: [PATCH] fully working ruby/ncurses version --- myhunt.rb | 126 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 35 deletions(-) diff --git a/myhunt.rb b/myhunt.rb index b70394e..89152d2 100755 --- a/myhunt.rb +++ b/myhunt.rb @@ -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