탱크 전쟁을하자!
Lazer와 함께 파괴하는 데 부분적으로 영향을 받음
객관적인
당신의 임무는 탱크를 제어하는 것입니다. 2D 전장에서 다른 탱크와 장애물을 이동하고 쏴라. 마지막 탱크 순위가 승자가 될 것입니다!
지도 형식
탱크는 단위 제곱 격자를 기준으로 2D 필드에 배치 n
됩니다 n
. n
제출 횟수를 기준으로 결정합니다 . 각 사각형은 다음 중 하나만 포함 할 수 있습니다.
- 탱크
- 나무
- 바위
- 벽
- 아무것도
모든 장애물과 탱크는 자신의 공간을 완전히 채우고, 충돌하는 모든 사격을 차단하여 물건을 더 손상시키지 않습니다.
다음은 #
= tank 인 필드의 예입니다 . T
= 트리; R
= 바위; W
= 벽; .
= n
10이없는 것
.....#....
..T....R..
WWW...WWWW
W......T..
T...R...Ww
W...W.....
W....W...T
WWWWWW...R
W.........
WWWWWWRT..
좌표의 형식은 증가 오른쪽 왼쪽 상단에 증가 하단. 왼쪽 하단 공간에는 좌표가 있습니다. 각 탱크는 빈 공간으로 이동하여 어떤 방향으로도 발사 할 수 있습니다.x, y
x
y
0, 0
지도 역학
탱크는 다른 탱크를 쏠 필요가 없습니다! 지도에서 무언가를 촬영하면 상황이 발생할 수 있습니다.
- 벽이 맞으면 1 ~ 4 범위의 몇 번의 발사 후에 벽이 파괴됩니다.
- 나무가 맞으면 즉시 파괴됩니다
- 바위가 총에 맞으면, 그 총은 그것을 지나쳐 다음에 닿는 것을 손상시킵니다.
무언가가 파괴되면 더 이상 맵에 표시되지 않습니다 (아무것도 대체되지 않습니다). 샷이 장애물을 파괴하면 막히고 경로를 따라 더 이상 손상되지 않습니다.
탱크 역학
각 탱크는 life
= 100으로 시작합니다 . 탱크에서 각 샷은 life
거리에 따라 20-30을 줄 입니다. 이는 계산 될 수있다 delta_life=-30+(shot_distance*10/diagonal_map_length)
(여기서, diagonal_map_length
이다 (n-1)*sqrt(2)
). 또한, 각 탱크 life
는 한 턴에 1을 재생 합니다.
회전
몇 차례의 라운드가 진행됩니다 (제출 후 결정합니다). 매 라운드가 시작될 때마다 맵이 무작위로 생성되고 탱크가 무작위로 빈 위치에 배치됩니다. 매 라운드마다, 각 탱크는 임의의 순서로 차례가 주어집니다. 모든 탱크에 턴이 주어진 후에는 같은 순서로 다시 턴이 주어집니다. 탱크가 하나만 남을 때까지 라운드가 계속됩니다. 그 전차가 승자가되고 1 점을받습니다. 게임은 다음 라운드로 진행됩니다.
모든 라운드가 완료되면이 질문에 점수를 게시합니다.
전차가 회전하는 동안 다음 중 하나를 수행 할 수 있습니다.
- 수평 또는 수직으로 한 방향으로 최대 3 칸 이동합니다. 탱크가 장애물이나 다른 탱크에 의해 막히면 장애물이나 탱크를 통하지 않고 가능한 멀리 이동합니다.
- 부동 소수점 각도 (도)로 표시되는 특정 방향으로 촬영합니다. 탱크의 로컬 공간 (가로로 왼쪽에서 오른쪽, 일명 동쪽 또는
TurnAction.Direction.EAST
) 의 x 축은 0 도이고 각도는 시계 반대 방향으로 증가합니다. 샷이 정확하지 않으며 실제 샷 각도는 선택한 각도보다 5도 크거나 작을 수 있습니다. - 아무것도하지 마세요.
턴은 시간에 제한이 없지만 모든 것을 끊는 데 의도적으로 시간을 낭비 할 수있는 것은 아닙니다.
제출물 / 프로토콜
제출 된 각 프로그램은 현장에서 한 탱크를 통제합니다. 제어 프로그램은 Java로되어 있으므로 지금은 프로그램이 Java로되어 있어야합니다 (어쩌면 다른 언어의 래퍼를 작성하거나 직접 작성할 수도 있습니다).
프로그램은 Tank
다음과 같은 방법으로 인터페이스 를 구현합니다 .
public interface Tank {
// Called when the tank is placed on the battlefield.
public void onSpawn(Battlefield field, MapPoint position);
// Called to get an action for the tank on each turn.
public TurnAction onTurn(Battlefield field, MapPoint position, float health);
// Called with feedback after a turn is executed.
// newPosition and hit will be populated if applicable.
public void turnFeedback(MapPoint newPosition, FieldObjectType hit);
// Called when the tank is destroyed, either by another tank,
// or because the tank won. The won parameter indicates this.
public void onDestroyed(Battlefield field, boolean won);
// Return a unique name for your tank here.
public String getName();
}
이 Battlefield
클래스에는 전장의 사물을 나타내는 2D 객체 배열 ( Battlefield.FIELD_SIZE
by Battlefield.FIELD_SIZE
)이 포함되어 있습니다 . Battlefield.getObjectTypeAt(...)
를 제공 FieldObjectType
지정된 좌표에 대한 오브젝트 (중 하나를 FieldObjectType.ROCK
, FieldObjectType.TREE
, FieldObjectType.TANK
, FieldObjectType.WALL
, 또는 FieldObjectType.NOTHING
). 맵 범위를 벗어난 객체 (좌표 <0 또는> = Battlefield.FIELD_SIZE
) 를 얻으려고 IllegalArgumentException
하면가 발생합니다.
MapPoint
지도에서 점을 지정하기위한 클래스입니다. 사용 MapPoint.getX()
및 MapPoint.getY()
좌표에 액세스 할 수 있습니다.
편집 : 일부 유틸리티 메소드가 추가되었습니다 : MapPoint.distanceTo(MapPoint)
, MapPoint.angleBetween(MapPoint)
, Battlefield.find(FieldObjectType)
,과 TurnAction.createShootActionRadians(double)
에 의해 제안 Wasmoo .
자세한 정보는 javadocs에서 찾을 수 있습니다 (아래 섹션 참조).
모든 (공용 API) 클래스는 패키지 아래에 zove.ppcg.tankwar
있습니다.
제어 프로그램
제어 프로그램 및 탱크 API의 전체 소스 및 javadoc은 내 GitHub 저장소에서 찾을 수 있습니다 : https://github.com/Hungary-Dude/TankWarControl
버그가 있거나 개선을 원할 경우 풀 요청 및 / 또는 의견을 보내주십시오.
나는 두 개의 샘플 탱크 프로그램을 작성 RandomMoveTank
했으며 RandomShootTank
(이름이 다 말해줍니다).
탱크를 가동하려면 정규화 된 (패키지 이름 + 클래스 이름) 탱크 클래스를 tanks.list
(한 줄에 한 클래스)에 추가하고, 필요에 따라 설정을 편집하십시오 zove.ppcg.tankwar.Control
(턴 지연, 필드의 GUI 표시 표시 여부 등), 실행합니다 zove.ppcg.tankwar.Control
. 목록에 탱크가 2 개 이상 있거나 결과가 정의되어 있지 않은지 확인하십시오. (필요한 경우 샘플 탱크를 사용하십시오).
귀하의 프로그램은이 제어 프로그램에 따라 내 컴퓨터에서 실행됩니다. 소스를 작성하면 소스에 대한 링크를 포함시킵니다. 소스 편집을 제안하십시오.
규칙
- 제출물은 위의 지침을 따라야합니다
- 귀하의 프로그램은 파일 시스템, 네트워크에 액세스하거나 어떤 방식 으로든 내 컴퓨터를 공격하려고 시도 할 수 없습니다
- 귀하의 프로그램이 내 제어 프로그램을 악용하여 시도하지 않을 수 있습니다
- 트롤링 금지 (예 : 의도적으로 모든 것을 끊기 위해 프로그램을 낭비하는 시간)
- 제출이 둘 이상있을 수 있습니다
- 제출물로 창의력을 발휘하십시오!
- 프로그램을 임의로 허용 할 수있는 권리를 보유합니다
행운을 빕니다!
업데이트 : 벽 순간 이동 버그를 수정하고 재생성을 구현 한 후 100 라운드 동안 현재 제출물을 실행했습니다.Battlefield.FIELD_SIZE = 30
업데이트 2 : Groovy에 약간의 속임수를 쓴 후 새로운 제출 인 RunTank를 추가했습니다 ...
업데이트 된 결과 :
+-----------------+----+
| RandomMoveTank | 0 |
| RandomShootTank | 0 |
| Bouncing Tank | 4 |
| Richard-A Tank | 9 |
| Shoot Closest | 19 |
| HunterKiller 2 | 22 |
| RunTank | 23 |
| Dodge Tank | 24 |
+-----------------+----+
현재 전차는 1 턴마다 1의 생명력을 재생합니다. 그 증가해야합니까?
MapPoint
이야 'x
하고y
floats
? 그들이해서는 안ints
됩니까?