The Purge

Albert Oliveras

Regles del Joc

Per tal de reduir el nombre de crims al país, el règim polític anomenat La Nova Fundació dels Pares d’Amèrica ha implementat una mesura catàrtica davant l’imperant violència que regna als carrers: la Purga Anual. Cada any, durant una sèrie de dies, es pot cometre qualsevol crim durant la nit sense haver de respondre davant la justícia. El país s’ha organitzat en clans de ciutadans afins que intenten sobreviure.

Es tracta d’un joc per a quatre jugadors, identificats amb números de 0 a 3. Cada jugador té el control d’un clan format per guerrers i constructors. Cadascun d’ells, que anomenarem de forma general ”ciutadà”, neix amb uns determinats punts de vida.

El joc dura un cert nombre de jornades, i cada jornada comença amb un nombre NN de rondes de dia, durant les quals no es permeten els crims, i continua amb NN rondes de nit durant les quals els crims són impunes. Hi ha elements del joc que tenen un comportament diferent de dia i de nit. A cada ronda, cada membre dels clans pot efectuar com a molt una acció. Com a resultat d’aquestes accions, els clans poden guanyar punts. Més concretament, es guanyen punts en recollir diners o matar a ciutadans rivals. El guanyador de la partida és el clan que obtingui més punts.

El tauler del joc és un rectangle N×MN\times M del qual ningú en pot sortir, que representa una ciutat. Una posició del tauler ve determinada per un parell d’enters (f,c)(f,c) on 0f<N0 \leq f < N i 0c<M0\leq c < M. La posició de més a dalt i a l’esquerra és la (0,0)(0,0), mentre que la de més a baix i a la dreta és (N1,M1)(N-1,M-1). Cada cel·la del tauler o bé forma part d’un carrer o bé d’un edifici. Els ciutadans no poden trepitjar cap edifici i s’han de moure pels carrers. En els carrers, s’hi poden trobar armes, diners i menjar. De cara a protegir-se dels possible atacs, s’hi poden construir barricades.

Barricades. Els únics que poden construir barricades són els constructors, però només durant el dia. Des de la seva posició, poden crear una barricada a una de les com a molt 4 cel·les adjacents en vertical o horitzontal, sempre i quan estiguin buides. Si un constructor està amagat en un barricada, no podrà construir-ne una altra a cap cel·la adjacent. Les barricades podran ser ocupades per qualsevol ciutadà del clan que l’ha creat, però no pels clans contraris. Les barricades tenen una resistència inicial, que pot ser incrementada fins a un cert valor màxim a base de repetides operacions de construcció. Cada clan pot tenir un nombre màxim de barricades. Quan acaba la nit i comença un nou dia, totes les barricades que han resistit desapareixen.

Guerrers. Els guerrers porten sempre una arma. Inicialment tots porten un senzill martell, però poden agafar una pistola o un bazuca. Durant el dia, un guerrer pot moure’s pel tauler de la manera següent:

Durant la nit, el comportament d’un guerrer és el mateix excepte quan es mou a una cel·la ocupada per un ciutadà o una barricada rival:

Constructors. Els constructors no porten mai cap arma. Durant el dia, els seus moviments són idèntics als moviments dels guerrers. L’única diferència és que quan un constructor es mou a una cel·la ocupada per una arma, el constructor ocuparà la cel·la i l’arma desapareixerà (es perdrà).

Durant la nit, el comportament d’un constructor és el mateix que durant el dia excepte quan:

En general, quan un ciutadà aconsegueix demolir una barricada on s’hi amaga un rival, aquest no mor, sinó que es queda al descobert i ja pot rebre atacs. Si un ciutadà està amagat dins una barricada, ningú put iniciar un atac contra ell. En canvi, ell sí pot iniciar un atac contra un altre ciutadà. Durant aquest atac, no tindrà cap protecció especial i per tant, podrà morir.

Regeneració d’objectes. Cada vegada que desapareixen diners o menjar, aquests reapareixen al cap d’un cert nombre de rondes. Les armes i ciutadans també reapareixen. Una arma es veu reemplaçada per una del mateix tipus. Els ciutadans es reemplacen per ciutadans del mateix tipus amb la corresponent vida inicial. Els guerrers reapareixen portant un martell. En tots aquests casos, l’objecte reapareixerà sempre en una cel·la buida CC i tal que no hi ha cap ciutadà en les posicions que l’envolten (les marcades amb una x a la taula):

x x x x x
x x x x x
x x C x x
x x x x x
x x x x x

Si en el moment de reaparèixer no existeix cap cel·la segura en aquest sentit, l’objecte intentarà reaparèixer a la següent ronda. A cada ronda primer s’intentarà fer reaparèixer tots els ciutadans, a continuació diners i menjar amb la mateixa prioritat, i finalment les armes, totes elles amb la mateixa prioritat. És a dir, si en una ronda ha de reaparèixer un ciutadà i un bonus de diners i només queda una cel·la segura, reapareixerà el ciutadà i els diners esperaran a la següent ronda.

