Bob the Bowman!

13

Bob the Bowman

      o         
    /( )\                                         This is Bob. 
     L L                                          Bob wants to be an archer.
#############

    .
   / \          <--- bow                          So he bought himself a
  (c -)->       <--- arrow                        nice longbow and is about
  ( )/          <--- highly focused Bob           shoot at a target.
  L L           
#############

___________________________________________________________________________________________
sky

                     Bob is a smart guy. He already knows what angle and
                     velocity his arrow has / will have. But only YOU know
                     the distance to the target, so Bob doesn't know if he
                     will hit or miss. This is where you have to help him.

     .                                                                                  +-+
    / \                                                                                 | |
   (c -)->                                                                              | |
   ( )/                                                                                 +++
   L L                                                                                   |
###########################################################################################

Task

Your task is to render an ASCII art picture of Bob hitting or missing the target. For the calculation:

  • Your program will receive arrow_x,angle,velocity,distance as comma-separated input in any order you wish.
  • One ASCII character equals 1m.
  • The first character in the last line has the coordinates (0,0), so the ground (rendered as #) is at y=0.
  • Bob always stands on the ground, his y position does not change.
  • There is no max y. However, the arrows apex should fit within the rendered picture.
  • All input is provided as decimal integer.
  • During calculation, assume the arrow is a point.
  • The arrow origin is the arrow head > of a shooting Bob (see above). So given arrow_x, you have to calculate arrow_y. The left foot of Bob in the output has to match the x coord. of the shooting Bob.
  • distance is the x coordinate of the target's foot. (ie. the middle of the target).
  • All measurements are supplied in meters and degrees respectively.
  • Attention: The shooting Bob is never rendered, only used for calculations! See below for the two valid output-Bobs
  • Hitting the target means the arrows path crosses either one of the two leftmost target walls (|) (That is either (distance-1,3) or (distance-1,4). If at some point the arrow is within those 2m², place the X instead of the wall it hits. The target is always the same height and only its x position can change.). Corner hits or an arrow falling from the sky onto the target does not count.
  • Standard earth g applies (9.81 m/s^2).
  • distance+1 is the end of the field, after that, everything is a miss and no arrow should be rendered.
  • If the arrow hits the target in any other way (distance-1 etc.), no arrow should be rendered.

Miss

This is an example rendering of Bob missing (arrow enters ground at 34m, angle is 45°, time in air is 10s, velocity is ~50 - but there are a lot more possible inputs to cause this output. Just show your program uses the usual formulas to calculate physically "accurate" results.):

                                                                                        +-+
                                                                                        | |
  c\                                                                                    | |
/( )                              v                                                     +++
 L L                              |                                                      |
###########################################################################################

Hit

This is an example rendering of Bob scoring (arrow enters target (= crosses its path)):

                                                                                        +-+
                                                                                     >--X |
 \c/                                                                                    | |
 ( )                                                                                    +++
 L L                                                                                     |
###########################################################################################

Example

  • arrow_x is 7. arrow_y is always 3.
  • angle is 30° or 0.523598776 radians.
  • velocity is 13m/s.
  • distance is 20.

So in order to hit the target, the arrow has to cross (19,3) or (19,4). Everything else will be a miss. In this case, the arrow will enter the ground (means y will be <1.0) at 12.9358m = ~13m after 1.149s.


Limits & Scoring

  • This is , so the shortest solution wins. There are no bonuses.
  • Your program (as in not function) must accept input in the format described above, additional input is not permitted.
  • You don't have to handle wrong/pointless/impossible inputs.
  • Print to whatever is the shortest reasonable output for your language (std, file, ...).
  • I don't care about trailing whitespace.
  • Tip: Width of output is distance+2. The height is apex+1.

mınxomaτ

Posted 2015-09-20T13:23:52.613

Reputation: 7 398

5Can you add the input used to generate the output given please? – Blue – 2015-09-20T13:29:07.460

3Why can't you post a function? – Loovjo – 2015-09-20T13:52:57.407

@steveverrill Standard g applies. – mınxomaτ – 2015-09-20T15:01:34.760

Do we have to draw bob? or just the arrow? – Mhmd – 2015-09-20T17:46:38.453

2@Mhmd You have to draw him, as stated in the task. The left foot of Bob in the output has to match the x coord. of the shooting Bob. and See below for the two valid output-Bobs – mınxomaτ – 2015-09-20T17:56:10.617

1And for those of us who haven't taken physics further than GCSE (or have just forgotten?) – Blue – 2015-09-20T19:11:45.480

2@muddyfish Just google for the trajectory equations. – mınxomaτ – 2015-09-20T19:25:47.740

Could you add more test cases input/output. – Mhmd – 2015-09-22T13:42:57.703

btw, in the exampe you say: the arrow will enter the ground (means y will be <1.0) shouldn't this be 0? – Mhmd – 2015-09-22T14:18:46.870

@Mhmd No, because the ground # is at y=0 and is 1m high. – mınxomaτ – 2015-09-22T14:50:57.363

@minxomat in the example above, it seems that you didn't take into account the initial height y0. Could you please elaborate? I'm getting a result of 18m. – Mhmd – 2015-09-26T08:39:21.263

@Mhmd Yes, I messed that up, you're right. – mınxomaτ – 2015-09-26T19:29:29.850

Answers

2

Ruby, 482

include Math
def f s,e,l
[s,' '*(l-s.size-e.size),e].join
end
alias p puts
X,o,V,d=$*[0].split(?,).map &:to_i
o*=PI/180
L=X+d
B='| |'
S=''
G=' L L'
p f S,'+-+',L
d.times{|x|y=3+x*tan(o)-(9.81*x**2)/(2*(V*cos(o))**2)
if x==d-1&&(3..5)===y
s='>--X |'
m=(3..4)===y
p f S,m ?B: s,L
p f ' \c/',m ?s: B,L
p f ' ( )',?+*3,L
p f G,'| ',L
elsif y<=1 || x==d-1
p f S,B,L
p f '  c\\',B,L
print f '/( )', y<1? 'V':' ',x
p f S,?+*3,L-x
print f G, y<1? '|':' ',x
p f S,'| ',L-x
break
end}
p ?#*L

Ungolfed

include Math
def fill s,e,l
   [s,' '*(l-s.size-e.size),e].join
end
arrow_x,angle,velocity,distance = $*[0].split(',').map(&:to_i)
angle *= PI/180
length=arrow_x+distance
loss = '| |'
puts fill '','+-+',length
distance.times { |x|
  y = 3 + x*tan(angle) - (9.81*x**2)/(2*(velocity*cos(angle))**2)
  if x == distance-1 && (3..5)===y
    puts fill '',(3..4)===y ? '| |':'>--X |',length
    puts fill ' \c/',(3..4)===y ? '>--X |':'| |',length
    puts fill ' ( )','+++',length
    puts fill ' L L','| ',length
  elsif y<=1 || x==distance-1
    puts fill '',loss,length
    puts fill '  c\\',loss,length
    print fill '/( )', y<1? 'v': ' ', x
    puts fill '','+++',length-x
    print fill ' L L', y<1? '|': ' ', x
    puts fill '',' | ',length-x
    break
  end
}
puts ?#*length

Method

The main equation here is:

trajectory equation

Note: image taken from https://en.wikipedia.org/wiki/Trajectory_of_a_projectile

Where,

y0: initial height (of arrow)  
Ө: the angle  
x: the position of the arrow  
g: gravity (9.81)
v: velocity

What I'm doing is to loop through numbers from 0 to (distance -1) and in every iteration check to see if the arrow hits the ground (or the target)

Mhmd

Posted 2015-09-20T13:23:52.613

Reputation: 2 019