Hlavní navigace

Robocode: zvoní na vyučovanie

5. 1. 2004
Doba čtení: 5 minut

Sdílet

Programátorská hra Robocode zábavnou a nenásilnou formou pomáha vyučovat súčasné programátorské techniky: objektovo orientované programovanie, dátové štruktúry, trigonometrické algoritmy, znovupoužiteľnost kódu alebo napríklad udalosti. Tento článok by mal tieto postupy priblížiť z pohľadu Robocode a tak inšpirovať študentov programovania, ich učitelov a samozrejme všetkých hravých algoritmizátorov.

minulom článku o Robocode sme túto programátorskú hru stručne predstavili. Dnes sa pozrieme na niektoré programátorské koncepty, ktoré sa v nej používajú. Text bude ilustrovaný jednoduchými príkladmi, avšak kompletné návody a príklady robotov sú nad jeho rozsah. Tie nájdete v odkazoch pod článkom, prípadne medzi vzorovými robotmi z inštalácie Robocode. Tento článok by mal pomôct pri orientácii, poukázať na možnosti. A snáď inšpirovať.

Robocode a vyučovanie

Na úvod mi dovoľte malé odbočenie z praxe do akademického sveta. Robocode sa totiž začína používať ako nástroj pri výuke programovania na stredných a vysokých školách a tak by som ho rád predstavil aj z tohto pohľadu. Za zmienku stoja tieto jeho vlastnosti:

Jednoduchosť

Robocode je kompletné vývojové prostredie s arénou, editorom a kompilerom. Odpadá preto zbytočná réžia, ktorá vzniká, keď študenti musia okrem algoritmov zápasiť aj s nástrahami pre výuku zbytočne komplexného IDE. Je veľmi ľahké vytvoriť vlastného jednoduchého robota a hneď vydieť výsledky svojej práce v praxi – na bojovom poli.

Názornosť

Mnohé programátorské postupy sa tažko učia kvôli ich abstraktnosti (objekty, udalosti). Robocode ponúka velmi názorné a pochopiteľné príklady týchto konceptov. Triedy ako Robot a Bullet alebo udalosť HitByBulletEvent môže študent vidiet okamžite v akcii.

Praktickosť

Roboti sa nevytvárajú pomocou nejakého „výukového“ alebo „zastaralého“ jazyka (každý doplní jazyk podľa vlastných skúseností:). Programuje sa v Jave, ktorá je v súčasnosti veľmi používaná.

Učenie pomocou problémov

Pri programovaní robotov vznikajú rôzne problémy – ako sa pohybovať, ako zameriavať nepriateľov, ako sa vyhýbať ich streľbe a podobne. Študent musí tieto problémy identifikovat a vyriešiť pomocou algoritmov.

Motivácia

Robocode si pomáha dvoma motivačnými zdrojmi: hrou a sútažou. Jeho prostredníctvom može byt výuka zábavná a navyše sa v ňom dá usporiadať turnaj alebo liga, kde študenti môžu porovnať svoje schopnosti s ostatnými.

Napriek všetkým prednostiam musím spomenút, že Robocode vyžaduje znalosť syntaxe jazyka Java a základných princípov algoritmizácie (premenné, cykly, vetvenia a podobne). Na výuku úplných zaciatočníkov sa veľmi nehodí.

Základná schéma

Vráťme sa ale k sľúbeným programátorským technikám. Aby som mohol o nich hovoriť, spomeniem najprv základnú schému programu robota. Kód je obvykle rozdelený do niekoľkých oblastí:

package mf;
import robocode.*;
import java.awt.Color;

public class MyFirstRobot extends Robot {
  // oblast 1a

  public void run() {
    // oblast 2
    setColors(Color.red, Color.blue, Color.green);

    while(true) {
      // oblast 3
      ahead(100);
      myTurnBack();
    }
  }

  // oblast 1b
  public void myTurnBack() {
    turnRight(180);
  }

  public void onScannedRobot(ScannedRobotEvent e) {
    fire(1);
  }
} 

Oblasť 1 (a,b)

Tu sa deklarujú pomocné premenné (obvykle 1a:), pomocné metódy používané v metóde run() a tiež tu môžu byť prekryté metódy obsluhy udalostí, na ktoré by mal robot reagovať (obvykle v 1b, pre poriadok:).

Oblasť 2

Kód v tejto oblasti prebehne iba raz – na začiatku boja. Tu sa robot inicializuje (nastavenie farieb, určenie pozície v aréne, určenie smeru útoku/úteku).

Oblasť 3

Táto nekonečná slučka určuje chovanie robota počas boja.

Triedy a dedičnosť

Každý vytvorený robot musí byť odvodený od triedy Robot alebo AdvancedRobot z Robocode API. (Existuje ešte TeamRobot, ale o tom niekedy inokedy.)

public class MyFirstRobot extends Robot

Trieda AdvancedRobot je dedičom triedy Robot a hierarchia týchto tried potom vyzerá nasledovne:

