티스토리 뷰

반응형
출처 : http://www.ibm.com/developerworks/kr/library/j-movement/index.html

타겟팅(targeting) 알고리즘에는 한계가 있습니다. 예견하기 어려운 움직임 패턴이 언제나 있기 때문입니다. 자신의 로봇이 상대편에 맞게 최상의 움직임 알고리즘을 선택하도록 하는 방법을 설명합니다.

이 글에서는 과거의 성능의 기반으로 움직임 상태를 선택하는 기술을 설명한다. 가능한 간략한 예제가 될 수 있도록, 본 예제에서는 장기적인 데이터의 영속성은 무시하기로 했다. 이 글에서는 코드에 대한 개요만 제공한다. 클래스나 메소드에 대한 상세한 설명이 필요하다면 소스 코드 문서를 참조하라. 전체 소스 코드는 참고자료 섹션을 참조하기 바란다.

수학 유틸리티 클래스

일반적으로, 로봇은 몇 가지 수학적 알고리즘에 기반하고 있다. 가장 많이 사용되는 알고리즘에 정적 메소드를 사용하여 유틸리티 클래스를 만드는 것이 좋은 방법이다.

이 예제의 유틸리티 클래스는 BotMath 클래스이다. 이 클래스에는 calculateDamage() 메소드가 있는데, 총알의 힘에 근거하여 총알에서 발생한 피해를 계산한다.




위로


AdvancedRobot 클래스를 확장하여 publisher/subscriber 지원하기

상태, 상태 매니저, 또 다른 지원 클래스를 로봇에 추가할 것이기 때문에 다른 이벤트에 대한 액세스가 필요하다. 이러한 이벤트들을 상태 매니저에 전달하고 개별 상태에 이벤트를 전달하도록 하지만, 관련 이벤트들만 이들을 필요로 하는 객체들로 직접 전달하는 것이 더 효율적이다.

ExtendedRobot 클래스는 객체들이 관심이 있는 이벤트들만 받도록 해준다. EventRegistry 클래스에는 다른 이벤트에 등록하는데 사용되는 상수들이 포함된다. 추상 EventListener 클래스는 이벤트를 받는데 필요한 메소드를 정의한다.

표준 Robocode 이벤트 외에도, ExtendedRobot 클래스는 상태 매니저와 상태에 필요한 세 개의 이벤트를 생성한다. enable, disable, execute 이벤트는 등록된 상태 매니저들로 직접 전달되는데, 이는 이벤트를 활성 상태로 전달할 책임이 있다. enable() 메소드는 각 라운드가 시작할 때 호출된다. 이 메소드는 변수를 실행하고, 관련 Robocode 이벤트에 대해 등록한다. disable() 메소드는 각 라운드의 끝에 호출된다. 이 메소드는 리소스를 릴리즈 하고, 클래스가 현재 등록되어 있는 Robocode 이벤트에서 등록을 해제한다. execute() 메소드는 매 회전마다 호출되면서, 상태 매니저와 상태들이 회전 기반 알고리즘을 실행할 수 있도록 한다. 이러한 이벤트들을 받아야 하는 클래스는 CommandListener 인터페이스를 구현해야 한다.




위로


상태 관리하기

StateManager 클래스는 최상의 상태를 선택하는 책임이 있다. 회전할 때마다, execute() 메소드는 현재 활성 상태에 있는 isValid() 메소드를 호출한다. 활성 상태의 isValid() 메소드가 false를 리턴하면, 새로운 상태가 선택된다. (이 프로세스는 상대편의 수에 따라서 상태들을 전환하는데 사용된다.)

새로운 상태를 선택하는데 개입된 대부분의 작업은 StateManagerselectNewState() 메소드에 의해 핸들된다. 이 메소드는 각 후보 상태로부터 통계 데이터를 요청하고, 그 데이터를 계산하여 최상의 상태를 선택한다. StateManager는 두 단계 접근 방식을 사용하여 최상의 상태를 선택한다. 우선, 최상의 승패 비율로 상태를 사용한다. 적합한 상태를 찾지 못하면 StateManager는 가장 낮은 damage/time 비율로 상태를 선택한다.




위로


상태

추상 State 클래스는 각 상태 실행에 필요한 메소드를 정의한다. 여기에는, 표준 enable(), disable(), execute() 메소드와, 상태 메니저와의 통신에 필요한 특수한 메소드가 포함된다. getStatistics() 메소드는 상태의 과거 성능에 대한 데이터를 가진 Statistics 객체를 리턴한다. (예를 들어, 상태는 하나의 Statistics 객체를 관리하지만, HashMap을 사용하여 상대편의 통계를 검색할 수 있도록 쉽게 수정될 수 있다.) getName() 메소드는 디버그 메시지에 사용할 친숙한 상태 이름을 리턴한다. isValid() 메소드는 상태가 사용될 때를 결정한다. 상태 선택 동안 그리고 상태가 선택된 후 각 회전 시 호출된다.

