minesweeprb 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16bc74524f23df3a1ab558f120560e152b2a1c7551379a6237eefac7cf48962b
4
- data.tar.gz: f879f2d59af8c486aa34114fcc77995a7a1951edeac59026d9c54ecbdeda09af
3
+ metadata.gz: d8570b88e453c2b2831d7b4d155ece9b35191aa989b38c3df409cde3258af522
4
+ data.tar.gz: b4d5c63637d268285cc2a0a08d9b3011b9ceed0aaeabfb36fb63004b90938f82
5
5
  SHA512:
6
- metadata.gz: 73cfcc1a3d6e6099f122eb340b567d7517d1853b7654d93ef00df9da1c08ba5ace35a36dbf54d8ec49651c9e5a97f3d09d7cec0255d9f910892aad26589400ec
7
- data.tar.gz: aae8f678ed0182f6d76cee2df5491c007a57b91ba1f45625e593a5ffc02d2b1e0d4eb96ea859f5d2b1107d78c1bbbbfe6f2cd4afffecd87a7f8e30cf539fb2ec
6
+ metadata.gz: 0250dbc2b118b525aad974cf1ab17001cff0484abdf4b2c49961d02e7f040a5f9dfdcb687473e3514f030899369ef650d61011cd68b9bf17c0ca0c36afa9ef7b
7
+ data.tar.gz: ecdb3eacfb7288c3f8383ac6936d782947c7c1fb06fcc57c80dba1e9b404508ff51526bebec7a793beee00e6d2e55e469354d3cae95cfebf5afce23c7727f990
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ### 2020-02-08 0.3.0
2
+
3
+ * Add mouse support
4
+
1
5
  ### 2020-02-08 0.2.0
2
6
 
3
7
  * Use curses for gameboard to reduce flickering
@@ -50,8 +50,8 @@ module Minesweeprb
50
50
  },
51
51
  ].freeze
52
52
 
53
- attr_reader :active_square,
54
- :flagged_squares,
53
+ attr_accessor :active_square
54
+ attr_reader :flagged_squares,
55
55
  :marked_squares,
56
56
  :mined_squares,
57
57
  :revealed_squares,
@@ -165,10 +165,10 @@ module Minesweeprb
165
165
  SPRITES[:mine]
166
166
  elsif flagged_squares.include?(pos)
167
167
  SPRITES[:flag]
168
- elsif marked_squares.include?(pos)
169
- SPRITES[:mark]
170
168
  elsif revealed_squares[pos]
171
169
  SPRITES[:clues][revealed_squares[pos]]
170
+ elsif marked_squares.include?(pos)
171
+ SPRITES[:mark]
172
172
  else
173
173
  SPRITES[:square]
174
174
  end
@@ -222,6 +222,7 @@ module Minesweeprb
222
222
  end
223
223
 
224
224
  def reveal_square(square)
225
+ return if over? || flagged_squares.include?(active_square)
225
226
  start_game if revealed_squares.empty?
226
227
  return if revealed_squares.keys.include?(square)
227
228
  return lose! if mined_squares.include?(square)
@@ -6,16 +6,18 @@ require_relative './game'
6
6
 
7
7
  module Minesweeprb
8
8
  class Gameboard
9
+ include Curses
10
+
9
11
  RESTART = ['r'].freeze
10
- REVEAL = [10, Curses::KEY_ENTER].freeze
12
+ REVEAL = [10, KEY_ENTER].freeze
11
13
  FLAG = ['f', ' '].freeze
12
14
  QUIT = ['q', 27].freeze
13
15
 
14
16
  MOVE = {
15
- Curses::KEY_UP => :up,
16
- Curses::KEY_DOWN => :down,
17
- Curses::KEY_LEFT => :left,
18
- Curses::KEY_RIGHT => :right,
17
+ KEY_UP => :up,
18
+ KEY_DOWN => :down,
19
+ KEY_LEFT => :left,
20
+ KEY_RIGHT => :right,
19
21
  'k' => :up,
20
22
  'j' => :down,
21
23
  'h' => :left,
@@ -23,38 +25,38 @@ module Minesweeprb
23
25
  }.freeze
24
26
 
