shoes 4.0.0.pre2 → 4.0.0.pre3
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/README.md +32 -21
- metadata +18 -337
- data/CHANGELOG +0 -84
- data/Gemfile +0 -24
- data/Guardfile +0 -11
- data/Rakefile +0 -14
- data/app.yaml +0 -60
- data/benchmark/app_clear.rb +0 -21
- data/benchmark/clear.rb +0 -69
- data/benchmark/memory/text_dispose.rb +0 -9
- data/benchmark/para_creator.rb +0 -9
- data/benchmark/paras.rb +0 -52
- data/benchmark/urls.rb +0 -40
- data/bin/ruby-shoes +0 -6
- data/bin/shoes-guard +0 -8
- data/bin/shoes-stub +0 -59
- data/ext/install/Rakefile +0 -29
- data/ext/install/shoes.bat +0 -9
- data/lib/shoes.rb +0 -5
- data/lib/shoes/ui/cli.rb +0 -102
- data/lib/shoes/ui/help.rb +0 -535
- data/lib/shoes/ui/manual.rb +0 -6
- data/lib/shoes/version.rb +0 -3
- data/manifests/common.rb +0 -34
- data/manifests/shoes.rb +0 -44
- data/samples/Gemfile +0 -3
- data/samples/Gemfile.lock +0 -35
- data/samples/README +0 -97
- data/samples/boom.rb +0 -239
- data/samples/class-book-adjusted.rb +0 -45
- data/samples/class-book.rb +0 -43
- data/samples/class-book.yaml +0 -387
- data/samples/clicky.rb +0 -24
- data/samples/cy.png +0 -0
- data/samples/expert-definr.rb +0 -23
- data/samples/expert-funnies.rb +0 -60
- data/samples/expert-game-of-life-adjusted.rb +0 -249
- data/samples/expert-game-of-life.rb +0 -243
- data/samples/expert-irb-adjusted.rb +0 -110
- data/samples/expert-irb.rb +0 -112
- data/samples/expert-minesweeper-adjusted.rb +0 -272
- data/samples/expert-minesweeper.rb +0 -267
- data/samples/expert-othello-adjusted.rb +0 -325
- data/samples/expert-othello.rb +0 -318
- data/samples/expert-pong.rb +0 -62
- data/samples/expert-snake.rb +0 -78
- data/samples/expert-tankspank.rb +0 -385
- data/samples/flow.rb +0 -63
- data/samples/good-arc.rb +0 -45
- data/samples/good-clock.rb +0 -51
- data/samples/good-displace.rb +0 -98
- data/samples/good-follow.rb +0 -26
- data/samples/good-potato-chopping.rb +0 -22
- data/samples/good-reminder.rb +0 -174
- data/samples/good-vjot.rb +0 -58
- data/samples/gray.rb +0 -11
- data/samples/loogink.png +0 -0
- data/samples/nks_booklist.rb +0 -24
- data/samples/nks_breadsticks.rb +0 -7
- data/samples/nks_dancing_circle.rb +0 -13
- data/samples/nks_dictionary.rb +0 -23
- data/samples/nks_edit_box.rb +0 -4
- data/samples/nks_edit_line.rb +0 -6
- data/samples/nks_notes.rb +0 -16
- data/samples/nks_poem.rb +0 -22
- data/samples/nks_self.rb +0 -6
- data/samples/nks_text_sizes.rb +0 -10
- data/samples/nks_trurl.rb +0 -5
- data/samples/original-manual-adjusted.rb +0 -475
- data/samples/original-manual.rb +0 -472
- data/samples/packaging/package_me.rb +0 -6
- data/samples/potato_chopping/1258_s001.gif +0 -0
- data/samples/potato_chopping/1258_s002.gif +0 -0
- data/samples/potato_chopping/1258_s003.gif +0 -0
- data/samples/potato_chopping/1258_s004.gif +0 -0
- data/samples/potato_chopping/1258_s005.gif +0 -0
- data/samples/potato_chopping/1258_s006.gif +0 -0
- data/samples/potato_chopping/1258_s007.gif +0 -0
- data/samples/potato_chopping/1258_s008.gif +0 -0
- data/samples/potato_chopping/1258_s009.gif +0 -0
- data/samples/potato_chopping/1258_s010.gif +0 -0
- data/samples/potato_chopping/1258_s011.gif +0 -0
- data/samples/potato_chopping/1258_s012.gif +0 -0
- data/samples/potato_chopping/1258_s013.gif +0 -0
- data/samples/potato_chopping/1258_s014.gif +0 -0
- data/samples/potato_chopping/1258_s015.gif +0 -0
- data/samples/potato_chopping/1258_s016.gif +0 -0
- data/samples/potato_chopping/1258_s017.gif +0 -0
- data/samples/potato_chopping/1258_s018.gif +0 -0
- data/samples/potato_chopping/1258_s019.gif +0 -0
- data/samples/potato_chopping/1258_s020.gif +0 -0
- data/samples/potato_chopping/1258_s021.gif +0 -0
- data/samples/potato_chopping/1258_s022.gif +0 -0
- data/samples/potato_chopping/1258_s023.gif +0 -0
- data/samples/potato_chopping/1258_s024.gif +0 -0
- data/samples/potato_chopping/1258_s025.gif +0 -0
- data/samples/potato_chopping/1258_s026.gif +0 -0
- data/samples/potato_chopping/1258_s027.gif +0 -0
- data/samples/potato_chopping/1258_s028.gif +0 -0
- data/samples/potato_chopping/1258_s029.gif +0 -0
- data/samples/potato_chopping/1258_s030.gif +0 -0
- data/samples/potato_chopping/1258_s031.gif +0 -0
- data/samples/potato_chopping/1258_s032.gif +0 -0
- data/samples/potato_chopping/1258_s033.gif +0 -0
- data/samples/potato_chopping/1258_s034.gif +0 -0
- data/samples/potato_chopping/1258_s035.gif +0 -0
- data/samples/potato_chopping/1258_s036.gif +0 -0
- data/samples/potato_chopping/1258_s037.gif +0 -0
- data/samples/potato_chopping/1258_s038.gif +0 -0
- data/samples/potato_chopping/1258_s039.gif +0 -0
- data/samples/potato_chopping/1258_s040.gif +0 -0
- data/samples/potato_chopping/1258_s041.gif +0 -0
- data/samples/potato_chopping/1258_s042.gif +0 -0
- data/samples/potato_chopping/1258_s043.gif +0 -0
- data/samples/potato_chopping/1258_s044.gif +0 -0
- data/samples/potato_chopping/1258_s045.gif +0 -0
- data/samples/potato_chopping/1258_s046.gif +0 -0
- data/samples/potato_chopping/1258_s047.gif +0 -0
- data/samples/potato_chopping/1258_s048.gif +0 -0
- data/samples/potato_chopping/1258_s049.gif +0 -0
- data/samples/potato_chopping/1258_s050.gif +0 -0
- data/samples/potato_chopping/1258_s051.gif +0 -0
- data/samples/potato_chopping/1258_s052.gif +0 -0
- data/samples/potato_chopping/1258_s053.gif +0 -0
- data/samples/potato_chopping/1258_s054.gif +0 -0
- data/samples/potato_chopping/1258_s055.gif +0 -0
- data/samples/potato_chopping/1258_s056.gif +0 -0
- data/samples/potato_chopping/1258_s057.gif +0 -0
- data/samples/potato_chopping/1258_s058.gif +0 -0
- data/samples/potato_chopping/1258_s059.gif +0 -0
- data/samples/present.rb +0 -27
- data/samples/progress.rb +0 -10
- data/samples/sample1.rb +0 -30
- data/samples/sample12.rb +0 -21
- data/samples/sample13.rb +0 -13
- data/samples/sample14.rb +0 -64
- data/samples/sample15.rb +0 -18
- data/samples/sample16.rb +0 -10
- data/samples/sample17.rb +0 -10
- data/samples/sample2.rb +0 -14
- data/samples/sample21.rb +0 -5
- data/samples/sample23.rb +0 -8
- data/samples/sample24.rb +0 -21
- data/samples/sample27.rb +0 -18
- data/samples/sample3.rb +0 -14
- data/samples/sample31.rb +0 -22
- data/samples/sample34.rb +0 -27
- data/samples/sample35.rb +0 -32
- data/samples/sample37.rb +0 -8
- data/samples/sample4.rb +0 -7
- data/samples/sample42.rb +0 -14
- data/samples/sample45.rb +0 -11
- data/samples/sample56.rb +0 -10
- data/samples/sample6.rb +0 -9
- data/samples/sample7.rb +0 -3
- data/samples/sample8.rb +0 -7
- data/samples/sample9.rb +0 -10
- data/samples/simple-accordion.rb +0 -75
- data/samples/simple-anim-shapes.rb +0 -17
- data/samples/simple-anim-text.rb +0 -13
- data/samples/simple-animate.rb +0 -12
- data/samples/simple-arc.rb +0 -23
- data/samples/simple-bounce.rb +0 -24
- data/samples/simple-brightness-transitions.rb +0 -8
- data/samples/simple-button-animate.rb +0 -16
- data/samples/simple-calc-2.rb +0 -34
- data/samples/simple-calc.rb +0 -70
- data/samples/simple-color-selector.rb +0 -10
- data/samples/simple-color-transitions.rb +0 -11
- data/samples/simple-control-sizes.rb +0 -24
- data/samples/simple-curve.rb +0 -26
- data/samples/simple-dialogs-outside.rb +0 -12
- data/samples/simple-dialogs.rb +0 -32
- data/samples/simple-displace.rb +0 -15
- data/samples/simple-downloader.rb +0 -27
- data/samples/simple-draw.rb +0 -13
- data/samples/simple-editor.rb +0 -28
- data/samples/simple-face.rb +0 -14
- data/samples/simple-flow-wrap.rb +0 -11
- data/samples/simple-font.rb +0 -17
- data/samples/simple-form.rb +0 -29
- data/samples/simple-form.shy +0 -0
- data/samples/simple-fullscreen.rb +0 -4
- data/samples/simple-guess-game.rb +0 -28
- data/samples/simple-keypress.rb +0 -14
- data/samples/simple-manual.rb +0 -2
- data/samples/simple-mask.rb +0 -21
- data/samples/simple-menu.rb +0 -47
- data/samples/simple-mouse-follow.rb +0 -8
- data/samples/simple-move.rb +0 -13
- data/samples/simple-oval.rb +0 -3
- data/samples/simple-sample-executor.rb +0 -6
- data/samples/simple-shoes-intro.rb +0 -22
- data/samples/simple-slide.rb +0 -56
- data/samples/simple-sound.rb +0 -30
- data/samples/simple-sphere.rb +0 -28
- data/samples/simple-stripes.rb +0 -8
- data/samples/simple-tictactoe.rb +0 -238
- data/samples/simple-timer.rb +0 -15
- data/samples/simple-video.rb +0 -13
- data/samples/simple-visibility.rb +0 -11
- data/samples/simple-widget.rb +0 -9
- data/samples/sounds/102719__sarge4267__explosion.mp3 +0 -0
- data/samples/sounds/145622__andybrannan__train-fog-horn-long-wyomming.aiff +0 -0
- data/samples/sounds/46492__phreaksaccount__shields1.ogg +0 -0
- data/samples/sounds/61847__simon-rue__boink-v3.wav +0 -0
- data/samples/swt-raw.rb +0 -20
- data/samples/troll.rb +0 -22
- data/shoes.gemspec +0 -29
- data/snapshots/sample1.png +0 -0
- data/snapshots/sample10.png +0 -0
- data/snapshots/sample11.png +0 -0
- data/snapshots/sample12.png +0 -0
- data/snapshots/sample13.png +0 -0
- data/snapshots/sample14.png +0 -0
- data/snapshots/sample15.png +0 -0
- data/snapshots/sample16.png +0 -0
- data/snapshots/sample17.png +0 -0
- data/snapshots/sample18.png +0 -0
- data/snapshots/sample19.png +0 -0
- data/snapshots/sample2.png +0 -0
- data/snapshots/sample20.png +0 -0
- data/snapshots/sample21.png +0 -0
- data/snapshots/sample22.png +0 -0
- data/snapshots/sample23.png +0 -0
- data/snapshots/sample24.png +0 -0
- data/snapshots/sample27.png +0 -0
- data/snapshots/sample28.png +0 -0
- data/snapshots/sample29.png +0 -0
- data/snapshots/sample3.png +0 -0
- data/snapshots/sample30.png +0 -0
- data/snapshots/sample31.png +0 -0
- data/snapshots/sample34.png +0 -0
- data/snapshots/sample35.png +0 -0
- data/snapshots/sample36.png +0 -0
- data/snapshots/sample37.png +0 -0
- data/snapshots/sample4.png +0 -0
- data/snapshots/sample42.png +0 -0
- data/snapshots/sample44.png +0 -0
- data/snapshots/sample45.png +0 -0
- data/snapshots/sample46.png +0 -0
- data/snapshots/sample5.png +0 -0
- data/snapshots/sample56.png +0 -0
- data/snapshots/sample6.png +0 -0
- data/snapshots/sample7.png +0 -0
- data/snapshots/sample8.png +0 -0
- data/snapshots/sample9.png +0 -0
- data/snapshots/sample99.png +0 -0
- data/static/PKGBUILD +0 -47
- data/static/Shoes.icns +0 -0
- data/static/avatar.png +0 -0
- data/static/code_highlighter.js +0 -188
- data/static/code_highlighter_ruby.js +0 -26
- data/static/downloading.png +0 -0
- data/static/icon-debug.png +0 -0
- data/static/icon-error.png +0 -0
- data/static/icon-info.png +0 -0
- data/static/icon-warn.png +0 -0
- data/static/listbox_button1.png +0 -0
- data/static/listbox_button2.png +0 -0
- data/static/man-app.png +0 -0
- data/static/man-builds.png +0 -0
- data/static/man-builds1.png +0 -0
- data/static/man-editor-notepad.png +0 -0
- data/static/man-editor-osx.png +0 -0
- data/static/man-ele-background.png +0 -0
- data/static/man-ele-border.png +0 -0
- data/static/man-ele-button.png +0 -0
- data/static/man-ele-check.png +0 -0
- data/static/man-ele-editbox.png +0 -0
- data/static/man-ele-editline.png +0 -0
- data/static/man-ele-image.png +0 -0
- data/static/man-ele-listbox.png +0 -0
- data/static/man-ele-progress.png +0 -0
- data/static/man-ele-radio.png +0 -0
- data/static/man-ele-shape.png +0 -0
- data/static/man-ele-textblock.png +0 -0
- data/static/man-ele-video.png +0 -0
- data/static/man-intro-dmg.png +0 -0
- data/static/man-intro-exe.png +0 -0
- data/static/man-look-tiger.png +0 -0
- data/static/man-look-ubuntu.png +0 -0
- data/static/man-look-vista.png +0 -0
- data/static/man-run-osx.png +0 -0
- data/static/man-run-vista.png +0 -0
- data/static/man-run-xp.png +0 -0
- data/static/man-shot1.png +0 -0
- data/static/manual-en.txt +0 -3531
- data/static/manual-ja.txt +0 -2829
- data/static/manual.css +0 -184
- data/static/menu-corner1.png +0 -0
- data/static/menu-corner2.png +0 -0
- data/static/menu-gray.png +0 -0
- data/static/menu-left.png +0 -0
- data/static/menu-right.png +0 -0
- data/static/menu-top.png +0 -0
- data/static/shoes-dmg.jpg +0 -0
- data/static/shoes-icon-blue.png +0 -0
- data/static/shoes-icon-brown.png +0 -0
- data/static/shoes-icon.png +0 -0
- data/static/shoes-manual-apps.gif +0 -0
- data/static/shoes-manual-apps.png +0 -0
- data/static/shoes_main_window.png +0 -0
- data/static/stripe.png +0 -0
- data/static/tutor-back.png +0 -0
- data/tasks/changelog.rb +0 -92
- data/tasks/gem.rb +0 -38
- data/tasks/rspec.rb +0 -106
- data/tasks/sample.rb +0 -66
- data/tasks/yard.rb +0 -13
data/samples/expert-othello.rb
DELETED
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
# Othello
|
|
2
|
-
# by tieg
|
|
3
|
-
# 1/13/08
|
|
4
|
-
# with help: DeeJay, Ryan M. from mailing list
|
|
5
|
-
#
|
|
6
|
-
# FIXME bug if it memorizes it but it's not a valid move
|
|
7
|
-
#
|
|
8
|
-
module Othello
|
|
9
|
-
|
|
10
|
-
PIECE_WIDTH = 62
|
|
11
|
-
PIECE_HEIGHT = 62
|
|
12
|
-
TOP_OFFSET = 47
|
|
13
|
-
LEFT_OFFSET = 12
|
|
14
|
-
|
|
15
|
-
class Game
|
|
16
|
-
BOARD_SIZE = [8,8]
|
|
17
|
-
|
|
18
|
-
attr_accessor :p1, :p2, :board, :board_history
|
|
19
|
-
|
|
20
|
-
def initialize
|
|
21
|
-
@board_history = []
|
|
22
|
-
@p1 = Player.new(:black, pieces_per_player)
|
|
23
|
-
@p2 = Player.new(:white, pieces_per_player)
|
|
24
|
-
@board = new_board
|
|
25
|
-
lay_initial_pieces
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def next_turn(check_available_moves=true)
|
|
29
|
-
@current_player = next_player
|
|
30
|
-
if check_available_moves && skip_turn?
|
|
31
|
-
# FIXME Possible infinite loop if neither player has a good move?
|
|
32
|
-
next_turn
|
|
33
|
-
raise "Player #{@current_player.piece} (#{@current_player.color}) has no available moves. Player #{next_player.piece}'s (#{next_player.color}) turn."
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def current_player
|
|
38
|
-
@current_player ||= @p1
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def next_player
|
|
42
|
-
current_player == @p1 ? @p2 : @p1
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Build the array for the board, with zero-based arrays.
|
|
46
|
-
def new_board
|
|
47
|
-
Array.new(BOARD_SIZE[0]) do # build each cols L to R
|
|
48
|
-
Array.new(BOARD_SIZE[1]) do # insert cells in each col
|
|
49
|
-
0
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Lay the initial 4 pieces in the middle
|
|
55
|
-
def lay_initial_pieces
|
|
56
|
-
lay_piece([4, 3], false)
|
|
57
|
-
next_turn(false)
|
|
58
|
-
lay_piece([3, 3], false)
|
|
59
|
-
next_turn(false)
|
|
60
|
-
lay_piece([3, 4], false)
|
|
61
|
-
next_turn(false)
|
|
62
|
-
lay_piece([4, 4], false)
|
|
63
|
-
next_turn(false)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def lay_piece(c=[0,0], check_adjacent_pieces=true)
|
|
67
|
-
memorize_board
|
|
68
|
-
piece = current_player.piece
|
|
69
|
-
opp_piece = current_player.opp_piece
|
|
70
|
-
raise "Spot already taken." if board_at(c) != 0
|
|
71
|
-
if check_adjacent_pieces
|
|
72
|
-
pieces_to_change = []
|
|
73
|
-
pieces_to_change << check_direction(c, [ 0, 1], piece, opp_piece) # N
|
|
74
|
-
pieces_to_change << check_direction(c, [ 1, 1], piece, opp_piece) # NE
|
|
75
|
-
pieces_to_change << check_direction(c, [ 1, 0], piece, opp_piece) # E
|
|
76
|
-
pieces_to_change << check_direction(c, [ 1,-1], piece, opp_piece) # SE
|
|
77
|
-
pieces_to_change << check_direction(c, [ 0,-1], piece, opp_piece) # S
|
|
78
|
-
pieces_to_change << check_direction(c, [-1,-1], piece, opp_piece) # SW
|
|
79
|
-
pieces_to_change << check_direction(c, [-1, 0], piece, opp_piece) # W
|
|
80
|
-
pieces_to_change << check_direction(c, [-1, 1], piece, opp_piece) # NW
|
|
81
|
-
raise "You must move to a spot that will turn your opponent's piece." if pieces_to_change.compact.all? { |a| a.empty? }
|
|
82
|
-
pieces_to_change.compact.each { |direction| direction.each { |i| @board[i[0]][i[1]] = piece } }
|
|
83
|
-
end
|
|
84
|
-
current_player.pieces -= 1
|
|
85
|
-
@board[c[0]][c[1]] = piece
|
|
86
|
-
current_winner = calculate_current_winner
|
|
87
|
-
raise "Game over. Player #{current_winner.piece} wins with #{current_winner.pieces_on_board} pieces!" if @p1.pieces + @p2.pieces == 0
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def skip_turn?
|
|
91
|
-
possibles = []
|
|
92
|
-
@board.each_with_index { |col,col_index|
|
|
93
|
-
col.each_with_index { |cell,row_index|
|
|
94
|
-
return false if possible_move?([col_index,row_index])
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
true
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def possible_move?(c=[0,0])
|
|
101
|
-
return nil if board_at(c) != 0
|
|
102
|
-
possible_moves = []
|
|
103
|
-
piece = current_player.piece
|
|
104
|
-
opp_piece = current_player.opp_piece
|
|
105
|
-
pieces_to_change = []
|
|
106
|
-
pieces_to_change << check_direction(c, [ 0, 1], piece, opp_piece) # N
|
|
107
|
-
pieces_to_change << check_direction(c, [ 1, 1], piece, opp_piece) # NE
|
|
108
|
-
pieces_to_change << check_direction(c, [ 1, 0], piece, opp_piece) # E
|
|
109
|
-
pieces_to_change << check_direction(c, [ 1,-1], piece, opp_piece) # SE
|
|
110
|
-
pieces_to_change << check_direction(c, [ 0,-1], piece, opp_piece) # S
|
|
111
|
-
pieces_to_change << check_direction(c, [-1,-1], piece, opp_piece) # SW
|
|
112
|
-
pieces_to_change << check_direction(c, [-1, 0], piece, opp_piece) # W
|
|
113
|
-
pieces_to_change << check_direction(c, [-1, 1], piece, opp_piece) # NW
|
|
114
|
-
return nil if pieces_to_change.compact.all? { |a| a.empty? }
|
|
115
|
-
true
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def memorize_board
|
|
119
|
-
dup_board = new_board
|
|
120
|
-
dup_board = []
|
|
121
|
-
@board.each do |col|
|
|
122
|
-
dup_board << col.dup
|
|
123
|
-
end
|
|
124
|
-
@board_history << { player: current_player, board: dup_board }
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def undo!
|
|
128
|
-
last_move = @board_history.pop
|
|
129
|
-
@board = last_move[:board]
|
|
130
|
-
@current_player = last_move[:player]
|
|
131
|
-
@current_player.pieces += 1
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def calculate_current_winner
|
|
135
|
-
@p1.pieces_on_board, @p2.pieces_on_board = 0, 0
|
|
136
|
-
@board.each { |row|
|
|
137
|
-
row.each { |cell|
|
|
138
|
-
if cell == 1
|
|
139
|
-
@p1.pieces_on_board += 1
|
|
140
|
-
else
|
|
141
|
-
@p2.pieces_on_board += 1
|
|
142
|
-
end
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
@p1.pieces_on_board > @p2.pieces_on_board ? @p1 : @p2
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def check_direction(c, dir, piece, opp_piece)
|
|
149
|
-
c_adjacent = next_in_direction(c.dup, dir)
|
|
150
|
-
c_last = nil
|
|
151
|
-
pieces_in_between = []
|
|
152
|
-
# Find the last piece if there is one.
|
|
153
|
-
while(valid_location?(c_adjacent))
|
|
154
|
-
if board_at(c_adjacent) == opp_piece
|
|
155
|
-
pieces_in_between << c_adjacent.dup
|
|
156
|
-
elsif board_at(c_adjacent) == piece && pieces_in_between.size > 0
|
|
157
|
-
c_last = c_adjacent
|
|
158
|
-
break
|
|
159
|
-
else
|
|
160
|
-
break
|
|
161
|
-
end
|
|
162
|
-
c_adjacent = next_in_direction(c_adjacent, dir)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
pieces_in_between.empty? || c_last.nil? ? nil : pieces_in_between
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
# Find the value of the board at the given coordinate.
|
|
169
|
-
def board_at(c)
|
|
170
|
-
@board[c[0]][c[1]]
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Is this a valid location on board?
|
|
174
|
-
def valid_location?(c=[1,1])
|
|
175
|
-
c[0] >= 0 && c[1] >= 0 && c[0] < BOARD_SIZE[0] && c[1] < BOARD_SIZE[1]
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
# Perform the operations to get the next spot in the appropriate direction
|
|
179
|
-
def next_in_direction(c, dir)
|
|
180
|
-
c[0] += dir[0]
|
|
181
|
-
c[1] += dir[1]
|
|
182
|
-
c
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
private
|
|
186
|
-
def pieces_per_player
|
|
187
|
-
total_squares / 2
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# The total number of squares
|
|
191
|
-
def total_squares
|
|
192
|
-
BOARD_SIZE[0] * BOARD_SIZE[1]
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
class Player
|
|
196
|
-
attr_accessor :pieces, :color, :pieces_on_board
|
|
197
|
-
|
|
198
|
-
def initialize(color=:black,pieces=0)
|
|
199
|
-
@pieces = pieces
|
|
200
|
-
@pieces_on_board = 0 # used only in calculating winner
|
|
201
|
-
@color = color
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
def piece
|
|
205
|
-
color == :black ? 1 : 2
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
def opp_piece
|
|
209
|
-
color == :black ? 2 : 1
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def draw_player_1(first_turn=false)
|
|
215
|
-
stack margin: 10 do
|
|
216
|
-
if GAME.current_player==GAME.p1
|
|
217
|
-
background yellow
|
|
218
|
-
para span("Player 1 (#{GAME.current_player.color}) turn", stroke: black, font: "Trebuchet 20px bold"), margin: 4
|
|
219
|
-
else
|
|
220
|
-
background white
|
|
221
|
-
para span("Player 1", stroke: black, font: "Trebuchet 10px bold"), margin: 4
|
|
222
|
-
|
|
223
|
-
button("Undo last move", top: 0, left: -150) { GAME.undo!; draw_board } unless GAME.board_history.empty?
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def draw_player_2(first_turn=false)
|
|
229
|
-
stack top: 550, left: 0, margin: 10 do
|
|
230
|
-
if GAME.current_player==GAME.p2
|
|
231
|
-
background yellow
|
|
232
|
-
para span("Player 2's (#{GAME.current_player.color}) turn", stroke: black, font: "Trebuchet 20px bold"), margin: 4
|
|
233
|
-
else
|
|
234
|
-
background white
|
|
235
|
-
para span("Player 2", stroke: black, font: "Trebuchet 10px bold"), margin: 4
|
|
236
|
-
|
|
237
|
-
button("Undo last move", top: 0, left: -150) { GAME.undo!; draw_board } unless GAME.board_history.empty?
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
def draw_board
|
|
244
|
-
clear do
|
|
245
|
-
background black
|
|
246
|
-
draw_player_1
|
|
247
|
-
stack margin: 10 do
|
|
248
|
-
fill rgb(0, 190, 0)
|
|
249
|
-
rect left: 0, top: 0, width: 495, height: 495
|
|
250
|
-
|
|
251
|
-
GAME.board.each_with_index do |col, col_index|
|
|
252
|
-
col.each_with_index do |cell, row_index|
|
|
253
|
-
left, top = left_top_corner_of_piece(col_index, row_index)
|
|
254
|
-
left = left - LEFT_OFFSET
|
|
255
|
-
top = top - TOP_OFFSET
|
|
256
|
-
fill rgb(0, 440, 0, 90)
|
|
257
|
-
strokewidth 1
|
|
258
|
-
stroke rgb(0, 100, 0)
|
|
259
|
-
rect left: left, top: top, width: PIECE_WIDTH, height: PIECE_HEIGHT
|
|
260
|
-
|
|
261
|
-
if cell != 0
|
|
262
|
-
strokewidth 0
|
|
263
|
-
fill (cell == 1 ? rgb(100,100,100) : rgb(155,155,155))
|
|
264
|
-
oval(left+3, top+4, PIECE_WIDTH-10, PIECE_HEIGHT-10)
|
|
265
|
-
|
|
266
|
-
fill (cell == 1 ? black : white)
|
|
267
|
-
oval(left+5, top+5, PIECE_WIDTH-10, PIECE_HEIGHT-10)
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
draw_player_2
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
def left_top_corner_of_piece(a,b)
|
|
277
|
-
[(a*PIECE_WIDTH+LEFT_OFFSET), (b*PIECE_HEIGHT+TOP_OFFSET)]
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
def right_bottom_corner_of_piece(a,b)
|
|
281
|
-
left_top_corner_of_piece(a,b).map { |coord| coord + PIECE_WIDTH }
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
def find_piece(x,y)
|
|
285
|
-
GAME.board.each_with_index { |row_array, row|
|
|
286
|
-
row_array.each_with_index { |col_array, col|
|
|
287
|
-
left, top = left_top_corner_of_piece(col, row).map { |i| i - 5}
|
|
288
|
-
right, bottom = right_bottom_corner_of_piece(col, row).map { |i| i -5 }
|
|
289
|
-
return [col, row] if x >= left && x <= right && y >= top && y <= bottom
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
return false
|
|
293
|
-
end
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
GAME = Othello::Game.new
|
|
297
|
-
|
|
298
|
-
Shoes.app width: 520, height: 600 do
|
|
299
|
-
extend Othello
|
|
300
|
-
|
|
301
|
-
draw_board
|
|
302
|
-
|
|
303
|
-
click { |button, x, y|
|
|
304
|
-
if coords = find_piece(x,y)
|
|
305
|
-
begin
|
|
306
|
-
GAME.lay_piece(coords)
|
|
307
|
-
GAME.next_turn
|
|
308
|
-
draw_board
|
|
309
|
-
rescue => e
|
|
310
|
-
draw_board
|
|
311
|
-
alert(e.message)
|
|
312
|
-
end
|
|
313
|
-
else
|
|
314
|
-
# alert("Not a piece.")
|
|
315
|
-
end
|
|
316
|
-
}
|
|
317
|
-
end
|
|
318
|
-
|
data/samples/expert-pong.rb
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Pong in Shoes
|
|
3
|
-
# a clone of http://billmill.org/pong.html
|
|
4
|
-
# and shoes is at http://shoooes.net
|
|
5
|
-
#
|
|
6
|
-
# This is just for kicks -- I'm very fond of NodeBox as well.
|
|
7
|
-
#
|
|
8
|
-
# There's a slightly different approach in Shoes: rather than
|
|
9
|
-
# redrawing the shapes, you can move the shapes around as objects.
|
|
10
|
-
# Yeah, see, notice how @you, @comp and @ball are used.
|
|
11
|
-
#
|
|
12
|
-
Shoes.app width: 400, height: 400, resizable: false do
|
|
13
|
-
paddle_size = 75
|
|
14
|
-
ball_diameter = 20
|
|
15
|
-
vx, vy = [3, 4]
|
|
16
|
-
compuspeed = 10
|
|
17
|
-
bounce = 1.2
|
|
18
|
-
|
|
19
|
-
# set up the playing board
|
|
20
|
-
nostroke and background white
|
|
21
|
-
@ball = oval 0, 0, ball_diameter, fill: "#9B7"
|
|
22
|
-
@you, @comp = [app.height-4, 0].map {|y| rect 0, y, paddle_size, 4, curve: 2}
|
|
23
|
-
|
|
24
|
-
# animates at 40 frames per second
|
|
25
|
-
@anim = animate 40 do
|
|
26
|
-
|
|
27
|
-
# check for game over
|
|
28
|
-
if @ball.top + ball_diameter < 0 or @ball.top > app.height
|
|
29
|
-
para strong("GAME OVER", size: 32), "\n",
|
|
30
|
-
@ball.top < 0 ? "You win!" : "Computer wins", top: 140, align: 'center'
|
|
31
|
-
@ball.hide and @anim.stop
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# move the @you paddle, following the mouse
|
|
35
|
-
@you.left = mouse[1] - (paddle_size / 2)
|
|
36
|
-
nx, ny = (@ball.left + vx).to_i, (@ball.top + vy).to_i
|
|
37
|
-
|
|
38
|
-
# move the @comp paddle, speed based on `compuspeed` variable
|
|
39
|
-
@comp.left +=
|
|
40
|
-
if nx + (ball_diameter / 2) > @comp.left + paddle_size; compuspeed
|
|
41
|
-
elsif nx < @comp.left; -compuspeed
|
|
42
|
-
else 0 end
|
|
43
|
-
|
|
44
|
-
# if the @you paddle hits the ball
|
|
45
|
-
if ny + ball_diameter > app.height and vy > 0 and
|
|
46
|
-
(0..paddle_size).include? nx + (ball_diameter / 2) - @you.left
|
|
47
|
-
vx, vy = (nx - @you.left - (paddle_size / 2)) * 0.25, -vy * bounce
|
|
48
|
-
ny = app.height - ball_diameter
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# if the @comp paddle hits the ball
|
|
52
|
-
if ny < 0 and vy < 0 and
|
|
53
|
-
(0..paddle_size).include? nx + (ball_diameter / 2) - @comp.left
|
|
54
|
-
vx, vy = (nx - @comp.left - (paddle_size / 2)) * 0.25, -vy * bounce
|
|
55
|
-
ny = 0
|
|
56
|
-
elsif nx + ball_diameter > app.width or nx < 0
|
|
57
|
-
vx = -vx
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
@ball.move nx, ny
|
|
61
|
-
end
|
|
62
|
-
end
|
data/samples/expert-snake.rb
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
Shoes.app title: 'Snake Game v0.1' do
|
|
2
|
-
def game_start
|
|
3
|
-
@score = para 'Score:', stroke: white
|
|
4
|
-
@pos = {up: [0, -10], down: [0, 10], left: [-10, 0], right: [10, 0]}
|
|
5
|
-
@rx, @ry = proc{20 + 10*rand(56)}, proc{40 + 10*rand(44)}
|
|
6
|
-
|
|
7
|
-
create_food
|
|
8
|
-
|
|
9
|
-
create_bricks
|
|
10
|
-
|
|
11
|
-
create_initial_snake
|
|
12
|
-
|
|
13
|
-
dir = :left
|
|
14
|
-
@run = animate 5 do
|
|
15
|
-
check_food
|
|
16
|
-
go dir
|
|
17
|
-
@score.text = "Score: #{@snake.length * 10}"
|
|
18
|
-
brick? @snake[0]
|
|
19
|
-
end
|
|
20
|
-
keypress{|k| dir = k if @pos.keys.include? k}
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def go k
|
|
24
|
-
x, y = @pos[k]
|
|
25
|
-
@snake.unshift @snake.pop
|
|
26
|
-
n = @snake.length > 1 ? 1 : 0
|
|
27
|
-
@snake[0].move @snake[n].left + x, @snake[n].top + y
|
|
28
|
-
@snake[0].style stroke: red
|
|
29
|
-
@snake[1].style stroke: white if n > 0
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def check_food
|
|
33
|
-
(@snake << rect(0, 0, 10, 10)) if eat? @snake[0]
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def eat? s
|
|
37
|
-
@foods.each_with_index do |f, i|
|
|
38
|
-
(f.move @rx[], @ry[]; return true) if f.left == s.left and f.top == s.top
|
|
39
|
-
end
|
|
40
|
-
return false
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def brick? s
|
|
44
|
-
@bricks.each do |b|
|
|
45
|
-
(@run.remove; alert 'Game Over. ') if b.left == s.left and b.top == s.top
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def create_food
|
|
50
|
-
@foods = []
|
|
51
|
-
stroke lime
|
|
52
|
-
50.times{@foods << rect(@rx[], @ry[], 10, 10)}
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def create_bricks
|
|
56
|
-
@bricks = []
|
|
57
|
-
stroke deepskyblue; fill blue
|
|
58
|
-
|
|
59
|
-
50.times{@bricks << rect(@rx[], @ry[], 10, 10)}
|
|
60
|
-
|
|
61
|
-
20.step(570, 10){|n| @bricks << rect(n, 40, 10, 10) << rect(n, 470, 10, 10)}
|
|
62
|
-
|
|
63
|
-
40.step(470, 10){|n| @bricks << rect(10, n, 10, 10) << rect(570, n, 10, 10)}
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def create_initial_snake
|
|
67
|
-
@snake = []
|
|
68
|
-
stroke white; nofill
|
|
69
|
-
|
|
70
|
-
@snake << rect(300, 100, 10, 10)
|
|
71
|
-
|
|
72
|
-
@snake[0].style stroke: red
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
background black
|
|
76
|
-
|
|
77
|
-
game_start
|
|
78
|
-
end
|