Lo sfondo del futuro
Nell'anno 2017, tu e il tuo avversario affronterete una battaglia futuristica con armi da fuoco in cui solo uno può sopravvivere. Sei tu abbastanza esperienza per sconfiggere il tuo avversario? Ora è il momento di perfezionare le tue abilità con le armi nel tuo linguaggio di programmazione preferito e combattere contro ogni previsione!
Risultati del torneo
Questo torneo è conclusa la mattina UTC di Feburary 2 ° , 2017. Grazie ai nostri concorrenti, abbiamo avuto un emozionante torneo futuristico!
MontePlayer è il vincitore finale dopo una battaglia ravvicinata con CBetaPlayer e StudiousPlayer. I tre duellanti principali hanno fatto una foto commemorativa:
MontePlayer - by TheNumberOne
+------------+
CBetaPlayer | | - by George V. Williams
+------------+ # 1 | StudiousPlayer - by H Walters
| +----------------+
| # 2 # 3 |
+------------------------------------------+
The Futurustic Gun Duel @ PPCG.SE 2017
Congratulazioni ai vincitori! La classifica dettagliata è visibile alla fine di questo post.
Guida generale
- Visita il repository ufficiale per il codice sorgente utilizzato in questo torneo.
- Voci C ++: si prega di ereditare la
Player
classe. - Voci non C ++: selezionare un'interfaccia nella sezione Interfaccia per invii non C ++ .
- Linguaggi non C ++ attualmente consentiti: Python 3, Java.
Il duello
- Ogni giocatore inizia con un'arma scarica che può caricare una quantità infinita di munizioni.
- Ad ogni turno, i giocatori sceglieranno simultaneamente una delle seguenti azioni:
0
- Carica 1 munizioni nella pistola.1
- Spara un proiettile contro l'avversario; costa 1 munizioni caricate.2
- Spara un raggio al plasma contro l'avversario; costa 2 munizioni caricate.-
- Difendi il proiettile in arrivo usando uno scudo di metallo.=
- Difendi il raggio al plasma in entrata usando un deflettore termico.
- Se entrambi i giocatori sopravvivono dopo il 100 ° turno, si esauriscono entrambi a morte, il che si traduce in un pareggio .
Un giocatore perde il duello con la pistola se lo fa
- Ha NON utilizzare la protezione metallica per difendere un proiettile in entrata.
- Ha NON utilizzare il deflettore termico difendere un plasma in entrata.
- Spara con una pistola senza caricare abbastanza munizioni, in cui la sua pistola esploderà e ucciderà il proprietario.
Avvertenze
Secondo il Manuale per i possessori di armi futuristiche :
- Uno schermo metallico NON PUO ' difendersi dal raggio al plasma in arrivo. Allo stesso modo, un deflettore termico NON PUO ' difendersi dal proiettile in arrivo.
- Il raggio al plasma sopraffà il proiettile (perché il primo richiede più munizioni caricate). Pertanto, se un giocatore spara un raggio al plasma contro l'avversario che spara un proiettile nello stesso turno, l'avversario viene ucciso.
- Se entrambi i giocatori sparano un proiettile l'uno contro l'altro nello stesso turno, i proiettili si annullano ed entrambi i giocatori sopravvivono. Allo stesso modo, se entrambi i giocatori sparano l'un l'altro un raggio al plasma nello stesso turno, entrambi i giocatori sopravvivono.
È anche interessante notare che:
- Potrai NON conoscere l'azione del tuo avversario in un turno fino alla fine.
- La deviazione dei raggi al plasma e la protezione dei proiettili NON danneggeranno il tuo avversario.
Pertanto, ci sono un totale di 25 combinazioni di azioni valide ogni turno:
+-------------+---------------------------------------------+
| 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.
Esempio Duello
Ecco un duello che ho avuto una volta con un amico. Allora, non sapevamo molto sulla programmazione, quindi abbiamo usato i gesti delle mani e segnalato alla velocità di due giri al secondo. Da sinistra a destra, le nostre azioni erano a loro volta:
Me: 001-000-1201101001----2
Friend: 00-10-=1-==--0100-1---1
Secondo le regole sopra, ho perso. Capisci perché? È perché ho sparato il raggio al plasma finale quando avevo solo 1 munizioni caricate, facendo esplodere la mia pistola.
Il lettore C ++
Tu , come programmatore futuristico civilizzato, non gestirai direttamente le armi. Invece, scrivi un codice Player
che combatte contro quello degli altri. Ereditando pubblicamente la classe c ++ nel progetto GitHub, puoi iniziare a scrivere la tua leggenda urbana.
Player.hpp can be found in Tournament\Player.hpp
An example of a derived class can be found in Tournament\CustomPlayer.hpp
Cosa devi o puoi fare
- Devi ereditare la
Player
classe attraverso l'eredità pubblica e dichiarare la tua classe finale. - È necessario eseguire l'override
Player::fight
, che restituisce un valore validoPlayer::Action
ogni volta che viene chiamato. - Opzionalmente, scavalcare
Player::perceive
ePlayer::declared
tenere d'occhio le azioni del tuo avversario e tenere traccia delle tue vittorie. - Facoltativamente, utilizzare membri e metodi statici privati nella classe derivata per eseguire calcoli più complessi.
- Facoltativamente, utilizzare altre librerie standard C ++.
Cosa NON devi fare
- NON devi usare alcun metodo diretto per riconoscere il tuo avversario diverso dall'identificativo avversario dato, che viene mischiato all'inizio di ogni torneo. Puoi indovinare solo chi sta giocando un giocatore all'interno di un torneo.
- NON è necessario sovrascrivere alcun metodo in
Player
classe che non sia dichiarato virtuale. - NON è necessario dichiarare o inizializzare nulla nell'ambito globale.
- Dal debutto di (ora squalificato)
BlackHatPlayer
, i giocatori NON sono autorizzati a sbirciare o modificare lo stato del tuo avversario.
Un duello di esempio
Il processo di un duello con armi viene eseguito usando la GunDuel
classe. Per un esempio di combattimento, consulta la Source.cpp
sezione Iniziare un duello .
Noi vetrina GunClubPlayer
, HumanPlayer
e la GunDuel
classe che si trova nella Tournament\
directory del repository.
In ogni duello, GunClubPlayer
verrà caricato un proiettile; licenzialo; risciacqua e ripeti. Durante ogni turno, HumanPlayer
ti chiederà un'azione da giocare contro il tuo avversario. I controlli da tastiera sono i personaggi 0
, 1
, 2
, -
e =
. Su Windows, è possibile utilizzare HumanPlayer
per eseguire il debug dell'invio.
Iniziare un duello
Ecco come è possibile eseguire il debug del lettore tramite la console.
// 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();
}
Giochi di esempio
Il minor numero di turni che devi sconfiggere GunClubPlayer
è 3. Ecco il replay dal giocare 0-1
contro GunClubPlayer
. Il numero nella paraesi è il numero di munizioni caricate per ciascun giocatore al termine del turno.
:: 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 . . .
Il modo più rapido per essere sconfitti GunClubPlayer
senza fare mosse non valide è la sequenza 0=
, perché il proiettile spara proprio attraverso il deflettore termico. Il replay è
:: 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 . . .
Il torneo
Il torneo segue il formato "Last Player Standing". In un torneo, tutti gli invii validi (incluso il GunClubPlayer
) vengono inseriti in un pool. A ogni invio viene assegnato un identificatore casuale ma univoco che rimarrà lo stesso durante l'intero torneo. Durante ogni round:
- Ogni invio inizia con 0 punti e giocherà 100 duelli contro ogni altro invio.
- Ogni duello vittorioso assegnerà 1 punto; disegnare e perdere danno 0 punti.
- Alla fine del round, le iscrizioni con il punteggio minimo lasciano il torneo. In caso di pareggio, il giocatore con il minor numero di punti guadagnati dall'inizio del torneo partirà.
- Se rimane più di un giocatore, deve iniziare il turno successivo.
- I punti NON vengono riportati al turno successivo.
Presentazione
Invierai un giocatore per risposta. Puoi inviare più file per un giocatore, purché NON interferiscano con altri invii. Per far scorrere le cose, per favore:
- Assegna un nome al tuo file di intestazione principale come
<Custom>Player.hpp
, - Assegna un nome agli altri file come
<Custom>Player*.*
, ad esempioMyLittlePlayer.txt
se il nome della tua classe èMyLittlePlayer
oEmoPlayerHates.cpp
se il nome della tua classe èEmoPlayer
. - Se il tuo nome contiene
Shooter
parole simili o simili al contesto di questo torneo, non è necessario aggiungerePlayer
alla fine. Se ritieni fortemente che il nome del tuo invio funzioni meglio senza il suffissoPlayer
, non devi nemmeno aggiungerePlayer
. - Assicurati che il tuo codice possa essere compilato e collegato in Windows.
Puoi commentare per chiedere chiarimenti o individuare scappatoie. Spero che ti piaccia questo futuristico Gun Duel e ti auguro un felice anno nuovo!
Una precisazione
- Ti è permesso avere un comportamento randomizzato.
- Sono consentite azioni non valide (sparare quando le munizioni caricate non sono sufficienti).
- Se un giocatore inserisce un valore non valido, la sua pistola esploderà immediatamente.
- Puoi studiare le risposte.
- Hai il permesso esplicito di registrare il comportamento degli avversari all'interno di ogni torneo.
- Ad ogni round, giocherai 100 duelli contro ogni avversario; l'ordine dei 100 duelli, tuttavia, è randomizzato: non ti viene garantito di combattere lo stesso avversario con 100 duelli di fila.
Risorse addizionali
@flawr ha tradotto l'origine C ++ fornita in Java come riferimento se si desidera inviare voci C ++.
Interfaccia per invii non C ++
Attualmente accettato: Python 3, Java.
Seguire una delle specifiche seguenti:
Specifica dell'interfaccia 1: codice di uscita
Il tuo invio verrà eseguito una volta per turno.
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.
Puoi testare la tua presentazione PythonPlayer\
e le JavaPlayer\
directory.
Specifica dell'interfaccia 2: stdin / stdout
(Ringraziamo H Walters)
Il tuo invio verrà eseguito una volta per torneo.
C'è un requisito fisso per tutte le voci su come eseguire l'I / O, poiché sia lo stdin che lo stdout sono collegati al pilota del torneo. La violazione di questo potrebbe portare a un punto morto. Tutte le voci DEVONO seguire questo algoritmo EXACT (in pseudo-codice):
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
Qui, F è uno dei 0
, 1
, 2
, -
, o =
per load / bullet / plasma / metal / thermal
. PROCESSO significa facoltativamente rispondere a ciò che il tuo avversario ha fatto (incluso il monitoraggio delle munizioni del tuo avversario se lo stai facendo). Nota che l'azione dell'avversario è anche una di '0', '1', '2', '-', o '=', ed è nel secondo personaggio.
Quadro di valutazione finale
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 |
Il torneo durerà fino al 1 ° febbraio 2017, se non diversamente indicato.
Player
un'implementazione che invoca un altro processo per calcolare il turno corrente. Ciò consentirebbe alle persone di partecipare in qualsiasi lingua tu sia felice di eseguire sul tuo computer.
Player::fight
'/' è possibile ereditare Player::perceive
" ... in entrambi i casi, il termine è di esclusione , non eredita .
GunDuel.hpp
entrambi validA
e validB
usiactionA