Programmeerimise algkursus Harjutus 6
Allikas: Lambda
Seinte vastu sõitmine on igatpidi paha. Esiteks kaotab robot energiat, teiseks võib ta sedasi nurka või seina äärde kinni jääda ja vastastele kergeks saagiks osutuda.
Uus sündmus
Algatuseks lisame "päris oma" sündmuse, mis hakkab käivituma siis, kui me seinale liiga lähedal oleme.
run meetodisse:
public void run() {
// Ära keera tukki koos kerega ega radarit koos tukiga!
setAdjustGunForRobotTurn(true);
setAdjustRadarForGunTurn(true);
// Registreerime uue sündmuse, mis käivitub, kui radaritiir on tehtud
addCustomEvent(new RadarTurnCompleteCondition(this));
// Registreerime sündmuse seina läheduse tunnetamiseks
addCustomEvent(new Condition("CloseToWallCondition") {
public boolean test() {
double x = getX();
double y = getY();
double w = getBattleFieldWidth();
double h = getBattleFieldHeight();
double wm = 100;
if (x <= wm || y <= wm || w - x < wm || h - y < wm) {
return true;
} else {
return false;
}
}
});
// Käivitame esimese radaritiiru
onRadarTurnComplete();
while(true) {
// Dingel-dangel, kellapendel
ahead(100 * suund);
suund = -suund;
}
}
onCustomEvent meetodisse:
public void onCustomEvent(CustomEvent e) {
String s = e.getCondition().getName();
if("robocode.RadarTurnCompleteCondition".equals(s)) {
onRadarTurnComplete();
}
if("CloseToWallCondition".equals(s)) {
onCloseToWall();
}
}
Hoidume matemaatikast ;)
Seinast eemale saamiseks on kõige parem viis sõita keskpunkti poole. Et teada kuhu poole jääb keskpunkt, on vaja funktsiooni, mis oskaks arvutada peilungit kahe punkti vahel. Ise jalgratast ei ole vaja leiutada, internet on täis koodinäiteid, mis on kirjutatud matemaatikat paremini jagavate kodanike poolt. Meie kasutame ühte, mida õppejõud on natuke kohendanud.
/** * Returns the distance between two points */ public double distance(double x1, double y1, double x2, double y2) { double x = x2-x1; double y = y2-y1; double range = Math.sqrt(x*x + y*y); return range; } /** * computes the absolute bearing between two points */ public double absoluteBearing(double x1, double y1, double x2, double y2) { double hyp = distance(x1, y1, x2, y2); double xo = x2-x1; double yo = y2-y1; double angle = Math.asin(xo / hyp); if(yo < 0) { angle = Math.PI - angle; } else if(xo < 0) { angle += Math.PI * 2; } angle = Math.toDegrees(angle); return angle; }
Lahkume seina lähedusest
Seina lähedusest lahkumine võiks käia umbes nii:
- Vaatame kuhu jääb mänguväljaku keskpunkt meie sõidusuuna suhtes
- Otsustame, kas keskpunkti poole sattumiseks tuleb liikuda edasi või tagasi
- Hakkame õiges suunas sõitma ja protsessi kiirendamiseks keerame vastavalt kas nina või saba keskpunkti poole
public void onCloseToWall() { double x = getX(); double y = getY(); double w = getBattleFieldWidth(); double h = getBattleFieldHeight(); double suund_keskele = absoluteBearing(x, y, w / 2, h / 2); double keeramisnurk = normalRelativeAngle(suund_keskele - getHeading()); double soita = Math.abs(getDistanceRemaining()); if(Math.abs(keeramisnurk) > 90) { soita = -soita; keeramisnurk = keeramisnurk - 90; } setAhead(soita); setTurnRight(keeramisnurk); }