25
27
  COLORS = {
26
- win: [Curses::A_BOLD | Curses::COLOR_GREEN],
27
- lose: [Curses::A_BOLD | Curses::COLOR_MAGENTA],
28
- Game::SPRITES[:clock] => [Curses::A_BOLD | Curses::COLOR_CYAN],
29
- Game::SPRITES[:win_face] => [Curses::A_BOLD | Curses::COLOR_YELLOW],
30
- Game::SPRITES[:lose_face] => [Curses::A_BOLD | Curses::COLOR_RED],
31
- Game::SPRITES[:play_face] => [Curses::A_BOLD | Curses::COLOR_CYAN],
32
-
33
- Game::SPRITES[:mine] => [Curses::A_BOLD | Curses::COLOR_RED],
34
- Game::SPRITES[:flag] => [Curses::A_BOLD | Curses::COLOR_RED],
35
- Game::SPRITES[:mark] => [Curses::A_BOLD | Curses::COLOR_MAGENTA],
36
- Game::SPRITES[:clues][0] => [Curses::COLOR_BLACK],
37
- Game::SPRITES[:clues][1] => [Curses::COLOR_BLUE],
38
- Game::SPRITES[:clues][2] => [Curses::COLOR_GREEN],
39
- Game::SPRITES[:clues][3] => [Curses::COLOR_MAGENTA],
40
- Game::SPRITES[:clues][4] => [Curses::COLOR_CYAN],
41
- Game::SPRITES[:clues][5] => [Curses::COLOR_RED],
42
- Game::SPRITES[:clues][6] => [Curses::COLOR_YELLOW],
43
- Game::SPRITES[:clues][7] => [Curses::A_BOLD | Curses::COLOR_MAGENTA],
44
- Game::SPRITES[:clues][8] => [Curses::A_BOLD | Curses::COLOR_RED],
28
+ win: [A_BOLD | COLOR_GREEN],
29
+ lose: [A_BOLD | COLOR_MAGENTA],
30
+ Game::SPRITES[:clock] => [A_BOLD | COLOR_CYAN],
31
+ Game::SPRITES[:win_face] => [A_BOLD | COLOR_YELLOW],
32
+ Game::SPRITES[:lose_face] => [A_BOLD | COLOR_RED],
33
+ Game::SPRITES[:play_face] => [A_BOLD | COLOR_CYAN],
34
+
35
+ Game::SPRITES[:mine] => [A_BOLD | COLOR_RED],
36
+ Game::SPRITES[:flag] => [A_BOLD | COLOR_RED],
37
+ Game::SPRITES[:mark] => [A_BOLD | COLOR_MAGENTA],
38
+ Game::SPRITES[:clues][0] => [COLOR_BLACK],
39
+ Game::SPRITES[:clues][1] => [COLOR_BLUE],
40
+ Game::SPRITES[:clues][2] => [COLOR_GREEN],
41
+ Game::SPRITES[:clues][3] => [COLOR_MAGENTA],
42
+ Game::SPRITES[:clues][4] => [COLOR_CYAN],
43
+ Game::SPRITES[:clues][5] => [COLOR_RED],
44
+ Game::SPRITES[:clues][6] => [COLOR_YELLOW],
45
+ Game::SPRITES[:clues][7] => [A_BOLD | COLOR_MAGENTA],
46
+ Game::SPRITES[:clues][8] => [A_BOLD | COLOR_RED],
45
47
  }.freeze
46
48
 
47
49
  COLOR_PAIRS = COLORS.keys.freeze
48
50
 
49
- attr_reader :game, :pastel, :window
51
+ attr_reader :game, :pastel, :window, :game_x, :game_y
50
52
 
51
53
  def initialize(size)
52
54
  @pastel = Pastel.new
53
55
  @game = Game.new(size)
54
56
  @timers = Timers::Group.new
55
57
  @game_timer = @timers.every(0.5) { paint }
56
- Thread.new { loop { @timers.wait } }
57
58
  setup_curses
59
+ Thread.new { loop { @timers.wait } }
58
60
  end
59
61
 
60
62
  def draw
@@ -63,28 +65,30 @@ module Minesweeprb
63
65
  end
64
66
 
65
67
  def clear
66
- Curses.close_screen
68
+ close_screen
67
69
  end
68
70
 
69
71
  private
70
72
 
71
73
  def setup_curses
