 |
|
난이도 : 초급 Sing Li, Author, Wrox Press
2004 년 6 월 29 일 성을 지켜라! 영토를 정복하라! 기사에게 명하여 창 시합을 벌여 적을 무찌르게 한다.
적의 위치를 파악하고 영토를 정복한다. 자바 코드를 작성하는 것이 지루하다면 중세적 판타지를 현실로 옮길
때가 됐다. 자바 프로그래밍 기술을 단련하고 Eclipse 개발 환경을 완전히 파악하는 과정 속에서 어느덧
자신의 왕국을 다스리게 된다.
2004 ACM 국제 대학생 프로그래밍 대회(2004 ACM International Collegiate
Programming Competition) (참고자료)에서
탄생한 CodeRuler는 IBM alphaWorks의 최신 판타지 게이밍 시뮬레이터이다. 이 게임은 몇
가지 전제가 있다: 당신은 중세의 한 왕국을 소유한 최고 RULER이다. PEASANT와 KNIGHT들은
당신의 명민한 전략적 사고, 민첩한 적응력, 고도의 자바 프로그래밍 스킬에 의존하여 생존하고, 번식하고,
번영한다. 플레이어로서 당신의 목표는 이 RULER를 시뮬레이팅하는 자바 코드를 작성하는 것이다. 이 게이밍
시뮬레이터는 당신의 RULER를 최대 6개의 적군들과 겨루게 하여 우승자를 결정한다.
게임 환경을 드러내고, 규칙을 설명하고, 일반 전략을 논의하고 바로 사용할 수 있는 두 개의 완전한 작동
RULER 엔트리를 제공한다.
시뮬레이션 환경
CodeRuler는 그래픽과 애니메이션이 조화된 게임 환경이다. 중세 RULER로서 당신은 다른 왕국 RULER들과
영토와 지배권을 위해 전쟁을 해야 한다. 왕국 구성은 다음과 같다:
- PEASANT: 영토를 소유하고 일할 수 있음.
- KNIGHT: 전투에 나가 싸워 다른 RULER들의 PEASANT, KNIGHT 또는 CASTLE을
포획함.
- CASTLE: 더 많은 KNIGHT와 PEASANT들을 만들 수 있음. 소유한 영토가 많을수록
생성 속도도 더 빨라진다.
그래픽 게이밍 세계
이 게임은 2차원의 세계에서 진행된다. (배경 경관 스케치는 단지 벽지로서 작용한다. 게임 플레이에 영향을
주지 않으며 게임 과정에 따라 변경되지도 않는다.) 그림 1은 실행중인 CodeRuler 게임 모습이다.
그림1. CodeRuler
그림 1은 두 RULER들이 겨루는 모습이다. RULER는 게임 세계에 나타나지 않는다. 이 게임 구성물들(PEASANT,
KNIGHT, CASTLE)은 시뮬레이션 세계에서 움직이는 색깔이 입혀진 점들이다. 그림 2는 이 구성물들의
모양과 움직임 방향을 설명하고 있다.
그림 2.CodeRuler 게임 구성물의 움직임 패턴
그림 2에서 보듯 KNIGHT와 PEASANT들은 같은 움직임 패턴을 사용한다. 그들은 회전할 때 8개의
방향 중 어떤 한 방향으로 1 스퀘어를 움직일 수 있다. 각 방향에는 관련 숫자들이 있는데 자바 코딩에서
사용하는 것이다. 각 숫자는 사전 정의된 상수(이를테면, NW)를 갖고 있다. 이것 역시 코드에서 사용하는
것이다.
콘솔 스코어 디스플레이
그림
1의 오른쪽에 상태 콘솔이 있다. 현재 작동중인 RULER들의 이름과 속해있는 조직들이 콘솔의 상단에
나와있다. 두 개의 숫자는 RULER의 현재 스코어(왼쪽)와 PEASANT들이 소유한 영토의 평방 수를
나타낸다. 그림 3은 스코어 디스플레이 예제이다.
그림 3. 콘솔 스코어 디스플레이
그림 3에서 RULER #18은 IBM developerWorks에서 Simple Ruler라는 이름을
붙였다. 이 RULER의 현재 스코어는 123이고 774 평방의 왕국 영토를 점령했다. 오른쪽 상단의 빨간색
X를 클릭하면 언제라도 이 시뮬레이션을 없앨 수 있다.
영토 점유 디스플레이
그림
1의 상태 콘솔 중간에 있는 것을 확대한 이미지로서 각 RULER의 현재 영토 점유 상태를 나타낸다.
파란색의 RULER가 빨간색의 RULER 보다 훨씬 많은 영토를 소유했음을 쉽게 알아볼 수 있다.
그림 4.영토 점유 디스플레이
시뮬레이션 시계
그림
1의 상태 콘솔에서 가장 밑에 있는 것은 시계이다. 그림 5에서 이를 확대했다.
그림 5. CodeRuler 시계
해는 시계의 다이얼 주위를 돈다. 해가 완전히 한 바퀴를 돈 후에 시합이 끝난다. 시계의 한 틱(tick)은
시뮬레이터에서는 회전을 의미한다. RULER로서 당신은 각 회전 동안 당신의 구성물들의 움직임을 결정한다.
전투 규칙
각 RULER의 초기 통치 대상들은 다음과 같다:
- PEASANT:10
- KNIGHT:10
- CASTLE:1
| 소유
영토 | 하나의
PEASANT 또는 KNIGHT를 만들기 위한 기회 | | 124 이하 | 만들 수 없음 | | 125 | 14 | | 250 | 12 | | 500 | 10 | | 1,000 | 8 | | 2,000 | 6 | | 4,000 이상 | 4 |
게임 과정 중에 당신은:
- PEASANT를 사용하여 가능한 한 많은 영토를 소유한다.
- KNIGHT를 사용하여 적이 소유한 PEASANT 만큼을 포획하여 그들이 땅을 정복하지 못하도록
한다.
- KNIGHT를 사용하여 적의 KNIGHT들 만큼 전투하여 포획한다. 이로써적군의 방어 기능이 약해진다.
- KNIGHT를 조종하여 다른 RULER의 CASTLE을 포획한다. CASTLE은 KNIGHT들과
PEASANT의 제작소라 할 수 있다. CASTLE 없이는 더 이상의 PEASANT들이나 KNIGHT들을
만들 수 없다. 여러 개의 CASTLE을 가지고 적들보다 빠르게 PEASANT들과 KNIGHT들을 만들
수 있는 능력을 보유한다. 새로운
PEASANT와 CASTLE 만들기 참조
- 당신의 CASTLE이 점령당하는 것을 전략적으로 막는다.
게임 점수 얻기
KNIGHT만이 상대편의 PEASANT, CASTLE, KNIGHT를 잡을 수 있다. 그들의 구역으로 들어가서
PEASANT들과 CASTLE을 쉽게 잡을 수 있다. 상대편 KNIGHT를 잡으려면 먼저 힘의 값을 0으로
내려야 한다. KNIGHT들은 힘의 값을 100으로 시작하여 15에서 30 사이에서 힘의 값을 소진한다.
포획을 성공한 KNIGHT는 20점을 얻는다.
점수 획득 전략
시합의 종료 후 가장 높은 점수를 보유한 RULER가 시합의 우승자가 된다. 표 1은 게임의 점수 획득
전략이다.
표 1. 포획에 따른 점수
| 내용 | 점수 | | PEASANT 포획 | 4 점 | | KNIGHT 포획 | 6 점 | | 성 포획 | 15 점 |
표 2. 잔여 구성요소에 따른 점수
| 남아있는
구성요소 | 점수 | | PEASANT | 1 점 | | KNIGHT | 2 점 | | 성 | 25 점 | | 영토 | 10 스퀘어 당 1 점 |
게임의 구성요소
CodeRuler 게임에서는 RULER의 코드를 작성, 디버깅, 테스트 할 Eclipse IDE가 필요하다.
(통합
'왕국' 개발 환경: Eclipse 참조)
CodeRuler에는 다음과 같은 것이 포함되어 있다:
- Eclipse IDE로 플러그인 되는 인터랙티브 게임 시뮬레이터.
- RULER 작성시 사용할 수 있는 API 문서.
- 움직임, 포획, 점수 규칙.
- 자신이 만든 RULER와 샘플 RULER의 모의 시합.
- 공식 토너먼트에 RULER를 출전시키기 위한 네트워킹 메커니즘.
가상 세계 좌표 시스템
이 게임은 4,608 스퀘어(넓이 72 스퀘어, 높이 64 스퀘어)로 구성된 가상 세계 속에 있다. 이
스퀘어는 (x, y) 좌표 시스템에 따라 숫자가 매겨진다. x 축은 왼쪽에서 오른쪽으로 확장되고 y 축은
위에서 아래로 확장된다. 그림 6은 CodeRuler 세계의 레이아웃이다. (0,0) 위치는 좌측 위쪽
코너에 있다.
그림 6.CodeRuler 좌표 시스템
CodeRuler API와 상속 체계
게임 구성요소에게 명령하기 전에, CodeRuler API를 이해해야 한다. API는 지극히 객체 지향적이고
뚜렷한 상속 체계를 갖고있다. 이 체계를 이해하는 것은 효과적인 CodeRuler 코딩에 매우 중요한 요소이다.
그림 7은 상속 체계이다.
그림 7. CodeRuler 상속 체계
그림 7의 상속 트리는 자바 인터페이스에 근거한다. 각 게임 구성물은 자신과 관련된 인터페이스를 구현해야
한다. PEASANT는 IPeasant를, KNIGHT들은 IKnight를
구현해야 한다. 하지만 CodeRuler 시뮬레이터는 빌트인 구현을 사용하기 때문에 클래스를 코딩 할 필요는
없다. RULER로서 게임 구성물들에 대한 정보를 얻는 데에만 인터페이스에서 제공하는 API를 사용해야
한다.
IObject
인터페이스
IObject 인터페이스는 게임 필드의 모든 구성물들에 대한 수퍼 인터페이스이다.
각 구성물은 IObject를 간접적으로 구현한다. IObject는
모든 구성물의 일반적인 작동을 분해한다:
getRuler(): 구성물이 속해있는 RULER
getX(), getY(): 구성물의 현재 위치
isAlive(): 구성물이 살아있는지(포획되지 않았는지)의 여부
getId(): 고유 ID (KNIGHT, PEASANT, CASTLE)
IObject 수퍼 인터페이스는 두 개의 편리한 메소드를 갖고 있다. 이 메소드들은
전략 계획에 도움이 되며 이것을 사용함으로서 복잡한 삼각법을 적용하지 않아도 된다:
getDirectionTo() 보드 상에 지정된 지점까지의 가장 가까운 방향
계산 .
getDistanceTo() 보드 상의 특정 지점과의 거리 계산 .
IPeasant
인터페이스
IPeasant 인터페이스는 IObject 인터페이스에 어떤
새로운 작동도 추가하지 않는다. RULER의 move() 메소드로 PEASANT들을
움직일 수 있다. PEASANT를 사용하여 영토를 소유할 수 있다. PEASANT의 자동적인 작동으로 이것이
움직인 모든 위치를 점령하는 것이다. 상대편 KNIGHT는 한번의 움직임으로 PEASANT를 잡을 수 있다.
힘의 계산이 개입되지 않는다.
ICastle 인터페이스
ICastle 인터페이스는 IPeasant 인터페이스와 마찬가지로
IObject 인터페이스에 새로운 작동을 추가하지는 않는다. CASTLE의 자동
작동은 더 많은 PEASANT 또는 KNIGHT들을 만드는 것이다. 생성 속도는 소유한 땅에 의존한다.
(새로운
PEASANT와 CASTLE 만들기 참조)
IKnight 인터페이스
IKnight 인터페이스는 getStrength()라는 하나의
메소드를 IObject 인터페이스에 추가한다. KNIGHT는 힘이 0으로 감소할
때 잡힌다. IKnight 인터페이스의getStrength()
메소드를 사용하면 KNIGHT의 손실을 피할 수 있다.
그림
7 인터페이스 계측은 시뮬레이션 동안 그 세계를 움직이는 게임 구성물을 나타낸다. 하지만 RULER는
게임 구성물이 아니며 시뮬레이션 세계에서 움직이지 않는다. IRuler 인터페이스는
RULER의 작동을 정의한다.
IRuler 인터페이스
IRuler 인터페이스는 IObject에서 상속 받을 필요가
없다. 그림 8은 IRuler 인터페이스의 상속 체계이다.
그림 8. IRuler 인터페이스의 상속 체계
IRuler 인터페이스는 모든 RULER가 구현하는 일반적인 작동을 정의한다.
전략 수립에 유용하게 쓰이는 정보성 메소드가 포함되어 있다:
getPeasants(): RULER의 지배를 받고 있는 모든 PEASANT들의
리스트.
getKnights(): RULER의 지배를 받고 있는 모든 KNIGHT들의
리스트.
getCastles(): RULER의 지배를 받고 있는 모든 CASTLE들의
리스트.
getLandCount(): RULER가 소유하고 있는 영토 스퀘어의 수.
getPoints() : RULER가 얻어낸 현재 점수.
getRulerName(): RULER의 이름.
getSchoolName(): RULER의 창시자가 속한 조직의 이름.
- 매 순서마다
orderSubjects() 메소드를 호출한다.
Ruler와 MyRuler 클래스
지정된 게임 규칙대로 작동을 실행하고, IRuler 인터페이스 구현을 보조하기 위해서
CodeRuler는 그림
8과 같은 Ruler 클래스를
제공한다. 이 클래스는 대부분의 IRuler 메소드의 디폴트 구현을 제공한다. Ruler
클래스에서 상속 받아야 하는 MyRuler 클래스의 내용을 작성한다. Ruler
클래스는 변경 할 필요가 없다.
getRulerName()과 getSchoolName()
메소드는 전략 코드를 포함해서는 안된다. 시뮬레이터가 언제라도 이들을 호출할 수 있다.
Ruler는 MyRuler 구현에 사용해야 하는 여러 중요한
액션 메소드를 제공한다:
move():구성물들이 가상 세계 주변을 돌도록 한다.
capture(): 상대편의 게임 구성물을 잡도록 시도한다.
l
Ruler는 CASTLE의 생성 모드를 변화시킬 수 있는 여러 메소드들도 구현한다.
기본적으로, CASTLE이 지속적으로 PEASANT를 만들어낸다. 하지만 이 메소드를 사용하여 KNIGHT들을
만들도록 명령한다:
createKnights() : CASTLE이 KNIGHT들을 만들도록 명령한다.
createPeasants(): CASTLE이 PEASANT를 만들도록 명령한다.
Ruler 클래스의 존재의 이유 중 하나는 MyRuler
클래스에서 구현해야 하는 추가적인 추상 메소드를 정의하기 위함이다. 시뮬레이션 엔진은 실행 중에 이 메소드를
호출한다.
작성할 유일한 코드는 표 3에 열거된 메소드를 구현하는 코드이다:
표
3. MyRuler 구현의 메소드
| 메소드 | 설명 | getSchoolName() | 그룹 또는 조직을 구분하는 25개 미만의 문자들로 구성된 스트링을 리턴한다. (CodeRuler는
원래 대학들 간 시합용으로 만들어졌다.) 이는 게임 하는 동안 RULER를 확인하는데 사용된다.
그림
1에서 Simple Ruler는 IBM developerWorks 라는 이름을 가진다. | getRulerName() | RULER를 독자적으로 구분하는 25개 미만의 문자들로 구성된 스트링을 리턴한다. 그림
1의 RULER 중 하나는 Simple Ruler라는 이름을 가지고 있다. | initialize() | RULER를 게임에 처음 배치시킬 때 시스템이 이 메소드를 호출한다. 이 곳에 필요한 초기화를
수행한다. 초기화 시간은 1초로 제한된다. 초기화 동안 머신이 수행할 수 있는 작업량은 CPU 속도와
Java VM에 따라 다르다. 하지만 1초면 코드 초기화 태스크가 충분하다. 느린 인풋/아웃풋을
야기하는 어떤 시도도 말라 | orderSubjects() | 이는 CodeRuler의 핵심이다. 시스템은 매 회전 마다 한번만 이 메소드를 호출한다. 전략을
먼저 연습하고 이 메소드에서 무엇을 할지 구성물들에게 명령한다. |
통합 '왕국' 개발 환경: Eclipse
CodeRuler 시뮬레이션 환경(참고자료)을
실행하려면 Eclipse IDE (2.1 버전 이상)를 다운로드하여 설치해야 한다. CodeRuler는
플러그인으로서 Eclipse IDE에 통합되어 이로서 개발자에게 편리한 기능을 활용할 수 있다.
Eclipse와 CodeRuler
설치하기
Eclipse를 설치하려면 압축을 풀고 Eclipse 실행파일을 실행한다. JDK/JRE 1.4.2 또는
이후 버전을 설치해야 한다. Eclipse를 설치한 후에 CodeRuler 엔진(참고자료)을
다운로드 한다. CodeRuler를 설치하려면 CodeRuler 배포판을 <eclipse installation
directory>/plugins 디렉토리에 푼다. 이렇게 되면 플러그인 디렉토리 밑에 com.ibm.games
디렉토리가 생긴다. Eclipse를 시작하면 CodeRuler 플러그인이 로딩된다.
CodeRuler 프로젝트 만들기
Eclipse에 새로운 프로젝트를 만들어 CodeRuler를 사용한다. 메인 메뉴에서 Windows|Preferences를
선택한다. 다이얼로그 박스가 나타난다. (그림 9)
그림 9. CodeRuler 프로젝트 만들기
IDE의 왼쪽 탭 바에서 Java Perspective 탭을 클릭한다. 그림 10에서 이 탭을 설명한다.
그림 10. Java Perspective 탭 선택하기
src 노드와 디폴트 패키지를 확장하면 MyRuler.java 노드가 나온다. (그림 10). 이 소스
코드 에디터는 MyRuler.java 노드를 더블클릭하면 편집용 파일을 연다. 여기가 코드를 작성할 공간이다.
첫 번째 RULER 코딩하기
당신이 만들 첫 번째 RULER는 간단하다. 이는 모든 PEASANT들을 무작위로 움직인다. Listing
1은 이 RULER에 대한 코드이다. 추가된 코드는 볼드체로 강조했다.
 |
