green_shoes 0.198.0 → 0.201.0

Sign up to get free protection for your applications and to get access to all the features.
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