rubysketch-solitaire 0.1.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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.bundle/config +2 -0
  3. data/.github/workflows/release-gem.yml +62 -0
  4. data/.github/workflows/test.yml +23 -0
  5. data/.github/workflows/utils.rb +56 -0
  6. data/.gitignore +11 -0
  7. data/Gemfile +5 -0
  8. data/Gemfile.lock +284 -0
  9. data/LICENSE +21 -0
  10. data/Podfile +31 -0
  11. data/Podfile.lock +59 -0
  12. data/README.md +21 -0
  13. data/Rakefile +100 -0
  14. data/RubySolitaire/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  15. data/RubySolitaire/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
  16. data/RubySolitaire/Assets.xcassets/Contents.json +6 -0
  17. data/RubySolitaire/BridgingHeader.h +10 -0
  18. data/RubySolitaire/GameView.swift +47 -0
  19. data/RubySolitaire/Preview Content/Preview Assets.xcassets/Contents.json +6 -0
  20. data/RubySolitaire/RubySolitaireApp.swift +10 -0
  21. data/RubySolitaireTests/RubySolitaireTests.swift +28 -0
  22. data/RubySolitaireUITests/RubySolitaireUITests.swift +35 -0
  23. data/RubySolitaireUITests/RubySolitaireUITestsLaunchTests.swift +25 -0
  24. data/VERSION +1 -0
  25. data/data/button.mp3 +0 -0
  26. data/data/card.png +0 -0
  27. data/data/deal1.mp3 +0 -0
  28. data/data/deal2.mp3 +0 -0
  29. data/data/deal3.mp3 +0 -0
  30. data/data/flip.mp3 +0 -0
  31. data/data/noop.mp3 +0 -0
  32. data/lib/rubysketch/solitaire/background.rb +34 -0
  33. data/lib/rubysketch/solitaire/card.rb +256 -0
  34. data/lib/rubysketch/solitaire/common/animation.rb +116 -0
  35. data/lib/rubysketch/solitaire/common/button.rb +67 -0
  36. data/lib/rubysketch/solitaire/common/dialog.rb +103 -0
  37. data/lib/rubysketch/solitaire/common/history.rb +94 -0
  38. data/lib/rubysketch/solitaire/common/particle.rb +71 -0
  39. data/lib/rubysketch/solitaire/common/scene.rb +128 -0
  40. data/lib/rubysketch/solitaire/common/score.rb +37 -0
  41. data/lib/rubysketch/solitaire/common/settings.rb +31 -0
  42. data/lib/rubysketch/solitaire/common/shake.rb +48 -0
  43. data/lib/rubysketch/solitaire/common/sound.rb +6 -0
  44. data/lib/rubysketch/solitaire/common/timer.rb +35 -0
  45. data/lib/rubysketch/solitaire/common/transitions.rb +149 -0
  46. data/lib/rubysketch/solitaire/common/utils.rb +89 -0
  47. data/lib/rubysketch/solitaire/extension.rb +25 -0
  48. data/lib/rubysketch/solitaire/klondike.rb +676 -0
  49. data/lib/rubysketch/solitaire/places.rb +177 -0
  50. data/lib/rubysketch/solitaire/start.rb +19 -0
  51. data/lib/rubysketch/solitaire.rb +80 -0
  52. data/main.rb +1 -0
  53. data/project.yml +91 -0
  54. data/solitaire.gemspec +28 -0
  55. metadata +137 -0