시간엄수의 중요성
RULER를 코딩 할 때 시간 제한이 있음을 명심하라. initialize()
메소드의 경우 1초로 제한되어 있다. 1초 이상 걸린다면 부분 초기화라는 고통을 감수해야 한다.
게임의 각 회전 마다 orderSubjects() 메소드는 0.5초의
시간을 제한하고 있다. orderSubjects() 호출의 인커밍 매개변수는
마지막 회전에 사용할 시간이 얼마나 남았는지를 알려준다. 제한된 시간을 초과하면 나머지 시합
자격을 잃게 된다.
|
|
Listing 1. orderSubjects()의 Simple Ruler
구현
import java.util.Random;
...
protected Random rand = new Random();
public String getRulerName() {
return "Simple Ruler";
}
public String getSchoolName() {
return "IBM developerWorks";
}
public void orderSubjects(int lastMoveTime) {
IPeasant[] peasants = getPeasants();
for (int i = 0; i < peasants.length; i++) {
move(peasants[i], rand.nextInt(8) + 1);
}
}
|
Listing 1의 코드는 java.util.Random을 사용하여 1과 8 사이의
무작위 숫자를 만들어 낸다. 이 숫자는 PEASANT가 움직이는 방향을 결정한다. Ruler
클래스의 getPeasants() 메소드를 사용하면 모든 PEASANT의 어레이를
얻을 수 있고, move() 메소드를 사용하면 PEASANT를 움직일 수 있다.
PEASANT를 무작위로 움직이게 하면 이들이 땅을 정복한다. 하지만 RULER가 어떤 것도 잡을 시도를
하지 않으므로 코드는 KNIGHT를 움직일 필요가 없다.
 |
