color_the_circles 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c5426d73dc07d55f6ce190272498d3fddd75aeeeca0a2e6a2ff15df28fccb876
4
+ data.tar.gz: e50438395f353c7b1091b5a988a73df56c5e0f166a0a8e503dbb718291533221
5
+ SHA512:
6
+ metadata.gz: 8a1c384df6d23faeb20810b7094a595136aaa792c94dcee4546b8da19a1293180cf07ae5b16943245594f904c989f6c320c45a55dd4d2873a272ca378cef0b73
7
+ data.tar.gz: dbdfa3b13bee63d9e8751d193d020759940195a0d6ba0cfff4222e6ecc463142806be80982a21b0f4c67cff57080069621ef45222d4ec1f7128566df45b930f6
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2023 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.
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Color The Circles
2
+ ## Glimmer DSL for LibUI Application
3
+ ## [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=40 /> Glimmer DSL for LibUI Application](https://github.com/AndyObtiva/glimmer-dsl-libui)
4
+ [![Gem Version](https://badge.fury.io/rb/color_the_circles.svg)](http://badge.fury.io/rb/color_the_circles)
5
+
6
+ Color The Circles is a game in which you must color all drawn circles to win. Your score starts negative, as the number of drawn uncolored circles in negative, and every time you color a circle, you add to it. If your score reaches -20, you lose. If your score reaches 0, you win.
7
+
8
+ Mac | Windows | Linux
9
+ ----|---------|------
10
+ ![glimmer-dsl-libui-mac-color-the-circles.png](/screenshots/glimmer-dsl-libui-mac-color-the-circles.png) ![glimmer-dsl-libui-mac-color-the-circles-lost.png](/screenshots/glimmer-dsl-libui-mac-color-the-circles-lost.png) ![glimmer-dsl-libui-mac-color-the-circles-won.png](/screenshots/glimmer-dsl-libui-mac-color-the-circles-won.png) | ![glimmer-dsl-libui-windows-color-the-circles.png](/screenshots/glimmer-dsl-libui-windows-color-the-circles.png) ![glimmer-dsl-libui-windows-color-the-circles-lost.png](/screenshots/glimmer-dsl-libui-windows-color-the-circles-lost.png) ![glimmer-dsl-libui-windows-color-the-circles-won.png](/screenshots/glimmer-dsl-libui-windows-color-the-circles-won.png) | ![glimmer-dsl-libui-linux-color-the-circles.png](/screenshots/glimmer-dsl-libui-linux-color-the-circles.png) ![glimmer-dsl-libui-linux-color-the-circles-lost.png](/screenshots/glimmer-dsl-libui-linux-color-the-circles-lost.png) ![glimmer-dsl-libui-linux-color-the-circles-won.png](/screenshots/glimmer-dsl-libui-linux-color-the-circles-won.png)
11
+
12
+ ## Setup
13
+
14
+ ```
15
+ gem install color_the_circles
16
+ ```
17
+
18
+ ## Run
19
+
20
+ ```
21
+ color_the_circles
22
+ ```
23
+
24
+ ## Contributing to color_the_circles
25
+
26
+ - Check out the latest master to make sure the feature hasn't been
27
+ implemented or the bug hasn't been fixed yet.
28
+ - Check out the issue tracker to make sure someone already hasn't
29
+ requested it and/or contributed it.
30
+ - Fork the project.
31
+ - Start a feature/bugfix branch.
32
+ - Commit and push until you are happy with your contribution.
33
+ - Make sure to add tests for it. This is important so I don't break it
34
+ in a future version unintentionally.
35
+ - Please try not to mess with the Rakefile, version, or history. If
36
+ you want to have your own version, or is otherwise necessary, that
37
+ is fine, but please isolate to its own commit so I can cherry-pick
38
+ around it.
39
+
40
+ ## Copyright
41
+
42
+ [MIT](LICENSE.txt)
43
+
44
+ Copyright (c) 2023 Andy Maleh. See
45
+ [LICENSE.txt](LICENSE.txt) for further details.
46
+
47
+
48
+ --
49
+
50
+ [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=40 />](https://github.com/AndyObtiva/glimmer) Built with [Glimmer DSL for LibUI](https://github.com/AndyObtiva/glimmer-dsl-libui) (Prerequisite-Free Ruby Desktop Development Cross-Platform Native GUI Library)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,3 @@
1
+ require_relative '../color_the_circles'
2
+
3
+ ColorTheCircles::View::ColorTheCircles.launch
@@ -0,0 +1,15 @@
1
+ class ColorTheCircles
2
+ module Model
3
+ class Game
4
+ attr_accessor :score
5
+
6
+ def initialize
7
+ @score = 0
8
+ end
9
+
10
+ def restart_game
11
+ @score = 0 # update variable directly to avoid notifying observers
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,57 @@
1
+ class ColorTheCircles
2
+ module Presenter
3
+ class Board
4
+ WINDOW_WIDTH = 800
5
+ WINDOW_HEIGHT = 600
6
+ COLOR_RANGE = (0..200)
7
+ SHAPE_MIN_SIZE = 15
8
+ SHAPE_MAX_SIZE = 75
9
+ MARGIN_WIDTH = 55
10
+ MARGIN_HEIGHT = 155
11
+
12
+ attr_reader :game, :circles_data
13
+
14
+ def initialize(game)
15
+ @game = game
16
+ @circles_data = []
17
+ end
18
+
19
+ def restart_game
20
+ game.restart_game
21
+ circles_data.clear
22
+ end
23
+
24
+ def add_circle
25
+ circle_x = rand * (WINDOW_WIDTH - MARGIN_WIDTH - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
26
+ circle_y = rand * (WINDOW_HEIGHT - MARGIN_HEIGHT - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
27
+ circle_size = rand * (SHAPE_MAX_SIZE - SHAPE_MIN_SIZE) + SHAPE_MIN_SIZE
28
+ stroke_color = [rand(COLOR_RANGE), rand(COLOR_RANGE), rand(COLOR_RANGE)]
29
+ circles_data << {
30
+ args: [circle_x, circle_y, circle_size],
31
+ fill: nil,
32
+ stroke: stroke_color
33
+ }
34
+ game.score -= 1 # notifies score observers automatically of change
35
+ end
36
+
37
+ def find_circle(x, y)
38
+ circles_data.find { |circle_data| circle_data[:fill].nil? && circle_data[:circle]&.contain?(x, y) }
39
+ end
40
+
41
+ def fill_circle(circle_data)
42
+ circle_data[:fill] = circle_data[:stroke]
43
+ push_colored_circle_behind_uncolored_circles(circle_data)
44
+ game.score += 1 # notifies score observers automatically of change
45
+ end
46
+
47
+ private
48
+
49
+ def push_colored_circle_behind_uncolored_circles(colored_circle_data)
50
+ removed_colored_circle_data = circles_data.delete(colored_circle_data)
51
+ last_colored_circle_data = circles_data.select {|cd| cd[:fill]}.last
52
+ last_colored_circle_data_index = circles_data.index(last_colored_circle_data) || -1
53
+ circles_data.insert(last_colored_circle_data_index + 1, removed_colored_circle_data)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,203 @@
1
+ require 'color_the_circles/model/game'
2
+ require 'color_the_circles/presenter/board'
3
+
4
+ class ColorTheCircles
5
+ module View
6
+ class ColorTheCircles
7
+ include Glimmer::LibUI::Application
8
+
9
+ TIME_MAX_EASY = 4
10
+ TIME_MAX_MEDIUM = 3
11
+ TIME_MAX_HARD = 2
12
+ TIME_MAX_INSANE = 1
13
+
14
+ before_body do
15
+ @game = Model::Game.new
16
+ @board = Presenter::Board.new(@game)
17
+ @time_max = TIME_MAX_HARD
18
+ @game_over = false
19
+
20
+ register_observers
21
+ setup_circle_factory
22
+ menus
23
+ end
24
+
25
+ body {
26
+ window('Color The Circles', Presenter::Board::WINDOW_WIDTH, Presenter::Board::WINDOW_HEIGHT) {
27
+ margined true
28
+
29
+ grid {
30
+ button('Restart') {
31
+ left 0
32
+ top 0
33
+ halign :center
34
+
35
+ on_clicked do
36
+ restart_game
37
+ end
38
+ }
39
+
40
+ label('Score goes down as circles are added. If it reaches -20, you lose!') {
41
+ left 0
42
+ top 1
43
+ halign :center
44
+ }
45
+
46
+ label('Click circles to color and score! Once score reaches 0, you win!') {
47
+ left 0
48
+ top 2
49
+ halign :center
50
+ }
51
+
52
+ horizontal_box {
53
+ left 0
54
+ top 3
55
+ halign :center
56
+
57
+ label('Score:') {
58
+ stretchy false
59
+ }
60
+
61
+ label {
62
+ stretchy false
63
+
64
+ text <= [@game, :score, on_read: :to_s]
65
+ }
66
+ }
67
+
68
+ @area = area {
69
+ left 0
70
+ top 4
71
+ hexpand true
72
+ vexpand true
73
+ halign :fill
74
+ valign :fill
75
+
76
+ on_draw do |area_draw_params|
77
+ path {
78
+ rectangle(0, 0, Presenter::Board::WINDOW_WIDTH, Presenter::Board::WINDOW_HEIGHT)
79
+
80
+ fill :white
81
+ }
82
+
83
+ @board.circles_data.each do |circle_data|
84
+ circle_data[:circle] = circle(*circle_data[:args]) {
85
+ fill circle_data[:fill]
86
+ stroke circle_data[:stroke]
87
+ }
88
+ end
89
+ end
90
+
91
+ on_mouse_down do |area_mouse_event|
92
+ color_circle(area_mouse_event[:x], area_mouse_event[:y])
93
+ end
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ def menus
100
+ menu('Actions') {
101
+ menu_item('Restart') {
102
+ on_clicked do
103
+ restart_game
104
+ end
105
+ }
106
+
107
+ quit_menu_item
108
+ }
109
+
110
+ menu('Difficulty') {
111
+ radio_menu_item('Easy') {
112
+ on_clicked do
113
+ @time_max = TIME_MAX_EASY
114
+ end
115
+ }
116
+
117
+ radio_menu_item('Medium') {
118
+ on_clicked do
119
+ @time_max = TIME_MAX_MEDIUM
120
+ end
121
+ }
122
+
123
+ radio_menu_item('Hard') {
124
+ checked true
125
+
126
+ on_clicked do
127
+ @time_max = TIME_MAX_HARD
128
+ end
129
+ }
130
+
131
+ radio_menu_item('Insane') {
132
+ on_clicked do
133
+ @time_max = TIME_MAX_INSANE
134
+ end
135
+ }
136
+ }
137
+
138
+ menu('Help') {
139
+ menu_item('Instructions') {
140
+ on_clicked do
141
+ msg_box('Instructions', "Score goes down as circles are added.\nIf it reaches -20, you lose!\n\nClick circles to color and score!\nOnce score reaches 0, you win!\n\nBeware of concealed light-colored circles!\nThey are revealed once darker circles intersect them.\n\nThere are four levels of difficulty.\nChange via difficulty menu if the game gets too tough.")
142
+ end
143
+ }
144
+ }
145
+ end
146
+
147
+ def register_observers
148
+ observe(@game, :score) do |new_score|
149
+ if !@handling_game_score
150
+ Glimmer::LibUI.queue_main do
151
+ @handling_game_score = true
152
+ @game.score = new_score
153
+ if new_score == -20
154
+ @game_over = true
155
+ msg_box('You Lost!', 'Sorry! Your score reached -20')
156
+ restart_game
157
+ elsif new_score == 0
158
+ @game_over = true
159
+ msg_box('You Won!', 'Congratulations! Your score reached 0')
160
+ restart_game
161
+ end
162
+ @handling_game_score = nil
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ def setup_circle_factory
169
+ consumer = Proc.new do
170
+ unless @game_over
171
+ if @board.circles_data.empty?
172
+ # start with 3 circles to make more challenging
173
+ add_circle until @board.circles_data.size > 3
174
+ else
175
+ add_circle
176
+ end
177
+ end
178
+ delay = rand * @time_max
179
+ Glimmer::LibUI.timer(delay, repeat: false, &consumer)
180
+ end
181
+ Glimmer::LibUI.queue_main(&consumer)
182
+ end
183
+
184
+ def add_circle
185
+ @board.add_circle
186
+ @area.queue_redraw_all
187
+ end
188
+
189
+ def restart_game
190
+ @board.restart_game
191
+ @game_over = false
192
+ end
193
+
194
+ def color_circle(x, y)
195
+ clicked_circle_data = @board.find_circle(x, y)
196
+ if clicked_circle_data
197
+ @board.fill_circle(clicked_circle_data)
198
+ @area.queue_redraw_all
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,18 @@
1
+ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ Bundler.require(:default)
6
+ rescue StandardError, Gem::LoadError
7
+ # this runs when packaged as a gem (no bundler)
8
+ require 'glimmer-dsl-libui'
9
+ # add more gems if needed
10
+ end
11
+
12
+ class ColorTheCircles
13
+ APP_ROOT = File.expand_path('../..', __FILE__)
14
+ VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
15
+ LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
16
+ end
17
+
18
+ require 'color_the_circles/view/color_the_circles'
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ runner = File.expand_path('../../app/color_the_circles/launch.rb', __FILE__)
4
+
5
+ require 'glimmer/launcher'
6
+
7
+ launcher = Glimmer::Launcher.new([runner] + ARGV)
8
+ launcher.launch
Binary file
Binary file
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: color_the_circles
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andy Maleh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-11-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: glimmer-dsl-libui
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.11.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.11.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.5.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.5.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: juwelier
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 2.4.9
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.4.9
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Color The Circles game (desktop application) produced during RubyConf
70
+ 2023 Community Day Glimmer Desktop Hacking event using Glimmer DSL for LibUI Application
71
+ Scaffolding and refactoring of original example.
72
+ email: andy.am@gmail.com
73
+ executables:
74
+ - color_the_circles
75
+ extensions: []
76
+ extra_rdoc_files:
77
+ - LICENSE.txt
78
+ - README.md
79
+ files:
80
+ - LICENSE.txt
81
+ - README.md
82
+ - VERSION
83
+ - app/color_the_circles.rb
84
+ - app/color_the_circles/launch.rb
85
+ - app/color_the_circles/model/game.rb
86
+ - app/color_the_circles/presenter/board.rb
87
+ - app/color_the_circles/view/color_the_circles.rb
88
+ - bin/color_the_circles
89
+ - color_the_circles.gemspec
90
+ - icons/linux/Color The Circles.png
91
+ - icons/macosx/Color The Circles.icns
92
+ - icons/windows/Color The Circles.ico
93
+ homepage: http://github.com/AndyObtiva/color_the_circles
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ - app
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubygems_version: 3.4.6
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Color The Circles
117
+ test_files: []