@@ -0,0 +1,177 @@
1
+ using RubySketch
2
+
3
+
4
+ class CardPlace
5
+
6
+ include HasSprite
7
+ include Enumerable
8
+
9
+ extend Forwardable
10
+
11
+ def initialize(name, linkCards: false)
12
+ @name, @linkCards = name.intern, linkCards
13
+ @cards = []
14
+ end
15
+
16
+ attr_reader :name, :cards
17
+
18
+ def_delegators :cards, :clear, :each, :last, :empty?
19
+
20
+ def add(*cards, updatePos: true)
21
+ cards.map(&:to_a).flatten.each do |card|
22
+ card.place&.pop card
23
+ @cards.push card
24
+ card.next = nil
25
+ card.pos = posFor card if updatePos
26
+ card.place = self
27
+ end
28
+ @cards.each_cons(2) {|prev, it| prev.next = @linkCards ? it : nil}
29
+ end
30
+
31
+ def pop(card = nil)
32
+ return nil if @cards.empty?
33
+ card ||= @cards.last
34
+ index = @cards.index card
35
+ poppeds =
36
+ if index
37
+ @cards[index..-1].tap {@cards[index..-1] = []}
38
+ else
39
+ [@cards.pop]
40
+ end
41
+ @cards.last&.next = nil
42
+ poppeds.each_cons(2) {|prev, it| prev.next = it}
43
+ poppeds.first.tap {|first| first.place = nil}
44
+ end
45
+
46
+ def id()
47
+ @id ||= "id:#{name}"
48
+ end
49
+
50
+ def accept?(x, y, card)
51
+ false
52
+ end
53
+
54
+ def posFor(card, index = nil)
55
+ index ||= indexFor card
56
+ createVector *pos.to_a(2), self.z + index + 1
57
+ end
58
+
59
+ def sprite()
60
+ @sprite ||= Sprite.new(0, 0, *Card.spriteSize).tap do |sp|
61
+ sp.draw do
62
+ noStroke
63
+ fill 0, 20
64
+ rect 0, 0, sp.w, sp.h, 4
65
+ end
66
+ end
67
+ end
68
+
69
+ def inspect()
70
+ "#<CardPlace #{name}>"
71
+ end
72
+
73
+ private
74
+
75
+ def indexFor(card)
76
+ cards.index(card) || cards.size
77
+ end
78
+
79
+ end# CardPlace
80
+
81
+
82
+ class NextsPlace < CardPlace
83
+
84
+ def initialize(*args, **kwargs, &block)
85
+ super
86
+ @drawCount = 1
87
+ end
88
+
89
+ attr_reader :drawCount
90
+
91
+ def add(*cards, **kwargs)
92
+ super
93
+ updateCards excludes: cards
94
+ end
95
+
96
+ def pop(*args)
97
+ super
98
+ updateCards
99
+ end
100
+
101
+ def updateCards(excludes: [])
102
+ cards.each.with_index do |card, index|
103
+ next if excludes.include? card
104
+ pos = posFor card, index
105
+ move card, pos, 0.2 if pos != card.pos
106
+ end
107
+ end
108
+
109
+ def drawCount=(count)
110
+ raise 'invalid drawCount' unless count
111
+
112
+ @drawCount = count
113
+
114
+ w = Card.spriteSize[0] + overlap * (count - 1)
115
+ self.x -= w - self.w
116
+ self.w = w
117
+ end
118
+
119
+ def posFor(card, index = nil)
120
+ index ||= indexFor card
121
+ super.tap do |pos|
122
+ rindex = cards.size - index
123
+ pos.x += overlap * (drawCount - rindex).clamp(0, drawCount - 1)
124
+ end
125
+ end
126
+
127
+ def overlap()
128
+ Card.spriteSize[0] * 0.4
129
+ end
130
+
131
+ end# NextsPlace
132
+
133
+
134
+ class MarkPlace < CardPlace
135
+
136
+ def mark()
137
+ last&.mark
138
+ end
139
+
140
+ def accept?(x, y, card)
141
+ return false if !card || card.closed? || !card.canDrop?
142
+ hit?(x, y) &&
143
+ card.last? &&
144
+ card.opened? &&
145
+ (!mark || mark == card.mark) &&
146
+ card.number == last&.number.then {|n| n ? n + 1 : 1}
147
+ end
148
+
149
+ end# MarkPlace
150
+
151
+
152
+ class ColumnPlace < CardPlace
153
+
154
+ def initialize(*args, **kwargs, &block)
155
+ super(*args, linkCards: true, **kwargs, &block)
156
+ end
157
+
158
+ def accept?(x, y, card)
159
+ return false if !card || card.closed? || !card.canDrop?
160
+ if empty?
161
+ hit?(x, y) &&
162
+ card.number == 13
163
+ else
164
+ any? {|card| card.hit?(x, y)} &&
165
+ card.number == last.number - 1 &&
166
+ card.color != last.color
167
+ end
168
+ end
169
+
170
+ def posFor(card, index = nil)
171
+ index ||= indexFor card
172
+ super.tap do |pos|
173
+ pos.y += self.h * 0.3 * index
174
+ end
175
+ end
176
+
177
+ end# ColumnPlace
@@ -0,0 +1,19 @@
1
+ using RubySketch
2
+
3
+
4
+ class Start < Scene
5
+
6
+ def activated()
7
+ super
8
+ transition (resume || Klondike.new), Fade, secOut: 0
9
+ end
10
+
11
+ private
12
+
13
+ def resume()
14
+ Klondike.new settings['state']
15
+ rescue
16
+ nil
17
+ end
18
+
19
+ end# Start
@@ -0,0 +1,80 @@
1
+ require 'forwardable'
2
+ require 'json'
3
+ require 'rubysketch'
4
+
5
+ require 'rubysketch/solitaire/common/utils'
6
+ require 'rubysketch/solitaire/common/settings'
7
+ require 'rubysketch/solitaire/common/timer'
8
+ require 'rubysketch/solitaire/common/history'
9
+ require 'rubysketch/solitaire/common/score'
10
+ require 'rubysketch/solitaire/common/animation'
11
+ require 'rubysketch/solitaire/common/particle'
12
+ require 'rubysketch/solitaire/common/shake'
13
+ require 'rubysketch/solitaire/common/scene'
14
+ require 'rubysketch/solitaire/common/sound'
15
+ require 'rubysketch/solitaire/common/dialog'
16
+ require 'rubysketch/solitaire/common/transitions'
17
+ require 'rubysketch/solitaire/common/button'
18
+
19
+ require 'rubysketch/solitaire/card'
20
+ require 'rubysketch/solitaire/places'
21
+
22
+ require 'rubysketch/solitaire/background'
23
+ require 'rubysketch/solitaire/start'
24
+ require 'rubysketch/solitaire/klondike'
25
+
26
+
27
+ using RubySketch
28
+
29
+
30
+ def settings()
31
+ $settings ||= Settings.new 'solitaire.json'
32
+ end
33
+
34
+ def centerPos()
35
+ [
36
+ (displayWidth - windowWidth) / 2,
37
+ (displayHeight - windowHeight) / 2
38
+ ]
39
+ end
40
+
41
+ setup do
42
+ setTitle "Solitaire"
43
+ size 375, 667
44
+ windowMove *windowPos
45
+ windowResizable false
46
+ angleMode DEGREES
47
+ noStroke
48
+
49
+ $root = RootScene.new 'Root', Background.new, Start.new
50
+ end
51
+
52
+ draw do
53
+ fireTimers
54
+ drawShake
55
+ push { $root.draw }
56
+ end
57
+
58
+ def windowPos()
59
+ settings['windowPos'] || centerPos
60
+ end
61
+
62
+ windowMoved do
63
+ settings['windowPos'] = [windowX, windowY]
64
+ end
65
+
66
+ mousePressed do
67
+ $root.mousePressed mouseX, mouseY, mouseButton
68
+ end
69
+
70
+ mouseReleased do
71
+ $root.mouseReleased mouseX, mouseY, mouseButton
72
+ end
73
+
74
+ mouseMoved do
75
+ $root.mouseMoved mouseX, mouseY, mouseX - pmouseX, mouseY - pmouseY
76
+ end
77
+
78
+ mouseDragged do
79
+ $root.mouseDragged mouseX, mouseY, mouseX - pmouseX, mouseY - pmouseY
80
+ end
data/main.rb ADDED
@@ -0,0 +1 @@
1
+ require 'rubysketch/solitaire'
data/project.yml ADDED
@@ -0,0 +1,91 @@
1
+ name: RubySolitaire
2
+
3
+ options:
4
+ bundleIdPrefix: org.xord
5
+ deploymentTarget:
6
+ iOS: 14.0
7
+ developmentLanguage: ja
8
+
9
+ settingGroups:
10
+ all:
11
+ SWIFT_OBJC_BRIDGING_HEADER: RubySolitaire/BridgingHeader.h
12
+ app:
13
+ ENABLE_PREVIEWS: YES
14
+ DEVELOPMENT_ASSET_PATHS: "\"RubySolitaire/Preview Content\""
15
+ test:
16
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: YES
17
+
18
+ settings:
19
+ base:
20
+ MARKETING_VERSION: 1.0.0
21
+ CURRENT_PROJECT_VERSION: 1.0.0
22
+ DEVELOPMENT_TEAM: XXXXXXXXX
23
+ configs:
24
+ debug:
25
+ DEBUG_INFORMATION_FORMAT: dwarf-with-dsym
26
+
27
+ targets:
28
+ RubySolitaire:
29
+ type: application
30
+ platform: iOS
31
+ dependencies:
32
+ - framework: CoreMedia.framework
33
+ embed: false
34
+ sources:
35
+ - RubySolitaire
36
+ - main.rb
37
+ - path: lib
38
+ type: folder
39
+ - path: data
40
+ type: folder
41
+ settings:
42
+ groups: [all, app]
43
+ info:
44
+ path: RubySolitaire/Info.plist
45
+ properties:
46
+ CFBundleVersion: $(CURRENT_PROJECT_VERSION)
47
+ CFBundleShortVersionString: $(MARKETING_VERSION)
48
+ LSRequiresIPhoneOS: YES
49
+ UILaunchScreen: ""
50
+ UIApplicationSupportsIndirectInputEvents: YES
51
+ UIApplicationSceneManifest:
52
+ UIApplicationSupportsMultipleScenes: YES
53
+ UISupportedInterfaceOrientations~iphone:
54
+ - UIInterfaceOrientationPortrait
55
+ #- UIInterfaceOrientationLandscapeLeft
56
+ #- UIInterfaceOrientationLandscapeRight
57
+ #UISupportedInterfaceOrientations~ipad:
58
+ #- UIInterfaceOrientationPortrait
59
+ #- UIInterfaceOrientationPortraitUpsideDown
60
+ #- UIInterfaceOrientationLandscapeLeft
61
+ #- UIInterfaceOrientationLandscapeRight
62
+
63
+ RubySolitaireTests:
64
+ type: bundle.unit-test
65
+ platform: iOS
66
+ dependencies:
67
+ - target: RubySolitaire
68
+ sources:
69
+ - RubySolitaireTests
70
+ settings:
71
+ groups: [all, test]
72
+ info:
73
+ path: RubySolitaireTests/Info.plist
74
+ properties:
75
+ CFBundleVersion: $(CURRENT_PROJECT_VERSION)
76
+ CFBundleShortVersionString: $(MARKETING_VERSION)
77
+
78
+ RubySolitaireUITests:
79
+ type: bundle.ui-testing
80
+ platform: iOS
81
+ dependencies:
82
+ - target: RubySolitaire
83
+ sources:
84
+ - RubySolitaireUITests
85
+ settings:
86
+ groups: [all, test]
87
+ info:
88
+ path: RubySolitaireUITests/Info.plist
89
+ properties:
90
+ CFBundleVersion: $(CURRENT_PROJECT_VERSION)
91
+ CFBundleShortVersionString: $(MARKETING_VERSION)
data/solitaire.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- mode: ruby -*-
2
+
3
+
4
+ require_relative 'lib/rubysketch/solitaire/extension'
5
+
6
+
7
+ Gem::Specification.new do |s|
8
+ ext = RubySketch::Solitaire::Extension
9
+
10
+ s.name = 'rubysketch-solitaire'
11
+ s.version = ext.version
12
+ s.license = 'MIT'
13
+ s.summary = 'Solitaire game made with RubySketch.'
14
+ s.description = 'Solitaire game made with RubySketch.'
15
+ s.authors = %w[xordog]
16
+ s.email = 'xordog@gmail.com'
17
+ s.homepage = "https://github.com/xord/solitaire"
18
+
19
+ s.platform = Gem::Platform::RUBY
20
+ s.required_ruby_version = '>= 3.0.0'
21
+
22
+ s.add_runtime_dependency 'xot', '~> 0.1.38'
23
+ s.add_runtime_dependency 'rubysketch', '~> 0.5.13'
24
+
25
+ s.add_development_dependency 'rake'
26
+
27
+ s.files = `git ls-files`.split $/
28
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubysketch-solitaire
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - xordog
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-05-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xot
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.38
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.38
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubysketch
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.5.13
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.5.13
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Solitaire game made with RubySketch.
56
+ email: xordog@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".bundle/config"
62
+ - ".github/workflows/release-gem.yml"
63
+ - ".github/workflows/test.yml"
64
+ - ".github/workflows/utils.rb"
65
+ - ".gitignore"
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - LICENSE
69
+ - Podfile
70
+ - Podfile.lock
71
+ - README.md
72
+ - Rakefile
73
+ - RubySolitaire/Assets.xcassets/AccentColor.colorset/Contents.json
74
+ - RubySolitaire/Assets.xcassets/AppIcon.appiconset/Contents.json
75
+ - RubySolitaire/Assets.xcassets/Contents.json
76
+ - RubySolitaire/BridgingHeader.h
77
+ - RubySolitaire/GameView.swift
78
+ - RubySolitaire/Preview Content/Preview Assets.xcassets/Contents.json
79
+ - RubySolitaire/RubySolitaireApp.swift
80
+ - RubySolitaireTests/RubySolitaireTests.swift
81
+ - RubySolitaireUITests/RubySolitaireUITests.swift
82
+ - RubySolitaireUITests/RubySolitaireUITestsLaunchTests.swift
83
+ - VERSION
84
+ - data/button.mp3
85
+ - data/card.png
86
+ - data/deal1.mp3
87
+ - data/deal2.mp3
88
+ - data/deal3.mp3
89
+ - data/flip.mp3
90
+ - data/noop.mp3
91
+ - lib/rubysketch/solitaire.rb
92
+ - lib/rubysketch/solitaire/background.rb
93
+ - lib/rubysketch/solitaire/card.rb
94
+ - lib/rubysketch/solitaire/common/animation.rb
95
+ - lib/rubysketch/solitaire/common/button.rb
96
+ - lib/rubysketch/solitaire/common/dialog.rb
97
+ - lib/rubysketch/solitaire/common/history.rb
98
+ - lib/rubysketch/solitaire/common/particle.rb
99
+ - lib/rubysketch/solitaire/common/scene.rb
100
+ - lib/rubysketch/solitaire/common/score.rb
101
+ - lib/rubysketch/solitaire/common/settings.rb
102
+ - lib/rubysketch/solitaire/common/shake.rb
103
+ - lib/rubysketch/solitaire/common/sound.rb
104
+ - lib/rubysketch/solitaire/common/timer.rb
105
+ - lib/rubysketch/solitaire/common/transitions.rb
106
+ - lib/rubysketch/solitaire/common/utils.rb
107
+ - lib/rubysketch/solitaire/extension.rb
108
+ - lib/rubysketch/solitaire/klondike.rb
109
+ - lib/rubysketch/solitaire/places.rb
110
+ - lib/rubysketch/solitaire/start.rb
111
+ - main.rb
112
+ - project.yml
113
+ - solitaire.gemspec
114
+ homepage: https://github.com/xord/solitaire
115
+ licenses:
116
+ - MIT
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: 3.0.0
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubygems_version: 3.4.10
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: Solitaire game made with RubySketch.
137
+ test_files: []