Execució d’ordres. A cada ronda es pot donar més d’una ordre al mateix ciutadà, tot i que només se seleccionarà la primera d’elles (si n’hi ha alguna). Tot programa que intenti donar més de 1000 comandes durant la mateixa ronda s’avortarà.

Cada ronda, les ordres seleccionades dels quatre jugadors s’executaran amb ordre aleatori, però respectant l’ordre relatiu entre els ciutadans d’un mateix clan. Com a conseqüència de la norma anterior, considereu la possibilitat de donar les ordres als vostres ciutadans a cada ronda de més urgent a menys urgent.

Tingueu en compte que s’aplica cada moviment sobre el tauler que resulta dels moviments anteriors. Per exemple, considereu el tauler

x x x x
x M C x
x G x x
x x x x

on M representa menjar, C un constructor i G un guerrer rival. Imaginem que el jugador que controla C ha decidit que vagi cap a l’esquerra, i el jugador que controla G ha decidit que vagi amunt. Si s’executa primer el moviment de G, aleshores C s’ha quedat sense menjar, perquè G ja l’ha consumit i a més, la posterior execució del moviment de C és un atac cap a G del qual segurament en sortirà malparat.

El Visor

A la Figura 1 es mostra una captura de pantalla amb tots els elements del joc.

Captura de pantalla del joc.

Com programar un jugador

El primer que heu de fer és descarregar-vos el codi font. Aquest inclou un programa C ++ que executa les partides i un visualitzador HTML per veure-les en un format raonable i animat. A més, us proporcionem un jugador “Null” i un jugador “Demo” per facilitar el començament de la codificació del jugador.

Executar la primera partida

Aquí us explicarem com executar el joc sota Linux, però hauria de funcionar també sota Windows, Mac, FreeBSD, OpenSolaris, ... Només necessiteu una versió recent de g ++, el make instal·lat al sistema, a més d’un navegador modern com Firefox o Chrome.

  1. Obriu una consola i feu cd al directori on us heu descarregat el codi font.

  2. Si, per exemple, teniu una versió de Linux en 64 bits, executeu:

    cp AIDummy.o.Linux64 AIDummy.o

    Amb altres arquitectures, cal escollir els objectes adequats que trobareu al directori.

  3. Executeu

    make all

    per compilar el joc i tots els jugadors. Tingueu en compte que el Makefile identifica com a jugador qualsevol fitxer que coincideixi amb AI*.cc

  4. Es crea un fitxer executable anomenat Game. Aquest executable us permet executar una partida mitjançant una comanda com la següent:

    ./Game Demo Demo Demo Demo -s 30 < default.cnf > default.res

    Aquesta comanda comença una partida, amb la llavor aleatòria 30, amb quatre instàncies del jugador Demo, al tauler definit a default.cnf. La sortida d’aquesta partida es redirigeix a default.res.

  5. Per veure una partida, obriu el fitxer visualitzador Viewer/viewer.html amb un navegador i carregueu el fitxer default.res.

Utilitzeu

./Game --help

per veure la llista de paràmetres que es poden usar. Particularment útil és

./Game --list

per veure tots els noms de jugadors reconeguts.

En cas que sigui necessari, recordeu que podeu executar

make clean

per esborrar l’executable i els objectes i començar la compilació de nou.

Arxiu de configuració

Us proporcionem dos exemples d’arxius de configuració. En totes les partides que es juguin al Jutge, incloent les eliminatòries i la final, utilitzarem sempre default.cnf. Aquest arxiu fixa els paràmetres de la Figura 5 al valor per defecte. La posició dels edificis, dels ciutadans, de les armes i dels bonus es decideixen de forma aleatòria.

L’arxiu de configuració default-fixed.cnf mostra com es poden canviar els paràmetres i definir el tauler d’entrada. Els caràcters de la graella són ’.’(carrer), ’B’ (edifici), ’G’ (pistola), ’Z’ (bazuca), ’M’ (diners), ’F’ (menjar). Pel que fa als ciutadans, el seu tipus és ’w’ (guerrer) o bé ’b’ (constructor), i les armes possibles són ’n’ (cap arma), ’h’ (martell), ’g’ (pistola) i ’b’ (bazuca).

Podeu crear arxius de configuració vosaltres mateixos per diversió o si voleu provar els vostres jugadors en taulers més petits o amb alguna peculiaritat. Els valors dels paràmetres han d’estar dins el rang establert a la Figura 5. Heu d’assegurar-vos que les forces d’atac i de demolició del bazuca han de ser majors o iguals que les de la pistola, i les de la pistola majors o iguals que les del martell. Una altra restricció és que BARRICADE_RESISTANCE_STEP ha de ser menor o igual que BARRICADE_MAX_RESISTANCE. Finalment, si voleu modificar els paràmetres i generar el tauler aleatòriament, heu d’assegurar-vos que el tauler és prou gran per encabir tots els objectes.