State 클래스는 로봇이 얼마나 잘 작동하는지를 검사하고, 데이터를 Statistics 객체에 기록한다.

소스 코드에 두 개의 간단한 예제 상태를 포함시켰다. TrackStateCannonFodderState는 추상 State 클래스의 구현 예제이다.




위로


통계(Statistics)

Statistics 클래스는 하나의 상태가 얼마나 잘 수행되는지를 추적하는 간단한 컨테이너 클래스이다. 여기에는 피해 비율에 대한 변수(damage/time), 상태가 사용되었던 시합 횟수, 패배 횟수, 승리 횟수가 포함된다. 또한 이러한 데이터를 설정 및 검색하는 세 개의 헬퍼 메소드가 있다. update() 메소드는 Statistics 객체에 변수를 설정하는 쉬운 방식을 제공한다. getDamageRatio()getWinLossRatio() 메소드는 그 상태에 대한 통계 데이터를 리턴한다.

한 개의 안 좋은 라운드가 우수한 상태의 격을 떨어뜨리지 못하도록, 통계 데이터는 상태가 최소한 세 개의 시합에서 사용되지 않는 한 무효한 것으로 간주한다. (Statistics 객체는 이 평가 기간 동안 기본 데이터 값을 리턴한다.)




위로


결론

메인 로봇 클래스는 상태 매니저와 상태를 설정하는 많은 책임을 수행한다. 매 라운드 마다, 상태 매니저를 만들고, 상태를 상태 매니저에 추가하고, 상태 매니저를 명령어 리스너로서 등록하고, ExtendedRobot enable() 메소드를 호출하여 명령 리스너를 활성화 한다. 메인 로봇 클래스는 매 회전 마다 ExtendedRobot executeTurn() 메소드를 호출해야 한다. (이 메소드는 모든 등록된 명령어 리스너의 execute() 메소드를 호출한다.) 각 라운드의 끝에, 메인 로봇 클래스는 disable() 메소드를 호출하여 명령 리스너들을 중지시킨다.

다중 상태를 지닌 로봇의 전형적인 run() 메소드는 Listing 1과 같다.


Listing 1. 다중 상태를 지닌 로봇의 전형적인 run() 메소드
                

public void run() {
        try {
            // Set up and enable the state manager
            StateManager navigation = new StateManager(this);
            navigation.addState(new CannonFodderState(this));
            navigation.addState(new TrackState(this));
            addCommandListener(navigation);
            enable();

            // Set turret to move independent of body
            setAdjustGunForRobotTurn(true);

            // Main bot execution loop
		    while(true) {
                // Spin gun
                setTurnGunRightRadians(Math.PI);
                // Allow StateManager to do it's thing
		    	executeTurn();
                // Finish the turn
                execute();
	    	}
        } finally {
            // Disable the State Manager
            disable();
        }
    }

구현하기가 다소 복잡하지만, 두가지 큰 이점이 있다. 아키텍처는 매우 확장성 있고, 상태를 추가하여 기능을 향상시킬 수 있다. 게다가, 최상의 상태를 선택할 수 있다는 이점 때문에 로봇은 더욱더 동적인 움직임을 보이게 되고, 패배시키기 어렵다.





위로


다운로드 하십시오

설명 이름 크기 다운로드 방식
Source code j-movemementstate.zip 13KB HTTP
다운로드 방식에 대한 정보


참고자료

  • Robocode 마스터의 비밀 관련 시리즈 보기: 로보코드 전문가들이 자신들이 로봇 전투에서의 성공의 비밀을 나눕니다.

  • 로보코드 창시자, Mathew Nelson은 로보코드 공식 사이트를 관리하고 있다. 로보코드에 대해 진지하게 검토중인 사람이라면 한번쯤은 들러야 한다. 요청을 받은 기능들이 들어 있는 "always current" 리스트에서 to-do list도 확인해 보기 바란다.

  • Christian Schnell의 RoboLeague는 로보코드 리그 매니저 겸 시즌 매니저이다. 여러가지 그룹핑을 통해서 시합을 펼치고, 결과를 관리하며, HTML로 된 현황 리포트를 만들어 낸다.

  • "Rock 'em, sock 'em Robocode (한글)" (한국 developerWorks, 2002년 1월) 총알을 피하고 정확한 공격 작전을 수행하면서 상속, 다형성, 이벤트 처리 및 내부 클래스를 배우는 것이 가능할까? 중독적인 게임광 대상 교육 툴인 Robocode가 전 세계 자바 개발자들에게 이를 가능하도록 한다.

  • "Rock 'em, sock 'em Robocode: 제 2 라운드 (한글)" (한국 developerWorks, 2002년 5월), 고급 로봇 구현과 팀 플레이로 기본에서 나아가기.

  • 자바에 입문했다면 체크하라. "자바 프로그래밍 소개" (developerWorks, 2004년 11월)

  • 한국 developerWorks: 자바 프로그래밍 관련 다양한 기술자료 보기

반응형
댓글