Skip to content

Instantly share code, notes, and snippets.

@RubyBrewsday
Last active August 29, 2015 14:03
Show Gist options
  • Save RubyBrewsday/b860c0558a3e3363ef37 to your computer and use it in GitHub Desktop.
Save RubyBrewsday/b860c0558a3e3363ef37 to your computer and use it in GitHub Desktop.
Minesweeper in ruby
class MinesweeperMap
def initialize(difficulty)
@difficulty = difficulty
case difficulty
when 1
grid_size = 4
when 2
grid_size = 7
when 3
grid_size = 10
when 4
grid_size = 15
else
raise "Wrong choice man"
end
@size = grid_size
@map = create_map(@size)
@mines = generate_mines(@map,@size,difficulty)
@flags = []
@boom = false
@safe = false
end
def still_alive? #returns true if you havent hit a mine yet
return !@boom
end
def mine_count
return @mines.size
end
def flag_count
return @flags.count
end
def not_solved?
return !@safe
end
def spaces_cleared
clear_spaces = 0
numbers = (0..9).to_a
@map.each do |row|
row.each { |space| clear_spaces += 1 if numbers.include?(space)}
end
return clear_spaces
end
def score(time,spaces_cleared) #time should be in seconds
return ((@difficulty * @size) * 2000.to_f / time + (spaces_cleared * @difficulty) )
end
def show_map
row_number = 1
while row_number <= @size
@map.each do |row|
p [row_number] + row
row_number += 1
end
end
end
def snitches_get
mine_locations
end
def choose_mine(guess)
if @mines.include?(guess)
puts "Sorry, you lose :("
@boom = true
elsif @map[guess[0]][guess[1]] == 0
return
else
check_for_mines_nearby(guess,@size)
end
end
def place_flag(guess)
@flags << guess
@map[guess[0]-1][guess[1]-1] = "!"
end
def remove_flag(spot)
@flags.reject! {|flag| flag == spot}
@map[spot[0]-1][spot[1]-1] = " "
end
def show_flags
@flags.each {|flag| p flag}
end
def check_flags
if @flags.sort == @mines.sort
@safe = true
end
end
private
def create_map(size)
map = []
size.times do
row = []
size.times do
row << " "
end
map << row
end
return map
end
def mine_locations
return @mines
end
def generate_mines(map,size,difficulty)
mine_locations = []
case difficulty
when 1
mines = 4
when 2
mines = 15
when 3
mines = 35
when 4
mines = 99
else
raise ArgumentError, "Bad stuff man"
end
counter = 1
while counter <= mines
mine_location = [rand(size),rand(size)]
if mine_locations.include?(mine_location)
next
else
mine_locations << mine_location
counter += 1
end
end
return mine_locations
end
def check_for_mines_nearby(starting_location,size)
number_of_mines = 0
if (starting_location[0] == 0) && (starting_location[1]==0)
adjacent_squares =[[ starting_location[0]+1, starting_location[1] ],[starting_location[0]+1, starting_location[1]+1],[starting_location[0], starting_location[1]+1]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
elsif (starting_location[0] == 0) && (starting_location[1]==size)
adjacent_squares =[[ starting_location[0]+1, starting_location[1] ],[starting_location[0]+1, starting_location[1]-1],[starting_location[0], starting_location[1]-1]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
elsif (starting_location[0] == size ) && (starting_location[1]== size)
adjacent_squares =[[ starting_location[0]-1, starting_location[1] ],[starting_location[0]-1, starting_location[1]-1],[starting_location[0], starting_location[1]-1]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
elsif (starting_location[0] == size) && (starting_location[1]==0)
adjacent_squares =[[ starting_location[0]-1, starting_location[1] ],[starting_location[0]-1, starting_location[1]+1],[starting_location[0], starting_location[1]+1]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
elsif (starting_location[0] == 0)
adjacent_squares = [[starting_location[0],starting_location[1]-1],[starting_location[0]+1,starting_location[1]-1],[starting_location[0]+1,starting_location[1]],[starting_location[0]+1,starting_location[1]+1],[starting_location[0],starting_location[1]+1]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
elsif (starting_location[1] == 0)
adjacent_squares = [[starting_location[0]-1,starting_location[1]],[starting_location[0]-1,starting_location[1]+1],[starting_location[0],starting_location[1]+1],[starting_location[0]+1,starting_location[1]+1],[starting_location[0]+1,starting_location[1]]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
elsif (starting_location[0] == size)
adjacent_squares = [[starting_location[0],starting_location[1]-1],[starting_location[0]-1,starting_location[1]-1],[starting_location[0]-1,starting_location[1]],[starting_location[0]-1,starting_location[1]+1],[starting_location[0],starting_location[1]+1]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
elsif (starting_location[1]==size)
adjacent_squares = [[starting_location[0]-1,starting_location[1]],[starting_location[0]-1,starting_location[1]-1],[starting_location[0],starting_location[1]-1],[starting_location[0]+1,starting_location[1]-1],[starting_location[0]+1,starting_location[1]]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
else
adjacent_squares = [[starting_location[0]-1,starting_location[1]-1],[starting_location[0]-1,starting_location[1]],[starting_location[0]-1,starting_location[1]+1],[starting_location[0],starting_location[1]+1],[starting_location[0]+1,starting_location[1]+1],[starting_location[0]+1,starting_location[1]],[starting_location[0]+1,starting_location[1]-1],[starting_location[0],starting_location[1]-1]]
adjacent_squares.each do |square|
number_of_mines += 1 if @mines.include?(square)
end
end
if number_of_mines == 0
@map[starting_location[0]][starting_location[1]] = 0
adjacent_squares.each do |square|
choose_mine(square) unless square.nil?
end
else
@map[starting_location[0]][starting_location[1]] = number_of_mines
end
end
end
puts "Greetings! Welcome to Minesweeper"
puts "Care to play? [y or n]"
play = gets.chomp.downcase
if play == "y"
puts "How hard do you want to go?" + "\n" + "(1) Easy [4x4 grid : 4 mines]"+"\n"+ "(2) Meh [7x7 grid : 15 mines]"+"\n"+"(3) Oh $h!t [10x10 grid : 35 mines]"+"\n"+"(4) 1n$@n3 [15x15 grid : 99 mines]"
difficulty = gets.chomp.to_i
map = MinesweeperMap.new(difficulty)
start_time = Time.now
while map.still_alive? && map.not_solved?
map.show_map
puts
puts "="*20
puts
puts map.mine_count.to_s + " mines on the field"
puts map.flag_count.to_s + " flags planted"
puts "What do you want to do? [D for dig, F for flag, R to remove existing flag]"
puts
choice = gets.chomp.downcase
case choice
when "d"
puts "Choose a space you think is empty"
puts "Enter row: "
row = gets.chomp.to_i
puts "Enter column: "
column = gets.chomp.to_i
map.choose_mine([row-1,column-1])
when "f"
puts "Where do you think a mine is?"
puts "Enter row: "
row = gets.chomp.to_i
puts "Enter column: "
column = gets.chomp.to_i
map.place_flag([row,column])
when "r"
puts "Which flag do you want to remove?"
map.show_flags
puts "Enter row: "
row = gets.chomp.to_i
puts "Enter column: "
column = gets.chomp.to_i
map.remove_flag([row,column])
else
raise "Not an acceptable answer bro!"
end
map.check_flags
end
if not map.still_alive?
puts "You scored: " + (map.score(Time.now - start_time, map.spaces_cleared ) * 0.1).to_s
gets
else
puts "You win!"
puts "You scored: " + (map.score(Time.now - start_time, map.spaces_cleared )).to_s
gets
end
elsif play == "n"
puts "Have a good day"
gets
else
raise "Wrong answer dude!"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment