minesweeper-cl 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/game_board.rb +65 -0
- data/lib/game_tile.rb +74 -0
- data/lib/minesweeper.rb +49 -0
- data/lib/minesweeper_game.rb +96 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9fdc983251f91396ce4c2aaa1c435990262cdeb7
|
4
|
+
data.tar.gz: 687edfe600a81d46b51c51cb5d4f0321b1727d77
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 78f51d2007178ad84aab9cb6b6a7c363ab5299c4f0327e120378b68066d860189962a0dd53f35612869acf1a9b30734a2ddce9dd85d88c01be0590f78e20764e
|
7
|
+
data.tar.gz: c7f0480b90f925eef8ce66ac8cdb631ba8755c2d1de731503c168b37574b61ccd0de12d654a1ad49371cfdff719d74c18683fa43306e5da98dbcf4be1397f66a
|
data/lib/game_board.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# GameBoard class will be used by the minesweeper game to keep track of tiles,
|
2
|
+
# bombs, and the conditions necessary to win the game.
|
3
|
+
require_relative 'game_tile'
|
4
|
+
|
5
|
+
class GameBoard
|
6
|
+
|
7
|
+
attr_accessor :rows, :cols, :board, :num_played, :win_value
|
8
|
+
|
9
|
+
def initialize(rows, cols, bomb_chance)
|
10
|
+
@board = {}
|
11
|
+
@num_played = 0
|
12
|
+
@win_value = rows * cols
|
13
|
+
# This sets the board's values and then checks for some of the bombs
|
14
|
+
rows.times do |row|
|
15
|
+
cols.times do |column|
|
16
|
+
if rand < bomb_chance
|
17
|
+
@board["(#{row}, #{column})"] = GameTile.new(self, nil, nil, nil, nil, nil, nil, nil, nil, true)
|
18
|
+
@win_value -= 1
|
19
|
+
else
|
20
|
+
@board["(#{row}, #{column})"] = GameTile.new(self, nil, nil, nil, nil, nil, nil, nil, nil, false)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# Set the left pointers to GameTile objects that have already been created.
|
25
|
+
if column > 0
|
26
|
+
@board["(#{row}, #{column})"].adjacent["left"] = @board["(#{row}, #{column - 1})"]
|
27
|
+
end
|
28
|
+
|
29
|
+
# Set the up_left, up, and up_right pointers to objects that have been created. Edge
|
30
|
+
# cases are automatically handled because Hashes return nil for keys that do not
|
31
|
+
# exist in the hash.
|
32
|
+
if row > 0
|
33
|
+
@board["(#{row}, #{column})"].adjacent["up"] = @board["(#{row - 1}, #{column})"]
|
34
|
+
@board["(#{row}, #{column})"].adjacent["up_left"] = @board["(#{row - 1}, #{column - 1})"]
|
35
|
+
@board["(#{row}, #{column})"].adjacent["up_right"] = @board["(#{row - 1}, #{column + 1})"]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Now finish the bomb checking
|
41
|
+
rows.times do |row|
|
42
|
+
cols.times do |column|
|
43
|
+
|
44
|
+
# Set the right pointer object based on objects that have already been created.
|
45
|
+
if column < cols - 1
|
46
|
+
@board["(#{row}, #{column})"].adjacent["right"] = @board["(#{row}, #{column + 1})"]
|
47
|
+
end
|
48
|
+
|
49
|
+
if row < rows - 1
|
50
|
+
@board["(#{row}, #{column})"].adjacent["down_left"] = @board["(#{row + 1}, #{column - 1})"]
|
51
|
+
@board["(#{row}, #{column})"].adjacent["down"] = @board["(#{row + 1}, #{column})"]
|
52
|
+
@board["(#{row}, #{column})"].adjacent["down_right"] = @board["(#{row + 1}, #{column + 1})"]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Search for bombs
|
59
|
+
@board.each do |key, value|
|
60
|
+
value.find_adjacent_bombs
|
61
|
+
value.find_adjacent_zeroes
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
data/lib/game_tile.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
|
2
|
+
# An object oriented take on the minesweeper game that's done in 131.
|
3
|
+
# Since it is un-Rubylike to use 2d arrays, I'm going to try and
|
4
|
+
# make the game using a more object oriented approach.
|
5
|
+
|
6
|
+
class GameTile
|
7
|
+
|
8
|
+
attr_accessor :adjacent, :adjacent_bombs, :been_played, :been_flagged, :adjacent_zeroes
|
9
|
+
|
10
|
+
def initialize(board, up_left, up, up_right, left, right, down_left, down, down_right, is_bomb)
|
11
|
+
@adjacent = {
|
12
|
+
"up_left" => up_left,
|
13
|
+
"up" => up,
|
14
|
+
"up_right" => up_right,
|
15
|
+
"left" => left,
|
16
|
+
"right" => right,
|
17
|
+
"down_left" => down_left,
|
18
|
+
"down" => down,
|
19
|
+
"down_right" => down_right
|
20
|
+
}
|
21
|
+
@is_bomb = is_bomb
|
22
|
+
@adjacent_bombs = 0
|
23
|
+
@adjacent_zeroes = {}
|
24
|
+
@been_played = false
|
25
|
+
@been_flagged = false
|
26
|
+
@board = board
|
27
|
+
end
|
28
|
+
|
29
|
+
# Method will iterate through the surrounding GameTiles to check how many bombs there are.
|
30
|
+
# The method returns the number of bombs that are adjacent to itself.
|
31
|
+
def find_adjacent_bombs
|
32
|
+
@adjacent.each do |key, value|
|
33
|
+
begin
|
34
|
+
if value.is_bomb?
|
35
|
+
@adjacent_bombs += 1
|
36
|
+
end
|
37
|
+
rescue
|
38
|
+
# This rescue catches the NoMethodError that arises when trying to call the find_adjacent_bombs
|
39
|
+
# method on an edge cell. The error arises when trying to access the is_bomb attribute of a
|
40
|
+
# nil class. Hence, the NoMethodError.
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# This method will "play" all of the adjacent cells that have zero mines surrounding them.
|
46
|
+
# The minesweeper game that comes standard with most computers has this behavior.
|
47
|
+
def find_adjacent_zeroes
|
48
|
+
@adjacent.each do |key, value|
|
49
|
+
begin
|
50
|
+
if value.adjacent_bombs == 0
|
51
|
+
@adjacent_zeroes[key] = value
|
52
|
+
end
|
53
|
+
rescue
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def play_adjacent_zeroes
|
59
|
+
@adjacent_zeroes.each do |key, value|
|
60
|
+
value.adjacent_zeroes.each do |key1, value1|
|
61
|
+
if !value1.been_played
|
62
|
+
value1.been_played = true
|
63
|
+
@board.num_played += 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
def is_bomb?
|
71
|
+
@is_bomb
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
data/lib/minesweeper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative 'game_tile'
|
3
|
+
require_relative 'minesweeper_game'
|
4
|
+
require_relative 'game_board'
|
5
|
+
|
6
|
+
puts "Welcome to the game of minesweeper!"
|
7
|
+
puts "-----------------------------------"
|
8
|
+
puts "Please enter the amount of rows that you would like to play with, anything more than 20 will be truncated."
|
9
|
+
rows = gets.chomp.to_i
|
10
|
+
|
11
|
+
while !rows.is_a?(Integer) do
|
12
|
+
puts "Please enter the amount of rows that you would like to play with, anything more than 20 will be truncated."
|
13
|
+
rows = gets.chomp.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
puts "Please enter the amount of cols that you would like to play with, anything more than 20 will be truncated."
|
17
|
+
cols = gets.chomp.to_i
|
18
|
+
|
19
|
+
while !cols.is_a?(Integer) do
|
20
|
+
puts "Please enter the amount of cols that you would like to play with, anything more than 20 will be truncated."
|
21
|
+
cols = gets.chomp.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
puts "Please enter the % chance you want for a bomb to occur"
|
25
|
+
bomb_chance = gets.chomp.to_f
|
26
|
+
|
27
|
+
while !bomb_chance.is_a?(Float) do
|
28
|
+
puts "Please enter the % chance you want for a bomb to occur"
|
29
|
+
bomb_chance = gets.chomp.to_f
|
30
|
+
end
|
31
|
+
|
32
|
+
# Create the board
|
33
|
+
board = GameBoard.new(rows, cols, bomb_chance)
|
34
|
+
|
35
|
+
|
36
|
+
# Use the MinesweeperGame class to play the game
|
37
|
+
game = MinesweeperGame.new(board, rows, cols)
|
38
|
+
|
39
|
+
game.print_the_board
|
40
|
+
while !game.game_over? && !game.win? do
|
41
|
+
game.play_the_game
|
42
|
+
end
|
43
|
+
|
44
|
+
if game.game_over?
|
45
|
+
puts "Oops! You selected a bomb. Please play again!"
|
46
|
+
elsif game.win?
|
47
|
+
puts "Congrats you won the game!"
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
class MinesweeperGame
|
2
|
+
|
3
|
+
attr_accessor :board
|
4
|
+
|
5
|
+
def initialize(board, rows, columns)
|
6
|
+
@board = board
|
7
|
+
@rows = rows
|
8
|
+
@columns = columns
|
9
|
+
@game_over = false
|
10
|
+
@win = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def print_the_board
|
14
|
+
@rows.times do |row|
|
15
|
+
@columns.times do |column|
|
16
|
+
if !@board.board["(#{row}, #{column})"].been_played
|
17
|
+
print "[ ] "
|
18
|
+
elsif @board.board["(#{row}, #{column})"].been_flagged
|
19
|
+
print "[|>] "
|
20
|
+
else
|
21
|
+
if @board.board["(#{row}, #{column})"].adjacent_bombs > 0
|
22
|
+
print "[ " + @board.board["(#{row}, #{column})"].adjacent_bombs.to_s + "] "
|
23
|
+
else
|
24
|
+
print "[--] "
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
puts
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def play_the_game
|
33
|
+
puts "Please put two numbers corresponding to the row and column that you'd like to play in the form"
|
34
|
+
puts "<pf> <row>, <column>"
|
35
|
+
puts
|
36
|
+
player_choice = gets.chomp
|
37
|
+
|
38
|
+
# Now match the player response with a regular expression
|
39
|
+
while /([pf]) (\d), (\d)$/.match(player_choice) == nil
|
40
|
+
puts "Please put two numbers corresponding to the row and column that you'd like to play in the form"
|
41
|
+
puts "<pf> <row>, <column>"
|
42
|
+
puts
|
43
|
+
player_choice = gets.chomp
|
44
|
+
end
|
45
|
+
match = /([pf]) (\d), (\d)$/.match(player_choice)
|
46
|
+
# A 'p' character indicates that the player wants to "play" the tile.
|
47
|
+
# An 'f' character indicates that the player would like to flag the
|
48
|
+
# tile because they believe there to be a bomb there. Flagged tiles
|
49
|
+
# may still be played after they have been flagged.
|
50
|
+
if match[1] == 'p'
|
51
|
+
play_tile(match[2].to_i - 1, match[3].to_i - 1)
|
52
|
+
elsif match[1] == 'f'
|
53
|
+
flag_tile(match[2].to_i - 1, match[3].to_i - 1)
|
54
|
+
end
|
55
|
+
puts
|
56
|
+
print_the_board
|
57
|
+
end
|
58
|
+
|
59
|
+
def play_tile(row, column)
|
60
|
+
if @board.board["(#{row}, #{column})"].is_bomb?
|
61
|
+
@game_over = true
|
62
|
+
else
|
63
|
+
@board.board["(#{row}, #{column})"].been_played = true
|
64
|
+
@board.num_played += 1
|
65
|
+
if @board.board["(#{row}, #{column})"].adjacent_bombs == 0
|
66
|
+
@board.board["(#{row}, #{column})"].play_adjacent_zeroes
|
67
|
+
end
|
68
|
+
if @board.num_played == @board.win_value
|
69
|
+
@win = true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def flag_tile(row, column)
|
75
|
+
if @board.board["(#{row}, #{column})"].been_flagged
|
76
|
+
@board.board["(#{row}, #{column})"].been_flagged = false
|
77
|
+
else
|
78
|
+
@board.board["(#{row}, #{column})"].been_flagged = true
|
79
|
+
@board.board["(#{row}, #{column})"].been_played = true
|
80
|
+
@board.num_played += 1
|
81
|
+
if @board.num_played == @board.win_value
|
82
|
+
@win = true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def game_over?
|
88
|
+
@game_over
|
89
|
+
end
|
90
|
+
|
91
|
+
def win?
|
92
|
+
@win
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minesweeper-cl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- gr1zzly_be4r
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-23 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Minesweeper, ported to the command line
|
14
|
+
email:
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/game_board.rb
|
20
|
+
- lib/game_tile.rb
|
21
|
+
- lib/minesweeper.rb
|
22
|
+
- lib/minesweeper_game.rb
|
23
|
+
homepage:
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.4.5
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: "**Minesweeper**"
|
47
|
+
test_files: []
|