CodeRuler의 금지 리스트
현명한 전략은 게임 승리에 있어서 중요하다. 하지만 CodeRuler는 자바의 기능을 교묘히
사용하여 게이밍 엔진을 훔치거나 악의적인 수단으로 게임을 이기는 행위를 금지한다. 코드
작성 시 다음을 금한다:
|
|
- 구조체 정의
- 초기와 블록 사용
- 쓰레드 생성
- 프로세스 생성
- 파일에 작성하기
- JDBC 사용
- Swing 또는 AWT를 사용하여 GUI 컴포넌트 만들기
- 네트워크나 다른 유사 시스템 기능에 접근하기
- 시뮬레이터 내부에 접근하기 위해 리플렉션이나 인트로스펙션 사용하기
모든 공식적인 시합과 토너먼트에서 위와 같은 행위를 하는 플레이어는 자격을 상실한다. Java
SecurityManager가 이 모든 행위들을 감시한다.
첫 번째 시합
첫 번째 시합을 하기에 앞서 우선 새로 편집된 RULER를 저장한다. 툴바의 저장 버튼을 클릭하거나 메뉴에서
File
>Save를 선택한다. 진행하기에 앞서 타이핑이나 구문 오류를 정정한다.
다섯 개의 아이콘 버튼을 숙지한다. (그림 11).
그림 11. Eclipse 툴바의 CodeRuler 버튼
표 4에서는 그림 11의 버튼 기능을 설명한다.
표 4. CodeRuler 버튼
기능
| 버튼 | 설명 | | Run against samples | 자신이 만든 RULER와 샘플 RULER 중 하나를 테스트 실행 한다. | | Debug against samples | 자신이 만든 RULER와 샘플 RULER 중 하나를 테스트 실행 한다. 디버그 모드에서 자신의
RULER를 실행하면서 자신이 설정한 정지점에 멈춘다. | | Run against other teams | 코드를 제출한 후에 다른 팀의 RULER들이 다운로드 된다. 이 버튼을 사용하여 다른 팀의 RULER와
자신의 RULER를 테스트 실행한다. | | Debug against other teams | 자신의 RULER와 다른 팀의 RULER를 테스트하는 동안 IDE의 디버그 모드에서 RULER를
실행한다. | | Submit code | 자신이 만든 RULER를 제출한다. 또한 다른 팀에서 제출한 암호화된 모든 RULER들을 다운로드
한다. |
그림 12. 게임 상대자 선택하기
하나의 Do Nothing Ruler를 추가한다. 시합을 시작하고 PEASANT의 무작위 움직임과 영토
점령 방법을 관찰한다. 이 시합은 쉽게 이긴다.
그런 다음, Random Ruler를 시도한다. 이 RULER는 당신이 만든 것과 거의 비슷하게 움직인다.
평균적인 영토 점유율도 거의 비슷하다.
다른 샘플 RULER를 추가한다면 Simple Ruler가 패배한다. 대부분의 다른 샘플 RULER들은
당신의 구성물을 공격적으로 포획하려 한다. 이제 공격 엣지를 Simple Ruler에 추가할 때이다.
공격 RULER 만들기
Listing 2는 변경된 RULER에 대한 코드이다. 추가된 코드가 강조되었다.
Listing 2. 변경된 Simple Ruler 구현- 공격성 강화
import com.ibm.ruler.*;
import java.awt.Point;
import java.util.Random;
import java.util.Vector;
public class MyRuler extends Ruler {
public String getRulerName() {
return "Simple Ruler";
}
public String getSchoolName() {
return "IBM developerWorks";
}
public void initialize() {
}
protected Random rand = new Random();
protected Vector enemies = new Vector();
public void orderSubjects(int lastMoveTime) {
IPeasant[] peasants = getPeasants();
IKnight[] knights = getKnights();
for (int i = 0; i < peasants.length; i++) {
move(peasants[i], rand.nextInt(8) + 1);
}
enemies.clear();
IPeasant[] otherPeasants = World.getOtherPeasants();
IKnight[] otherKnights = World.getOtherKnights();
ICastle[] otherCastles = World.getOtherCastles();
for (int i=0; i<otherPeasants.length; i++) {
enemies.add(otherPeasants[i]);
}
for (int i=0; i<otherKnights.length; i++ ){
enemies.add(otherKnights[i]);
}
for (int i=0; i<otherCastles.length; i++) {
enemies.add(otherCastles[i]);
}
int size = knights.length;
for (int i = 0; i < size; i++) {
IKnight curKnight = knights[i];
if (!enemies.isEmpty()) {
IObject curEnemy = (IObject) enemies.remove(0);
moveAndCapture(curKnight, curEnemy);
}
else
break;
} // of outter for
}
public void moveAndCapture(IKnight knight, IObject enemy) {
if ((enemy == null) || !enemy.isAlive())
return;
// find the next position in the direction of the enemy
int dir = knight.getDirectionTo(enemy.getX(), enemy.getY());
Point np = World.getPositionAfterMove(knight.getX(), knight.getY(), dir);
if (np == null)
return;
if ((np.x == knight.getX()) && (np.y == knight.getY())) {
move(knight, rand.nextInt(8) + 1);
return;
}
// capture anything that is in our way
IObject obj = World.getObjectAt(np.x, np.y);
if ((obj != null) && (obj.getRuler()!= this))
capture(knight, dir);
else
move(knight, dir);
}
}
|
 |