Naši roboti odvodení z týchto základných tried potom musia prekryť metódu run(), aby robot niečo robil. Rovnako sa prekrývajú aj metódy obsluhy udalostí, na ktoré by mal robot reagovať.

Samozrejme, v záujme prehľadnosti kódu si programátor môže vytvoriť aj vlastné abstraktné triedy, v ktorých ukryje napríklad bežne používanú logiku a z týchto potom dediť svojich skutočných robotov:

public class MyAbstractRobot extends AdvancedRobot
...
public class MyRealRobot extends MyAbstractRobot
...

Na dizajn kódu v Robocode sa však pozrieme neskôr.

Blokovacie a neblokovacie volania API

Na začiatku boja správca arény spustí robotovi jeho metódu run(). V tej by mala byť nekonečná slučka, ktorá obsahuje správanie robota. Kód v tejto slučke pobeží dovtedy, kým nenastane jedna z nasledujúcich vecí (potom sa odovzdá kontrola ďalšiemu robotovi a tak dokola):

  • Je prekročený časový limit – na vykonanie svojich príkazov má každý robot istý čas, ten je však dostatočne dlhý aj na vykonanie zložitých výpočtov. Toto sa teda zvyčajne nestáva, je to skôr ochrana pred nekonečnými cyklami.
  • Vyskytne sa udalosť – udalosť preruší vykonávanie kódu v metóde run() a zavolá obslužnú metódu (viď nižšie).
  • Je zavolaná blokovacia metóda (blocking call) – blokovacie metódy nevracajú kontrolu dovtedy, kým nie je dokončená určitá činnosť, neobjaví sa nejaká udalosť alebo nie je splnená návratová podmienka.

Typicky sú blokovacie volania metódy na pohyb robota z triedy Robot, napríklad void ahead(double distance). Ich volaním však nie je možné vykonávať viac činností naraz, príkazy sa vykonávajú jeden po druhom:

while(true) {
  ahead(100);
  turnLeft(90);
}

Takto teda vyzerá pohyb do štvorca. To ale zvládol už Robot Karel™, doba pokročila a my tu máme preto triedu AdvancedRobot, ktorá umožňuje volania neblokovacie. Tie na pohyb majú prefix set a tak napríklad blokovaciemu void ahead(double distance) zodpovedá neblokovacie void setAhead(double distance). Neblokovacie metódy nastavujú istý spôsob správania sa, ktorý sa začne vykonávať v momente volania blokovacej metódy. Pohyb po kruhu bude:

setMaxVelocity(5);
while(true) {
  setAhead(1000);
  turnLeft(360);  // blokovacie volanie
}

alebo, s rovnakým výsledkom:

setMaxVelocity(5);
while(true) {
  setAhead(1000);
  setTurnLeft(360);
  waitFor(new TurnCompleteCondition(this));
    // blokovacie volanie s podmienkou
}

Udalosti

Robot na okolie reaguje vďaka udalostiam, ktoré mu posiela správca arény. Je to ako pri programovaní skutočných aplikácií, ale namiesto poklepania myši udalosť vyvoláva dopad nepriatelského granátu na vežu nášho tanku. Ak robot prekrýva metódu public void onHitByBullet(HitByBulletEvent event), môžete sa z miesta nešťastia pokúsiť utiecť:

public void onHitByBullet(HitByBulletEvent e) {
  turnRight(180);
  ahead(100 * e.getPower());
}

Užívateľom definované udalosti a anonymné triedy

V API je celá sada preddefinovaných udalostí (viď Robocode Javadoc:), programátor si však môže vytvárať vlastné. Môžu sa pri tom využívať anonymné triedy:

public void run() {
  int limit = 50;
  addCustomEvent(
    new Condition("lowEnergy") {
      public boolean test() {
        return (getEnergy() < limit);
      };
    }
  );
}

V tomto príklade vnútri volania addCustomEvent() anonymne definujeme podtriedu triedy Condition a prekrývame jej metódu test(). Obsluha tejto užívateľskej udalosti vyzerá nasledovne:

public void onCustomEvent(CustomEvent e) {
  if (e.getCondition().getName().equals("lowEnergy")) {
    limit = 0;
    out.println("Low energy!");
  }
} 

Záver

Tento článok bol trochu viac zameraný na princípy samotnej hry, ukázal však tiež, že sa pri nej dá naučiť niečo o objektoch, dedičnosti, udalostiach či o používaní anonymných tried. Nabudúce sa budeme venovať všeobecnejším konceptom ako sú dátové štruktúry, efektívny návrh znovupoužiteľného kódu, trigonometria alebo vstup/výstup. Samozrejme všetko v rámci Robocode.

Linky

Linky užitočné pri učení (sa) Robocode:

Rock 'em, sock 'em Robocode!
Rock 'em, sock 'em Robocode: Round 2
Secrets from the Robocode masters
Robocode Tutorial
Robocode FAQ

Seriál: Robocode

Byl pro vás článek přínosný?