#!/usr/bin/env ruby # frozen_string_literal: true module MineHunt VERSION = '1.1.1' class Cell attr_accessor :mine, :open def initialize( mine: false, open: false ) @mine = mine @open = open end def explore @open = true @mine end end class Board attr_reader :width, :height, :field, :number_of_mines, :explorer_x, :explorer_y, :score def initialize( number_of_mines = 20, height = 8, width = 16 ) @height = height @width = width @explorer_x = 0 @explorer_y = 0 @score = 1 @field = {} @number_of_mines = if number_of_mines.negative? && number_of_mines > ((@height * @width) - 2) 20 else number_of_mines end @width.times do |x| @height.times do |y| @field[[x, y]] = Cell.new( open: x.zero? && y.zero? ) end end placed_mines = 0 while placed_mines < @number_of_mines coordinates = [rand( @width ), rand( @height )] next if coordinates == [0, 0] next if @field[ coordinates ].mine @field[ coordinates ].mine = true placed_mines += 1 end end def update_explorer_location( direction ) case direction when 'up' @explorer_y -= 1 if @explorer_y.positive? when 'right' @explorer_x += 1 if @explorer_x < (@width - 1) when 'down' @explorer_y += 1 if @explorer_y < (@height - 1) when 'left' @explorer_x -= 1 if @explorer_x.positive? when 'up-right' if @explorer_x < (@width - 1) && @explorer_y.positive? @explorer_x += 1 @explorer_y -= 1 end when 'down-right' if @explorer_x < (@width - 1) && @explorer_y < (@height - 1) @explorer_x += 1 @explorer_y += 1 end when 'down-left' if @explorer_x.positive? && @explorer_y < (@height - 1) @explorer_x -= 1 @explorer_y += 1 end when 'up-left' if @explorer_x.positive? && @explorer_y.positive? @explorer_x -= 1 @explorer_y -= 1 end end end def move( direction ) update_explorer_location( direction ) @score += 1 unless @field[[@explorer_x, @explorer_y]].open { 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? next if y.negative? next if x == @width next if y == @height next if x == @explorer_x && y == @explorer_y counter += 1 if @field[[x, y]].mine end end counter end end end