From: "Simon Kröger" Date: 2005-11-16T08:24:21+09:00 Subject: Re: Equvialent of RoboCode and/or Terrarium for Ruby? Ok, i realy don't know if it will be of any help but perhaps someone gets inspired. (i will continue this if i have time but someone else could think of a frontend - start with the graphics from robocode...) Here is my first approach ... very unfinished, more like an idea than the real thing: (for now, there is a stupid robot running in circles shooting nonestisting bullets in every direction - there is plenty of room for improvements :) ) ############################################## $stdout.sync = true class Numeric def to_rad self / 180.0 * Math::PI end end module Battlefield HEIGHT = 1600 WIDTH = 1600 end module Robot #the height of the battlefield attr_reader :battlefield_height #the width of the battlefield attr_reader :battlefield_width #your remaining energy (if this drops below 0 you are dead) attr_reader :energy #the heading of your gun, 0 pointing east, 90 pointing north, 180 pointing west, 270 pointing south attr_reader :gun_heading #your gun heat, if this is above 0 you can't shoot attr_reader :gun_heat #your robots heading, 0 pointing east, 90 pointing north, 180 pointing west, 270 pointing south attr_reader :heading #your robots radius, if x <= size you hit the left wall attr_reader :size #the heading of your radar, 0 pointing east, 90 pointing north, 180 pointing west, 270 pointing south attr_reader :radar_heading #ticks since match start attr_reader :time #your velocity (-8/8) attr_reader :velocity #your x coordinate, 0...battlefield_width attr_reader :x #your y coordinate, 0...battlefield_height attr_reader :y #accelerate (max speed is 8, max accelerate is 1/-1, negativ speed means moving backwards) def accelerate param @actions[:accelerate] = param end #accelerates negativ if moving forward (and vice versa), may take 8 ticks to stop (and you have to call it every tick) def stop @actions[:accelerate] = (velocity > 0) ? -1 : ((velocity < 0) ? 1 :0) end #fires a bullet in the direction of your gun, power is 0.1 - 3, this power is taken from your energy def fire power @actions[:fire] = power end #turns the robot (and the gun and the radar), max 10 degrees per tick def turn degrees @actions[:turn] = degrees end #turns the gun (and the radar), max 30 degrees per tick def turn_gun degrees @actions[:turn_gun] = degrees end #turns the radar, max 60 degrees per tick def turn_radar degrees @actions[:turn_radar] = degrees end private def initialize bf_height, bf_width @battlefield_height = bf_height @battlefield_width = bf_width @x = (rand * bf_width).to_i @y = (rand * bf_height).to_i @gun_heat = 3 @heading = (rand * 360).to_i @gun_heading = @heading @radar_heading = @heading @time = 0 @velocity = 0 @energy = 100 @events = Hash.new{[]} @@robots ||= [] @@robots << self end def Robot.robots @@robots end def internal_tick @actions = Hash.new(0) tick @events @actions[:fire] = 3 if @actions[:fire] > 3 @actions[:fire] = 0 if @actions[:fire] < 0 @actions[:turn] = 10 if @actions[:turn] > 10 @actions[:turn] = -10 if @actions[:turn] < -10 @actions[:turn_gun] = 30 if @actions[:turn_gun] > 30 @actions[:turn_gun] = -30 if @actions[:turn_gun] < -30 @actions[:turn_radar] = 60 if @actions[:turn_radar] > 60 @actions[:turn_radar] = -60 if @actions[:turn_radar] < -60 @actions[:accelerate] = 1 if @actions[:accelerate] > 1 @actions[:accelerate] = -1 if @actions[:accelerate] > -1 old_radar_heading = @radar_heading @heading += @actions[:turn] @gun_heading += @actions[:turn] + @actions[:turn_radar] @radar_heading += @actions[:turn] + @actions[:turn_radar] + @actions[:turn_radar] @velocity += @actions[:accelerate] @velocity = 8 if @velocity > 8 @velocity = -8 if @velocity < -8 @x += Math::cos(@heading.to_rad) * @velocity @y -= Math::sin(@heading.to_rad) * @velocity @@robots.each do |other| if other != self #if old_radar_heading < angle_to_other < @radar_heading # @events['robot_scanned'] << [angle_to_other, distance_to_other] #end end end @time += 1 end end ############################################## # robot code (will be dynamicaly required) ############################################## class MyRobot include Robot def tick events accelerate 1 turn 5 fire 3 end end ############################################## # arena ############################################## w, h = Battlefield::WIDTH, Battlefield::HEIGHT robot1 = MyRobot.new w, h #robot2 = MyRobot.new w, h loop do Robot.robots.each do |robot| robot.send :internal_tick if robot.energy < 0 puts "robot died" break end puts robot.x.to_i.to_s + ', ' + robot.y.to_i.to_s end sleep 0.1 end