[ANN] RRobots - ducks, armed and dangerous

RRobots v0.1

First there was CRobots, followed by PRobots and many others,
recently (well also years ago) Robocode emerged and finally
this is RRobots bringing all the fun to the ruby community.

What is he talking about?

RRobots is a simulation environment for robots, these robots have
a scanner and a gun, can move forward and backwards and are entirely
controlled by ruby scripts. All robots are equal (well at the moment,
maybe this will change) except for the ai.

A simple robot script may look like this:
----------------------- code -----------------------
require 'robot'

class NervousDuck
    include Robot

   def tick events
     turn_radar 1 if time == 0
     turn_gun 30 if time < 3
     accelerate 1
     turn 2
     fire 3 unless events['robot_scanned'].empty?
   end
end
----------------------- code -----------------------

all you need to implement is the tick method which should
accept a hash of events occured turing the last tick.

By including Robot you get all this methods to controll your bot:

   battlefield_height #the height of the battlefield
   battlefield_width #the width of the battlefield
   energy #your remaining energy (if this drops
                       #below 0 you are dead)
   gun_heading #the heading of your gun, 0 pointing east,
                       #90 pointing
                       #north, 180 pointing west, 270 pointing south
   gun_heat #your gun heat, if this is above 0 you can't shoot
   heading #your robots heading, 0 pointing east, 90 pointing
                       #north, 180 pointing west, 270 pointing south
   size #your robots radius, if x <= size you hit
                       #the left wall
   radar_heading #the heading of your radar, 0 pointing east,
                       #90 pointing north, 180 pointing west,
                       #270 pointing south
   time #ticks since match start
   velocity #your velocity (-8/8)
   x #your x coordinate, 0...battlefield_width
   y #your y coordinate, 0...battlefield_height
   accelerate(param) #accelerate (max speed is 8,
                       #max accelerate is 1/-1,
                       #negativ speed means moving backwards)
   stop #accelerates negativ if moving forward
                       #(and vice versa), may take 8 ticks to stop (and
                       #you have to call it every tick)
   fire(power) #fires a bullet in the direction of your gun,
                       #power is 0.1 - 3, this power will heat your gun
   turn(degrees) #turns the robot (and the gun and the radar),
                       #max 10 degrees per tick
   turn_gun(degrees) #turns the gun (and the radar), max 30 degrees
                       #per tick
   turn_radar(degrees) #turns the radar, max 60 degrees per tick
   dead #true if you are dead

These methods are intentionally of very basic nature, you are free to
unleash the whole power of ruby to create higher level functions.
(e.g. move_to, fire_at and so on)

Some words of explanation: The gun is mounted on the body, if you turn
the body the gun will follow. In a simmilar way the radar is mounted on
the gun. The radar scans everything it sweeps over in a single tick (100
degrees if you turn your body, gun and radar in the same direction) but
will report only the distance of scanned robots, not the angle. If you
want more precission you have to turn your radar slower.

RRobots is implemented in pure ruby using a tk ui and should run on all
platforms that have ruby and tk. (until now it's tested on windows only)

To start a match call e.g.

ruby rrobots.rb SittingDuck NervousDuck

the classes have to be defined in files with the same name.
(SittingDuck.rb and NervousDuck.rb for the example above)

You can download the 0.1 release from rubyforge:

http://rubyforge.org/frs/?group_id=1109

The best way to help and keep me motivated would be to post some cool
bots here (along with the bug-reports and feature requests)

cheers

Simon

(and thanks to the robocode project for the nice graphics)

Simon announced:

RRobots v0.1
...
RRobots is a simulation environment for robots...

Looks great, Simon - I can't wait to try it out!

Cheers,
Dave

SimonKroeger wrote:

(along with the bug-reports and feature requests)

Just tried it out, and here is the first bug report. You use \\ for the
images dir, this doesn't work on unix based platforms (all except
windows?). If you replace these with / it should work on all platforms
(including windows).

