2022-09-14 16:17:32 +02:00
|
|
|
#!/usr/bin/env ruby
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2022-11-22 11:48:26 +01:00
|
|
|
require 'curses'
|
2022-09-14 16:17:32 +02:00
|
|
|
|
2022-11-22 11:34:19 +01:00
|
|
|
require 'minehunt'
|
2022-09-14 16:17:32 +02:00
|
|
|
|
2022-09-15 12:31:32 +02:00
|
|
|
def display_curses( field,
|
|
|
|
state = { dead: false, victory: false },
|
2022-10-31 22:49:04 +01:00
|
|
|
theme = { explorer: '()',
|
|
|
|
dead_explorer: '☠ ',
|
|
|
|
door: '=>',
|
|
|
|
mine: '<>',
|
|
|
|
cell: '██',
|
|
|
|
visited_cell: ' ' } )
|
2022-09-14 16:17:32 +02:00
|
|
|
Curses.setpos 0, 0
|
|
|
|
|
|
|
|
if state[:dead]
|
2022-10-31 22:49:04 +01:00
|
|
|
Curses.addstr "You died! :(, score #{field.score} "
|
2022-09-14 16:17:32 +02:00
|
|
|
elsif state[:victory]
|
2022-10-31 22:49:04 +01:00
|
|
|
Curses.addstr "You won!! :), score #{field.score} "
|
2022-09-14 16:17:32 +02:00
|
|
|
else
|
2022-10-31 22:49:04 +01:00
|
|
|
Curses.addstr "#{field.number_of_mines} mines, #{field.count_nearby_mines} nearby, score #{field.score}"
|
2022-09-14 16:17:32 +02:00
|
|
|
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]
|
2022-09-15 12:31:32 +02:00
|
|
|
Curses.addstr state[:dead] ? theme[:dead_explorer] : theme[:explorer]
|
2022-09-14 16:17:32 +02:00
|
|
|
elsif [field.width, field.height] == [x + 1, y + 1]
|
2022-09-15 12:31:32 +02:00
|
|
|
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]
|
2022-09-14 16:17:32 +02:00
|
|
|
else
|
2022-09-15 12:31:32 +02:00
|
|
|
Curses.addstr theme[:cell]
|
2022-09-14 16:17:32 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
Curses.refresh
|
|
|
|
end
|
|
|
|
|
2022-09-14 16:38:56 +02:00
|
|
|
def ncurses_main( number_of_mines )
|
2022-11-22 11:34:19 +01:00
|
|
|
field = MineHunt::Board.new( number_of_mines )
|
2022-09-14 16:17:32 +02:00
|
|
|
finished = false
|
|
|
|
|
|
|
|
Curses.init_screen
|
|
|
|
Curses.cbreak
|
|
|
|
Curses.noecho
|
|
|
|
Curses.stdscr.keypad = true
|
|
|
|
|
|
|
|
at_exit do
|
2022-09-20 13:23:43 +02:00
|
|
|
Curses.close_screen
|
2022-09-14 16:17:32 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
display_curses( field )
|
|
|
|
|
|
|
|
loop do
|
|
|
|
direction = ''
|
|
|
|
ch = Curses.getch
|
|
|
|
if finished
|
|
|
|
begin
|
|
|
|
case ch
|
|
|
|
when 'r'
|
2022-11-22 11:34:19 +01:00
|
|
|
field = MineHunt::Board.new( number_of_mines )
|
2022-09-14 16:17:32 +02:00
|
|
|
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
|
|
|
|
|
2022-09-14 16:38:56 +02:00
|
|
|
number_of_mines = 20
|
|
|
|
number_of_mines = ARGV.first.to_i if ARGV.length == 1
|
|
|
|
|
|
|
|
ncurses_main( number_of_mines )
|