reight 0.1.2

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/release-gem.yml +62 -0
  3. data/.github/workflows/tag.yml +35 -0
  4. data/.github/workflows/test.yml +37 -0
  5. data/.github/workflows/utils.rb +56 -0
  6. data/.gitignore +1 -0
  7. data/ChangeLog.md +23 -0
  8. data/Gemfile +6 -0
  9. data/LICENSE +21 -0
  10. data/README.md +62 -0
  11. data/Rakefile +30 -0
  12. data/VERSION +1 -0
  13. data/bin/r8 +35 -0
  14. data/lib/reight/all.rb +59 -0
  15. data/lib/reight/app/map/brush.rb +27 -0
  16. data/lib/reight/app/map/brush_base.rb +54 -0
  17. data/lib/reight/app/map/canvas.rb +150 -0
  18. data/lib/reight/app/map/chips.rb +84 -0
  19. data/lib/reight/app/map/editor.rb +117 -0
  20. data/lib/reight/app/map/line.rb +35 -0
  21. data/lib/reight/app/map/rect.rb +29 -0
  22. data/lib/reight/app/map/tool.rb +32 -0
  23. data/lib/reight/app/map.rb +8 -0
  24. data/lib/reight/app/music/editor.rb +25 -0
  25. data/lib/reight/app/music.rb +1 -0
  26. data/lib/reight/app/navigator.rb +172 -0
  27. data/lib/reight/app/runner.rb +275 -0
  28. data/lib/reight/app/sound/editor.rb +25 -0
  29. data/lib/reight/app/sound.rb +1 -0
  30. data/lib/reight/app/sprite/brush.rb +43 -0
  31. data/lib/reight/app/sprite/canvas.rb +254 -0
  32. data/lib/reight/app/sprite/chips.rb +92 -0
  33. data/lib/reight/app/sprite/color.rb +30 -0
  34. data/lib/reight/app/sprite/editor.rb +272 -0
  35. data/lib/reight/app/sprite/fill.rb +45 -0
  36. data/lib/reight/app/sprite/line.rb +37 -0
  37. data/lib/reight/app/sprite/select.rb +58 -0
  38. data/lib/reight/app/sprite/shape.rb +43 -0
  39. data/lib/reight/app/sprite/tool.rb +27 -0
  40. data/lib/reight/app/sprite.rb +10 -0
  41. data/lib/reight/app.rb +123 -0
  42. data/lib/reight/button.rb +93 -0
  43. data/lib/reight/chip.rb +150 -0
  44. data/lib/reight/extension.rb +24 -0
  45. data/lib/reight/helpers.rb +69 -0
  46. data/lib/reight/history.rb +135 -0
  47. data/lib/reight/map.rb +264 -0
  48. data/lib/reight/project.rb +115 -0
  49. data/lib/reight/reight.rb +83 -0
  50. data/lib/reight.rb +18 -0
  51. data/reight.gemspec +40 -0
  52. data/res/icons.png +0 -0
  53. data/test/helper.rb +15 -0
  54. data/test/test_chip.rb +108 -0
  55. data/test/test_chip_list.rb +68 -0
  56. data/test/test_map.rb +232 -0
  57. data/test/test_map_chunk.rb +226 -0
  58. metadata +244 -0
