ruby_arena 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +31 -0
- data/LICENSE.txt +22 -0
- data/README.md +118 -0
- data/Rakefile +5 -0
- data/bin/ruby_arena +7 -0
- data/lib/ruby_arena/ai.rb +68 -0
- data/lib/ruby_arena/arena.rb +75 -0
- data/lib/ruby_arena/bullet.rb +53 -0
- data/lib/ruby_arena/bullet_renderer.rb +53 -0
- data/lib/ruby_arena/class_loader.rb +20 -0
- data/lib/ruby_arena/command_parser.rb +41 -0
- data/lib/ruby_arena/game.rb +74 -0
- data/lib/ruby_arena/gui.rb +62 -0
- data/lib/ruby_arena/level.rb +42 -0
- data/lib/ruby_arena/level0.rb +6 -0
- data/lib/ruby_arena/level1.rb +9 -0
- data/lib/ruby_arena/movable.rb +18 -0
- data/lib/ruby_arena/option_parser.rb +29 -0
- data/lib/ruby_arena/robot.rb +196 -0
- data/lib/ruby_arena/robot_renderer.rb +180 -0
- data/lib/ruby_arena/value_sanitizer.rb +11 -0
- data/lib/ruby_arena/version.rb +3 -0
- data/lib/ruby_arena.rb +23 -0
- data/ruby_arena.gemspec +25 -0
- data/screenshot.png +0 -0
- data/spec/ai_spec.rb +11 -0
- data/spec/ai_test.rb +11 -0
- data/spec/arena_spec.rb +79 -0
- data/spec/bullet_renderer_spec.rb +4 -0
- data/spec/bullet_spec.rb +36 -0
- data/spec/class_loader_spec.rb +14 -0
- data/spec/command_parser_spec.rb +72 -0
- data/spec/fake_gui.rb +28 -0
- data/spec/game_spec.rb +4 -0
- data/spec/gui_spec.rb +50 -0
- data/spec/level_spec.rb +29 -0
- data/spec/movable_tests.rb +48 -0
- data/spec/option_parser_spec.rb +49 -0
- data/spec/robot_renderer_spec.rb +4 -0
- data/spec/robot_spec.rb +294 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/value_sanitizer_spec.rb +21 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a7683767c61f9ba12e956de9c4a7ddaff97653fc
|
4
|
+
data.tar.gz: 6b613e090ef7477e2c0b6bd0f4c4680fdbc67881
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3b358f8e27cecf896b8bdfd39400a5fe623d0a662505ebe63f0020f909f8e44e52c20116c2f276d95ff034903f0c42427dbe0b529922236fdb9262686465f69b
|
7
|
+
data.tar.gz: ae3790d093b6a7597cd72d92cba6b7835d21e6de8d417cb741d683de54be98304221879ccc8fa16a53da05b726a58e9c3ef0be276bdf1926a2c298ae32e9fa25
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
rvm:
|
2
|
+
- 2.1.0
|
3
|
+
before_install:
|
4
|
+
- sudo apt-get update -qq
|
5
|
+
- sudo apt-get install -qq build-essential freeglut3-dev libfreeimage-dev libgl1-mesa-dev libopenal-dev libpango1.0-dev libsdl-ttf2.0-dev libsndfile-dev libxinerama-dev
|
6
|
+
script:
|
7
|
+
- bundle exec rspec spec/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ruby_arena (0.0.1.alpha)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.2.5)
|
10
|
+
gosu (0.7.50)
|
11
|
+
rake (10.1.1)
|
12
|
+
rspec (3.0.0.beta1)
|
13
|
+
rspec-core (= 3.0.0.beta1)
|
14
|
+
rspec-expectations (= 3.0.0.beta1)
|
15
|
+
rspec-mocks (= 3.0.0.beta1)
|
16
|
+
rspec-core (3.0.0.beta1)
|
17
|
+
rspec-expectations (3.0.0.beta1)
|
18
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
19
|
+
rspec-support (= 3.0.0.beta1)
|
20
|
+
rspec-mocks (3.0.0.beta1)
|
21
|
+
rspec-support (3.0.0.beta1)
|
22
|
+
|
23
|
+
PLATFORMS
|
24
|
+
ruby
|
25
|
+
|
26
|
+
DEPENDENCIES
|
27
|
+
bundler (~> 1.5)
|
28
|
+
gosu
|
29
|
+
rake
|
30
|
+
rspec (~> 3.0.0.beta1)
|
31
|
+
ruby_arena!
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Patrik Bóna
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# ruby_arena
|
2
|
+
[](https://codeclimate.com/github/mrhead/ruby_arena)
|
4
|
+
[](https://travis-ci.org/mrhead/ruby_arena)
|
5
|
+
|
6
|
+

|
7
|
+
|
8
|
+
Ruby Arena is a game for programmers and people who wants to learn how to program in Ruby.
|
9
|
+
|
10
|
+
Instead of controling your robot with keys you have to program its AI (artifical intelligence) and see if it can beat other robots!
|
11
|
+
|
12
|
+
This project has been inspired by [robocode][robocode] (Java, .NET) and [rrobots][rrobots] (Ruby).
|
13
|
+
|
14
|
+
## Goals of the project
|
15
|
+
|
16
|
+
- create arena from scratch
|
17
|
+
- learn
|
18
|
+
- have fun!
|
19
|
+
|
20
|
+
## How to run arena (and battles)
|
21
|
+
|
22
|
+
```
|
23
|
+
git@github.com:mrhead/ruby_arena.git
|
24
|
+
cd ruby_arena
|
25
|
+
bundle # or gem install gosu
|
26
|
+
./bin/ruby_arena.rb path_to/robot.rb path_to/another_robot.rb
|
27
|
+
```
|
28
|
+
|
29
|
+
You can run game with some predefined robots (levels).
|
30
|
+
|
31
|
+
```
|
32
|
+
./bin/ruby_arena.rb -l 0 path_to/your_ai.rb
|
33
|
+
```
|
34
|
+
|
35
|
+
You can see example robot here: https://gist.github.com/mrhead/7917528. Just put it to some dir in ruby_arena.
|
36
|
+
|
37
|
+
```
|
38
|
+
./bin/ruby_arena.rb test_robots/test_ai.rb test_robots/test_ai.rb # ...
|
39
|
+
```
|
40
|
+
|
41
|
+
### Example robots (AIs)
|
42
|
+
|
43
|
+
If you have your own robot (well AI), then please publish it as gist and then add it here:
|
44
|
+
|
45
|
+
* https://gist.github.com/mrhead/7917528
|
46
|
+
* https://gist.github.com/mrhead/8086991
|
47
|
+
* https://gist.github.com/mrhead/8087011
|
48
|
+
|
49
|
+
Please note that mentioned Ais are not were nice (code) and pretty stupid right now, but at least you can try to run them.
|
50
|
+
|
51
|
+
### How to create your own robot (AI)
|
52
|
+
|
53
|
+
Just extend `Ai` class and implement your own `#tick` method.
|
54
|
+
|
55
|
+
```
|
56
|
+
class TestAi < Ai
|
57
|
+
def tick(events)
|
58
|
+
fire # do nothing but fire when possible
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
### API for AI
|
64
|
+
|
65
|
+
AI api is very similar to robot api from [rrobots][rrobots].
|
66
|
+
|
67
|
+
```
|
68
|
+
# change speed by 1, max to 8
|
69
|
+
accelerate
|
70
|
+
|
71
|
+
# change speed by -1, min to -8
|
72
|
+
decelerate
|
73
|
+
|
74
|
+
# turn robot, gun and radar
|
75
|
+
turn(angle)
|
76
|
+
|
77
|
+
# turn gun and radar
|
78
|
+
turn_gun(angle)
|
79
|
+
|
80
|
+
# turn radar
|
81
|
+
turn_radar(angle)
|
82
|
+
|
83
|
+
# fire a bullet
|
84
|
+
fire
|
85
|
+
|
86
|
+
# change radar view angle
|
87
|
+
set_radar_view_angle(angle)
|
88
|
+
```
|
89
|
+
|
90
|
+
You can do each action just once in each tick, so:
|
91
|
+
|
92
|
+
```
|
93
|
+
turn(2)
|
94
|
+
turn(2)
|
95
|
+
```
|
96
|
+
|
97
|
+
Will do just turn by 2 degrees. In is the same for other actions.
|
98
|
+
|
99
|
+
## Current status
|
100
|
+
|
101
|
+
Project is in very early stage with unstable API. Any contribution (your own robot, reported issue, new pull request, advice regarding code/OO design) is very much appreciated.
|
102
|
+
|
103
|
+
However you can already start the game and the battle between robots! Detais were mentioned above.
|
104
|
+
|
105
|
+
## How to contribute
|
106
|
+
|
107
|
+
1. Fork the repo
|
108
|
+
2. Create your own branch
|
109
|
+
3. Do your changes
|
110
|
+
4. Create pull request
|
111
|
+
|
112
|
+
### Rules for contribution
|
113
|
+
|
114
|
+
* Everything needs to be tested! Well not everything. I really do not have an idea how to test Gui. But rest of the code must be tested before merging to master. If you do not now how to test it, than open new issue and we can discuss it.
|
115
|
+
* If something is hard to implement or change, then please refactor the code first so change is easy and then implement it.
|
116
|
+
|
117
|
+
[robocode]: http://robocode.sourceforge.net/
|
118
|
+
[rrobots]: http://rrobots.rubyforge.org/
|
data/Rakefile
ADDED
data/bin/ruby_arena
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class Ai
|
3
|
+
attr_reader :robot, :command_parser
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@robot = args.fetch(:robot)
|
7
|
+
@command_parser = args.fetch(:command_parser)
|
8
|
+
end
|
9
|
+
|
10
|
+
def tick
|
11
|
+
raise NotImplementedError, 'Your robot should implement tick method'
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def x
|
17
|
+
@robot.x
|
18
|
+
end
|
19
|
+
|
20
|
+
def y
|
21
|
+
@robot.y
|
22
|
+
end
|
23
|
+
|
24
|
+
def speed
|
25
|
+
@robot.speed
|
26
|
+
end
|
27
|
+
|
28
|
+
def heading
|
29
|
+
@robot.heading
|
30
|
+
end
|
31
|
+
|
32
|
+
def time
|
33
|
+
robot.time
|
34
|
+
end
|
35
|
+
|
36
|
+
def radar_view_angle
|
37
|
+
robot.radar_view_angle
|
38
|
+
end
|
39
|
+
|
40
|
+
def turn(angle)
|
41
|
+
command_parser.turn(angle)
|
42
|
+
end
|
43
|
+
|
44
|
+
def turn_gun(angle)
|
45
|
+
command_parser.turn_gun(angle)
|
46
|
+
end
|
47
|
+
|
48
|
+
def turn_radar(angle)
|
49
|
+
command_parser.turn_radar(angle)
|
50
|
+
end
|
51
|
+
|
52
|
+
def accelerate
|
53
|
+
command_parser.accelerate
|
54
|
+
end
|
55
|
+
|
56
|
+
def decelerate
|
57
|
+
command_parser.decelerate
|
58
|
+
end
|
59
|
+
|
60
|
+
def fire
|
61
|
+
command_parser.fire
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_radar_view_angle(angle)
|
65
|
+
command_parser.radar_view_angle(angle)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class Arena
|
3
|
+
WIDTH = 800
|
4
|
+
HEIGHT = 600
|
5
|
+
|
6
|
+
attr_reader :robots, :bullets, :time, :total_robots_count
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@robots = []
|
10
|
+
@bullets = []
|
11
|
+
@time = 0
|
12
|
+
@total_robots_count = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_robot(robot)
|
16
|
+
@robots << robot
|
17
|
+
@total_robots_count += 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_bullet(bullet)
|
21
|
+
@bullets << bullet
|
22
|
+
end
|
23
|
+
|
24
|
+
def update
|
25
|
+
send_tick_to_all_robots
|
26
|
+
send_update_to_all_robots
|
27
|
+
send_update_to_all_bullets
|
28
|
+
remove_dead_robots
|
29
|
+
remove_dead_bullets
|
30
|
+
update_time
|
31
|
+
end
|
32
|
+
|
33
|
+
def game_over?
|
34
|
+
robots_count <= 1 and total_robots_count > 1
|
35
|
+
end
|
36
|
+
|
37
|
+
def robots_count
|
38
|
+
robots.count
|
39
|
+
end
|
40
|
+
|
41
|
+
def width
|
42
|
+
WIDTH
|
43
|
+
end
|
44
|
+
|
45
|
+
def height
|
46
|
+
HEIGHT
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def send_tick_to_all_robots
|
52
|
+
robots.each(&:tick)
|
53
|
+
end
|
54
|
+
|
55
|
+
def send_update_to_all_robots
|
56
|
+
robots.each(&:update)
|
57
|
+
end
|
58
|
+
|
59
|
+
def send_update_to_all_bullets
|
60
|
+
bullets.each(&:update)
|
61
|
+
end
|
62
|
+
|
63
|
+
def remove_dead_robots
|
64
|
+
robots.delete_if { |robot| robot.dead? }
|
65
|
+
end
|
66
|
+
|
67
|
+
def remove_dead_bullets
|
68
|
+
bullets.delete_if { |bullet| bullet.dead? }
|
69
|
+
end
|
70
|
+
|
71
|
+
def update_time
|
72
|
+
@time += 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class Bullet
|
3
|
+
include Movable
|
4
|
+
|
5
|
+
DEFAULT_SPEED = 10
|
6
|
+
DEFAULT_ENERGY = 10
|
7
|
+
SIZE = 4
|
8
|
+
|
9
|
+
attr_reader :x, :y, :heading, :speed, :arena, :origin
|
10
|
+
|
11
|
+
def initialize(args)
|
12
|
+
@x = args.fetch(:x)
|
13
|
+
@y = args.fetch(:y)
|
14
|
+
@heading = args.fetch(:heading)
|
15
|
+
@speed = args.fetch(:speed, DEFAULT_SPEED)
|
16
|
+
@arena = args.fetch(:arena)
|
17
|
+
@origin = args.fetch(:origin)
|
18
|
+
@dead = false
|
19
|
+
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
move
|
23
|
+
check_if_hit_some_robot
|
24
|
+
end
|
25
|
+
|
26
|
+
def intersect?(object)
|
27
|
+
Gosu.distance(x, y, object.x, object.y) < size/2 + object.size/2
|
28
|
+
end
|
29
|
+
|
30
|
+
def size
|
31
|
+
SIZE
|
32
|
+
end
|
33
|
+
|
34
|
+
def energy
|
35
|
+
DEFAULT_ENERGY
|
36
|
+
end
|
37
|
+
|
38
|
+
def dead?
|
39
|
+
@dead
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def check_if_hit_some_robot
|
45
|
+
arena.robots.each do |robot|
|
46
|
+
if robot != origin && intersect?(robot)
|
47
|
+
robot.hit(self)
|
48
|
+
@dead = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class BulletRenderer
|
3
|
+
attr_reader :bullet, :window
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@bullet = args.fetch(:bullet)
|
7
|
+
@window = args.fetch(:window)
|
8
|
+
end
|
9
|
+
|
10
|
+
def draw
|
11
|
+
window.draw_quad(
|
12
|
+
x1, y1, color,
|
13
|
+
x1, y2, color,
|
14
|
+
x2, y2, color,
|
15
|
+
x2, y1, color
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def x1
|
22
|
+
x - size/2
|
23
|
+
end
|
24
|
+
|
25
|
+
def x2
|
26
|
+
x + size/2
|
27
|
+
end
|
28
|
+
|
29
|
+
def y1
|
30
|
+
y - size/2
|
31
|
+
end
|
32
|
+
|
33
|
+
def y2
|
34
|
+
y + size/2
|
35
|
+
end
|
36
|
+
|
37
|
+
def x
|
38
|
+
bullet.x
|
39
|
+
end
|
40
|
+
|
41
|
+
def y
|
42
|
+
bullet.y
|
43
|
+
end
|
44
|
+
|
45
|
+
def color
|
46
|
+
Gosu::Color::YELLOW
|
47
|
+
end
|
48
|
+
|
49
|
+
def size
|
50
|
+
bullet.size
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class ClassLoader
|
3
|
+
attr_reader :filename
|
4
|
+
|
5
|
+
def initialize(filename)
|
6
|
+
@filename = filename
|
7
|
+
require filename
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_class
|
11
|
+
Object.const_get(class_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def class_name
|
17
|
+
File.basename(filename, '.rb').split('_').map(&:capitalize).join
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class CommandParser
|
3
|
+
attr_reader :actions
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
reset_actions
|
7
|
+
end
|
8
|
+
|
9
|
+
def turn(angle)
|
10
|
+
@actions[:turn] = angle
|
11
|
+
end
|
12
|
+
|
13
|
+
def turn_gun(angle)
|
14
|
+
@actions[:turn_gun] = angle
|
15
|
+
end
|
16
|
+
|
17
|
+
def turn_radar(angle)
|
18
|
+
@actions[:turn_radar] = angle
|
19
|
+
end
|
20
|
+
|
21
|
+
def accelerate
|
22
|
+
@actions[:accelerate] = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def decelerate
|
26
|
+
@actions[:decelerate] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
def fire
|
30
|
+
@actions[:fire] = true
|
31
|
+
end
|
32
|
+
|
33
|
+
def radar_view_angle(angle)
|
34
|
+
@actions[:radar_view_angle] = angle
|
35
|
+
end
|
36
|
+
|
37
|
+
def reset_actions
|
38
|
+
@actions = {}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class Game
|
3
|
+
attr_reader :arena, :level
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@arena = Arena.new
|
7
|
+
@robot_files = args[:robot_files]
|
8
|
+
@level = Level.new(args[:options][:level]) if args[:options][:level]
|
9
|
+
add_robots_to_arena
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
gui.show
|
14
|
+
end
|
15
|
+
|
16
|
+
def game_over?
|
17
|
+
arena.game_over?
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def gui
|
23
|
+
Gui.new(arena)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_robots_to_arena
|
27
|
+
add_user_robots
|
28
|
+
add_cpu_robots if level
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_user_robots
|
32
|
+
user_robots.each do |robot|
|
33
|
+
add_robot(robot)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def user_robots
|
38
|
+
@robot_files.map do |file|
|
39
|
+
ai_class = load_class_from_file(file)
|
40
|
+
|
41
|
+
Robot.new(options_for_user_robot(ai_class))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def options_for_user_robot(ai_class)
|
46
|
+
options = { arena: arena, ai: ai_class }
|
47
|
+
options.merge!(level.options_for_user_robot) if level
|
48
|
+
options
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_cpu_robots
|
52
|
+
options_for_user_robots.each do |options|
|
53
|
+
options.merge!({ arena: arena })
|
54
|
+
add_robot(Robot.new(options))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def options_for_user_robots
|
59
|
+
level.options_for_cpu_robots
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_robot(robot)
|
63
|
+
arena.add_robot(robot)
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_class_from_file(file)
|
67
|
+
ClassLoader.new("#{pwd}/#{file}").get_class
|
68
|
+
end
|
69
|
+
|
70
|
+
def pwd
|
71
|
+
Dir.getwd
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class Gui < Gosu::Window
|
3
|
+
WIDTH = 800
|
4
|
+
HEIGHT = 600
|
5
|
+
|
6
|
+
attr_reader :arena, :robot_renderers
|
7
|
+
|
8
|
+
def initialize(arena)
|
9
|
+
@arena = arena
|
10
|
+
@_robot_renderers = {}
|
11
|
+
@_bullet_renderers = {}
|
12
|
+
super(width, height, false)
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
arena.update
|
17
|
+
end
|
18
|
+
|
19
|
+
def draw
|
20
|
+
draw_robots
|
21
|
+
draw_bullets
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def width
|
27
|
+
arena.width
|
28
|
+
end
|
29
|
+
|
30
|
+
def height
|
31
|
+
arena.height
|
32
|
+
end
|
33
|
+
|
34
|
+
def draw_robots
|
35
|
+
robots.each do |robot|
|
36
|
+
robot_renderer(robot).draw
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def draw_bullets
|
41
|
+
bullets.each do |bullet|
|
42
|
+
bullet_renderer(bullet).draw
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def robot_renderer(robot)
|
47
|
+
@_robot_renderers[robot] ||= RobotRenderer.new(window: self, robot: robot)
|
48
|
+
end
|
49
|
+
|
50
|
+
def bullet_renderer(bullet)
|
51
|
+
@_bullet_renderers[bullet] ||= BulletRenderer.new(window: self, bullet: bullet)
|
52
|
+
end
|
53
|
+
|
54
|
+
def robots
|
55
|
+
arena.robots
|
56
|
+
end
|
57
|
+
|
58
|
+
def bullets
|
59
|
+
arena.bullets
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RubyArena
|
2
|
+
class Level
|
3
|
+
LEVELS = {
|
4
|
+
0 => {
|
5
|
+
robots: [
|
6
|
+
{ ai: Level0, x: 600, y: 300 }
|
7
|
+
],
|
8
|
+
user_robot_options: { x: 200, y: 300 }
|
9
|
+
},
|
10
|
+
1 => {
|
11
|
+
robots: [
|
12
|
+
{ ai: Level1, x: 600, y: 300 }
|
13
|
+
],
|
14
|
+
user_robot_options: { x: 200, y: 300 }
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
attr_reader :level
|
19
|
+
|
20
|
+
def initialize(level)
|
21
|
+
@level = level
|
22
|
+
exit_if_level_is_not_defined
|
23
|
+
end
|
24
|
+
|
25
|
+
def options_for_cpu_robots
|
26
|
+
LEVELS[level][:robots]
|
27
|
+
end
|
28
|
+
|
29
|
+
def options_for_user_robot
|
30
|
+
LEVELS[level][:user_robot_options]
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def exit_if_level_is_not_defined
|
36
|
+
if LEVELS[level].nil?
|
37
|
+
puts "Level is not defined"
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|