# Thinking in OO

**URL:** <https://www.ruby-forum.com/t/thinking-in-oo/94147>\
**Category:** Ruby\
**Created:** [April 22, 2006, 10:41pm UTC](https://www.ruby-forum.com/t/thinking-in-oo/94147 "2006-04-22T22:41:49Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![snow-templar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/977dab/32.png) [@snow-templar](https://www.ruby-forum.com/u/snow-templar)\
**Post date:** [April 22, 2006, 10:41pm UTC](https://www.ruby-forum.com/t/thinking-in-oo/94147/1 "2006-04-22T22:41:49Z")

</div>

Hi all,

Trying hard to get my brain wrapped around the concepts of OO (using  
Ruby which i’m also new to but doesn’t seem as foreign to me). I’m  
using rrobots (at rubyforge) to practice…

This is what’s provided to me:

#state:

# team

# battlefield\_height

# battlefield\_width

# energy

# gun\_heading

# gun\_heat

# heading

# size

# radar\_heading

# time

# game\_over

# speed

# x

# y

#actions:

# accelerate

# stop

# fire

# turn

# turn\_gun

# turn\_radar

# broadcast

# say

#events:

# broadcast

# got\_hit

# robot\_scanned

Now I’ve started to write a bot serveral times, but I’m thinking I need  
to back up a bit and figure out who to approach this from an OO  
standpoint.

Ruby reinforces the idea of passing messages to objects (right?). My  
instinct  
is to write methods named turn.left, turn.right, sleep.up, speed.down,  
gun.fire, radar.sweep, etc…

But maybe that’s not abstract enough. Maybe methods like evade,  
attack, attacked are more inline with OO thinking?

Is there _one_ best way to think about this problem? Or am I  
over-analyzing?

Thanks!

Greg

---

<div class="post-metadata">

**Author:** ![snow-templar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/977dab/32.png) [@snow-templar](https://www.ruby-forum.com/u/snow-templar)\
**Post date:** [April 22, 2006, 10:54pm UTC](https://www.ruby-forum.com/t/thinking-in-oo/94147/2 "2006-04-22T22:54:11Z")

</div>

Hi –

On Sun, 23 Apr 2006, Greg C. wrote:

> # battlefield\_height
> 
> # x
> 
> #events:  
> gun.fire, radar.sweep, etc…  
> The question you should ask is: is there an entity called a “turn” in  
> the universe of your application – the domain – which can perform an  
> action, or which has a property, called “left”? I would say the  
> answer is no. A turn might have a “direction” property, and that  
> might be “left”. But turn.left suggests that you’re telling a turn to  
> left, or to show you its left, neither of which really fits.

(It’s true that you’ll see libraries that do things like:  
turn.five.degrees.to.the.left, but I consider that serious dot-abuse  
and would stay away from it.)

So, you’re likely to see things like:

robot.turn :direction =\> “left”, :degrees =\> 5

where direction and degrees are actually hash keys that can be parsed  
out in the turn method and used to modify state (x and y, I would  
assume).

Anyway, for me, the main thing is that every message that goes to an  
object should make sense either as a command to the object, or as a  
request for information from the object.

David

–  
David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light, LLC ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” PDF now on sale! [Ruby for Rails](http://www.manning.com/black)  
Paper version coming in early May!

---

<div class="post-metadata">

**Author:** ![snow-templar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/977dab/32.png) [@snow-templar](https://www.ruby-forum.com/u/snow-templar)\
**Post date:** [April 23, 2006, 1:58am UTC](https://www.ruby-forum.com/t/thinking-in-oo/94147/3 "2006-04-23T01:58:29Z")

</div>

In my latest attempt at writing a bot, my objects are radar, gun and  
tank.

methods are things like increase (scan), decrease (scan), reverse,  
adjust, etc.

There’s also a bit of procedural code in the main (tick) method to  
know what object to call with what method. Is that acceptable in OO?

Code follows - not the smartest bot in the world (he doesn;t even move  
yet - trying to get the radar to lock-on consitently), but i’m hoping  
it’s a good start that I can add to.

Any/all suggestion and criticism are very welcome!

Greg

require ‘robot’

#in this script, heading is absolute (0-360), dir (direction) is  
relative (± and probably no more than 60)

#available options:

# 

#state:

# team

# battlefield\_height

# battlefield\_width

# energy

# gun\_heading

# gun\_heat

# heading

# size

# radar\_heading

# time

# game\_over

# speed

# x

# y

#actions:

# accelerate

# stop

# fire

# turn

# turn\_gun

# turn\_radar

# broadcast

# say

#events:

# broadcast

# got\_hit

# robot\_scanned

####### Need Unit Tests!!!

class GoofeyDuck  
include Robot

def initialize  
@got\_hit = 0  
@found  
@seen #found previous round…

```
@radar = Radar.new
@gun = Gun.new
@tank = Tank.new

```

end

def tick(events)

```
@got_hit = events['got_hit']
@found = events['robot_scanned'] if 

```

(!events[‘robot\_scanned’].empty?)

```
#set radar
if (@found)
  @radar.decrease(1) unless (@radar.dir.abs <= 1)
  @radar.reverse
  @seen = 1
  say "Locked"
elsif (@seen)
  @radar.increase(3)
  @radar.reverse
  @seen = !@seen
  say "Dang, Lost em"
else
  @radar.increase(2)
  say "Tracking...."
end
@radar.dir = verify(@radar.dir, @radar.max)

#set gun
@gun.adjust(@radar.mid(radar_heading), gun_heading)
@gun.dir = verify(@gun.dir, @gun.max)

#fire or no?
if (@found)
  @gun.fire += 0.1
else
  @gun.fire -= 0.1 unless (@gun.fire <= 0)
end

@gun.fire = verify(@gun.fire, 3)

#pass results
turn_radar(verify(@radar.adjust(@gun.dir), @radar.max)) #adjust 

```

radar to gun  
turn\_gun(@gun.dir)  
turn(@tank.dir)  
accelerate(@tank.vel)  
fire(@gun.fire)  
say “Uh oh” if (energy \<= 10)

```
puts @gun.fire

#reset
@found = !@found if (@found)

```

end

def verify(dir, max)  
if (dir \> max)  
dir = max  
elsif (dir.abs \> max)  
dir = (max \* -1)  
end  
dir  
end

end

class Radar  
include Robot

attr\_reader :dir, :max  
attr\_writer :dir

def initialize  
@dir = 60  
@max = 60 #max delta  
end

def increase(amt)  
z = @dir \<=\> 0  
@dir += (amt \* z)  
end

def decrease(amt)  
z = @dir \<=\> 0  
@dir -= (amt \* z)  
end

def reverse  
@dir \*= -1  
end

def adjust(gun)  
@dir - gun  
end

def mid(head) #in degrees…  
head + (@dir/2)  
end

end

class Gun  
include Robot

attr\_reader :dir, :fire, :max  
attr\_writer :dir, :fire

def initialize  
@dir = 0  
@max = 30 #max delta  
@fire = 0.1  
end

def adjust(target, gun\_head)  
@dir = target - gun\_head  
end

end

class Tank  
include Robot

attr\_reader :dir, :vel  
attr\_writer :dir, :vel

def initialize  
@dir = 0  
@max = 10 #max delta  
@vel = 0  
end

end
