외부 라이브러리나 프레임워크는 쓸 수 없습니다사이냅소프트 2010 상반기 추가채용에 지원하기 위해 풀어야 하는 퀴즈다. 관심을 가지고 있는 회사라 당연히 퀴즈를 풀어보았다.
- 입력된 발사각도와 초기속도를 가지고 포탄의 궤적을 그립니다.
- 궤적은 x축을 따라 8픽셀씩 이동하면서 y축 값을 asterisk 문자로 찍어줍니다.
- 화면의 크기는 600 x 400 으로 하며, 화면을 벗어난 궤적은 보여주지 않습니다.
- 타겟의 위치는 x축상의 300 ~ 600픽셀 사이에서 랜덤하게 정합니다.
- 적당한 오차범위 내에서 궤적이 타겟에 일치하면 메시지를 보여줍니다.
- 1 pixel 은 0.1m
퀴즈를 정리해서 구현해야 할 부분을 뽑아내면
- 포탄의 각도와 속도를 입력하면 포탄이 날아간다.(x축 8픽셀마다 포탄을 표시한다)
- 포탄은 각도와 속도를 가진다.
- 포탄을 화면상에서 이동시키기 위해 각도와 속도를 통해 가로속도, 세로속도로 변환한다. - 포탄은 x축 8픽셀마다 표시된다.
- x축의 이동거리는 0.8m 로 고정하고 y축의 이동거리를 이에 맞게 보정한다. - 포탄은 날아가면서 중력의 영향을 받는다.
- 포탄의 가로속도는 고정된다.
- 포탄의 세로속도는 중력에 따라 속도가 변한다.
- y축의 이동거리를 중력값으로 보정한다. - 정해진 크기의 화면 밖으로 나간 포탄은 보여주지 않는다.
- 포탄이 오차범위 내로 타겟에 접근하면 메세지를 보여준다.
1.1 을 구현하기 위한 테스트코드는
function testGetVerticalVelocity() { var bullet = new Bullet(90, 10); assertEquals("when degree is 90, VerticalVelocity is equals Velocity", 10, bullet.getVerticalVelocity()); var bullet = new Bullet(0, 10); assertTrue("when degree is 0, VerticalVelocity is 0", 0.0001 > bullet.getVerticalVelocity()); var bullet = new Bullet(23, 10); var expected = 10 * getSin(23); assertEquals(expected, bullet.getVerticalVelocity()); } function testGetHorizontalVelocity() { var bullet = new Bullet(90, 10); assertEquals("when degree is 90, HorizontalVelocity is 0", 0, bullet.getHorizontalVelocity()); bullet = new Bullet(0, 10); assertEquals("when degree is 0, HorizontalVelocity is equals Velocity", 10, bullet.getHorizontalVelocity()); bullet = new Bullet(23, 10); var expected = 10 * getCos(23); assertEquals(expected, bullet.getHorizontalVelocity()); }
물론 getSin, getCos 은 라디안 값으로 바꿔서 Math.sin Math.cos 을 사용하면 되겠다.
1.2 는 각 세로, 가로 속도를 보정해야한다. 즉 가로 속도는 8px/[시간] 으로 표현되고 일반적인 1초에 이동하는 pixel 이 아니라 8pixel 을 이동하는 시간을 계산하고 계산된 시간으로 세로속도도 표현한다.
function testGetVerticalDistanceForPixelUnit() { var bullet = new Bullet(0, 8); assertEquals(0, bullet.getVerticalDistanceForPixelUnit()); var bullet = new Bullet(45, 10); assertEquals(8, bullet.getVerticalDistanceForPixelUnit()); var bullet = new Bullet(23, 10); assertEquals(3.4, bullet.getVerticalDistanceForPixelUnit()); } function testGetNewHorizontalDistance() { // 속도에 상관없이 수평이동거리는 항상 0.8m 즉 8px 이다. var bullet = new Bullet(0, 10); assertEquals(8, bullet.getHorizontalDistanceForPixelUnit()); var bullet = new Bullet(0, 50); assertEquals(8, bullet.getHorizontalDistanceForPixelUnit()); var bullet = new Bullet(45, 10); assertEquals(8, bullet.getHorizontalDistanceForPixelUnit()); }