minesweeper-curses 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +2 -2
- data/.ruby-version +1 -1
- data/.travis.yml +3 -1
- data/Rakefile +3 -6
- data/bin/console +1 -0
- data/bin/minesweeper-curses +1 -0
- data/lib/minesweeper.rb +4 -4
- data/lib/minesweeper/board.rb +29 -31
- data/lib/minesweeper/board_builder.rb +1 -1
- data/lib/minesweeper/bomb_injector.rb +1 -1
- data/lib/minesweeper/cells/base.rb +44 -0
- data/lib/minesweeper/cells/bomb.rb +17 -0
- data/lib/minesweeper/cells/cell.rb +17 -0
- data/lib/minesweeper/cells/state.rb +23 -0
- data/lib/minesweeper/game_initializer.rb +0 -6
- data/lib/minesweeper/ui.rb +13 -1
- data/lib/minesweeper/version.rb +1 -1
- data/readme.md +4 -2
- metadata +7 -8
- data/lib/minesweeper/base_cell.rb +0 -42
- data/lib/minesweeper/bomb_cell.rb +0 -15
- data/lib/minesweeper/cell.rb +0 -15
- data/lib/minesweeper/cell_state.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b505c67f37bbf83ec7880ebfc8bcd879e386733c15640dbd469643770589e9c1
|
4
|
+
data.tar.gz: c82a9785a2bfda4c76f8b6c840ab83ca76376a75944bb5f830b748511750dc92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 750e136e11cc3019c932e8d3557e608461cabdb2e316411827883ecca20f8d8068111052899b675d3d2b9d5dd18a254b5233023f71988a8730ceb11d2861525d
|
7
|
+
data.tar.gz: ba164d83089740fb9db67eed88e3f324fbf37f52f25703b17aa7732e177b01c91019c146fb64ac66f5aabac209d23184b9c94bc6f3d7233e11202ade66367a93
|
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.3
|
data/.travis.yml
CHANGED
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bundler/gem_tasks'
|
2
4
|
require 'rake/testtask'
|
3
5
|
|
@@ -7,9 +9,4 @@ Rake::TestTask.new(:test) do |t|
|
|
7
9
|
t.test_files = FileList['test/**/*_test.rb']
|
8
10
|
end
|
9
11
|
|
10
|
-
task :
|
11
|
-
|
12
|
-
task :build_and_install do
|
13
|
-
sh('bundle install')
|
14
|
-
sh("gem install ./pkg/minesweeper-#{Minesweeper::VERSION}.gem")
|
15
|
-
end
|
12
|
+
task default: :test
|
data/bin/console
CHANGED
data/bin/minesweeper-curses
CHANGED
data/lib/minesweeper.rb
CHANGED
@@ -11,12 +11,12 @@ require_relative 'minesweeper/board_params'
|
|
11
11
|
require_relative 'minesweeper/board'
|
12
12
|
require_relative 'minesweeper/board_builder'
|
13
13
|
require_relative 'minesweeper/params_builder'
|
14
|
-
require_relative 'minesweeper/
|
15
|
-
require_relative 'minesweeper/cell'
|
16
|
-
require_relative 'minesweeper/
|
14
|
+
require_relative 'minesweeper/cells/base'
|
15
|
+
require_relative 'minesweeper/cells/cell'
|
16
|
+
require_relative 'minesweeper/cells/bomb'
|
17
17
|
require_relative 'minesweeper/bomb_injector'
|
18
18
|
require_relative 'minesweeper/game_initializer'
|
19
|
-
require_relative 'minesweeper/
|
19
|
+
require_relative 'minesweeper/cells/state'
|
20
20
|
|
21
21
|
module Minesweeper
|
22
22
|
end
|
data/lib/minesweeper/board.rb
CHANGED
@@ -9,25 +9,23 @@ module Minesweeper
|
|
9
9
|
LEFT_RIGHT_PADDING = 2
|
10
10
|
SPACE = ' '
|
11
11
|
|
12
|
-
def_delegators :@window, :curx, :cury
|
13
12
|
def_delegators :board_params, :height, :width
|
14
13
|
|
15
|
-
attr_reader :board_params, :cells, :
|
14
|
+
attr_reader :board_params, :cells, :ui
|
16
15
|
|
17
16
|
def initialize(board_params)
|
18
17
|
@board_params = board_params
|
19
|
-
@
|
20
|
-
@cells
|
18
|
+
@ui = Minesweeper::Ui
|
19
|
+
@cells = []
|
21
20
|
end
|
22
21
|
|
23
22
|
def play(stdy = nil, stdx = nil)
|
24
|
-
window.keypad = true
|
25
23
|
draw_board
|
26
|
-
|
24
|
+
ui.setpos(stdy, stdx) if stdx && stdy
|
27
25
|
noecho
|
28
26
|
|
29
27
|
loop do
|
30
|
-
ch =
|
28
|
+
ch = ui.getch
|
31
29
|
case ch
|
32
30
|
when KEY_UP
|
33
31
|
move_up
|
@@ -42,7 +40,7 @@ module Minesweeper
|
|
42
40
|
when SPACE
|
43
41
|
toggle_bomb_flag
|
44
42
|
end
|
45
|
-
play(cury, curx)
|
43
|
+
play(ui.cury, ui.curx)
|
46
44
|
end
|
47
45
|
rescue GameWon, GameOver => e
|
48
46
|
end_game(e)
|
@@ -52,30 +50,30 @@ module Minesweeper
|
|
52
50
|
private
|
53
51
|
|
54
52
|
def draw_board
|
55
|
-
|
53
|
+
ui.clear
|
56
54
|
cells.each_index do |row_index|
|
57
55
|
(0..(width * 3 - 1)).each_slice(3).with_index do |cell_ary, index|
|
58
56
|
cell = cells[row_index][index]
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
ui.setpos(row_index, cell_ary[0])
|
58
|
+
ui.attron(color_pair(COLOR_BLUE)) { ui.addstr '[' }
|
59
|
+
ui.attron(color_pair(cell.color)) { ui.addstr cell.view }
|
60
|
+
ui.attron(color_pair(COLOR_BLUE)) { ui.addstr ']' }
|
63
61
|
end
|
64
62
|
end
|
65
|
-
|
66
|
-
|
63
|
+
ui.refresh
|
64
|
+
ui.setpos(0, 1)
|
67
65
|
end
|
68
66
|
|
69
67
|
def cell_x
|
70
|
-
curx / STEP
|
68
|
+
ui.curx / STEP
|
71
69
|
end
|
72
70
|
|
73
71
|
def open_cell
|
74
|
-
open_original(cury, cell_x)
|
72
|
+
open_original(ui.cury, cell_x)
|
75
73
|
end
|
76
74
|
|
77
75
|
def toggle_bomb_flag
|
78
|
-
cell = cells[cury][cell_x]
|
76
|
+
cell = cells[ui.cury][cell_x]
|
79
77
|
cell.toggle_bomb_flag!
|
80
78
|
raise GameWon if game_won?
|
81
79
|
end
|
@@ -111,33 +109,33 @@ module Minesweeper
|
|
111
109
|
end
|
112
110
|
|
113
111
|
def move_up
|
114
|
-
return if cury.zero?
|
115
|
-
|
112
|
+
return if ui.cury.zero?
|
113
|
+
ui.setpos(ui.cury - 1, ui.curx)
|
116
114
|
end
|
117
115
|
|
118
116
|
def move_down
|
119
|
-
return if cury + 1 >= height
|
120
|
-
|
117
|
+
return if ui.cury + 1 >= height
|
118
|
+
ui.setpos(ui.cury + 1, ui.curx)
|
121
119
|
end
|
122
120
|
|
123
121
|
def move_left
|
124
|
-
return if curx <= LEFT_RIGHT_PADDING
|
125
|
-
|
122
|
+
return if ui.curx <= LEFT_RIGHT_PADDING
|
123
|
+
ui.setpos(ui.cury, ui.curx - STEP)
|
126
124
|
end
|
127
125
|
|
128
126
|
def move_right
|
129
|
-
return if curx >= (width * 3 - LEFT_RIGHT_PADDING)
|
130
|
-
|
127
|
+
return if ui.curx >= (width * 3 - LEFT_RIGHT_PADDING)
|
128
|
+
ui.setpos(ui.cury, ui.curx + STEP)
|
131
129
|
end
|
132
130
|
|
133
131
|
def end_game(e)
|
134
132
|
found_bombs_count = found_bombs.count
|
135
133
|
reveal_bombs
|
136
134
|
draw_board
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
135
|
+
ui.setpos(height + 1, 0)
|
136
|
+
ui.addstr e.message
|
137
|
+
ui.setpos(height + 3, 0)
|
138
|
+
ui.addstr <<~STR
|
141
139
|
Game Stats: you have found #{found_bombs_count} out of #{bombs.count} bombs
|
142
140
|
|
143
141
|
- `R` to replay with same parameters
|
@@ -150,7 +148,7 @@ module Minesweeper
|
|
150
148
|
# used when user won/lose game & decided to begin anew
|
151
149
|
# eventually will be moved to game initializer
|
152
150
|
def start_or_restart_game
|
153
|
-
case
|
151
|
+
case ui.getch
|
154
152
|
when ENTER
|
155
153
|
echo
|
156
154
|
game_initializer.start
|
@@ -18,7 +18,7 @@ module Minesweeper
|
|
18
18
|
cell_index = random_cell
|
19
19
|
cell = board.cells[row_index][cell_index]
|
20
20
|
unless cell.bomb?
|
21
|
-
board.cells[row_index][cell_index] =
|
21
|
+
board.cells[row_index][cell_index] = Cells::Bomb.new
|
22
22
|
number -= 1
|
23
23
|
end
|
24
24
|
add_bombs(number)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minesweeper
|
4
|
+
module Cells
|
5
|
+
class Base
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@state, :view, :color, :opened?, :marked_as_bomb?
|
9
|
+
|
10
|
+
attr_reader :state
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@state = initial_state
|
14
|
+
end
|
15
|
+
|
16
|
+
def bomb?
|
17
|
+
raise NotImplementedError, 'defined in subclass'
|
18
|
+
end
|
19
|
+
|
20
|
+
def toggle_bomb_flag!
|
21
|
+
return if opened?
|
22
|
+
if marked_as_bomb?
|
23
|
+
state.view = ' '
|
24
|
+
state.color = COLOR_MAGENTA
|
25
|
+
state.status = :initial
|
26
|
+
else
|
27
|
+
state.view = '*'
|
28
|
+
state.color = COLOR_MAGENTA
|
29
|
+
state.status = :marked_as_bomb
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def open!(*)
|
34
|
+
raise NotImplementedError, 'defined in subclass'
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def initial_state
|
40
|
+
State.new(color: COLOR_MAGENTA, view: ' ', status: :initial)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minesweeper
|
4
|
+
module Cells
|
5
|
+
class Bomb < Base
|
6
|
+
def bomb?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
def open!(*)
|
11
|
+
state.view = '*'
|
12
|
+
state.color = marked_as_bomb? ? COLOR_WHITE : COLOR_RED
|
13
|
+
state.status = :opened
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minesweeper
|
4
|
+
module Cells
|
5
|
+
class Cell < Base
|
6
|
+
def bomb?
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def open!(number_of_boms_nearby)
|
11
|
+
state.view = number_of_boms_nearby.to_s
|
12
|
+
state.color = COLOR_CYAN
|
13
|
+
state.status = :opened
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minesweeper
|
4
|
+
module Cells
|
5
|
+
class State
|
6
|
+
attr_accessor :color, :view, :status
|
7
|
+
|
8
|
+
def initialize(color:, status:, view:)
|
9
|
+
@view = view
|
10
|
+
@color = color
|
11
|
+
@status = status
|
12
|
+
end
|
13
|
+
|
14
|
+
def opened?
|
15
|
+
status == :opened
|
16
|
+
end
|
17
|
+
|
18
|
+
def marked_as_bomb?
|
19
|
+
status == :marked_as_bomb
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -2,10 +2,6 @@
|
|
2
2
|
|
3
3
|
module Minesweeper
|
4
4
|
class GameInitializer
|
5
|
-
def initialize
|
6
|
-
@window = nil
|
7
|
-
end
|
8
|
-
|
9
5
|
def start
|
10
6
|
init_curses
|
11
7
|
Ui.greeting_message
|
@@ -29,8 +25,6 @@ module Minesweeper
|
|
29
25
|
.play
|
30
26
|
end
|
31
27
|
|
32
|
-
attr_reader :window
|
33
|
-
|
34
28
|
def init_curses
|
35
29
|
init_screen
|
36
30
|
init_colors
|
data/lib/minesweeper/ui.rb
CHANGED
@@ -20,7 +20,19 @@ module Minesweeper
|
|
20
20
|
instance.respond_to?(:method_name) || super
|
21
21
|
end
|
22
22
|
|
23
|
-
def_delegators :window,
|
23
|
+
def_delegators :window,
|
24
|
+
:clear,
|
25
|
+
:addch,
|
26
|
+
:addstr,
|
27
|
+
:refresh,
|
28
|
+
:maxy,
|
29
|
+
:maxx,
|
30
|
+
:getstr,
|
31
|
+
:setpos,
|
32
|
+
:attron,
|
33
|
+
:getch,
|
34
|
+
:curx,
|
35
|
+
:cury
|
24
36
|
|
25
37
|
def greeting_message
|
26
38
|
clear
|
data/lib/minesweeper/version.rb
CHANGED
data/readme.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
#### Requirements
|
9
9
|
|
10
|
-
- ruby 2.4
|
10
|
+
- ruby 2.4 or higher
|
11
11
|
|
12
12
|
#### Setup
|
13
13
|
|
@@ -17,7 +17,9 @@
|
|
17
17
|
|
18
18
|
- `git clone git@github.com:ruba-ruba/minesweeper.git`
|
19
19
|
- `cd minesweeper`
|
20
|
-
- `
|
20
|
+
- `gem install bundler`
|
21
|
+
- `bundle install`
|
22
|
+
- `rake install`
|
21
23
|
|
22
24
|
#### Launching
|
23
25
|
|
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.4.
|
4
|
+
version: 0.4.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:
|
11
|
+
date: 2019-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -116,14 +116,14 @@ files:
|
|
116
116
|
- bin/minesweeper-curses
|
117
117
|
- bin/setup
|
118
118
|
- lib/minesweeper.rb
|
119
|
-
- lib/minesweeper/base_cell.rb
|
120
119
|
- lib/minesweeper/board.rb
|
121
120
|
- lib/minesweeper/board_builder.rb
|
122
121
|
- lib/minesweeper/board_params.rb
|
123
|
-
- lib/minesweeper/bomb_cell.rb
|
124
122
|
- lib/minesweeper/bomb_injector.rb
|
125
|
-
- lib/minesweeper/
|
126
|
-
- lib/minesweeper/
|
123
|
+
- lib/minesweeper/cells/base.rb
|
124
|
+
- lib/minesweeper/cells/bomb.rb
|
125
|
+
- lib/minesweeper/cells/cell.rb
|
126
|
+
- lib/minesweeper/cells/state.rb
|
127
127
|
- lib/minesweeper/exceptions.rb
|
128
128
|
- lib/minesweeper/game_initializer.rb
|
129
129
|
- lib/minesweeper/params_builder.rb
|
@@ -151,8 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
requirements: []
|
154
|
-
|
155
|
-
rubygems_version: 2.6.11
|
154
|
+
rubygems_version: 3.0.1
|
156
155
|
signing_key:
|
157
156
|
specification_version: 4
|
158
157
|
summary: Minesweeper CLI game using curses
|
@@ -1,42 +0,0 @@
|
|
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 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/cell.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Minesweeper
|
4
|
-
class Cell < BaseCell
|
5
|
-
def bomb?
|
6
|
-
false
|
7
|
-
end
|
8
|
-
|
9
|
-
def open!(number_of_boms_nearby)
|
10
|
-
state.view = number_of_boms_nearby.to_s
|
11
|
-
state.color = COLOR_CYAN
|
12
|
-
state.status = :opened
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,21 +0,0 @@
|
|
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
|