İletişim
Programın, her robotta bulunan iki cihaz aracılığıyla oyunla konuşur:
- Verici (emitter) oyuna mesaj gönderir. Etkinleştirilmesi gerekmez.
- Alıcı (receiver) oyundan mesaj alır. Onu bir sensör gibi etkinleştir.
Aşağıdaki her bölüm, başlangıç robotu için eksiksiz bir programdır. Tüm mesajlar Mesaj başvurusu sayfasında listelenmiştir.
Duvar işaretleriyle puan kazanma
Bölüm başlığı “Duvar işaretleriyle puan kazanma”Bir harf kazazede ya da bilişsel hedeften puan almak için robot şunları yapmalıdır:
- İşaretin yakınında 1 saniyeden uzun süre durmak. Robot son bir saniye içinde hareket ettiyse Erebus bildirimi dikkate almaz.
- İşaretin konumunu ve türünü göndermek: X ve Z santimetre cinsinden, tür ise tek bir harf olarak gönderilir.
| Duvar işareti | Tür |
|---|---|
| Harf kazazede Φ (yaralı) | H |
| Harf kazazede Ψ (stabil) | S |
| Harf kazazede Ω (yarasız) | U |
| Bilişsel hedef, toplam 0 (Yanıcı Gaz) | F |
| Bilişsel hedef, toplam 1 (Zehir) | P |
| Bilişsel hedef, toplam 2 (Aşındırıcı) | C |
| Bilişsel hedef, toplam 3 (Organik Peroksit) | O |
Kazazedeler 2026’dan beri sembol gösterse de türler harftir. GPS metre verdiği için 100 ile çarp.
from controller import Robotimport struct
robot = Robot()timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter") # Always on the robot. It does not need to be enabled.gps = robot.getDevice("gps")gps.enable(timeStep)leftWheel = robot.getDevice("left wheel motor")rightWheel = robot.getDevice("right wheel motor")leftWheel.setPosition(float("inf"))rightWheel.setPosition(float("inf"))
def wait(seconds): start = robot.getTime() while robot.step(timeStep) != -1: if robot.getTime() - start >= seconds: break
def report(tokenType): # 1. Stop for more than 1 second leftWheel.setVelocity(0) rightWheel.setVelocity(0) wait(1.2) # 2. Send the position in centimeters, and the type as one letter x, _, z = gps.getValues() message = struct.pack("i i c", int(x * 100), int(z * 100), tokenType.encode()) emitter.send(message) robot.step(timeStep)
report("H") # Reports a harmed victim (Φ) where the robot isprint("Reported")#include <iostream>#include <cmath>#include <cstring>#include <webots/Robot.hpp>#include <webots/Emitter.hpp>#include <webots/GPS.hpp>#include <webots/Motor.hpp>
using namespace webots;
Robot *robot;Emitter *emitter;GPS *gps;Motor *leftWheel, *rightWheel;int timeStep;
void wait(double seconds) { double start = robot->getTime(); while (robot->step(timeStep) != -1) { if (robot->getTime() - start >= seconds) break; }}
void report(char tokenType) { // 1. Stop for more than 1 second leftWheel->setVelocity(0); rightWheel->setVelocity(0); wait(1.2); // 2. Send the position in centimeters, and the type as one letter int position[2] = {(int)(gps->getValues()[0] * 100), (int)(gps->getValues()[2] * 100)}; char message[9]; memcpy(message, position, sizeof(position)); message[8] = tokenType; emitter->send(message, sizeof(message)); robot->step(timeStep);}
int main() { robot = new Robot(); timeStep = (int)robot->getBasicTimeStep();
emitter = robot->getEmitter("emitter"); // Always on the robot. It does not need to be enabled. gps = robot->getGPS("gps"); gps->enable(timeStep); leftWheel = robot->getMotor("left wheel motor"); rightWheel = robot->getMotor("right wheel motor"); leftWheel->setPosition(INFINITY); rightWheel->setPosition(INFINITY);
report('H'); // Reports a harmed victim (Φ) where the robot is std::cout << "Reported" << std::endl;
delete robot; return 0;}Robot, işaretle duvarın aynı tarafında olmalı; hem robot hem de gönderdiğin konum işarete yakın olmalıdır. Kurallar en fazla yarım kare mesafe ister, bunu hedefle. Erebus v26.1, 9 cm’lik bir mesafeyi kontrol eder.
Bu programı world1.wbt’nin başında çalıştır: orada hiç işaret yoktur, bu yüzden kontrol penceresinin geçmişinde Misidentification of Victim -5 görünür. Sahte bir işareti bildirmek de dahil olmak üzere her yanlış bildirim 5 puana mal olur ve her işaretten yalnızca bir kez puan alınabilir.

İlerleme eksikliği
Bölüm başlığı “İlerleme eksikliği”Robot sıkıştığında bir ilerleme eksikliği (lack of progress, LoP), robotu son kontrol noktasına geri götürür ve 5 puana mal olur. Robot 20 saniye hareketsiz kalınca bu otomatik olarak gerçekleşir; programın da L göndererek ilerleme eksikliği çağırabilir. Her seferinde oyun robota L gönderir; böylece programın, robotun konumunun değiştiğini anlar.
from controller import Robotimport struct
robot = Robot()timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter")receiver = robot.getDevice("receiver")receiver.enable(timeStep) # The receiver must be enabled
askedAt = Nonewhile robot.step(timeStep) != -1: # Call a lack of progress once, after 2 seconds if askedAt is None and robot.getTime() > 2: emitter.send(struct.pack("c", b"L")) askedAt = robot.getTime()
# Listen for messages from the game while receiver.getQueueLength() > 0: data = receiver.getBytes() if len(data) == 1 and data == b"L": print("Lack of progress! The robot is back at the last checkpoint.") receiver.nextPacket()#include <iostream>#include <webots/Robot.hpp>#include <webots/Emitter.hpp>#include <webots/Receiver.hpp>
using namespace webots;using namespace std;
int main() { Robot *robot = new Robot(); int timeStep = (int)robot->getBasicTimeStep();
Emitter *emitter = robot->getEmitter("emitter"); Receiver *receiver = robot->getReceiver("receiver"); receiver->enable(timeStep); // The receiver must be enabled
bool asked = false; while (robot->step(timeStep) != -1) { // Call a lack of progress once, after 2 seconds if (!asked && robot->getTime() > 2) { char message = 'L'; emitter->send(&message, 1); asked = true; }
// Listen for messages from the game while (receiver->getQueueLength() > 0) { const char *data = (const char *)receiver->getData(); if (receiver->getDataSize() == 1 && data[0] == 'L') cout << "Lack of progress! The robot is back at the last checkpoint." << endl; receiver->nextPacket(); } }
delete robot; return 0;}Alıcı farklı mesajlar alabilir, bu yüzden örnekteki gibi her mesajı okumadan önce uzunluğunu kontrol et.
Oyun bilgileri
Bölüm başlığı “Oyun bilgileri”Puanı ve kalan süreyi öğrenmek için G gönder. Oyun 16 baytlık bir mesajla yanıt verir: G harfi, puan, kalan oyun süresi ve kalan gerçek zaman (saniye cinsinden).
from controller import Robotimport struct
robot = Robot()timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter")receiver = robot.getDevice("receiver")receiver.enable(timeStep)
lastAsked = 0while robot.step(timeStep) != -1: # Ask for the game information once a second if robot.getTime() - lastAsked > 1: emitter.send(struct.pack("c", b"G")) lastAsked = robot.getTime()
while receiver.getQueueLength() > 0: data = receiver.getBytes() if len(data) == 16: # The game information is 16 bytes long _, score, timeLeft, realTimeLeft = struct.unpack("c f i i", data) print("Score:", round(score, 2), "Time left:", timeLeft, "s", "Real time left:", realTimeLeft, "s") receiver.nextPacket()#include <iostream>#include <cstring>#include <webots/Robot.hpp>#include <webots/Emitter.hpp>#include <webots/Receiver.hpp>
using namespace webots;using namespace std;
int main() { Robot *robot = new Robot(); int timeStep = (int)robot->getBasicTimeStep();
Emitter *emitter = robot->getEmitter("emitter"); Receiver *receiver = robot->getReceiver("receiver"); receiver->enable(timeStep);
double lastAsked = 0; while (robot->step(timeStep) != -1) { // Ask for the game information once a second if (robot->getTime() - lastAsked > 1) { char message = 'G'; emitter->send(&message, 1); lastAsked = robot->getTime(); }
while (receiver->getQueueLength() > 0) { const char *data = (const char *)receiver->getData(); if (receiver->getDataSize() == 16 && data[0] == 'G') { // The game information is 16 bytes long float score; int timeLeft, realTimeLeft; memcpy(&score, data + 4, 4); memcpy(&timeLeft, data + 8, 4); memcpy(&realTimeLeft, data + 12, 4); cout << "Score: " << score << " Time left: " << timeLeft << " s Real time left: " << realTimeLeft << " s" << endl; } receiver->nextPacket(); } }
delete robot; return 0;}Oyun süresi bataklıklarda daha hızlı akar ve iki süreden biri dolduğunda oyun biter. Başlangıca ne zaman döneceğini bilmek için ikisini de kullan.
Oyunu bitirme
Bölüm başlığı “Oyunu bitirme”Oyunu bitirmek için E gönder. Robot başlangıç karesindeyse ve en az bir duvar işaretini tanımladıysa %10’luk çıkış bonusunu alır.
from controller import Robotimport struct
robot = Robot()timeStep = int(robot.getBasicTimeStep())emitter = robot.getDevice("emitter")
robot.step(timeStep)print("Ending the game")# Ends the game. Send it on the starting tile, after identifying a token, to get the exit bonus.# The game stops your program right after this message.emitter.send(struct.pack("c", b"E"))robot.step(timeStep)#include <iostream>#include <webots/Robot.hpp>#include <webots/Emitter.hpp>
using namespace webots;
int main() { Robot *robot = new Robot(); int timeStep = (int)robot->getBasicTimeStep(); Emitter *emitter = robot->getEmitter("emitter");
robot->step(timeStep); std::cout << "Ending the game" << std::endl; // Ends the game. Send it on the starting tile, after identifying a token, to get the exit bonus. // The game stops your program right after this message. char message = 'E'; emitter->send(&message, 1); robot->step(timeStep);
delete robot; return 0;}Sırada, Duvar işaretleri sayfasında işaretleri birbirinden ayırt etmeyi öğrenmek var.