Paràmetre Valor per defecte Rang
@ NUM_PLAYERS @ 4 [4,4][4,4]
@ NUM_DAYS @ 5 [1,)[1,\infty)
@ NUM_ROUNDS_PER_DAY @ 50 [2,)[2,\infty) (parell)
@ BOARD_ROWS @ 15 [12,25][12,25]
@ BOARD_COLS @ 30 [12,50][12,50]
@ NUM_INI_BUILDERS @ 4 [1,6][1,6]
@ NUM_INI_WARRIORS @ 2 [1,4][1,4]
@ NUM_INI_MONEY @ 10 [0,10][0,10]
@ NUM_INI_FOOD @ 5 [0,10][0,10]
@ NUM_INI_GUNS @ 4 [0,5][0,5]
@ NUM_INI_BAZOOKAS @ 2 [0,4][0,4]
@ BUILDER_INI_LIFE @ 60 [1,)[1,\infty)
@ WARRIOR_INI_LIFE @ 100 [1,)[1,\infty)
@ MONEY_POINTS @ 5 [1,)[1,\infty)
@ KILL_BUILDER_POINTS @ 100 [1,)[1,\infty)
@ KILL_WARRIOR_POINTS @ 250 [1,)[1,\infty)
@ FOOD_INCR_LIFE @ 20 [1,)[1,\infty)
@ LIFE_LOST_IN_ATTACK @ 20 [1,)[1,\infty)
@ BUILDER_STRENGTH_ATTACK @ 1 [1,)[1,\infty)
@ HAMMER_STRENGTH_ATTACK @ 10 [1,)[1,\infty)
@ GUN_STRENGTH_ATTACK @ 100 [1,)[1,\infty)
@ BAZOOKA_STRENGTH_ATTACK @ 1000 [1,)[1,\infty)
@ BUILDER_STRENGTH_DEMOLISH @ 3 [1,)[1,\infty)
@ HAMMER_STRENGTH_DEMOLISH @ 10 [1,)[1,\infty)
@ GUN_STRENGTH_DEMOLISH @ 10 [1,)[1,\infty)
@ BAZOOKA_STRENGTH_DEMOLISH @ 30 [1,)[1,\infty)
@ NUM_ROUNDS_REGEN_BUILDER @ 50 [1,)[1,\infty)
@ NUM_ROUNDS_REGEN_WARRIOR @ 50 [1,)[1,\infty)
@ NUM_ROUNDS_REGEN_FOOD @ 10 [1,)[1,\infty)
@ NUM_ROUNDS_REGEN_MONEY @ 5 [1,)[1,\infty)
@ NUM_ROUNDS_REGEN_WEAPON @ 40 [1,)[1,\infty)
@ BARRICADE_RESISTANCE_STEP @ 40 [1,)[1,\infty)
@ BARRICADE_MAX_RESISTANCE @ 320 [1,)[1,\infty)
@ MAX_NUM_BARRICADES @ 3 [1,)[1,\infty)
Paràmetres del joc. La seva explicació la trobareu a l’arxiu Settings.hh.

Afegir el vostre jugador

Per crear un jugador nou copieu AINull.cc (un jugador buit que proporcionem com a plantilla) a un fitxer nou AIElquesigui.cc. A continuació, editeu el fitxer nou i canvieu la línia

@#define PLAYER_NAME Null@

a

@#define PLAYER_NAME Elquesigui@

El nom que trieu pel vostre jugador ha de ser únic, no ofensiu i tenir com a màxim 12 caràcters. Aquest nom es mostrarà al lloc web i durant les partides.

A continuació, podeu començar a implementar el mètode virtual @play()@, heretat de la classe base @Player@. Aquest mètode, que serà cridat a cada ronda, ha de determinar les ordres que s’enviaran a les vostres unitats.

Podeu utilitzar definicions de tipus, variables i mètodes a la vostra classe de jugador, però el punt d’entrada del vostre codi serà sempre el mètode @play()@.

Des de la vostra classe jugador també podeu cridar funcions que trobareu especificades als arxius següents:

També podeu examinar el codi del jugador “Demo” a AIDemo.cc com a exemple de com usar aquestes funcions.

Tingueu en compte que no heu d’editar el mètode @factory()@ de la classe del vostre jugador, ni l’última línia que afegeix el vostre jugador a la llista de jugadors disponibles.

Jugar contra el jugador Dummy

Per a provar la vostra estratègia contra el jugador Dummy, proporcionem el seu arxiu objecte. D’aquesta manera, no teniu accés al seu codi font però podreu afegir-lo com a jugador i competir contra ell en local.

Com ja hem comentat, per afegir el jugador Dummy a la llista de jugadors registrats, heu de copiar l’arxiu corresponent a la vostra arquitectura cap a AIDummy.o. Per exemple:

cp AIDummy.o.Linux64 AIDummy.o

Recordeu que els arxius objecte contenen instruccions binàries per a una arquitectura concreta, pel que no podem proporcionar un únic arxiu.

Consell de pro: demaneu als vostres amics els seus arxius objecte (mai codi font!!!) i afegiu-los al vostre Makefile!

Restriccions en enviar el vostre jugador

Quan creieu que el vostre jugador és prou fort per entrar a la competició, podeu enviar-lo al Jutge. Degut a que s’executarà en un entorn segur per prevenir trampes, algunes restriccions s’apliquen al vostre codi:

Consells