minesweeper-curses 0.2.0 → 0.2.1
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/minesweeper/base_cell.rb +42 -0
- data/lib/minesweeper/board.rb +18 -20
- data/lib/minesweeper/board_builder.rb +5 -0
- data/lib/minesweeper/board_params.rb +2 -0
- data/lib/minesweeper/bomb_cell.rb +6 -54
- data/lib/minesweeper/bomb_injector.rb +2 -0
- data/lib/minesweeper/cell.rb +6 -43
- data/lib/minesweeper/cell_state.rb +21 -0
- data/lib/minesweeper/exceptions.rb +15 -0
- data/lib/minesweeper/game_initializer.rb +13 -5
- data/lib/minesweeper/params_builder.rb +15 -11
- data/lib/minesweeper/version.rb +1 -1
- data/lib/minesweeper.rb +4 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5044d455ac72b38a323598331efbbcebb378e973
|
4
|
+
data.tar.gz: a0fc42e08fd4db82e3fb584c8e6db970a7c9435a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cddaf8165b7f84a45dc59e5f53b168ec80cc3c1157b7a9a58c7b9b47a12d1f3b638222b8a012a2233756c9a0d5dbc7f4726888f774037107fdae8b4796c899d8
|
7
|
+
data.tar.gz: 188b9d315dd4e5fe31bcd7ec1205a79b54f2fe96237480e5b21fac75a399a3d113f0f95de0f013fb6bc3e5ca9c72a00203f4a3d37ca23cae23c2ab209bae1d70
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minesweeper
|
4
|
+
class BaseCell
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :@state, :view, :color, :opened?, :marked_as_bomb?
|
8
|
+
|
9
|
+
attr_reader :state
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@state = initial_state
|
13
|
+
end
|
14
|
+
|
15
|
+
def bomb?
|
16
|
+
raise NotImplementedError, 'defined in subclass'
|
17
|
+
end
|
18
|
+
|
19
|
+
def toggle_bomb_flag!
|
20
|
+
return if opened?
|
21
|
+
if state.marked_as_bomb?
|
22
|
+
state.view = ' '
|
23
|
+
state.color = COLOR_MAGENTA
|
24
|
+
state.status = :initial
|
25
|
+
else
|
26
|
+
state.view = '*'
|
27
|
+
state.color = COLOR_MAGENTA
|
28
|
+
state.status = :marked_as_bomb
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def open!(*)
|
33
|
+
raise NotImplementedError, 'defined in subclass'
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def initial_state
|
39
|
+
CellState.new(color: COLOR_MAGENTA, view: ' ', status: :initial)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/minesweeper/board.rb
CHANGED
@@ -1,18 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Minesweeper
|
4
|
-
class GameOver < StandardError
|
5
|
-
def message
|
6
|
-
'You Lost'
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class GameWon < StandardError
|
11
|
-
def message
|
12
|
-
'You Won'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
4
|
class Board
|
17
5
|
extend Forwardable
|
18
6
|
|
@@ -71,7 +59,7 @@ module Minesweeper
|
|
71
59
|
cell = cells[row_index][index]
|
72
60
|
window.setpos(row_index, cell_ary[0])
|
73
61
|
window.attron(color_pair(COLOR_BLUE)) { window.addstr '[' }
|
74
|
-
window.attron(color_pair(cell.color)) { window.addstr cell.
|
62
|
+
window.attron(color_pair(cell.color)) { window.addstr cell.view }
|
75
63
|
window.attron(color_pair(COLOR_BLUE)) { window.addstr ']' }
|
76
64
|
end
|
77
65
|
end
|
@@ -148,19 +136,25 @@ module Minesweeper
|
|
148
136
|
window.setpos(height + 3, 0)
|
149
137
|
window.addstr e.message
|
150
138
|
window.setpos(height + 5, 0)
|
151
|
-
window.addstr
|
152
|
-
Game Stats: you have found #{found_bombs_count} out of #{bombs.count} bombs
|
139
|
+
window.addstr <<~STR
|
140
|
+
Game Stats: you have found #{found_bombs_count} out of #{bombs.count} bombs
|
153
141
|
|
154
|
-
- `R` to replay with same parameters
|
155
|
-
- `Enter` to start a new game
|
156
|
-
- any other key to exit
|
142
|
+
- `R` to replay with same parameters
|
143
|
+
- `Enter` to start a new game
|
144
|
+
- any other key to exit
|
157
145
|
STR
|
146
|
+
start_or_restart_game
|
147
|
+
end
|
148
|
+
|
149
|
+
# used when user won/lose game & decided to begin anew
|
150
|
+
# eventually will be moved to game initializer
|
151
|
+
def start_or_restart_game
|
158
152
|
case window.getch
|
159
153
|
when ENTER
|
160
154
|
echo
|
161
|
-
|
155
|
+
game_initializer.start
|
162
156
|
when 'r', 'R'
|
163
|
-
|
157
|
+
game_initializer.restart
|
164
158
|
end
|
165
159
|
end
|
166
160
|
|
@@ -207,6 +201,10 @@ Game Stats: you have found #{found_bombs_count} out of #{bombs.count} bombs
|
|
207
201
|
cells.flatten(1).reject(&:bomb?)
|
208
202
|
end
|
209
203
|
|
204
|
+
def game_initializer
|
205
|
+
@game_initializer ||= Minesweeper::GameInitializer.new
|
206
|
+
end
|
207
|
+
|
210
208
|
public
|
211
209
|
|
212
210
|
def bombs
|
@@ -1,63 +1,15 @@
|
|
1
|
-
|
2
|
-
class BombCell
|
3
|
-
attr_accessor :status, :pointer, :force_color
|
4
|
-
|
5
|
-
def initialize(status: :initial)
|
6
|
-
@status = status
|
7
|
-
@pointer = nil
|
8
|
-
@force_color = nil
|
9
|
-
end
|
1
|
+
# frozen_string_literal: true
|
10
2
|
|
3
|
+
module Minesweeper
|
4
|
+
class BombCell < BaseCell
|
11
5
|
def bomb?
|
12
6
|
true
|
13
7
|
end
|
14
8
|
|
15
|
-
def draw
|
16
|
-
case status
|
17
|
-
when :initial
|
18
|
-
' '
|
19
|
-
when :marked_as_bomb
|
20
|
-
'*'
|
21
|
-
when :opened
|
22
|
-
'*'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def toggle_bomb_flag!
|
27
|
-
if marked_as_bomb?
|
28
|
-
self.force_color = nil
|
29
|
-
self.status = :initial
|
30
|
-
else
|
31
|
-
self.force_color = COLOR_WHITE
|
32
|
-
self.status = :marked_as_bomb
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
9
|
def open!(*)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
%i[initial marked_as_bomb opened].each do |method|
|
41
|
-
define_method("#{method}?") do
|
42
|
-
status == method
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def color
|
47
|
-
case status
|
48
|
-
when :initial
|
49
|
-
COLOR_MAGENTA
|
50
|
-
when :marked_as_bomb
|
51
|
-
COLOR_MAGENTA
|
52
|
-
when :opened
|
53
|
-
color_when_opened
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def color_when_opened
|
60
|
-
force_color.nil? ? COLOR_RED : force_color
|
10
|
+
state.view = '*'
|
11
|
+
state.color = state.marked_as_bomb? ? COLOR_WHITE : COLOR_RED
|
12
|
+
state.status = :opened
|
61
13
|
end
|
62
14
|
end
|
63
15
|
end
|
data/lib/minesweeper/cell.rb
CHANGED
@@ -1,52 +1,15 @@
|
|
1
|
-
|
2
|
-
class Cell
|
3
|
-
attr_accessor :status, :pointer
|
4
|
-
|
5
|
-
def initialize(status: :initial)
|
6
|
-
@status = status
|
7
|
-
@pointer = nil
|
8
|
-
end
|
1
|
+
# frozen_string_literal: true
|
9
2
|
|
3
|
+
module Minesweeper
|
4
|
+
class Cell < BaseCell
|
10
5
|
def bomb?
|
11
6
|
false
|
12
7
|
end
|
13
8
|
|
14
|
-
def draw
|
15
|
-
case status
|
16
|
-
when :initial
|
17
|
-
' '
|
18
|
-
when :marked_as_bomb
|
19
|
-
'*'
|
20
|
-
when :opened
|
21
|
-
pointer.to_s
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def toggle_bomb_flag!
|
26
|
-
return if opened?
|
27
|
-
self.status = marked_as_bomb? ? :initial : :marked_as_bomb
|
28
|
-
end
|
29
|
-
|
30
9
|
def open!(number_of_boms_nearby)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
%i[initial marked_as_bomb opened].each do |method|
|
36
|
-
define_method("#{method}?") do
|
37
|
-
status == method
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def color
|
42
|
-
case status
|
43
|
-
when :initial
|
44
|
-
COLOR_MAGENTA
|
45
|
-
when :marked_as_bomb
|
46
|
-
COLOR_MAGENTA
|
47
|
-
when :opened
|
48
|
-
COLOR_CYAN
|
49
|
-
end
|
10
|
+
state.view = number_of_boms_nearby.to_s
|
11
|
+
state.color = COLOR_CYAN
|
12
|
+
state.status = :opened
|
50
13
|
end
|
51
14
|
end
|
52
15
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minesweeper
|
4
|
+
class CellState
|
5
|
+
attr_accessor :color, :view, :status
|
6
|
+
|
7
|
+
def initialize(color:, status:, view:)
|
8
|
+
@view = view
|
9
|
+
@color = color
|
10
|
+
@status = status
|
11
|
+
end
|
12
|
+
|
13
|
+
def opened?
|
14
|
+
status == :opened
|
15
|
+
end
|
16
|
+
|
17
|
+
def marked_as_bomb?
|
18
|
+
status == :marked_as_bomb
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -14,20 +14,28 @@ module Minesweeper
|
|
14
14
|
window.refresh
|
15
15
|
window.addch("\n")
|
16
16
|
window.addstr("Welcome to Minesweeper \n")
|
17
|
-
window.addstr("screen size: rows: #{window.maxy}; columns: #{window.maxx} \n")
|
17
|
+
window.addstr("screen size: rows: #{window.maxy}; columns: #{window.maxx / Minesweeper::Board::STEP} \n")
|
18
18
|
window.addstr("controls: `space` to mark/unmark cell as bomb, `arrow keys` to navigate \n")
|
19
|
-
|
20
|
-
.new(window, flush_params: true)
|
21
|
-
.build
|
22
|
-
.play
|
19
|
+
play
|
23
20
|
rescue SystemExit, Interrupt
|
24
21
|
ensure
|
25
22
|
close_screen
|
26
23
|
at_exit { puts 'good bye' }
|
27
24
|
end
|
28
25
|
|
26
|
+
def restart
|
27
|
+
play(false)
|
28
|
+
end
|
29
|
+
|
29
30
|
private
|
30
31
|
|
32
|
+
def play(flush_params = true)
|
33
|
+
Minesweeper::BoardBuilder
|
34
|
+
.new(window, flush_params: flush_params)
|
35
|
+
.build
|
36
|
+
.play
|
37
|
+
end
|
38
|
+
|
31
39
|
attr_reader :window
|
32
40
|
|
33
41
|
def init_colors
|
@@ -1,6 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Minesweeper
|
4
|
+
# used for reading / creating board params.
|
2
5
|
class ParamsBuilder
|
3
6
|
extend Forwardable
|
7
|
+
|
4
8
|
DEFAULTS = { height: 10, width: 10, level: 'advanced' }.freeze
|
5
9
|
|
6
10
|
attr_reader :window, :flush_params
|
@@ -23,20 +27,21 @@ module Minesweeper
|
|
23
27
|
::Minesweeper::BoardParams.first
|
24
28
|
end
|
25
29
|
|
26
|
-
def build(
|
30
|
+
def build(y_position = 4)
|
27
31
|
window.addstr('Start game with default parameters? (Y/N)')
|
28
|
-
window.setpos(
|
32
|
+
window.setpos(y_position, 42)
|
29
33
|
str = window.getstr
|
30
|
-
|
34
|
+
params =
|
31
35
|
if str.casecmp('y').zero?
|
32
|
-
|
36
|
+
DEFAULTS
|
33
37
|
else
|
34
|
-
|
38
|
+
{ height: ask_y, width: ask_x, level: ask_level }
|
35
39
|
end
|
36
|
-
|
40
|
+
board_params = ::Minesweeper::BoardParams.new(params)
|
41
|
+
validate_and_save(board_params)
|
37
42
|
end
|
38
43
|
|
39
|
-
def
|
44
|
+
def validate_and_save(instance)
|
40
45
|
if instance.valid?
|
41
46
|
instance.save
|
42
47
|
instance
|
@@ -52,15 +57,14 @@ module Minesweeper
|
|
52
57
|
def ask_x
|
53
58
|
window.addstr('Number of columns: ')
|
54
59
|
x = window.getstr
|
55
|
-
|
56
|
-
x
|
60
|
+
max_x = window.maxx / Minesweeper::Board::STEP
|
61
|
+
x.to_i > max_x ? max_x : x
|
57
62
|
end
|
58
63
|
|
59
64
|
def ask_y
|
60
65
|
window.addstr('Number of rows: ')
|
61
66
|
y = window.getstr
|
62
|
-
y
|
63
|
-
y
|
67
|
+
y.to_i > window.maxy ? window.maxy - 1 : y
|
64
68
|
end
|
65
69
|
|
66
70
|
def ask_level
|
data/lib/minesweeper/version.rb
CHANGED
data/lib/minesweeper.rb
CHANGED
@@ -6,14 +6,17 @@ include Curses
|
|
6
6
|
require 'pry'
|
7
7
|
require 'forwardable'
|
8
8
|
require 'sequel'
|
9
|
+
require_relative 'minesweeper/exceptions'
|
9
10
|
require_relative 'minesweeper/board_params'
|
10
11
|
require_relative 'minesweeper/board'
|
11
12
|
require_relative 'minesweeper/board_builder'
|
12
13
|
require_relative 'minesweeper/params_builder'
|
14
|
+
require_relative 'minesweeper/base_cell'
|
15
|
+
require_relative 'minesweeper/cell'
|
13
16
|
require_relative 'minesweeper/bomb_cell'
|
14
17
|
require_relative 'minesweeper/bomb_injector'
|
15
|
-
require_relative 'minesweeper/cell'
|
16
18
|
require_relative 'minesweeper/game_initializer'
|
19
|
+
require_relative 'minesweeper/cell_state'
|
17
20
|
|
18
21
|
module Minesweeper
|
19
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minesweeper-curses
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mykhailo Rybak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -130,12 +130,15 @@ files:
|
|
130
130
|
- bin/minesweeper-curses
|
131
131
|
- bin/setup
|
132
132
|
- lib/minesweeper.rb
|
133
|
+
- lib/minesweeper/base_cell.rb
|
133
134
|
- lib/minesweeper/board.rb
|
134
135
|
- lib/minesweeper/board_builder.rb
|
135
136
|
- lib/minesweeper/board_params.rb
|
136
137
|
- lib/minesweeper/bomb_cell.rb
|
137
138
|
- lib/minesweeper/bomb_injector.rb
|
138
139
|
- lib/minesweeper/cell.rb
|
140
|
+
- lib/minesweeper/cell_state.rb
|
141
|
+
- lib/minesweeper/exceptions.rb
|
139
142
|
- lib/minesweeper/game_initializer.rb
|
140
143
|
- lib/minesweeper/params_builder.rb
|
141
144
|
- lib/minesweeper/version.rb
|