glimmer-dsl-swt 4.20.13.13 → 4.20.13.17

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.
@@ -0,0 +1,77 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require_relative '../model/grid'
23
+
24
+ require_relative 'cell'
25
+
26
+ class Battleship
27
+ module View
28
+ class Grid
29
+ include Glimmer::UI::CustomWidget
30
+
31
+ options :game, :player
32
+
33
+ body {
34
+ composite {
35
+ grid_layout(Model::Grid::WIDTH + 1, true) {
36
+ margin_width 0
37
+ margin_height 0
38
+ horizontal_spacing 0
39
+ vertical_spacing 0
40
+ }
41
+
42
+ label(:center) {
43
+ layout_data(:fill, :center, true, false) {
44
+ horizontal_span (Model::Grid::WIDTH + 1)
45
+ }
46
+
47
+ text player.to_s.capitalize
48
+ font height: 20, style: :bold
49
+ }
50
+
51
+ label # filler
52
+ Model::Grid::WIDTH.times do |column_index|
53
+ label {
54
+ text (column_index + 1).to_s
55
+ font height: 16
56
+ }
57
+ end
58
+
59
+ Model::Grid::HEIGHT.times do |row_index|
60
+ label {
61
+ text Model::Grid::ROW_ALPHABETS[row_index]
62
+ font height: 16
63
+ }
64
+ Model::Grid::WIDTH.times do |column_index|
65
+ cell(game: game, player: player, row_index: row_index, column_index: column_index) {
66
+ layout_data {
67
+ width_hint 25
68
+ height_hint 25
69
+ }
70
+ }
71
+ end
72
+ end
73
+ }
74
+ }
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,65 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require_relative 'cell'
23
+
24
+ class Battleship
25
+ module View
26
+ class Ship
27
+ include Glimmer::UI::CustomWidget
28
+
29
+ options :game, :player, :ship_name, :ship_length
30
+
31
+ body {
32
+ composite {
33
+ row_layout(:vertical) {
34
+ fill true
35
+ margin_width 0
36
+ margin_height 0
37
+ }
38
+
39
+ label {
40
+ text ship_name.to_s.titlecase
41
+ font height: 16
42
+ }
43
+
44
+ composite {
45
+ grid_layout(ship_length, true) {
46
+ margin_width 0
47
+ margin_height 0
48
+ horizontal_spacing 0
49
+ vertical_spacing 0
50
+ }
51
+
52
+ ship_length.times do |column_index|
53
+ cell(game: game, player: player, type: :ship, column_index: column_index, ship: game.ship_collections[player].ships[ship_name]) {
54
+ layout_data {
55
+ width_hint 25
56
+ height_hint 25
57
+ }
58
+ }
59
+ end
60
+ }
61
+ }
62
+ }
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,49 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require_relative '../model/game'
23
+ require_relative '../model/ship_collection'
24
+
25
+ require_relative 'ship'
26
+
27
+ class Battleship
28
+ module View
29
+ class ShipCollection
30
+ include Glimmer::UI::CustomWidget
31
+
32
+ options :game, :player
33
+
34
+ body {
35
+ composite {
36
+ row_layout(:vertical) {
37
+ fill true
38
+ margin_width 0
39
+ margin_height 0
40
+ }
41
+
42
+ Model::ShipCollection::BATTLESHIPS.each do |ship_name, ship_length|
43
+ ship(game: game, player: player, ship_name: ship_name, ship_length: ship_length)
44
+ end
45
+ }
46
+ }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,116 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer-dsl-swt'
23
+
24
+ require_relative 'connect4/model/grid'
25
+
26
+ class Connect4
27
+ include Glimmer::UI::CustomShell
28
+
29
+ COLOR_BACKGROUND = rgb(63, 104, 212)
30
+ COLOR_EMPTY_SLOT = :white
31
+ COLOR_COIN1 = rgb(236, 223, 56)
32
+ COLOR_COIN2 = rgb(176, 11, 23)
33
+
34
+ attr_accessor :current_player_color
35
+
36
+ before_body do
37
+ @grid = Model::Grid.new
38
+ select_player_color
39
+ end
40
+
41
+ after_body do
42
+ observe(@grid, :current_player) do
43
+ select_player_color
44
+ end
45
+
46
+ observe(@grid, :game_over) do |game_over_value|
47
+ if game_over_value
48
+ game_over_message = case game_over_value
49
+ when true
50
+ "Game over!\nDraw!"
51
+ when 1
52
+ "Game over!\nPlayer 1 (yellow) wins!"
53
+ when 2
54
+ "Game over!\nPlayer 2 (red) wins!"
55
+ end
56
+
57
+ message_box {
58
+ text 'Game Over!'
59
+ message game_over_message
60
+ }.open
61
+
62
+ @grid.restart!
63
+ end
64
+ end
65
+ end
66
+
67
+ body {
68
+ shell(:no_resize) {
69
+ grid_layout(Model::Grid::WIDTH, true)
70
+
71
+ text 'Glimmer Connect 4'
72
+ background COLOR_BACKGROUND
73
+
74
+ Model::Grid::HEIGHT.times do |row_index|
75
+ Model::Grid::WIDTH.times do |column_index|
76
+ canvas {
77
+ layout_data {
78
+ width_hint 50
79
+ height_hint 50
80
+ }
81
+
82
+ background :transparent
83
+
84
+ the_oval = oval(0, 0, 50, 50) {
85
+ background <= [@grid.slot_rows[row_index][column_index], :value, on_read: ->(v) { v == 0 ? COLOR_EMPTY_SLOT : (v == 1 ? COLOR_COIN1 : COLOR_COIN2)}]
86
+ }
87
+
88
+ if row_index == 0
89
+ entered = false
90
+ on_mouse_enter do
91
+ entered = true
92
+ the_oval.background = current_player_color if @grid.slot_rows[row_index][column_index].value == 0
93
+ end
94
+
95
+ on_mouse_exit do
96
+ entered = false
97
+ the_oval.background = COLOR_EMPTY_SLOT if @grid.slot_rows[row_index][column_index].value == 0
98
+ end
99
+
100
+ on_mouse_up do
101
+ @grid.insert!(column_index)
102
+ the_oval.background = current_player_color if entered && @grid.slot_rows[row_index][column_index].value == 0
103
+ end
104
+ end
105
+ }
106
+ end
107
+ end
108
+ }
109
+ }
110
+
111
+ def select_player_color
112
+ self.current_player_color = @grid.current_player == 1 ? COLOR_COIN1 : COLOR_COIN2
113
+ end
114
+ end
115
+
116
+ Connect4.launch
@@ -0,0 +1,174 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require_relative 'slot'
23
+
24
+ class Connect4
25
+ module Model
26
+ class Grid
27
+ WIDTH = 7
28
+ HEIGHT = 6
29
+
30
+ attr_reader :slot_rows
31
+ attr_accessor :current_player, :game_over
32
+
33
+ def initialize
34
+ build_slots
35
+ start!
36
+ end
37
+
38
+ def start!
39
+ self.game_over = false
40
+ self.current_player = 1
41
+ reset_slots
42
+ end
43
+ alias restart! start!
44
+
45
+ def insert!(column_index)
46
+ found_row_index = bottom_most_free_row_index(column_index)
47
+ raise "Illegal move at #{column_index}" if found_row_index == -1
48
+ @slot_rows[found_row_index][column_index].value = @current_player
49
+ self.current_player = @current_player%2 + 1
50
+ evaluate_game_over
51
+ end
52
+
53
+ # returns bottom most free row index
54
+ # returns -1 if none
55
+ def bottom_most_free_row_index(column_index)
56
+ found_row_index = @slot_rows.size - 1
57
+ found_row_index -= 1 until found_row_index == -1 || @slot_rows[found_row_index][column_index].value == 0
58
+ found_row_index
59
+ end
60
+
61
+ private
62
+
63
+ def build_slots
64
+ @slot_rows = HEIGHT.times.map do |row_index|
65
+ WIDTH.times.map do |column_index|
66
+ Slot.new(self)
67
+ end
68
+ end
69
+ end
70
+
71
+ def reset_slots
72
+ @slot_rows.flatten.each {|s| s.value = 0}
73
+ end
74
+
75
+ def evaluate_game_over
76
+ evaluate_horizontal_win
77
+ evaluate_vertical_win
78
+ evaluate_sw_ne_diagonal_win
79
+ evaluate_se_nw_diagonal_win
80
+ self.game_over ||= true if @slot_rows.flatten.map(&:value).all? {|v| v > 0}
81
+ end
82
+
83
+ def evaluate_horizontal_win
84
+ connections = nil
85
+ last_slot_value = nil
86
+ HEIGHT.times do |row_index|
87
+ connections = nil
88
+ last_slot_value = nil
89
+ WIDTH.times do |column_index|
90
+ slot = @slot_rows[row_index][column_index]
91
+ if slot.value.to_i > 0 && slot.value == last_slot_value
92
+ connections += 1
93
+ else
94
+ last_slot_value = slot.value
95
+ connections = 1
96
+ end
97
+ break if connections == 4
98
+ end
99
+ break if connections == 4
100
+ end
101
+ self.game_over = last_slot_value if connections == 4
102
+ end
103
+
104
+ def evaluate_vertical_win
105
+ connections = nil
106
+ last_slot_value = nil
107
+ WIDTH.times do |column_index|
108
+ connections = nil
109
+ last_slot_value = nil
110
+ HEIGHT.times do |row_index|
111
+ slot = @slot_rows[row_index][column_index]
112
+ if slot.value.to_i > 0 && slot.value == last_slot_value
113
+ connections += 1
114
+ else
115
+ last_slot_value = slot.value
116
+ connections = 1
117
+ end
118
+ break if connections == 4
119
+ end
120
+ break if connections == 4
121
+ end
122
+ self.game_over = last_slot_value if connections == 4
123
+ end
124
+
125
+ def evaluate_sw_ne_diagonal_win
126
+ sw_ne_coordinates = [
127
+ [[3, 0], [2, 1], [1, 2], [0, 3]],
128
+ [[4, 0], [3, 1], [2, 2], [1, 3], [0, 4]],
129
+ [[5, 0], [4, 1], [3, 2], [2, 3], [1, 4], [0, 5]],
130
+ [[5, 1], [4, 2], [3, 3], [2, 4], [1, 5], [0, 6]],
131
+ [[5, 2], [4, 3], [3, 4], [2, 5], [1, 6]],
132
+ [[5, 3], [4, 4], [3, 5], [2, 6]],
133
+ ]
134
+ evaluate_diagonal_win(sw_ne_coordinates)
135
+ end
136
+
137
+ def evaluate_se_nw_diagonal_win
138
+ sw_ne_coordinates = [
139
+ [[0, 3], [1, 4], [2, 5], [3, 6]],
140
+ [[0, 2], [1, 3], [2, 4], [3, 5], [4, 6]],
141
+ [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6]],
142
+ [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5]],
143
+ [[1, 0], [2, 1], [3, 2], [4, 3], [5, 4]],
144
+ [[2, 0], [3, 1], [4, 2], [5, 3]],
145
+ ]
146
+ evaluate_diagonal_win(sw_ne_coordinates)
147
+ end
148
+
149
+ def evaluate_diagonal_win(diagonal_coordinates)
150
+ connections = nil
151
+ last_slot_value = nil
152
+ diagonal_coordinates.each do |group|
153
+ connections = nil
154
+ last_slot_value = nil
155
+ group.each do |row_index, column_index|
156
+ slot = @slot_rows[row_index][column_index]
157
+ if slot.value.to_i > 0 && slot.value == last_slot_value
158
+ connections += 1
159
+ else
160
+ last_slot_value = slot.value
161
+ connections = 1
162
+ end
163
+ break if connections == 4
164
+ end
165
+ break if connections == 4
166
+ end
167
+ self.game_over = last_slot_value if connections == 4
168
+ end
169
+
170
+ end
171
+
172
+ end
173
+
174
+ end