2011
12
30
12
30
ソニーのプログラマテスト(例題)

ソニーのプログラマ試験の例題を解いてみた。
要は”あたり判定”の実装。格ゲーのムックをみるとあたり判定が矩形になっているが、こういうアルゴリズムで実装しているとなるとそれもうなずける。
利便のためx,y,z方向に分けて考える。x1もしくはx1+w1がx0からx0+w0までの間にあるか、もしくはx0とx0+w0がx1からx1+w1までの間にあるか。これをx,y,zの三方向で出して、最後に三方向で出した真理値を論理積。一方向でもFalseなら三次元空間では重なっていないということ。
テストは、
・x,y,z,w,h,dに小数を入れるとFalse
・w,h,dに負数を入れるとFalse
・二つの直方体で一面以上重なる場合、内包される場合、外包される場合にTrueが返されるか

同様のアルゴリズムを別の式で表現したものを"othercheck()"として用意してある。
sonytest.py
# coding: utf-8
class Collision:
def set(self, x, y, z, w, h, d):
if w<0 or h<0 or d<0:
print u"マイナスエラー set w0 h0 d0 without minus"
self.ready=False
return False
if x%1. or y%1. or z%1. or w%1. or h%1. or d%1.:
print u"小数エラー set x0 y0 z0 w0 h0 d0 without decimal"
self.ready=False
return False
self.x0=x
self.y0=y
self.z0=z
self.w0=w
self.h0=h
self.d0=d
self.ready=1
def check(self, x1, y1, z1, w1, h1, d1):
if not self.ready:
print u"set C0"
return False
if w1<0 or h1<0 or d1<0:
print u"マイナスエラー"
return False
if x1%1. or y1%1. or z1%1. or w1%1. or h1%1. or d1%1.:
print u"小数エラー"
return False
x_collision = ((self.x0 <= x1 <= self.x0+self.w0) or
(self.x0 <= x1+w1 <= self.x0+self.w0) or
((x1 <= self.x0 <= x1+w1) and (x1 <= self.x0+self.w0 <= x1+w1)))
y_collision = ((self.y0 <= y1 <= self.y0+self.h0) or
(self.y0 <= y1+h1 <= self.y0+self.h0) or
((y1 <= self.y0 <= y1+h1) and (y1 <= self.y0+self.h0 <= y1+h1)))
z_collision = ((self.z0 <= z1 <= self.z0+self.d0) or
(self.z0 <= z1+d1 <= self.z0+self.d0) or
((z1 <= self.z0 <= z1+d1) and (z1 <= self.z0+self.d0 <= z1+d1)))
collision3d = x_collision and y_collision and z_collision
return collision3d
def othercheck(self, x1, y1, z1, w1, h1, d1):
x_collision = ((x1 <= self.x0 <= x1+w1) or
(x1 <= self.x0+self.w0 <= x1+w1) or
((self.x0 <= x1 <= self.x0+self.w0) and (self.x0 <= x1+w1 <= self.x0+self.w0)))
y_collision = ((y1 <= self.y0 <= y1+h1) or
(y1 <= self.y0+self.h0 <= y1+h1) or
((self.y0 <= y1 <= self.y0+self.h0) and (self.y0 <= y1+h1 <= self.y0+self.h0)))
z_collision = ((z1 <= self.z0 <= z1+d1) or
(z1 <= self.z0+self.d0 <= z1+d1) or
((self.z0 <= z1 <= self.z0+self.d0) and (self.z0 <= z1+d1 <= self.z0+self.d0)))
collision3d = x_collision and y_collision and z_collision
return collision3d
import sonytest
test = sonytest.Collision()
test.set(5, 5, 5, 5, 5, 5)
assert test.check(3, 3, 3, 3, 3, 3)
assert test.check(7, 7, 7, 1, 1, 1)
assert test.check(0, 0, 0, 15, 15, 15)
assert test.check(7, 7, 7, 5, 5, 5)
assert test.check(3, 3, 3, 1, 1, 1)==False
assert test.check(13, 13, 13, 1, 1, 1)==False
assert test.check(6, 6, 15, 1, 1, 1)==False
assert test.check(7, 7, 7, -5, 5, 5)==False
assert test.check(7, 7, 7, 5, -5, 5)==False
assert test.check(7, 7, 7, 5, 5, -5)==False
test.set(-5, -5, -5, 5, 5, 5)
assert test.check(-3, -3, -3, 3, 3, 3)
assert test.check(-2, -2, -2, 1, 1, 1)
assert test.check(-15, -15, -15, 15, 15, 15)
assert test.check(-7, -7, -7, 5, 5, 5)
スポンサーサイト