green_shoes 0.198.0 → 0.201.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.
data/README.md CHANGED
@@ -8,7 +8,7 @@ This is **Green Shoes** written in Ruby. One of the colorful [Shoes](http://shoe
8
8
 
9
9
  Fantastic logo icon was created by [Zachary Scott](https://github.com/zacharyscott). Thanks!
10
10
 
11
- Now, there are 48 [samples](https://github.com/ashbb/green_shoes/tree/master/samples). Each has a [snapshot](https://github.com/ashbb/green_shoes/tree/master/snapshots).
11
+ Now, there are 50 [samples](https://github.com/ashbb/green_shoes/tree/master/samples). Each has a [snapshot](https://github.com/ashbb/green_shoes/tree/master/snapshots).
12
12
 
13
13
 
14
14
  Tiny Streaming Flash videos
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.198.0
1
+ 0.201.0
@@ -699,7 +699,7 @@ class Shoes
699
699
  Shoes.call_back_procs self
700
700
  end
701
701
 
702
- [:append, :prepend, :after, :before].each do |m|
702
+ [:append, :prepend, :after, :before, :click, :hover, :leave, :release].each do |m|
703
703
  define_method m do |*args, &blk|
704
704
  top_slot.send m, *args, &blk
705
705
  end
@@ -4,13 +4,13 @@ class Shoes
4
4
  m = klass.inspect.downcase.split('::').last
5
5
  Shoes::App.class_eval do
6
6
  define_method m do |*args, &blk|
7
- klass.class_variable_set :@@app, self
7
+ klass.class_variable_set :@@__app__, self
8
8
  klass.new *args, &blk
9
9
  end
10
10
  end
11
11
  klass.class_eval do
12
- def method_missing m, *arg, &blk
13
- @@app.send m, *arg, &blk
12
+ define_method :method_missing do |*args, &blk|
13
+ klass.class_variable_get(:@@__app__).send *args, &blk
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,326 @@
1
+ require '../lib/green_shoes'
2
+ # The original is Red Shoes built-in sample: expert-othello.rb
3
+ # A little bit edited for Green Shoes.
4
+
5
+ # Othello
6
+ # by tieg
7
+ # 1/13/08
8
+ # with help: DeeJay, Ryan M. from mailing list
9
+ #
10
+ # FIXME bug if it memorizes it but it's not a valid move
11
+ #
12
+ module Othello
13
+
14
+ PIECE_WIDTH = 62
15
+ PIECE_HEIGHT = 62
16
+ TOP_OFFSET = 47
17
+ LEFT_OFFSET = 12
18
+ SPACE = ' ' * 57
19
+
20
+ class Game
21
+ BOARD_SIZE = [8,8]
22
+
23
+ attr_accessor :p1, :p2, :board, :board_history
24
+
25
+ def initialize
26
+ @board_history = []
27
+ @p1 = Player.new(:black, pieces_per_player)
28
+ @p2 = Player.new(:white, pieces_per_player)
29
+ @board = new_board
30
+ lay_initial_pieces
31
+ end
32
+
33
+ def next_turn(check_available_moves=true)
34
+ @current_player = next_player
35
+ if check_available_moves && skip_turn?
36
+ # FIXME Possible infinite loop if neither player has a good move?
37
+ next_turn
38
+ raise "Player #{@current_player.piece} (#{@current_player.color}) has no available moves. Player #{next_player.piece}'s (#{next_player.color}) turn."
39
+ end
40
+ end
41
+
42
+ def current_player
43
+ @current_player ||= @p1
44
+ end
45
+
46
+ def next_player
47
+ current_player == @p1 ? @p2 : @p1
48
+ end
49
+
50
+ # Build the array for the board, with zero-based arrays.
51
+ def new_board
52
+ Array.new(BOARD_SIZE[0]) do # build each cols L to R
53
+ Array.new(BOARD_SIZE[1]) do # insert cells in each col
54
+ 0
55
+ end
56
+ end
57
+ end
58
+
59
+ # Lay the initial 4 pieces in the middle
60
+ def lay_initial_pieces
61
+ lay_piece([4, 3], false)
62
+ next_turn(false)
63
+ lay_piece([3, 3], false)
64
+ next_turn(false)
65
+ lay_piece([3, 4], false)
66
+ next_turn(false)
67
+ lay_piece([4, 4], false)
68
+ next_turn(false)
69
+ end
70
+
71
+ def lay_piece(c=[0,0], check_adjacent_pieces=true)
72
+ memorize_board
73
+ piece = current_player.piece
74
+ opp_piece = current_player.opp_piece
75
+ raise "Spot already taken." if board_at(c) != 0
76
+ if check_adjacent_pieces
77
+ pieces_to_change = []
78
+ pieces_to_change << check_direction(c, [ 0, 1], piece, opp_piece) # N
79
+ pieces_to_change << check_direction(c, [ 1, 1], piece, opp_piece) # NE
80
+ pieces_to_change << check_direction(c, [ 1, 0], piece, opp_piece) # E
81
+ pieces_to_change << check_direction(c, [ 1,-1], piece, opp_piece) # SE
82
+ pieces_to_change << check_direction(c, [ 0,-1], piece, opp_piece) # S
83
+ pieces_to_change << check_direction(c, [-1,-1], piece, opp_piece) # SW
84
+ pieces_to_change << check_direction(c, [-1, 0], piece, opp_piece) # W
85
+ pieces_to_change << check_direction(c, [-1, 1], piece, opp_piece) # NW
86
+ raise "You must move to a spot that will turn your opponent's piece." if pieces_to_change.compact.all? { |a| a.empty? }
87
+ pieces_to_change.compact.each { |direction| direction.each { |i| @board[i[0]][i[1]] = piece } }
88
+ end
89
+ current_player.pieces -= 1
90
+ @board[c[0]][c[1]] = piece
91
+ current_winner = calculate_current_winner
92
+ raise "Game over. Player #{current_winner.piece} wins with #{current_winner.pieces_on_board} pieces!" if @p1.pieces + @p2.pieces == 0
93
+ end
94
+
95
+ def skip_turn?
96
+ possibles = []
97
+ @board.each_with_index { |col,col_index|
98
+ col.each_with_index { |cell,row_index|
99
+ return false if possible_move?([col_index,row_index])
100
+ }
101
+ }
102
+ true
103
+ end
104
+
105
+ def possible_move?(c=[0,0])
106
+ return nil if board_at(c) != 0
107
+ possible_moves = []
108
+ piece = current_player.piece
109
+ opp_piece = current_player.opp_piece
110
+ pieces_to_change = []
111
+ pieces_to_change << check_direction(c, [ 0, 1], piece, opp_piece) # N
112
+ pieces_to_change << check_direction(c, [ 1, 1], piece, opp_piece) # NE
113
+ pieces_to_change << check_direction(c, [ 1, 0], piece, opp_piece) # E
114
+ pieces_to_change << check_direction(c, [ 1,-1], piece, opp_piece) # SE
115
+ pieces_to_change << check_direction(c, [ 0,-1], piece, opp_piece) # S
116
+ pieces_to_change << check_direction(c, [-1,-1], piece, opp_piece) # SW
117
+ pieces_to_change << check_direction(c, [-1, 0], piece, opp_piece) # W
118
+ pieces_to_change << check_direction(c, [-1, 1], piece, opp_piece) # NW
119
+ return nil if pieces_to_change.compact.all? { |a| a.empty? }
120
+ true
121
+ end
122
+
123
+ def memorize_board
124
+ dup_board = new_board
125
+ dup_board = []
126
+ @board.each do |col|
127
+ dup_board << col.dup
128
+ end
129
+ @board_history << { :player => current_player, :board => dup_board }
130
+ end
131
+
132
+ def undo!
133
+ last_move = @board_history.pop
134
+ @board = last_move[:board]
135
+ @current_player = last_move[:player]
136
+ @current_player.pieces += 1
137
+ end
138
+
139
+ def calculate_current_winner
140
+ @p1.pieces_on_board, @p2.pieces_on_board = 0, 0
141
+ @board.each { |row|
142
+ row.each { |cell|
143
+ if cell == 1
144
+ @p1.pieces_on_board += 1
145
+ else
146
+ @p2.pieces_on_board += 1
147
+ end
148
+ }
149
+ }
150
+ @p1.pieces_on_board > @p2.pieces_on_board ? @p1 : @p2
151
+ end
152
+
153
+ def check_direction(c, dir, piece, opp_piece)
154
+ c_adjacent = next_in_direction(c.dup, dir)
155
+ c_last = nil
156
+ pieces_in_between = []
157
+ # Find the last piece if there is one.
158
+ while(valid_location?(c_adjacent))
159
+ if board_at(c_adjacent) == opp_piece
160
+ pieces_in_between << c_adjacent.dup
161
+ elsif board_at(c_adjacent) == piece && pieces_in_between.size > 0
162
+ c_last = c_adjacent
163
+ break
164
+ else
165
+ break
166
+ end
167
+ c_adjacent = next_in_direction(c_adjacent, dir)
168
+ end
169
+
170
+ pieces_in_between.empty? || c_last.nil? ? nil : pieces_in_between
171
+ end
172
+
173
+ # Find the value of the board at the given coordinate.
174
+ def board_at(c)
175
+ @board[c[0]][c[1]]
176
+ end
177
+
178
+ # Is this a valid location on board?
179
+ def valid_location?(c=[1,1])
180
+ c[0] >= 0 && c[1] >= 0 && c[0] < BOARD_SIZE[0] && c[1] < BOARD_SIZE[1]
181
+ end
182
+
183
+ # Perform the operations to get the next spot in the appropriate direction
184
+ def next_in_direction(c, dir)
185
+ c[0] += dir[0]
186
+ c[1] += dir[1]
187
+ c
188
+ end
189
+
190
+ private
191
+ def pieces_per_player
192
+ total_squares / 2
193
+ end
194
+
195
+ # The total number of squares
196
+ def total_squares
197
+ BOARD_SIZE[0] * BOARD_SIZE[1]
198
+ end
199
+
200
+ class Player
201
+ attr_accessor :pieces, :color, :pieces_on_board
202
+
203
+ def initialize(color=:black,pieces=0)
204
+ @pieces = pieces
205
+ @pieces_on_board = 0 # used only in calculating winner
206
+ @color = color
207
+ end
208
+
209
+ def piece
210
+ color == :black ? 1 : 2
211
+ end
212
+
213
+ def opp_piece
214
+ color == :black ? 2 : 1
215
+ end
216
+ end
217
+ end
218
+
219
+ def draw_player_1(first_turn=false)
220
+ stack width: width-5, height: 50 do
221
+ if GAME.current_player==GAME.p1
222
+ background yellow
223
+ border black, strokewidth: 10
224
+ para strong("Player 1 (#{GAME.current_player.color}) turn"), margin: [20, 15, 0, 0]
225
+ else
226
+ background white
227
+ border black, strokewidth: 10
228
+ undo = GAME.board_history.empty? ? nil : link("Undo last move"){ GAME.undo!; draw_board }
229
+ para strong("Player 1"), SPACE, undo, margin: [20, 15, 0, 0]
230
+ end
231
+ end
232
+ end
233
+
234
+ def draw_player_2(first_turn=false)
235
+ stack width: width-5, height: 50 do
236
+ if GAME.current_player==GAME.p2
237
+ background yellow
238
+ border black, strokewidth: 10
239
+ para strong("Player 2 (#{GAME.current_player.color}) turn"), margin: [20, 15, 0, 0]
240
+ else
241
+ background white
242
+ border black, strokewidth: 10
243
+ undo = GAME.board_history.empty? ? nil : link("Undo last move"){ GAME.undo!; draw_board }
244
+ para strong("Player 2"), SPACE, undo, margin: [20, 15, 0, 0]
245
+ end
246
+ end
247
+ end
248
+
249
+
250
+ def draw_board
251
+ clear do
252
+ background black
253
+ draw_player_1
254
+
255
+ stack width: width, height: 500 do
256
+ fill rgb(0, 190, 0)
257
+ #rect :left => 0, :top => 0, :width => 495, :height => 495
258
+
259
+ GAME.board.each_with_index do |col, col_index|
260
+ col.each_with_index do |cell, row_index|
261
+ left, top = left_top_corner_of_piece(col_index, row_index)
262
+ left = left - LEFT_OFFSET + 10
263
+ top = top - TOP_OFFSET + 50
264
+ fill rgb(0, 440, 0, 90)
265
+ strokewidth 1
266
+ stroke rgb(0, 100, 0)
267
+ rect :left => left, :top => top, :width => PIECE_WIDTH, :height => PIECE_HEIGHT
268
+
269
+ if cell != 0
270
+ strokewidth 0
271
+ fill (cell == 1 ? rgb(100,100,100) : rgb(155,155,155))
272
+ oval(left+3, top+4, PIECE_WIDTH-10, PIECE_HEIGHT-10)
273
+
274
+ fill (cell == 1 ? black : white)
275
+ oval(left+5, top+5, PIECE_WIDTH-10, PIECE_HEIGHT-10)
276
+ end
277
+ end
278
+ end
279
+ end
280
+
281
+ draw_player_2
282
+ end
283
+ end
284
+
285
+ def left_top_corner_of_piece(a,b)
286
+ [(a*PIECE_WIDTH+LEFT_OFFSET), (b*PIECE_HEIGHT+TOP_OFFSET)]
287
+ end
288
+
289
+ def right_bottom_corner_of_piece(a,b)
290
+ left_top_corner_of_piece(a,b).map { |coord| coord + PIECE_WIDTH }
291
+ end
292
+
293
+ def find_piece(x,y)
294
+ GAME.board.each_with_index { |row_array, row|
295
+ row_array.each_with_index { |col_array, col|
296
+ left, top = left_top_corner_of_piece(col, row).map { |i| i - 5}
297
+ right, bottom = right_bottom_corner_of_piece(col, row).map { |i| i -5 }
298
+ return [col, row] if x >= left && x <= right && y >= top && y <= bottom
299
+ }
300
+ }
301
+ return false
302
+ end
303
+ end
304
+
305
+
306
+ Shoes.app :width => 520, :height => 600 do
307
+ extend Othello
308
+ GAME = Othello::Game.new
309
+
310
+ draw_board
311
+
312
+ click { |button, x, y|
313
+ if coords = find_piece(x,y)
314
+ begin
315
+ GAME.lay_piece(coords)
316
+ GAME.next_turn
317
+ draw_board
318
+ rescue => e
319
+ draw_board
320
+ alert(e.message)
321
+ end
322
+ else
323
+ # alert("Not a piece.")
324
+ end
325
+ }
326
+ end
Binary file
@@ -77,7 +77,7 @@ We'll talk through all the steps.
77
77
 
78
78
  At first, install Ruby. On '''Windows''',
79
79
  visit the site of [[http://rubyinstaller.org/ RubyInstaller for Windows]] to
80
- download '''RubyInstaller 1.9.2-p136'''.
80
+ download the latest '''RubyInstaller 1.9.2'''.
81
81
 
82
82
  Then just do the following one line.
83
83
 
@@ -101,8 +101,8 @@ Here are a few ways to create a blank text file:
101
101
  Now, in your blank window, type in the following:
102
102
 
103
103
  {{{
104
+ require 'green_shoes'
104
105
  Shoes.app do
105
- background "#DFA"
106
106
  para "Welcome to Shoes"
107
107
  end
108
108
  }}}
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 198
7
+ - 201
8
8
  - 0
9
- version: 0.198.0
9
+ version: 0.201.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - ashbb
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-03-26 00:00:00 +09:00
17
+ date: 2011-04-04 00:00:00 +09:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -194,6 +194,7 @@ files:
194
194
  - samples/sample48.rb
195
195
  - samples/sample49.rb
196
196
  - samples/sample5.rb
197
+ - samples/sample50.rb
197
198
  - samples/sample6.rb
198
199
  - samples/sample7.rb
199
200
  - samples/sample8.rb
@@ -250,6 +251,7 @@ files:
250
251
  - snapshots/sample48.png
251
252
  - snapshots/sample49.png
252
253
  - snapshots/sample5.png
254
+ - snapshots/sample50.png
253
255
  - snapshots/sample6.png
254
256
  - snapshots/sample7.png
255
257
  - snapshots/sample8.png