배경 미래
2017 년에, 당신과 상대는 오직 하나만 생존 할 수있는 미래형 총기 전투에서 맞서게됩니다. 있습니까 당신은 상대를 물리 칠 수있을만큼 경험? 이제 좋아하는 프로그래밍 언어로 총기 기술 을 연마 하고 모든 확률에 맞서 싸울 때입니다!
토너먼트 결과
2 월 2의 UTC 아침에 끝난이 대회 ND는 , 우리의 참가자에 2017 덕분에, 우리는 흥미로운 미래 토너먼트 있었다!
MontePlayer는 CBetaPlayer 및 StudiousPlayer와의 긴밀한 전투 후 최종 승자입니다. 3 명의 최고 guen 결투가 기념 사진을 찍었습니다.
MontePlayer - by TheNumberOne
+------------+
CBetaPlayer | | - by George V. Williams
+------------+ # 1 | StudiousPlayer - by H Walters
| +----------------+
| # 2 # 3 |
+------------------------------------------+
The Futurustic Gun Duel @ PPCG.SE 2017
우승자 축하합니다! 자세한 게시물은이 게시물의 끝 부분에서 볼 수 있습니다.
일반 안내
- 이 토너먼트에 사용 된 소스 코드 는 공식 저장소 를 방문하십시오 .
- C ++ 항목 :
Player
클래스 를 상속하십시오 . - 비 C ++ 항목 : 비 C ++ 제출을위한 인터페이스 섹션에서 하나의 인터페이스를 선택하십시오 .
- 현재 허용되는 비 C ++ 언어 : Python 3, Java.
결투
- 각 플레이어는 무한대의 탄약을 적재 할 수있는 언로드 건으로 시작합니다.
- 매 턴마다 플레이어는 동시에 다음 행동 중 하나를 선택합니다.
0
-총에 탄약 1 개를 넣습니다.1
-상대방에게 총알을 발사; 탄약 1 개가 들어갑니다.2
-상대방에게 플라즈마 빔을 발사; 탄약 2 개가 들어갑니다.-
-금속 실드를 사용하여 들어오는 총알을 방어하십시오.=
-열 편향기를 사용하여 들어오는 플라즈마 빔을 방어하십시오.
- 100 번째 턴 후에도 두 선수가 모두 생존하면 모두 죽 습니다 .
플레이어 가 총 결투를 잃으면
- 나요 NOT 들어오는 총알을 방어하기 위해 금속 실드를 사용합니다.
- 나요 NOT 들어오는 플라즈마를 방어하기 위해 열 디플렉터를 사용합니다.
- 탄약을 충분히 넣지 않은 상태에서 총을 발사하면 총이 스스로 폭발하여 주인을 죽일 수 있습니다.
경고
미래의 총기 소유자 매뉴얼에 따르면 :
- 금속 실드 는 들어오는 플라즈마 빔으로부터 방어 할 수 없습니다 . 마찬가지로, 열 편향 기는 들어오는 총알을 막을 수 없습니다 .
- 플라즈마 빔은 탄환을 압도합니다 (전포에는 탄약이 더 많이 필요하기 때문에). 따라서 플레이어가 같은 차례에 총알을 발사하는 상대방에게 플라즈마 빔을 발사하면 상대방이 죽습니다.
- 두 플레이어가 같은 차례에 총알을 발사하면 총알이 취소되고 두 플레이어 모두 생존합니다. 마찬가지로 두 선수가 같은 차례에 서로 플라즈마 빔을 발사하면 두 선수 모두 생존합니다.
또한 주목할만한 점은 다음과 같습니다.
- 당신은 상대의 행동이 끝날 때까지 한 번에 알 수 없습니다 .
- 플라즈마 빔을 차단하고 총알을 막아도 상대에게 피해를주지 않습니다 .
따라서 턴마다 총 25 개의 유효한 액션 조합이 있습니다.
+-------------+---------------------------------------------+
| Outcome | P L A Y E R B |
| Table +--------+-----------------+------------------+
| for Players | Load | Bullet Plasma | Metal Thermal |
+---+---------+--------+--------+--------+--------+---------+
| P | Load | | B wins | B wins | | |
| L +---------+--------+--------+--------+--------+---------+
| A | Bullet | A wins | | B wins | | A wins |
| Y | +--------+--------+--------+--------+---------+
| E | Plasma | A wins | A wins | | A wins | |
| R +---------+--------+--------+--------+--------+---------+
| | Metal | | | B wins | | |
| | +--------+--------+--------+--------+---------+
| A | Thermal | | B wins | | | |
+---+---------+--------+--------+---------------------------+
Note: Blank cells indicate that both players survive to the next turn.
결투 예
여기 친구와 함께한 결투가 있습니다. 당시에는 프로그래밍에 대해 잘 몰랐기 때문에 손 동작을 사용하여 초당 2 회전의 속도로 신호를 보냈습니다. 왼쪽에서 오른쪽으로 우리의 행동은 차례로 이루어졌습니다.
Me: 001-000-1201101001----2
Friend: 00-10-=1-==--0100-1---1
위의 규칙에 따라, 나는졌다. 왜 그런지 알아? 탄약이 1 개만있을 때 최종 플라즈마 빔을 발사하여 총이 폭발하기 때문입니다.
C ++ 플레이어
문명화 된 미래의 프로그래머 인 당신 은 총을 직접 다루지 않을 것입니다. 대신, 당신 Player
은 다른 사람들과 싸우는 a를 코딩합니다 . GitHub 프로젝트에서 c ++ 클래스 를 공개적으로 상속함으로써 도시의 전설을 작성할 수 있습니다.
Player.hpp can be found in Tournament\Player.hpp
An example of a derived class can be found in Tournament\CustomPlayer.hpp
당신이 해야 하거나 할 수있는 것
- 당신은 상속 할 필요가
Player
공공 상속을 통해 클래스 및 클래스의 마지막을 선언합니다. - 를 호출 할 때마다
Player::fight
유효한 값을 반환하는 override를 무시해야합니다Player::Action
. - 선택적으로, 상대방의 행동을 무시
Player::perceive
하고Player::declared
감시하고 승리를 추적하십시오. - 선택적으로 파생 클래스에서 전용 정적 멤버 및 메서드를 사용하여보다 복잡한 계산을 수행 할 수 있습니다.
- 선택적으로 다른 C ++ 표준 라이브러리를 사용하십시오.
하지 말아야 할 것
- 당신은 있어야 하지 각 대회의 시작 부분에 셔플 주어진 상대 식별자가 아닌 다른 상대를 인식하는 직접적인 방법을 사용합니다. 토너먼트 내에서 누가 게임 플레이를하는지 추측 할 수 있습니다.
- 당신은 있어야 하지 어떤 방법 오버라이드 (override)
Player
가상 선언되지 않은 클래스를. - 전역 범위에서 어떤 것도 선언하거나 초기화 해서는 안됩니다 .
- (현재 실격) 데뷔 한 이래로
BlackHatPlayer
플레이어는 상대방의 상태를 들여다 보거나 수정할 수 없습니다 .
결투의 예
총 결투 과정은 GunDuel
클래스를 사용하여 수행됩니다 . 싸움의 예 는 결투 시작Source.cpp
섹션을 참조하십시오 .
우리는 전시 GunClubPlayer
, HumanPlayer
그리고 GunDuel
클래스는에서 찾을 수있는 Tournament\
저장소의 디렉토리.
각 결투에서 GunClubPlayer
총알을로드합니다. 해고; 헹구고 반복하십시오. 매 턴마다 HumanPlayer
상대와의 대전을 요구합니다. 키보드 컨트롤은 문자입니다 0
, 1
, 2
, -
와 =
. Windows에서는 HumanPlayer
제출을 디버그 하는 데 사용할 수 있습니다 .
결투 시작
콘솔을 통해 플레이어를 디버깅하는 방법입니다.
// Source.cpp
// An example duel between a HumanPlayer and GunClubPlayer.
#include "HumanPlayer.hpp"
#include "GunClubPlayer.hpp"
#include "GunDuel.hpp"
int main()
{
// Total number of turns per duel.
size_t duelLength = 100;
// Player identifier 1: HumanPlayer.
HumanPlayer human(2);
// Player identifier 2: GunClubPlayer.
GunClubPlayer gunClub(1);
// Prepares a duel.
GunDuel duel(human, gunClub, duelLength);
// Start a duel.
duel.fight();
}
게임 예
당신이 패배 할 필요가 회전의 최소 금액은 GunClubPlayer
여기에 3입니다 재생에서 재생의 0-1
에 대해 GunClubPlayer
. 마비의 숫자는 턴이 끝났을 때 각 플레이어의 탄약 수입니다.
:: Turn 0
You [0/12/-=] >> [0] load ammo (1 ammo)
Opponent selects [0] load ammo (1 ammo)
:: Turn 1
You [0/12/-=] >> [-] defend using metal shield (1 ammo)
Opponent selects [1] fire a bullet (0 ammo)
:: Turn 2
You [0/12/-=] >> [1] fire a bullet (0 ammo)
Opponent selects [0] load ammo (1 ammo)
:: You won after 3 turns!
:: Replay
YOU 0-1
FOE 010
Press any key to continue . . .
총알이 열 편향기를 통해 바로 쏘기 때문에 GunClubPlayer
무효 한 움직임없이 패배하는 가장 빠른 방법 은 순서 0=
입니다. 재생은
:: Turn 0
You [0/12/-=] >> [0] load ammo (1 ammo)
Opponent selects [0] load ammo (1 ammo)
:: Turn 1
You [0/12/-=] >> [=] defend using thermal deflector (1 ammo)
Opponent selects [1] fire a bullet (0 ammo)
:: You lost after 2 turns!
:: Replay
YOU 0=
FOE 01
Press any key to continue . . .
토너먼트
토너먼트는 "최종 선수 순위"형식을 따릅니다. 토너먼트에서 모든 유효한 제출물 (을 포함하여 GunClubPlayer
)은 풀에 배치됩니다. 각 제출물에는 전체 토너먼트 동안 동일하게 유지되는 무작위이지만 고유 한 식별자가 할당됩니다. 각 라운드 동안 :
- 각 제출은 0 점으로 시작하며 다른 모든 제출에 대해 100 개의 결투를합니다.
- 각 승리 한 결투는 1 점을 부여합니다. 그리기와 잃는 것은 0 점을줍니다.
- 라운드가 끝나면 최소 점수로 제출하면 토너먼트가 종료됩니다. 동점 인 경우, 토너먼트 시작 후 획득 한 포인트가 가장 적은 플레이어가 떠나게됩니다.
- 한 명 이상의 선수가 남으면 다음 라운드가 시작됩니다.
- 포인트는 다음 라운드로 넘어 가지 않습니다 .
제출
답변 당 한 명의 플레이어를 제출합니다. 다른 제출을 방해 하지 않는 한 플레이어에 여러 파일을 제출할 수 있습니다 . 흐름을 유지하려면 다음을 수행하십시오.
- 기본 헤더 파일 이름을로 지정하십시오
<Custom>Player.hpp
. - 로 다른 파일 이름
<Custom>Player*.*
예,MyLittlePlayer.txt
당신의 클래스 이름 인 경우MyLittlePlayer
, 또는EmoPlayerHates.cpp
클래스 이름 인 경우EmoPlayer
. - 귀하의 이름
Shooter
에이 토너먼트의 상황에 맞는 단어가 포함 된 경우Player
끝에 추가 할 필요가 없습니다 . 제출 이름이 접미사없이 더 잘 작동한다고 강하게 느끼면Player
추가 할 필요가 없습니다Player
. - Windows에서 코드를 컴파일하고 링크 할 수 있는지 확인하십시오.
설명을 요청하거나 허점을 발견하기 위해 주석을 달 수 있습니다. 이 미래형 건 결투를 즐기시고 새해 복 많이 받으시기 바랍니다.
설명
- 무작위 행동을 할 수 있습니다.
- 유효하지 않은 행동 (탄약이 충분하지 않은 경우 발사)이 허용됩니다.
- 플레이어가 유효하지 않은 입력을하면 총이 즉시 폭발합니다.
- 당신은 답을 연구 할 수 있습니다.
- 각 토너먼트 내에서 상대방의 행동을 명시 적 으로 기록 할 수 있습니다 .
- 각 라운드마다 각 상대에 대해 100 개의 결투를합니다. 그러나 100 개의 결투의 순서는 무작위입니다. 같은 상대에게 100 개의 결투를 연속해서 싸울 수는 없습니다.
추가 자료
C ++ 항목을 제출하려면 @flawr이 제공된 C ++ 소스를 참조 로 Java 로 변환했습니다 .
비 C ++ 제출을위한 인터페이스
현재 허용 : Python 3, Java.
아래 사양 중 하나를 따르십시오.
인터페이스 사양 1 : 종료 코드
제출은 한 차례에 한 번 실행됩니다.
Expected Command Line Argument Format:
<opponent-id> <turn> <status> <ammo> <ammo-opponent> <history> <history-opponent>
Expected Return Code: The ASCII value of a valid action character.
'0' = 48, '1' = 49, '2' = 50, '-' = 45, '=' = 61
<opponent-id> is an integer in [0, N), where N is size of tournament.
<turn> is 0-based.
If duel is in progress, <status> is 3.
If duel is draw / won / lost, <status> is 0 / 1 / 2.
<history> and <history-opponent> are strings of actions, e.g. 002 0-=
If turn is 0, <history> and <history-opponent> are not provided.
You can ignore arguments you don't particularly need.
제출물 PythonPlayer\
및 JavaPlayer\
디렉토리를 테스트 할 수 있습니다 .
인터페이스 사양 2 : stdin / stdout
(H 월터스 크레딧)
귀하의 제출물은 토너먼트마다 한 번씩 실행됩니다.
stdin과 stdout이 토너먼트 드라이버에 연결되어 있기 때문에 I / O 수행 방법에 대한 모든 항목에 대해 고정 된 요구 사항이 있습니다. 이를 위반하면 교착 상태가 발생할 수 있습니다. 모든 항목 은 이 정확한 알고리즘 (의사 코드)을 따라야합니다 .
LOOP FOREVER
READ LINE INTO L
IF (LEFT(L,1) == 'I')
INITIALIZE ROUND
// i.e., set your/opponent ammo to 0, if tracking them
// Note: The entire line at this point is a unique id per opponent;
// optionally track this as well.
CONTINUE LOOP
ELSE IF (LEFT(L,1) == 'F')
WRITELN F // where F is your move
ELSE IF (LEFT(L,1) == 'P')
PROCESS MID(L,2,1) // optionally perceive your opponent's action.
END IF
CONTINUE LOOP
QUIT
여기서, F 중 하나입니다 0
, 1
, 2
, -
, 또는 =
를 위해 load / bullet / plasma / metal / thermal
. PROCESS는 상대방의 탄약 추적을 포함하여 상대방의 행동에 선택적으로 반응하는 것을 의미합니다. 상대방의 행동도 '0', '1', '2', '-'또는 '='중 하나이며 두 번째 문자입니다.
최종 스코어 보드
08:02 AM Tuesday, February 2, 2017 Coordinated Universal Time (UTC)
| Player | Language | Points | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
|:------------------ |:---------- | ------:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:|
| MontePlayer | C++ | 11413 | 1415 | 1326 | 1247 | 1106 | 1049 | 942 | 845 | 754 | 685 | 555 | 482 | 381 | 287 | 163 | 115 | 61 |
| CBetaPlayer | C++ | 7014 | 855 | 755 | 706 | 683 | 611 | 593 | 513 | 470 | 414 | 371 | 309 | 251 | 192 | 143 | 109 | 39 |
| StudiousPlayer | C++ | 10014 | 1324 | 1233 | 1125 | 1015 | 907 | 843 | 763 | 635 | 555 | 478 | 403 | 300 | 201 | 156 | 76 |
| FatedPlayer | C++ | 6222 | 745 | 683 | 621 | 655 | 605 | 508 | 494 | 456 | 395 | 317 | 241 | 197 | 167 | 138 |
| HanSoloPlayer | C++ | 5524 | 748 | 668 | 584 | 523 | 490 | 477 | 455 | 403 | 335 | 293 | 209 | 186 | 153 |
| SurvivorPlayer | C++ | 5384 | 769 | 790 | 667 | 574 | 465 | 402 | 354 | 338 | 294 | 290 | 256 | 185 |
| SpecificPlayer | C++ | 5316 | 845 | 752 | 669 | 559 | 488 | 427 | 387 | 386 | 340 | 263 | 200 |
| DeceptivePlayer | C++ | 4187 | 559 | 445 | 464 | 474 | 462 | 442 | 438 | 369 | 301 | 233 |
| NotSoPatientPlayer | C++ | 5105 | 931 | 832 | 742 | 626 | 515 | 469 | 352 | 357 | 281 |
| BarricadePlayer | C++ | 4171 | 661 | 677 | 614 | 567 | 527 | 415 | 378 | 332 |
| BotRobotPlayer | C++ | 3381 | 607 | 510 | 523 | 499 | 496 | 425 | 321 |
| SadisticShooter | C++ | 3826 | 905 | 780 | 686 | 590 | 475 | 390 |
| TurtlePlayer | C++ | 3047 | 754 | 722 | 608 | 539 | 424 |
| CamtoPlayer | C++ | 2308 | 725 | 641 | 537 | 405 |
| OpportunistPlayer | C++ | 1173 | 426 | 420 | 327 |
| GunClubPlayer | C++ | 888 | 500 | 388 |
| PlasmaPlayer | C++ | 399 | 399 |
달리 명시되지 않는 한 토너먼트는 2017 년 2 월 1 일 까지 지속됩니다 .
Player
다른 프로세스를 호출하여 현재 회전을 계산 하는 구현을 허용 할 수 있습니다. 그것은 사람들이 당신이 당신의 머신에서 실행하기에 좋은 언어로 참여할 수있게 해줄 것입니다.
Player::fight
"/ 상속을 상속해야합니다. " Player::perceive
라는 용어는 상속이 아니라 재정의 입니다.
GunDuel.hpp
둘 다에 버그가 validA
있고 validB
사용 한다고 생각합니다actionA