фонова майбутнє
У 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
клас. - Non C ++ записи: виберіть один інтерфейс в розділі Інтерфейс для подання Non-C ++ .
- На даний момент дозволені мови, що не містять мови C ++: Python 3, Java.
Поєдинок
- Кожен гравець починає з незарядженого пістолета, який може завантажувати нескінченну кількість боєприпасів.
- Кожного кроку гравці одночасно вибирають одну з наступних дій:
0
- Завантажте в гармати 1 патрони.1
- Стріляйте по противнику кулею; коштує 1 завантажений боєприпас.2
- Стріляйте по противнику плазмовим пучком; коштує 2 завантажені боєприпаси.-
- Захистіть вхідну кулю за допомогою металевого щита.=
- Захистіть вхідний пучок плазми за допомогою теплового дефлектора.
- Якщо обидва гравці виживають після 100- го ходу, вони обоє виснажуються до смерті, що призводить до нічиї .
Гравець програє дуель гармати, якщо вони
- Можливо , НЕ використовувати металевий екран для захисту вхідної кулі.
- Можливо , НЕ використовуйте теплової дефлектор , щоб захистити входить плазму.
- Стріляйте з пістолета, не завантажуючи достатньо боєприпасів, в якому їхнє пістолет самовибухне та вб'є власника.
Коваджі
Відповідно до Посібника для власників футуристичних гармат :
- Металевий щит CANNOT захищає від вхідного плазмового променя. Так само тепловий дефлектор НЕ МОЖЕ захищати від вхідної кулі.
- Плазмовий промінь переважає кулю (тому що для першого потрібна боєприпаси). Тому, якщо гравець вистрілює плазмовий промінь на опонента, який стріляє кулею в ту саму чергу, суперник вбивається.
- Якщо обидва гравці вистрілюють кулю один на одного однаковою чергою, кулі скасовуються, і обидва гравці виживають. Так само, якщо обидва гравці вистрілюють плазмовий промінь один на одного однаковою чергою, обидва гравці виживають.
Також примітно, що:
- Ви НЕ будете знати дії свого опонента по черзі, поки він не закінчиться.
- Відхилення від плазмових променів та захисних куль НЕ шкодить опоненту.
Тому в цілому є 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
Згідно з правилами вище, я програв. Ви бачите, чому? Це тому, що я вистрілив остаточний промінь плазми, коли в мене було лише 1 завантажений боєприпас, внаслідок чого мій пістолет вибухнув.
Програвач C ++
Ви , як цивілізований футуристичний програміст, не будете безпосередньо керувати зброєю. Натомість ви кодуєте 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.
Ви можете коментувати, щоб попросити роз'яснення або помітити лазівки. Сподіваємось, вам сподобається цей футуристичний поєдинок з гарматами та бажаю вам щасливого нового року!
Уточнення
- Вам дозволяється рандомізована поведінка.
- Недійсні дії (стрілянина при навантаженні боєприпасів недостатня) дозволені.
- Якщо гравець зробить недійсний вхід, його пістолет вибухне негайно.
- Вам дозволяється вивчити відповіді.
- Вам явно дозволяється фіксувати поведінку суперника в рамках кожного турніру.
- Кожен раунд ви будете грати по 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
(Кредит H Walters)
Подання буде проведено один раз на турнір.
Існує фіксована вимога до всіх записів щодо того, як робити введення-виведення, оскільки і 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