After replacing these it worked fine though, and great graphics :slight_smile: I
might start building some robots :slight_smile:

Edwin

···

--
Posted via http://www.ruby-forum.com/\.

Great work!

Really great work!

It runs on my Linux desktop very well by only modifying image path. :slight_smile:
However, ruby can handle unix style path separator(/) on other platforms,
(If I am wrong, correct me.) though 'File.join' will be better for that use.

--- rrobots.rb.orig 2005-11-24 23:14:55.000000000 +0900
+++ rrobots.rb 2005-11-24 23:15:20.000000000 +0900
@@ -136,15 +136,15 @@
%w{red green}.each do |color|
        bodies, guns, radars = , ,
        36.times do |i|
- bodies << TkPhotoImage.new(:file =>
"images\\#{color}_body#{(i*10).to_s.rjust(3, '0')}.gif")
- guns << TkPhotoImage.new(:file =>
"images\\#{color}_turret#{(i*10).to_s.rjust(3, '0')}.gif")
- radars << TkPhotoImage.new(:file =>
"images\\#{color}_radar#{(i*10).to_s.rjust(3, '0')}.gif")
+ bodies << TkPhotoImage.new(:file =>
"images/#{color}_body#{(i*10).to_s.rjust(3, '0')}.gif")
+ guns << TkPhotoImage.new(:file =>
"images/#{color}_turret#{(i*10).to_s.rjust(3, '0')}.gif")
+ radars << TkPhotoImage.new(:file =>
"images/#{color}_radar#{(i*10).to_s.rjust(3, '0')}.gif")
        end
        colors << TkRobot.new(bodies << bodies[0], guns << guns[0],
radars << radars[0])
end

bum = (0..14).map do |i|
- TkPhotoImage.new(:file => "images\\explosion#{i.to_s.rjust(2, '0')}.gif")
+ TkPhotoImage.new(:file => "images/explosion#{i.to_s.rjust(2, '0')}.gif")
end

robots, bullets, explosions = {}, {}, {}
@@ -177,4 +177,4 @@
   end
}).start

-Tk.mainloop
\ No newline at end of file
+Tk.mainloop

···

On 11/24/05, Simon Kröger <SimonKroeger@gmx.de> wrote:

RRobots v0.1

First there was CRobots, followed by PRobots and many others,
recently (well also years ago) Robocode emerged and finally
this is RRobots bringing all the fun to the ruby community.

What is he talking about?

RRobots is a simulation environment for robots, these robots have
a scanner and a gun, can move forward and backwards and are entirely
controlled by ruby scripts. All robots are equal (well at the moment,
maybe this will change) except for the ai.

A simple robot script may look like this:
----------------------- code -----------------------
require 'robot'

class NervousDuck
    include Robot

   def tick events
     turn_radar 1 if time == 0
     turn_gun 30 if time < 3
     accelerate 1
     turn 2
     fire 3 unless events['robot_scanned'].empty?
   end
end
----------------------- code -----------------------

all you need to implement is the tick method which should
accept a hash of events occured turing the last tick.

By including Robot you get all this methods to controll your bot:

   battlefield_height #the height of the battlefield
   battlefield_width #the width of the battlefield
   energy #your remaining energy (if this drops
                       #below 0 you are dead)
   gun_heading #the heading of your gun, 0 pointing east,
                       #90 pointing
                       #north, 180 pointing west, 270 pointing south
   gun_heat #your gun heat, if this is above 0 you can't shoot
   heading #your robots heading, 0 pointing east, 90 pointing
                       #north, 180 pointing west, 270 pointing south
   size #your robots radius, if x <= size you hit
                       #the left wall
   radar_heading #the heading of your radar, 0 pointing east,
                       #90 pointing north, 180 pointing west,
                       #270 pointing south
   time #ticks since match start
   velocity #your velocity (-8/8)
   x #your x coordinate, 0...battlefield_width
   y #your y coordinate, 0...battlefield_height
   accelerate(param) #accelerate (max speed is 8,
                       #max accelerate is 1/-1,
                       #negativ speed means moving backwards)
   stop #accelerates negativ if moving forward
                       #(and vice versa), may take 8 ticks to stop (and
                       #you have to call it every tick)
   fire(power) #fires a bullet in the direction of your gun,
                       #power is 0.1 - 3, this power will heat your gun
   turn(degrees) #turns the robot (and the gun and the radar),
                       #max 10 degrees per tick
   turn_gun(degrees) #turns the gun (and the radar), max 30 degrees
                       #per tick
   turn_radar(degrees) #turns the radar, max 60 degrees per tick
   dead #true if you are dead

