Фоновая будущее
В 2017 году вы и ваш противник встретитесь в футуристическом бою, в котором выживет только один. Действительно ли вы достаточно опытный , чтобы победить вашего противника? Сейчас самое время отточить свои навыки владения оружием на вашем любимом языке программирования и бороться со всеми трудностями!
Результаты турнира
Этот турнир завершился в UTC утром Feburary 2 - й , 2017. Благодаря нашим конкурсанток, мы имели захватывающий футуристический турнир!
MontePlayer - окончательный победитель после близких сражений с CBetaPlayer и StudiousPlayer. Три лучших дуэлянта Гена сделали памятную фотографию:
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- го хода, они истощаются до смерти, что приводит к ничьей .
Игрок проигрывает дуэль с оружием, если он
- Возможно , НЕ использовать металлический экран для защиты входящей пули.
- Возможно , НЕ используйте тепловой дефлектор , чтобы защитить входящую плазму.
- Стреляйте из пистолета, не загружая достаточно патронов, в результате чего их пистолет сам взорвется и убьет владельца.
Предостережения
Согласно Руководству для владельцев футуристических ружей :
- Металлический щит НЕ МОЖЕТ защищать от поступающего плазменного луча. Аналогично, тепловой дефлектор НЕ МОЖЕТ защищать от входящей пули.
- Плазменный луч подавляет пулю (потому что первый требует больше заряженных боеприпасов). Поэтому, если игрок стреляет плазменным лучом по противнику, который стреляет пулей в тот же ход, противник убивается.
- Если оба игрока одновременно выпускают пули друг в друга, пули отменяются, и оба игрока выживают. Аналогично, если оба игрока стреляют друг в друга плазменным лучом в один ход, оба игрока выживают.
Также стоит отметить, что:
- Вы НЕ будете знать действия своего противника в ход, пока он не закончится.
- Отражение плазменных лучей и защитных пуль НЕ причинит вреда вашему противнику.
Таким образом, в каждом ходу есть всего 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.
Пример дуэли
Вот дуэль, которую я когда-то имел с другом. В то время мы мало что знали о программировании, поэтому мы использовали жесты рук и передавали сигналы со скоростью два оборота в секунду. Слева направо наши действия были в свою очередь:
Me: 001-000-1201101001----2
Friend: 00-10-=1-==--0100-1---1
По правилам выше я проиграл. Вы понимаете почему? Это потому, что я выпустил последний плазменный луч, когда у меня был только один заряженный патрон, и мой пистолет взорвался.
C ++ Player
Вы , как цивилизованный футуристический программист, не будете напрямую обращаться с оружием. Вместо этого вы пишете код, Player
который борется против других. Публично наследуя класс c ++ в проекте GitHub, вы можете начать писать свою городскую легенду.
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
, который возвращает действительныйPlayer::Action
каждый раз, когда он вызывается. - При желании, переопределить
Player::perceive
иPlayer::declared
следить за действиями вашего противника и отслеживать ваши победы. - При желании используйте частные статические члены и методы в производном классе для выполнения более сложных вычислений.
- При желании используйте другие стандартные библиотеки C ++.
Что вы не должны делать
- Вы НЕ ДОЛЖНЫ использовать какой-либо прямой метод для распознавания своего противника, кроме указанного идентификатора противника, который перемешивается в начале каждого турнира. Вы можете только догадываться, кто является игроком через их игру в турнире.
- Вы должны НЕ переопределить любые методы в
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.
Вы можете комментировать, чтобы попросить разъяснений или определить лазейки. Надеюсь, вам понравится этот футуристический Gun Duel и желаю вам счастливого Нового года!
осветление
- Вам разрешено иметь случайное поведение.
- Недопустимые действия (стрельба при загруженных боеприпасах недостаточно) разрешены.
- Если игрок делает неверный ввод, его пистолет взорвется немедленно.
- Вам разрешено изучать ответы.
- Вам явно разрешено записывать поведение противника в каждом турнире.
- Каждый раунд вы будете играть 100 поединков против каждого противника; порядок 100 поединков, однако, рандомизирован - вам не гарантировано, что вы будете сражаться с одним и тем же противником 100 поединков подряд.
Дополнительные ресурсы
@flawr перевел предоставленный источник C ++ на Java в качестве ссылки, если вы хотите отправить записи C ++.
Интерфейс для не-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 подключены к драйверу турнира. Нарушение этого может привести к тупику. Все записи ДОЛЖНЫ следовать этому алгоритму EXACT (в псевдокоде):
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
. ПРОЦЕСС означает опционально реагировать на действия противника (включая отслеживание патронов противника, если вы это делаете). Обратите внимание, что действие противника также является одним из «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 |
Турнир продлится до 1 февраля 2017 года, если не указано иное.
Player
реализации, которая вызывает другой процесс, чтобы вычислить текущий ход. Это позволило бы людям участвовать на любом языке, который вы с удовольствием используете на своей машине.
Player::fight
» / «Вы можете наследовать Player::perceive
» ... в обоих случаях термин переопределяет , а не наследует .
GunDuel.hpp
, как validA
и validB
использоватьactionA