#!/usr/bin/env ruby # frozen_string_literal: true require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'curses' end require 'minehunt' def display_curses( field, state = { dead: false, victory: false }, theme = { explorer: '()', dead_explorer: '☠ ', door: '=>', mine: '<>', cell: '██', visited_cell: ' ' } ) Curses.setpos 0, 0 if state[:dead] Curses.addstr "You died! :(, score #{field.score} " elsif state[:victory] Curses.addstr "You won!! :), score #{field.score} " else Curses.addstr "#{field.number_of_mines} mines, #{field.count_nearby_mines} nearby, score #{field.score}" end field.height.times do |y| Curses.setpos y + 2, 0 field.width.times do |x| if [field.explorer_x, field.explorer_y] == [x, y] Curses.addstr state[:dead] ? theme[:dead_explorer] : theme[:explorer] elsif [field.width, field.height] == [x + 1, y + 1] Curses.addstr theme[:door] elsif field.field[[x, y]].open Curses.addstr theme[:visited_cell] elsif field.field[[x, y]].mine && ( state[:dead] || state[:victory] ) Curses.addstr theme[:mine] else Curses.addstr theme[:cell] end end end Curses.refresh end def ncurses_main( number_of_mines ) field = MineHunt::Board.new( number_of_mines ) finished = false Curses.init_screen Curses.cbreak Curses.noecho Curses.stdscr.keypad = true at_exit do Curses.close_screen end display_curses( field ) loop do direction = '' ch = Curses.getch if finished begin case ch when 'r' field = MineHunt::Board.new( number_of_mines ) 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 exit! end number_of_mines = 20 number_of_mines = ARGV.first.to_i if ARGV.length == 1 ncurses_main( number_of_mines )