72
- Curses.init_screen
73
- Curses.use_default_colors
74
- Curses.start_color
75
- Curses.curs_set(0)
76
- Curses.noecho
77
- Curses.ESCDELAY = 1;
78
- @window = Curses::Window.new(0, 0, 0, 0)
74
+ init_screen
75
+ use_default_colors
76
+ start_color
77
+ curs_set(0)
78
+ noecho
79
+ self.ESCDELAY = 1;
80
+ mousemask(BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED|BUTTON4_CLICKED)
81
+ @window = Window.new(0, 0, 0, 0)
79
82
  @window.keypad(true)
80
83
  COLOR_PAIRS.each.with_index do |char, index|
81
84
  fg, bg = COLORS[char]
82
- Curses.init_pair(index + 1, fg, bg || -1)
85
+ init_pair(index + 1, fg, bg || -1)
83
86
  end
84
87
  end
85
88
 
86
89
  def process_input(key)
87
90
  case key
91
+ when KEY_MOUSE then process_mouse(getmouse)
88
92
  when *MOVE.keys then game.move(MOVE[key])
89
93
  when *REVEAL then game.reveal_active_square
90
94
  when *FLAG then game.cycle_flag
@@ -95,6 +99,25 @@ module Minesweeprb
95
99
  true
96
100
  end
97
101
 
102
+ def process_mouse(m)
103
+ top = game_y
104
+ left = game_x
105
+ bottom = game_y + game.height
106
+ right = game_x + game.width * 2 - 1
107
+ on_board = (top..bottom).include?(m.y) &&
108
+ (left..right).include?(m.x) &&
109
+ (m.x - game_x).even?
110
+
111
+ return if !on_board && !game.over?
112
+
113
+ game.active_square = [(m.x - game_x) / 2, m.y - game_y]
114
+
115
+ case m.bstate
116
+ when BUTTON1_CLICKED then game.reveal_active_square
117
+ when BUTTON2_CLICKED, (BUTTON_CTRL | BUTTON1_CLICKED) then game.cycle_flag
118
+ end
119
+ end
120
+
98
121
  def how_to_play
99
122
  instructions = []
100
123
  instructions << '(←↓↑→ or hjkl)Move' unless game.over?
@@ -111,27 +134,28 @@ module Minesweeprb
111
134
  game.header.center(window.maxx - 1).chars.each do |char|
112
135
  window.attron(color_for(char)) { window << char }
113
136
  end
114
- Curses.clrtoeol
137
+ clrtoeol
115
138
  window << "\n"
116
139
 
117
140
  # COLOR_PAIRS.each do |char|
118
141
  # window.attron(color_for(char)) { window << char }
119
142
  # end
120
- # Curses.clrtoeol
143
+ # clrtoeol
121
144
  # window << "\n"
122
145
 
123
146
  padding = (window.maxx - game.width * 2) / 2
124
147
  game.squares.each.with_index do |line, row|
125
148
  window << ' ' * padding
149
+ @game_x, @game_y = window.curx, window.cury if row.zero?
126
150
  line.each.with_index do |char, col|
127
151
  if game.active_square == [col, row]
128
- window.attron(color_for(char) | Curses::A_REVERSE) { window << char }
152
+ window.attron(color_for(char) | A_REVERSE) { window << char }
129
153
  else
130
154
  window.attron(color_for(char)) { window << char }
131
155
  end
132
156
  window << ' ' if col < line.length
133
157
  end
134
- Curses.clrtoeol
158
+ clrtoeol
135
159
  window << "\n"
136
160
  end
137
161
 
@@ -148,13 +172,13 @@ module Minesweeprb
148
172
  window.attron(char_color) { window << char }
149
173
  end
150
174
  end
151
- Curses.clrtoeol
175
+ clrtoeol
152
176
  window << "\n"
153
177
  end
154
178
 
155
179
  window << "\n"
156
180
  window << how_to_play.center(window.maxx - 1)
157
- Curses.clrtoeol
181
+ clrtoeol
158
182
  window << "\n"
159
183
 
160
184
  window.refresh
@@ -164,7 +188,7 @@ module Minesweeprb
164
188
  pair = COLOR_PAIRS.index(char)
165
189
 
166
190
  if pair
167
- Curses.color_pair(pair + 1)
191
+ color_pair(pair + 1)
168
192
  else
169
193
  0
170
194
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Minesweeprb
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minesweeprb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - scudco
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-08 00:00:00.000000000 Z
11
+ date: 2020-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: timers