These methods are intentionally of very basic nature, you are free to
unleash the whole power of ruby to create higher level functions.
(e.g. move_to, fire_at and so on)

Some words of explanation: The gun is mounted on the body, if you turn
the body the gun will follow. In a simmilar way the radar is mounted on
the gun. The radar scans everything it sweeps over in a single tick (100
degrees if you turn your body, gun and radar in the same direction) but
will report only the distance of scanned robots, not the angle. If you
want more precission you have to turn your radar slower.

RRobots is implemented in pure ruby using a tk ui and should run on all
platforms that have ruby and tk. (until now it's tested on windows only)

To start a match call e.g.

ruby rrobots.rb SittingDuck NervousDuck

the classes have to be defined in files with the same name.
(SittingDuck.rb and NervousDuck.rb for the example above)

You can download the 0.1 release from rubyforge:

http://rubyforge.org/frs/?group_id=1109

The best way to help and keep me motivated would be to post some cool
bots here (along with the bug-reports and feature requests)

cheers

Simon

(and thanks to the robocode project for the nice graphics)

--
http://nohmad.sub-port.net

In article <4385BB50.5000408@gmx.de>,

The best way to help and keep me motivated would be to post some cool
bots here (along with the bug-reports and feature requests)

It looks cool. Now only if I could find time to write a bot or series of
bots...

Here is a tiny bug report/feature request. The first I did was:

    ruby rrobots.rb SittingDuck.rb NervousDuck.rb

result:

    Error loading SittingDuck.rb!
    usage: rrobots.rb <FirstRobotClassName> <SecondRobotClassName>
            the names of the rb files have to match the class names of
            the robots e.g. 'ruby rrobots.rb SittingDuck NervousDuck'

This is easily corrected, but I think the code c/should be smart enough
to notice that the '.rb' extensions already are there (with tab
completion, typing the '.rb' is easier than not typing it)

I also have the first security breach to report. I do not think you
intend that the following should be valid inside a robot:

    @battlefield.robots.each do |other|
      puts "robot #{other}: x #{other.x}, y #{other.y}"
    end

If a robot can do that, the radar seems extremely limited.

Reinder

···

Simon Kröger <SimonKroeger@gmx.de> wrote:

Minor nitpick - as a scalar, this should really be called "speed". Velocity indicates a magnitude and direction (a vector), while speed is a pure rate measurement.

···

On Nov 24, 2005, at 8:05 AM, Simon Kröger wrote:

  velocity #your velocity (-8/8)

Hi,

I converted a new explosion animation based on the robocode one but
with alpha dithering.

http://www.harderweb.de/jix/ml/exppack.zip

···

--
Jannis

Feature request: support an arbitrary number of bots on the field,
instead of 2. Most of the time bots will probably be designed for 1-1
battles, but it would be cool to see how tactics differ as you add more
enemies to the field.

Ooh, and then perhaps the concept of same-team bots (radar would show
the bot as 'friendly') so you could have multiple instances of two bots
on the field.

Damn. I had some free time until I found this.
Brilliant work !

···

On 24/11/05, Simon Kröger <SimonKroeger@gmx.de> wrote:

RRobots v0.1

First there was CRobots, followed by PRobots and many others,
recently (well also years ago) Robocode emerged and finally
this is RRobots bringing all the fun to the ruby community.

--
Rasputin :: Jack of All Trades - Master of Nuns
http://number9.hellooperator.net/

Edwin van Leeuwen wrote:

SimonKroeger wrote:

(along with the bug-reports and feature requests)

Just tried it out, and here is the first bug report. You use \\ for the images dir, this doesn't work on unix based platforms (all except windows?). If you replace these with / it should work on all platforms (including windows).

After replacing these it worked fine though, and great graphics :slight_smile: I might start building some robots :slight_smile:

Edwin

Doh!

Lazy me.

v0.1.1 is ready for download.
(and hopefully realy platform independent)

cheers

Simon

Reinder Verlinde wrote:

In article <4385BB50.5000408@gmx.de>,

The best way to help and keep me motivated would be to post some cool
bots here (along with the bug-reports and feature requests)

It looks cool. Now only if I could find time to write a bot or series of bots...

Would make me happy too :slight_smile:

Here is a tiny bug report/feature request. The first I did was:

    ruby rrobots.rb SittingDuck.rb NervousDuck.rb

result:

    Error loading SittingDuck.rb!
    usage: rrobots.rb <FirstRobotClassName> <SecondRobotClassName>
            the names of the rb files have to match the class names of
            the robots e.g. 'ruby rrobots.rb SittingDuck NervousDuck'

This is easily corrected, but I think the code c/should be smart enough to notice that the '.rb' extensions already are there (with tab completion, typing the '.rb' is easier than not typing it)

Ok, will be in the next release.

I also have the first security breach to report. I do not think you intend that the following should be valid inside a robot:

    @battlefield.robots.each do |other|
      puts "robot #{other}: x #{other.x}, y #{other.y}"
    end

If a robot can do that, the radar seems extremely limited.

Robots are distributed as source code (i don't see another way anyway)
so nobody would want to compete against such a bot.
(You can search ObjectSpace and find the other robot, setting his energy
to -1, easy victory but without honour)
Maybe there is a way to protect against such strategies i didn't thought
of, any ideas?

Reinder

cheers

Simon

···

Simon Kröger <SimonKroeger@gmx.de> wrote:

Jannis Harder wrote:

Hi,

I converted a new explosion animation based on the robocode one but
with alpha dithering.

http://www.harderweb.de/jix/ml/exppack.zip

--
Jannis

Hehe, nice!

i like it.

cheers

Simon

Another robot to play with...

require 'robot'
class Testing
    include Robot
    def initialize bf
        super(bf)
        @saw_robot = false
    end
    def tick events
        accelerate 1
        if @saw_robot
            direction = time%2==0 ? -1 : 1
            turn_gun 20*direction
            turn 1*direction
            @saw_robot = false
        else
            turn_gun 10
            turn 2
        end
        if !events['robot_scanned'].empty?
            fire 1
            @saw_robot=true
        end
    end
end

···

---

this robot may have problems if it gets stuck in a corner or along the
side but so far it has seemed effective against those posted.

My screenshot:

···

On 11/24/05, Simon Kröger <SimonKroeger@gmx.de> wrote:

v0.1.1 is ready for download.
(and hopefully realy platform independent)

--
http://nohmad.sub-port.net

On

so nobody would want to compete against such a bot.
(You can search ObjectSpace and find the other robot, setting his energy
to -1, easy victory but without honour)
Maybe there is a way to protect against such strategies i didn't thought
of, any ideas?

Judicious use of freeze?

"Simon Kröger" <SimonKroeger@gmx.de> wrote in message
news:43862881.10605@gmx.de...
Reinder Verlinde wrote:

In article <4385BB50.5000408@gmx.de>,

The best way to help and keep me motivated would be to post some cool
bots here (along with the bug-reports and feature requests)

It looks cool. Now only if I could find time to write a bot or series of
bots...

Would make me happy too :slight_smile:

Here is a tiny bug report/feature request. The first I did was:

    ruby rrobots.rb SittingDuck.rb NervousDuck.rb

result:

    Error loading SittingDuck.rb!
    usage: rrobots.rb <FirstRobotClassName> <SecondRobotClassName>
            the names of the rb files have to match the class names of
            the robots e.g. 'ruby rrobots.rb SittingDuck NervousDuck'

This is easily corrected, but I think the code c/should be smart enough to
notice that the '.rb' extensions already are there (with tab completion,
typing the '.rb' is easier than not typing it)

Ok, will be in the next release.

I also have the first security breach to report. I do not think you intend
that the following should be valid inside a robot:

    @battlefield.robots.each do |other|
      puts "robot #{other}: x #{other.x}, y #{other.y}"
    end

If a robot can do that, the radar seems extremely limited.

Robots are distributed as source code (i don't see another way anyway)
so nobody would want to compete against such a bot.
(You can search ObjectSpace and find the other robot, setting his energy
to -1, easy victory but without honour)
Maybe there is a way to protect against such strategies i didn't thought
of, any ideas?

Reinder

cheers

Simon

···

Simon Kröger <SimonKroeger@gmx.de> wrote:

Sure, move the communication to a client server architecture so you can control this better. You've got to stop them running in the same process, to make it easier on yourself.

James Edward Gray II

···

On Nov 24, 2005, at 2:51 PM, Simon Kröger wrote:

Reinder Verlinde wrote:

I also have the first security breach to report. I do not think you intend that the following should be valid inside a robot:
    @battlefield.robots.each do |other|
      puts "robot #{other}: x #{other.x}, y #{other.y}"
    end
If a robot can do that, the radar seems extremely limited.

Robots are distributed as source code (i don't see another way anyway)
so nobody would want to compete against such a bot.
(You can search ObjectSpace and find the other robot, setting his energy
to -1, easy victory but without honour)
Maybe there is a way to protect against such strategies i didn't thought
of, any ideas?

Hi,

I added a little status display in the canvas so each robot's health
is shown - easier to have it all in one window rather than having the
health in the terminal window.

Diff attached, against 0.1.1

robot.diff (1.58 KB)

···

On 11/24/05, Simon Kröger <SimonKroeger@gmx.de> wrote:

v0.1.1 is ready for download.

--
Terje

I wasted my time creating my first real bot (should have fixed
more bugs instead) and named it quite arrogant 'Killer':
(found one very anoying bug with the scanner pointing east, fixed
it, new version v0.1.3)

···

-------------------------------------------------------------------
require 'robot'

class Killer
   include Robot

   def min_max value, m
     value-= 360 if value > 180
     value+= 360 if value < -180
     value = -m if value < -m
     value = m if value > m
     return value
   end

   def tick events
     @dist = 1000 if @dist.nil?
     @target_heading = 0 if @target_heading.nil?
     @radar_range = 60 if @radar_range.nil?
     @approach = false if @approach.nil?

     if !events['robot_scanned'].empty?
       @dist = events['robot_scanned'].first.first
       @target_heading = (radar_heading - @radar_range * 0.5 + 360.0) % 360 if @radar_range.abs < 10
       @radar_range = (@radar_range.abs > 0.5) ? -@radar_range * 0.5 : -@radar_range
     else
       @radar_range *= -2 if (@radar_range.abs < 60)
     end

     fire 3 if @radar_range.abs < 10

     @approach = true if (@dist < 200 || @dist > 500)
     @approach = false if (@dist > 250 && @dist < 300)

     if @approach
       turn_body = min_max(@target_heading - heading, 10)
       accelerate(@dist > 275 ? 1 : -1)
     else
       turn_body = min_max(@target_heading - heading + 90, 10)
       accelerate((time / 100) % 2 * 2 - 1)
     end

     gun = min_max(@target_heading - gun_heading - turn_body, 30)
     radar = min_max(@radar_range - gun - turn_body, 60)

     turn(turn_body)
     turn_gun(gun)
     turn_radar(radar)
   end
end
-------------------------------------------------------------------

cheers

Simon