World 객체
값비싼 RULER 코딩을 감행하기 전에 World 객체 문서를 공부하라. 이 객체에는 전략 구현에
유용하게 쓰일 정적 메소드가 포함되어 있다.
|
|
Listing 2에서 연두색으로 강조한 코드를 주목하라.
빨간색 코드는 시뮬레이션 세계에서 살아있는 상대편 게임 구성물들로 구성된 Vector
를 설정한다.World 객체를 사용하여 이 정보를 얻는다. (World.getOtherPeasants()).
파란색으로 강조된 코드는 당신의 모든 KNIGHT들을 루핑하고 이들을 살아있는 상대편의 게임 구성물쪽으로
움직인다. 제자리에 있는 상대편 구성물을 잡기도 한다. moveAndCapture()메소드를
사용하여 움직이고 포획한다.
moveAndCapture()메소드는 특정 KNIGHT를 상대편의 특정 구성물
쪽으로 움직인다. World 객체 getPositionAfterMove()
메소드를 사용하여 KNIGHT가 멈출 지의 여부를 결정하고 무작위 움직임을 만든다. World
객체 getObjectAt() 메소드를 사용하여 이 경로에 있는 적의 구성물을 테스트
및 포획한다.
새로운 Simple Ruler와 몇몇의 샘플 RULER를 테스트한다. 많은 부분이 향상되어야 한다. 연습
삼아, 다음과 같이 변경해도 좋다:
- CASTLE에 명령하여 KNIGHT의 수가 줄어들 때 KNIGHT들을 만들도록 한다.
- KNIGHT에 타겟을 효율적으로 할당한다.
- PEASANT들이 보다 효율적으로 땅을 차지하도록 프로그래밍한다.
- PEASANT들이 잡히지 않도록 프로그래밍한다.
- PEASANT와 KNIGHT들의 수가 줄어들면 방어적인 생존 전략으로 바꾼다.
참고자료
필자소개  | |  | Sing Li
has authored this article |
기사에 대한 평가
|