@@ -0,0 +1,115 @@
1
+ using Reight
2
+
3
+
4
+ class Reight::Project
5
+
6
+ def initialize(project_dir)
7
+ raise 'the project directory is required' unless project_dir
8
+ @project_dir = project_dir
9
+ @settings = {}
10
+ load
11
+ end
12
+
13
+ attr_reader :project_dir, :settings
14
+
15
+ def project_path = "#{project_dir}/project.json"
16
+
17
+ def code_paths = settings[__method__]&.then {[_1].flatten} || ['game.rb']
18
+
19
+ def codes()
20
+ code_paths.map {File.read _1 rescue nil}
21
+ end
22
+
23
+ def chips_json_name = settings[__method__] || 'chips.json'
24
+
25
+ def chips_json_path = "#{project_dir}/#{chips_json_name}"
26
+
27
+ def chips()
28
+ @chips ||= load_chips
29
+ end
30
+
31
+ def chips_image_name = settings[__method__] || 'chips.png'
32
+
33
+ def chips_image_path = "#{project_dir}/#{chips_image_name}"
34
+
35
+ def chips_image_width = settings[__method__] || 1024
36
+
37
+ def chips_image_height = settings[__method__] || 1024
38
+
39
+ def chips_image()
40
+ @chips_image ||= -> {
41
+ create_graphics(chips_image_width, chips_image_height).tap do |g|
42
+ g.begin_draw {g.background 0, 0, 0}
43
+ img = load_image chips_image_path
44
+ g.begin_draw {g.image img, 0, 0}
45
+ rescue Rays::RaysError
46
+ end
47
+ }.call
48
+ end
49
+
50
+ def maps_json_name = settings[__method__] || 'maps.json'
51
+
52
+ def maps_json_path = "#{project_dir}/#{maps_json_name}"
53
+
54
+ def maps()
55
+ @maps ||= load_maps
56
+ end
57
+
58
+ def font = @font ||= create_font(nil, font_size)
59
+
60
+ def font_size = 8
61
+
62
+ def palette_colors = %w[
63
+ #000000 #1D2B53 #7E2553 #008751 #AB5236 #5F574F #C2C3C7 #FFF1E8
64
+ #FF004D #FFA300 #FFEC27 #00E436 #29ADFF #83769C #FF77A8 #FFCCAA
65
+ ]
66
+
67
+ def save()
68
+ File.write project_path, to_json_string(@settings)
69
+ save_chips
70
+ save_maps
71
+ end
72
+
73
+ private
74
+
75
+ def load()
76
+ @settings = JSON.parse File.read(project_path), symbolize_names: true
77
+ rescue Errno::ENOENT
78
+ @settings = {}
79
+ end
80
+
81
+ def save_chips()
82
+ File.write chips_json_path, to_json_string(chips.to_hash)
83
+ end
84
+
85
+ def load_chips()
86
+ if File.file? chips_json_path
87
+ json = JSON.parse File.read(chips_json_path), symbolize_names: true
88
+ Reight::ChipList.restore json, chips_image
89
+ else
90
+ Reight::ChipList.new chips_image
91
+ end
92
+ end
93
+
94
+ def save_maps()
95
+ File.write maps_json_path, to_json_string(maps.map {_1.to_hash})
96
+ end
97
+
98
+ def load_maps()
99
+ if File.file? maps_json_path
100
+ json = JSON.parse File.read(maps_json_path), symbolize_names: true
101
+ json.map {Reight::Map.restore _1, chips}
102
+ else
103
+ [Reight::Map.new]
104
+ end
105
+ end
106
+
107
+ def to_json_string(obj, readable: true)
108
+ if readable
109
+ JSON.pretty_generate obj
110
+ else
111
+ JSON.generate obj
112
+ end
113
+ end
114
+
115
+ end# Project
@@ -0,0 +1,83 @@
1
+ using Reight
2
+
3
+
4
+ class Reight::R8
5
+
6
+ def initialize(path)
7
+ raise if $r8__
8
+ $r8__ = self
9
+
10
+ @path = path
11
+ self.current = apps.first
12
+ end
13
+
14
+ attr_reader :current
15
+
16
+ def version()
17
+ '0.1'
18
+ end
19
+
20
+ def project()
21
+ @project ||= Reight::Project.new @path
22
+ end
23
+
24
+ def apps()
25
+ @apps ||= [
26
+ Reight::Runner.new(project),
27
+ Reight::SpriteEditor.new(project),
28
+ Reight::MapEditor.new(project),
29
+ Reight::SoundEditor.new(project),
30
+ Reight::MusicEditor.new(project)
31
+ ]
32
+ end
33
+
34
+ def flash(...) = current.flash(...)
35
+
36
+ def icons()
37
+ @icons ||= loadImage(File.expand_path('../../res/icons.png', __dir__)).tap do |img|
38
+ transp = color '#FF77A8'
39
+ img.load_pixels
40
+ img.pixels.map! {|c| c == transp ? color(0, 0, 0, 0) : c}
41
+ img.update_pixels
42
+ end
43
+ end
44
+
45
+ def current=(app)
46
+ return if app == @current
47
+ @current&.deactivated
48
+ @current = app
49
+ @current.activated
50
+
51
+ set_title [
52
+ self.class.name.split('::').first,
53
+ version,
54
+ '|',
55
+ current.class.name.split('::').last
56
+ ].join ' '
57
+ end
58
+
59
+ def setup()
60
+ w, h = Reight::App::SCREEN_WIDTH, Reight::App::SCREEN_HEIGHT
61
+ createCanvas w, h
62
+ window_resize(*[w, h].map {_1 * 3})
63
+ text_font r8.project.font, r8.project.font_size
64
+ end
65
+
66
+ def draw() = current.draw
67
+ def key_pressed() = current.key_pressed
68
+ def key_released() = current.key_released
69
+ def key_typed() = current.key_typed
70
+ def mouse_pressed() = current.mouse_pressed
71
+ def mouse_released() = current.mouse_released
72
+ def mouse_moved() = current.mouse_moved
73
+ def mouse_dragged() = current.mouse_dragged
74
+ def mouse_clicked() = current.mouse_clicked
75
+ def double_clicked() = current.double_clicked
76
+ def mouse_wheel() = current.mouse_wheel
77
+ def touch_started() = current.touch_started
78
+ def touch_ended() = current.touch_ended
79
+ def touch_moved() = current.touch_moved
80
+ def window_moved() = apps.each {_1.window_moved}
81
+ def window_resized() = apps.each {_1.window_resized}
82
+
83
+ end# R8
data/lib/reight.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'json'
2
+ require 'rubysketch/all'
3
+ require 'reight/all'
4
+
5
+
6
+ begin
7
+ w, c = Reight::WINDOW__, Reight::CONTEXT__
8
+
9
+ c.class.constants.reject {_1 =~ /__$/}.each do |const|
10
+ self.class.const_set const, c.class.const_get(const)
11
+ end
12
+
13
+ w.__send__ :begin_draw
14
+ at_exit do
15
+ w.__send__ :end_draw
16
+ Processing::App.new {w.show}.start if c.hasUserBlocks__ && !$!
17
+ end
18
+ end
data/reight.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # -*- mode: ruby -*-
2
+
3
+
4
+ require_relative 'lib/reight/extension'
5
+
6
+
7
+ Gem::Specification.new do |s|
8
+ glob = -> *patterns do
9
+ patterns.map {|pat| Dir.glob(pat).to_a}.flatten
10
+ end
11
+
12
+ ext = Reight::Extension
13
+ name = ext.name.downcase
14
+ rdocs = glob.call *%w[README]
15
+
16
+ s.name = name
17
+ s.version = ext.version
18
+ s.license = 'MIT'
19
+ s.summary = 'A Retro Game Engine for Ruby.'
20
+ s.description = 'A Retro Game Engine for Ruby.'
21
+ s.authors = %w[xordog]
22
+ s.email = 'xordog@gmail.com'
23
+ s.homepage = "https://github.com/xord/reight"
24
+
25
+ s.platform = Gem::Platform::RUBY
26
+ s.required_ruby_version = '>= 3.0.0'
27
+
28
+ s.add_dependency 'xot', '~> 0.3.2', '>= 0.3.2'
29
+ s.add_dependency 'rucy', '~> 0.3.2', '>= 0.3.2'
30
+ s.add_dependency 'beeps', '~> 0.3.2', '>= 0.3.2'
31
+ s.add_dependency 'rays', '~> 0.3.2', '>= 0.3.2'
32
+ s.add_dependency 'reflexion', '~> 0.3.2', '>= 0.3.2'
33
+ s.add_dependency 'processing', '~> 1.1', '>= 1.1.2'
34
+ s.add_dependency 'rubysketch', '~> 0.7.2', '>= 0.7.2'
35
+
36
+ s.files = `git ls-files`.split $/
37
+ s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
38
+ s.test_files = s.files.grep %r{^(test|spec|features)/}
39
+ s.extra_rdoc_files = rdocs.to_a
40
+ end
data/res/icons.png ADDED
Binary file
data/test/helper.rb ADDED
@@ -0,0 +1,15 @@
1
+ %w[../xot ../rucy ../beeps ../rays ../reflex ../processing ../rubysketch .]
2
+ .map {|s| File.expand_path "../#{s}/lib", __dir__}
3
+ .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
4
+
5
+ require 'xot/test'
6
+ require 'rubysketch/all'
7
+ require 'reight/all'
8
+
9
+ require 'test/unit'
10
+
11
+ include Xot::Test
12
+
13
+
14
+ R8 = Reight
15
+ RS = RubySketch
data/test/test_chip.rb ADDED
@@ -0,0 +1,108 @@
1
+ require_relative 'helper'
2
+ using Reight
3
+
4
+
5
+ class TestChip < Test::Unit::TestCase
6
+
7
+ def chip(...) = R8::Chip.new(...)
8
+
9
+ def image(w = 1, h = 1) = create_image w, h
10
+
11
+ def vec(...) = create_vector(...)
12
+
13
+ def test_initialize()
14
+ assert_equal 1, chip(1, image(2, 3), 4, 5, 6, 7) .id
15
+ assert_equal [2, 3], chip(1, image(2, 3), 4, 5, 6, 7) .image.size
16
+ assert_equal [4, 5, 6, 7], chip(1, image(2, 3), 4, 5, 6, 7) .frame
17
+ assert_nil chip(1, image(2, 3), 4, 5, 6, 7, pos: nil) .pos
18
+ assert_equal vec(8, 9), chip(1, image(2, 3), 4, 5, 6, 7, pos: vec(8, 9)).pos
19
+ assert_nil chip(1, image(2, 3), 4, 5, 6, 7) .shape
20
+ assert_nil chip(1, image(2, 3), 4, 5, 6, 7, shape: nil) .shape
21
+ assert_equal :rect, chip(1, image(2, 3), 4, 5, 6, 7, shape: :rect) .shape
22
+ assert_false chip(1, image(2, 3), 4, 5, 6, 7) .sensor?
23
+ assert_false chip(1, image(2, 3), 4, 5, 6, 7, sensor: false) .sensor?
24
+ assert_true chip(1, image(2, 3), 4, 5, 6, 7, sensor: true) .sensor?
25
+ end
26
+
27
+ def test_with()
28
+ i23 = image 2, 3
29
+ assert_equal 9, chip(1, i23, 4, 5, 6, 7) .with(id: 9) .id
30
+ assert_equal [8, 9], chip(1, i23, 4, 5, 6, 7) .with(image: image(8, 9)).image.size
31
+ assert_equal 9, chip(1, i23, 4, 5, 6, 7) .with(x: 9) .x
32
+ assert_equal 9, chip(1, i23, 4, 5, 6, 7) .with(y: 9) .y
33
+ assert_equal 9, chip(1, i23, 4, 5, 6, 7) .with(w: 9) .w
34
+ assert_equal 9, chip(1, i23, 4, 5, 6, 7) .with(h: 9) .h
35
+ assert_equal vec(10, 11), chip(1, i23, 4, 5, 6, 7, pos: nil) .with(pos: vec(10, 11)) .pos
36
+ assert_equal vec(10, 11), chip(1, i23, 4, 5, 6, 7, pos: vec(8, 9)).with(pos: vec(10, 11)) .pos
37
+ assert_equal :rect, chip(1, i23, 4, 5, 6, 7, shape: nil) .with(shape: :rect) .shape
38
+ assert_nil chip(1, i23, 4, 5, 6, 7, shape: :rect) .with(shape: nil) .shape
39
+ assert_true chip(1, i23, 4, 5, 6, 7, sensor: nil) .with(sensor: true) .sensor?
40
+ assert_false chip(1, i23, 4, 5, 6, 7, sensor: nil) .with(sensor: false) .sensor?
41
+ assert_false chip(1, i23, 4, 5, 6, 7, sensor: true) .with(sensor: false) .sensor?
42
+ assert_false chip(1, i23, 4, 5, 6, 7, sensor: true) .with(sensor: nil) .sensor?
43
+
44
+ i2030 = image 20, 30
45
+ c1 = chip 1, i23, 4, 5, 6, 7, pos: nil, shape: nil, sensor: nil
46
+ c2 = c1.with id: 10, image: i2030, x: 40, y: 50, w: 60, h: 70, pos: vec(80, 90), shape: :rect, sensor: true
47
+ assert_equal chip(1, i23, 4, 5, 6, 7, pos: nil, shape: nil, sensor: nil), c1
48
+ assert_equal chip(10, i2030, 40, 50, 60, 70, pos: vec(80, 90), shape: :rect, sensor: true), c2
49
+ end
50
+
51
+ def test_to_hash()
52
+ assert_equal(
53
+ {id: 1, x: 4, y: 5, w: 6, h: 7},
54
+ chip(1, image(2, 3), 4, 5, 6, 7).to_hash)
55
+ assert_equal(
56
+ {id: 1, x: 4, y: 5, w: 6, h: 7, pos: [8, 9], shape: :rect, sensor: true},
57
+ chip(1, image(2, 3), 4, 5, 6, 7, pos: vec(8, 9), shape: :rect, sensor: true).to_hash)
58
+ end
59
+
60
+ def test_compare()
61
+ i = image 8, 9
62
+ assert_equal(
63
+ chip(1, i, 2, 3, 4, 5, pos: nil, shape: nil, sensor: false),
64
+ chip(1, i, 2, 3, 4, 5, pos: nil, shape: nil, sensor: false))
65
+ assert_equal(
66
+ chip(1, i, 2, 3, 4, 5, pos: vec(6, 7), shape: :rect, sensor: true),
67
+ chip(1, i, 2, 3, 4, 5, pos: vec(6, 7), shape: :rect, sensor: true))
68
+
69
+ assert_not_equal(
70
+ chip(1, i, 2, 3, 4, 5),
71
+ chip(0, i, 2, 3, 4, 5))
72
+ assert_not_equal(
73
+ chip(1, i, 2, 3, 4, 5),
74
+ chip(1, i, 0, 3, 4, 5))
75
+ assert_not_equal(
76
+ chip(1, i, 2, 3, 4, 5),
77
+ chip(1, i, 2, 0, 4, 5))
78
+ assert_not_equal(
79
+ chip(1, i, 2, 3, 4, 5),
80
+ chip(1, i, 2, 3, 0, 5))
81
+ assert_not_equal(
82
+ chip(1, i, 2, 3, 4, 5),
83
+ chip(1, i, 2, 3, 4, 0))
84
+ assert_not_equal(
85
+ chip(1, i, 2, 3, 4, 5),
86
+ chip(1, image(8, 9), 2, 3, 4, 5))
87
+ assert_not_equal(
88
+ chip(1, i, 2, 3, 4, 5),
89
+ chip(1, i, 2, 3, 4, 5, pos: vec(6, 7)))
90
+ assert_not_equal(
91
+ chip(1, i, 2, 3, 4, 5),
92
+ chip(1, i, 2, 3, 4, 5, shape: :rect))
93
+ assert_not_equal(
94
+ chip(1, i, 2, 3, 4, 5),
95
+ chip(1, i, 2, 3, 4, 5, sensor: true))
96
+ end
97
+
98
+ def test_restore()
99
+ img = image 8, 9
100
+ assert_equal(
101
+ chip( 1, img, 2, 3, 4, 5, pos: nil, shape: nil, sensor: false),
102
+ R8::Chip.restore({id: 1, x: 2, y: 3, w: 4, h: 5, pos: nil, shape: nil, sensor: false}, img))
103
+ assert_equal(
104
+ chip( 1, img, 2, 3, 4, 5, pos: vec(6, 7), shape: :rect, sensor: true),
105
+ R8::Chip.restore({id: 1, x: 2, y: 3, w: 4, h: 5, pos: [6, 7], shape: :rect, sensor: true}, img))
106
+ end
107
+
108
+ end# TestChip
@@ -0,0 +1,68 @@
1
+ require_relative 'helper'
2
+ using Reight
3
+
4
+
5
+ class TestChipList < Test::Unit::TestCase
6
+
7
+ def chip(...) = R8::Chip.new(...)
8
+
9
+ def chips(...) = R8::ChipList.new(...)
10
+
11
+ def image(w = 100, h = 100) = create_image w, h
12
+
13
+ def test_initialize()
14
+ i = image
15
+ assert_equal i, chips(i).image
16
+ end
17
+
18
+ def test_at()
19
+ i = image
20
+ cs = chips i
21
+ assert_equal chip(1, i, 1, 2, 3, 4, shape: :rect), cs.at(1, 2, 3, 4)
22
+ assert_equal chip(2, i, 5, 6, 7, 8, shape: :rect), cs.at(5, 6, 7, 8)
23
+ assert_equal chip(1, i, 1, 2, 3, 4, shape: :rect), cs.at(1, 2, 3, 4)
24
+ end
25
+
26
+ def test_to_hash()
27
+ i = image
28
+ cs = chips(i).tap do |o|
29
+ o.at 1, 2, 3, 4
30
+ o.at 5, 6, 7, 8
31
+ end
32
+ assert_equal(
33
+ {
34
+ next_id: 3,
35
+ chips: [
36
+ {id: 1, x: 1, y: 2, w: 3, h: 4, shape: :rect},
37
+ {id: 2, x: 5, y: 6, w: 7, h: 8, shape: :rect}
38
+ ]
39
+ },
40
+ cs.to_hash)
41
+ end
42
+
43
+ def test_compare()
44
+ i = image
45
+ cs = chips(i).tap {_1.at 1, 2, 3, 4}
46
+
47
+ assert_equal cs, chips(i).tap {_1.at 1, 2, 3, 4}
48
+
49
+ assert_not_equal cs, chips(image 8, 9).tap {_1.at 0, 2, 3, 4}
50
+ assert_not_equal cs, chips(i)
51
+ assert_not_equal cs, chips(i) .tap {_1.at 0, 2, 3, 4}
52
+ assert_not_equal cs, chips(i) .tap {_1.at 1, 0, 3, 4}
53
+ assert_not_equal cs, chips(i) .tap {_1.at 1, 2, 0, 4}
54
+ assert_not_equal cs, chips(i) .tap {_1.at 1, 2, 3, 0}
55
+ assert_not_equal cs, chips(i).tap {
56
+ _1.at 1, 2, 3, 4
57
+ _1.at 5, 6, 7, 8
58
+ }
59
+ end
60
+
61
+ def test_restore()
62
+ img = image 8, 9
63
+ assert_equal(
64
+ chips(img).tap { _1.at 2, 3, 4, 5},
65
+ R8::ChipList.restore({next_id: 2, chips: [{id: 1, x: 2, y: 3, w: 4, h: 5, shape: :rect}]}, img))
66
+ end
67
+
68
+ end# TestChipList
data/test/test_map.rb ADDED
@@ -0,0 +1,232 @@
1
+ require_relative 'helper'
2
+ using Reight
3
+
4
+
5
+ class TestMap < Test::Unit::TestCase
6
+
7
+ def map(...) = R8::Map.new(...)
8
+
9
+ def chunk(...) = R8::Map::Chunk.new(...)
10
+
11
+ def chip(x, y, w, h, id: 1, image: self.image, pos: nil) =
12
+ R8::Chip.new id, image, x, y, w, h, pos: pos
13
+
14
+ def image(w = 1, h = 1) = create_image w, h
15
+
16
+ def vec(...) = create_vector(...)
17
+
18
+ def test_initialize()
19
+ assert_nothing_raised {map chip_size: 2, chunk_size: 6}
20
+ assert_raise(ArgumentError) {map chip_size: 2, chunk_size: 7}
21
+ assert_raise(ArgumentError) {map chip_size: 2.2, chunk_size: 6}
22
+ assert_raise(ArgumentError) {map chip_size: 2, chunk_size: 6.6}
23
+ end
24
+
25
+ def test_put()
26
+ img = image
27
+ new_chip = -> id, size, pos: nil {
28
+ chip 0, 0, size, size, id: id, image: img, pos: pos
29
+ }
30
+
31
+ map(chip_size: 10, chunk_size: 30).tap do |m|
32
+ assert_equal 0, count_all_chips(m)
33
+ end
34
+
35
+ map(chip_size: 10, chunk_size: 30).tap do |m|
36
+ m.put 10, 20, new_chip[1, 10]
37
+ assert_equal new_chip[1, 10, pos: vec(10, 20)], m[10, 20]
38
+ assert_equal 1, count_all_chips(m)
39
+ end
40
+
41
+ map(chip_size: 10, chunk_size: 30).tap do |m|
42
+ m.put(-10, -20, new_chip[1, 10])
43
+ assert_equal new_chip[1, 10, pos: vec(-10, -20)], m[-10, -20]
44
+ assert_equal 1, count_all_chips(m)
45
+ end
46
+
47
+ map(chip_size: 10, chunk_size: 30).tap do |m|
48
+ m.put 15, 25, new_chip[2, 10]
49
+ assert_equal new_chip[2, 10, pos: vec(10, 20)], m[15, 25]
50
+ assert_equal new_chip[2, 10, pos: vec(10, 20)], m[10, 20]
51
+ assert_equal 1, count_all_chips(m)
52
+ end
53
+
54
+ map(chip_size: 10, chunk_size: 30).tap do |m|
55
+ m.put 10.1, 20.2, new_chip[3, 10]
56
+ assert_equal new_chip[3, 10, pos: vec(10, 20)], m[10.1, 20.2]
57
+ assert_equal new_chip[3, 10, pos: vec(10, 20)], m[10, 20]
58
+ assert_equal 1, count_all_chips(m)
59
+ end
60
+
61
+ map(chip_size: 10, chunk_size: 30).tap do |m|
62
+ m.put 15, 25, new_chip[4, 20]
63
+ assert_equal new_chip[4, 20, pos: vec(10, 20)], m[15, 25]
64
+ assert_equal new_chip[4, 20, pos: vec(10, 20)], m[10, 20]
65
+ assert_equal new_chip[4, 20, pos: vec(10, 20)], m[25, 25]
66
+ assert_equal new_chip[4, 20, pos: vec(10, 20)], m[20, 20]
67
+ assert_equal new_chip[4, 20, pos: vec(10, 20)], m[15, 35]
68
+ assert_equal new_chip[4, 20, pos: vec(10, 20)], m[10, 30]
69
+ assert_equal new_chip[4, 20, pos: vec(10, 20)], m[25, 35]
70
+ assert_equal new_chip[4, 20, pos: vec(10, 20)], m[20, 30]
71
+ assert_equal 4, count_all_chips(m)
72
+
73
+ assert_equal m[10, 20].object_id, m[20, 20].object_id
74
+ assert_equal m[10, 30].object_id, m[20, 30].object_id
75
+ assert_not_equal m[10, 20].object_id, m[10, 30].object_id
76
+ end
77
+
78
+ map(chip_size: 10, chunk_size: 30).tap do |m|
79
+ assert_nothing_raised {m.put 10, 20, chip(0, 0, 10, 10)}
80
+ assert_raise {m.put 10, 20, chip(0, 0, 10, 10)}
81
+ end
82
+ end
83
+
84
+ def test_delete()
85
+ [
86
+ [0, 0], [10, 20], [90, 90]
87
+ ].each do |xx, yy|
88
+ map(chip_size: 10, chunk_size: 30).tap do |m|
89
+ m.delete xx, yy
90
+ assert_equal 0, count_all_chips(m)
91
+ end
92
+ end
93
+
94
+ [
95
+ [10, 20, 0], [11, 21, 0], [15, 25, 0], [19, 29, 0],
96
+ [ 9, 19, 1], [20, 30, 1],
97
+ [19.999, 29.999, 0],
98
+ [ 9.999, 19.999, 1]
99
+ ].each do |xx, yy, count|
100
+ map(chip_size: 10, chunk_size: 30).tap do |m|
101
+ m.put 10, 20, chip(0, 0, 10, 10)
102
+ assert_equal 1, count_all_chips(m)
103
+ m.delete xx, yy
104
+ assert_equal count, count_all_chips(m)
105
+ end
106
+ end
107
+
108
+ [
109
+ [10, 20, 0], [20, 20, 0], [10, 30, 0], [20, 30, 0],
110
+ [29, 30, 0], [20, 39, 0], [29, 39, 0],
111
+ [ 9, 19, 4], [30, 40, 4],
112
+ [29.999, 39.999, 0], [29.999, 30, 0], [20, 39.999, 0],
113
+ [ 9.999, 19.999, 4],
114
+ ].each do |xx, yy, count|
115
+ map(chip_size: 10, chunk_size: 30).tap do |m|
116
+ m.put 10, 20, chip(0, 0, 20, 20)
117
+ assert_equal 4, count_all_chips(m)
118
+ m.delete xx, yy
119
+ assert_equal count, count_all_chips(m)
120
+ end
121
+ end
122
+ end
123
+
124
+ def test_delete_chip()
125
+ map(chip_size: 10, chunk_size: 30).tap do |m|
126
+ m.put 10, 20, chip(0, 0, 10, 10)
127
+ assert_equal 1, count_all_chips(m)
128
+ m.delete_chip m[10, 20]
129
+ assert_equal 0, count_all_chips(m)
130
+ end
131
+ end
132
+
133
+ def test_each_chip()
134
+ m = map chip_size: 10, chunk_size: 30
135
+ m.put 10, 20, chip(0, 0, 10, 10, id: 1)
136
+ m.put 20, 30, chip(0, 0, 20, 20, id: 2)
137
+ m.put 100, 200, chip(0, 0, 10, 10, id: 3)
138
+
139
+ assert_equal(
140
+ [],
141
+ m.each_chip( 0, 0, 10, 20).map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
142
+ assert_equal(
143
+ [[1, 10, 20]],
144
+ m.each_chip( 0, 0, 11, 21).map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
145
+ assert_equal(
146
+ [],
147
+ m.each_chip(20, 20, 10, 10).map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
148
+ assert_equal(
149
+ [[1, 10, 20]],
150
+ m.each_chip(19, 20, 10, 10).map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
151
+ assert_equal(
152
+ [],
153
+ m.each_chip(10, 30, 10, 10).map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
154
+ assert_equal(
155
+ [[1, 10, 20]],
156
+ m.each_chip(10, 29, 10, 10).map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
157
+ assert_equal(
158
+ [[1, 10, 20]],
159
+ m.each_chip(0, 0, 30, 30).map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
160
+ assert_equal(
161
+ [[1, 10, 20], [2, 20, 30]],
162
+ m.each_chip(0, 0, 31, 31).map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
163
+ assert_equal(
164
+ [[1, 10, 20], [2, 20, 30], [3, 100, 200]],
165
+ m.each_chip .map {|chip| [chip.id, chip.pos.x, chip.pos.y]})
166
+ end
167
+
168
+ def test_to_hash()
169
+ assert_equal(
170
+ {
171
+ chip_size: 10, chunk_size: 30,
172
+ chunks: [{x: 30, y: 30, w: 30, h: 30, chip_size: 10, chips: [nil,nil,nil, [1, 30, 40]]}]
173
+ },
174
+ map(chip_size: 10, chunk_size: 30).tap {_1.put 30, 40, chip(0, 0, 10, 10, id: 1)}.to_hash)
175
+ end
176
+
177
+ def test_compare()
178
+ assert_not_equal map(chip_size: 10, chunk_size: 20), map(chip_size: 1, chunk_size: 20)
179
+ assert_not_equal map(chip_size: 10, chunk_size: 20), map(chip_size: 10, chunk_size: 10)
180
+
181
+ m1, m2 = map(chip_size: 10, chunk_size: 30), map(chip_size: 10, chunk_size: 30)
182
+ assert_equal m1, m2
183
+
184
+ img = image
185
+ m1.put 10, 20, chip(0, 0, 10, 10, id: 1, image: img); assert_not_equal m1, m2
186
+ m2.put 10, 20, chip(0, 0, 10, 10, id: 1, image: img); assert_equal m1, m2
187
+ m2.delete 10, 20
188
+ m2.put 10, 20, chip(0, 0, 10, 10, id: 2, image: img); assert_not_equal m1, m2
189
+ end
190
+
191
+ def test_restore()
192
+ img = image
193
+ chips = R8::ChipList.restore({
194
+ next_id: 3, chips: [
195
+ {id: 1, x: 0, y: 0, w: 10, h: 10},
196
+ {id: 2, x: 0, y: 0, w: 20, h: 20},
197
+ ]
198
+ }, img)
199
+ restored = R8::Map.restore({
200
+ chip_size: 10, chunk_size: 30, chunks: [
201
+ {
202
+ x: 0, y: 0, w: 30, h: 30, chip_size: 10,
203
+ chips: [nil,nil,nil, nil,nil,[2,20,10], nil,[1,10,20],[2,20,10]]
204
+ },
205
+ {
206
+ x: 30, y: 0, w: 30, h: 30, chip_size: 10,
207
+ chips: [nil,nil,nil, [2,20,10],nil,nil, [2,20,10]]
208
+ },
209
+ ]
210
+ }, chips)
211
+
212
+ assert_equal(
213
+ map(chip_size: 10, chunk_size: 30).tap {
214
+ _1.put 10, 20, chip(0, 0, 10, 10, id: 1, image: img)
215
+ _1.put 20, 10, chip(0, 0, 20, 20, id: 2, image: img)
216
+ },
217
+ restored)
218
+ assert_equal restored[20, 10].object_id, restored[20, 20].object_id
219
+ assert_equal restored[30, 10].object_id, restored[30, 20].object_id
220
+ assert_not_equal restored[20, 10].object_id, restored[30, 10].object_id
221
+ end
222
+
223
+ private
224
+
225
+ def count_all_chips(map_, map_size = 90, chip_size: 10)
226
+ range = (-map_size...map_size).step(chip_size).to_a
227
+ range.product(range)
228
+ .map {|x, y| map_[x, y]}
229
+ .count {_1 != nil}
230
+ end
231
+
232
+ end# TestMap