|
Forum - Polski Portal COLOBOTa |
|
|
Przesunięty przez: Abadon 20-02-2010, 14:02 |
AlienKiller2 |
Autor |
Wiadomość |
Bartek c++
Twoja ulubiona misja: Tropica - Czas na atak
Pomógł: 6 razy Wiek: 20 Dołączył: 07 Lip 2009 Posty: 390
|
Wysłany: 22-12-2009, 11:49 AlienKiller2
|
|
|
To drugi program z serii AlienKiller
Sam idzie do naprawy i do ładowania gdy to potrzebne i jeszcze załatwiajaja obcych.
Kod: | extern void object::AlienKiller2()
{
while ( true )
{
object wrog,repair,power;
float A,B,alfa;
int alien[];
alien[0] = AlienAnt;
alien[1] = AlienSpider;
alien[2] = AlienWasp;
alien[3] = AlienWorm;
alien[4] = AlienEgg;
wrog = radar(alien);
repair = radar(RepairCenter);
power = radar(PowerStation);
while ( shieldLevel < 0.4 )
{
goto(repair.position);
wait(10);
}
while ( energyCell.energyLevel < 0.4 )
{
goto(power.position);
wait(10);
}
turn(direction(wrog.position));
motor(1,1);
if(position.z > wrog.position.z +35)
{
jet(-0.9);
}
if(position.z < wrog.position.z - 1)
{
jet(0.8);
}
wait(1);
A = wrog.position.z-position.z;
B = distance2d(position,wrog.position)-1.5;
alfa = atan(A/B);
if (distance(position, wrog.position) < 42)
{
aim(alfa-2);
turn(direction(wrog.position));
motor(0.6,0.6);
fire(0.5);
wait(4);
if ( wrog == null)
{
message("wszystkie szkodniki zestrelone",3);
goto(repair.position);
break;
}
}
}
} |
|
_________________
|
Ostatnio zmieniony przez Bartek c++ 01-01-2010, 13:21, w całości zmieniany 1 raz |
|
|
|
|
Berserker
Dark Ness
Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy Wiek: 24 Dołączył: 24 Mar 2009 Posty: 496 Skąd: Bigos
|
Wysłany: 22-12-2009, 17:56
|
|
|
Bez sensu, bez sensu i kompletny brak sensu.
Najpierw sprawa z naprawa i ladowaniem sie. Pomine milczeniem czekanie 10s, to bylo juz duzo razy walkowane. Ale to pochopnie wstawione errmode(0) bedzie zguba robota, jesli stacja naprawcza badz energetyczna bedzie zajeta. Robot pewnie po prostu stanie w miejscu i bedzie czekal. Prawdopodobnie az go mrowki zalatwia.
Po co definiujesz zmienne dopiero w petli? Zmienne i stale lepiej sie definiuje przed petla, wtedy nie ma takiego balaganu.
Zamiast bezsensownie porownywac swoja wysokosc z wysokoscia mrowki lepiej skorzystac ze swojej wysokosci nad poziomem gruntu.
Polecam rowniez zastanowic sie nad tym co ma robic robot kiedy juz moze strzelic oraz zdefiniowac kiedy moze strzelic |
_________________
|
|
|
|
|
FE4R
Twoja ulubiona misja: Saari - Inwazja
Pomógł: 4 razy Wiek: 24 Dołączył: 21 Paź 2009 Posty: 144
|
Wysłany: 22-12-2009, 20:59
|
|
|
Tak tak Bartek. Wciąż jest kilka problemów do rozwiązania.
Niepotrzebne kompletnie. Robot to nie owad, a błędy pomogą Ci udoskonalić program.
Kod: | object wrog;
wrog = radar(alien);
turn(direction(wrog.position)); |
A co, jeśli wroga nie ma? Można odpalić program, a robot sam poczeka, aż coś wykryje.
Dodatkowo ten turn(direction(wrog.position));. Nauczcie się ludzie dawać zmianę kierunków w funkcji motor();. To jest nawet opisane w Ćwiczeniach, lecz postaram się dać pewien rysunek. Może pomóc.
Jeśli użyjesz kodu:
Kod: | float dir = direction(Cel1.position);
turn(dir); |
Robot najpierw zwróci się w stronę przeciwnika, a potem dopiero ustawi silniki na pełną moc.
Można jednak zrobić to trochę inaczej, aby robot obrócił się płynnie oraz natychmiastowo zareagował na zmianę kierunku:
Kod: | float dir = direction(Cel1.position);
if( dir > 0) motor(1-dir/90, 1);
if( dir < 0) motor(1, 1+dir/90); |
Już wyjaśniam. Jak pewnie wiesz, w Colobocie są kąty tylko do 180 stopni. Kąt +180 stopni to kąt w lewo, a kąt -180 stopni to kąt w prawo. Dlatego używając warunku if() sprawdzamy, czy obiekt jest po lewo(dir > 0) czy po prawo (dir < 0). Jeśli jest w jednym z tych kierunków, robot ustawi moc silników w zależności od kąta. Biorąc z rysunku:
Jeśli dir = 120, to dir/90 = 1.3. A więc, jeśli cel jest po lewo, sterowanie silnikiem będzie wyglądało tak: motor(-0.3, 1); i robot będzie zwracał się w lewo, póki cel nie znajdzie się na środku celownika. Oczywiście cały czas jedzie na pełnych obrotach. Zajmijmy się teraz prawą stroną.
Jeśli dir = -120, to dir/90 = -1.3. Wtedy motor() będzie wyglądał tak: motor(1, -0.3); i robot skręci w prawo. Zależnie, jak duży jest kąt, robot będzie skręcał powoli / szybko. Można również dostosować to zamieniając dir/90 na dir/40. Nie polecam schodzić poniżej dir/20, gdyż potem robot zaczął latać do tyłu.
Dla uproszczenia powiem, że:
Kod: | if( dir > 0) motor(1-dir/90, 1);
if( dir < 0) motor(1, 1+dir/90); |
to jest to samo co: Kod: | motor(1-dir/90, 1+dir/90); |
Kolejny problem to rozróżnienie, czy obiekt to osa czy obiekt naziemny. Podpatrz sobie rozwiązanie z mojego programu na dole. Wnioskuję, że Kod: | if(position.z > wrog.position.z +35) | to właśnie nieudana próba dostosowania się do tego.
Sam daję swój program, który niedawno lekko udoskonaliłem. Być może uda Ci się coś z niego podpatrzeć, Bartek. Tym razem dodałem komentarze do wszystkiego, co robot robi. Poczytaj je, żeby zrozumieć rzeczy, których nie wiesz, ewentualnie napisz tutaj. Mam nadzieję, że będzie pomocne.
Kod: | extern void object::ActiveKiller2()
{
while(true)
{
ShieldCheck(); // sprawdz czy uszkodzony
EnergyCheck(); // sprawdz baterie
int i, list [];
i = 0;
list[i++] = AlienAnt;
list[i++] = AlienSpider;
list[i++] = AlienWorm;
list[i++] = AlienWasp;
while(radar(list) != null) // jesli wykryto wroga
{
ShieldCheck(); // sprawdzaj stan oslony za kazdym podejsciem do wroga
EnergyCheck(); // sprawdzaj stan baterii za kazdym podejsciem do wroga
object enemy = radar(list);
if(enemy.category == list[3]) // jesli wrog to osa
{
ActiveWaspKiller(); // zastosuj funkcje do zabijania os
}
else // jesli naziemny
{
ActiveLandKiller(); // zastosuj funkcje do zabijania mrowek
}
}
motor(0,0); // jesli nie wykryto zatrzymaj sie
jet(0);
wait(1); // i czekaj...
}
}
void object::ActiveWaspKiller() // funkcja do zabijania os
{
object wasp = radar(AlienWasp); // zmienne...
float h, d, dir;
if(altitude < wasp.altitude) // jesli osa jest wyzej...
{
jet(0.5); // wznies sie...
}
if(altitude > wasp.altitude) // jesli nizej...
{
jet(-0.5); // opadnij...
}
h = wasp.position.z - position.z; // zmienne...
d = distance2d(position, wasp.position);
aim(atan(h/d)); // celuj w ose
dir = direction(wasp.position);
motor(1-dir/40, 1+dir/40); // ustaw silniki
if(distance(position, wasp.position) < 40) // jesli osa jest w zasiegu
{
if(dir < 5 && dir > -5) // jesli jest na celowniku
{
fire(0.1); // strzelaj
wait(0.4);
}
}
if(temperature == 1) // jesli silnik sie przegrzal
{
do
{
jet(-1); // zatrzymaj sie
motor(0,0);
}
while(temperature != 0); // az ostygnie
}
}
void object::ActiveLandKiller() // funkcja do zabijania mrowek
{
int list[], i = 0;
list[i++] = AlienAnt;
list[i++] = AlienSpider;
list[i++] = AlienWorm;
object enemy = radar(list); // zmienne...
float h, d, dir, posZ, pitchK;
posZ = position.z - topo(position);
if(posZ < 8) // jesli wysokosc lotu jest mniejsza niz 8
{
jet(0.5); // wznies sie
}
posZ = position.z - topo(position);
if(posZ > 12) // jesli wysokosc lotu jest wieksza niz 12
{
jet(-0.5); // opadnij
}
h = enemy.position.z - position.z; // zmienne...
d = distance2d(position, enemy.position);
dir = direction(enemy.position); // poprawka na celowanie
pitchK = pitch*cos(dir) - roll*sin(dir);
aim(atan(h/d) - pitchK); // celuj w mrowke
motor(1-dir/40, 1+dir/40); // ustaw silniki
if(distance(position, enemy.position) < 40) // jesli jest w zasiegu
{
if(dir < 5 && dir > -5) // jesli jest na celowniku
{
fire(0.1); // strzelaj
}
if((atan(h/d) - pitchK) < -25) // jesli jest za blisko - nie trafi
{
jet(0);
motor(1,1);
do wait(0.1); while((atan(h/d) - pitchK) >= -25); // poczekaj az sie oddali
}
}
if(temperature == 1) // jesli silnik sie przegrzal
{
jet(0); // zatrzymaj sie
motor(0,0);
do wait(0.1); while(temperature != 0); // poczekaj az ostygnie
}
}
void object::ShieldCheck() // sprawdzaj oslone
{
if(shieldLevel < 0.5) // jesli jest naruszona
{
object spot = radar(RepairCenter);
if(spot != null) // jesli warsztat istnieje
{
errmode(0);
int err = goto(spot.position); // jesli warsztat jest wolny
errmode(1);
if(err != 0) // jesli jest zajety, zatrzymaj sie 4 metry od warsztatu i czekaj
{
turn(direction(spot.position));
errmode(0);
move(distance(position, spot.position) -4);
errmode(1);
do
{
wait(1);
errmode(0);
goto(spot.position);
errmode(1);
}
while(err != 0);
}
do
{
wait(2);
}
while(shieldLevel != 1); // czekaj az naladuje oslone
}
}
}
void object::EnergyCheck() // sprawdzaj baterie
{
if(energyCell.category == NuclearCell) // jesli atomowka
{
if(energyCell.energyLevel < 0.1) // jesli wyczerpana
{
motor(0,0); // zatrzymaj
jet(0);
message("Potrzebuje ogniwa! Pozycja: x: "+position.x+" y: "+position.y); // wezwij pomoc
do wait(1); while(energyCell == null || energyCell.energyLevel != 1); // czekaj
}
}
else // jesli normalne ogniwo
{
if(energyCell.energyLevel < 0.3) // jesli wyczerpane
{
object px = radar(PowerStation);
if(px != null) // jesli stacja istnieje
{
errmode(0);
int err = goto(px.position); // jesli nie jest zajeta
errmode(1);
if(err != 0) // jesli jest zajeta, zatrzymaj sie 4 metry przed i poczekaj
{
turn(direction(px.position));
errmode(0);
move(distance(position, px.position) -4);
errmode(1);
do
{
wait(1);
errmode(0);
goto(px.position);
errmode(1);
}
while(err != 0);
}
do
{
wait(2);
}
while(energyCell.energyLevel != 1); // poczekaj az sie naladuje
}
else // jesli stacja nie istnieje
{
motor(0,0); // zatrzymaj
jet(0);
message("Potrzebuje ogniwa! Pozycja: x: "+position.x+" y: "+position.y); // wezwij pomoc
do wait(1); while(energyCell == null || energyCell.energyLevel != 1); // czekaj
}
}
}
}
|
|
|
|
|
|
Berserker
Dark Ness
Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy Wiek: 24 Dołączył: 24 Mar 2009 Posty: 496 Skąd: Bigos
|
Wysłany: 22-12-2009, 23:22
|
|
|
Cytat: | motor(0,0); // jesli nie wykryto zatrzymaj sie
jet(0);
wait(1); // i czekaj...
|
Jak czesto robot z takimi instrukcjami laduje w wodzie? |
_________________
|
|
|
|
|
FE4R
Twoja ulubiona misja: Saari - Inwazja
Pomógł: 4 razy Wiek: 24 Dołączył: 21 Paź 2009 Posty: 144
|
Wysłany: 22-12-2009, 23:44
|
|
|
Berserker napisał/a: | Cytat: | motor(0,0); // jesli nie wykryto zatrzymaj sie
jet(0);
wait(1); // i czekaj...
|
Jak czesto robot z takimi instrukcjami laduje w wodzie? |
Jaką masz wersję Colobota, że Twój robot ma dostęp do mapy terenu w postaci siatki. Nie ma skutecznego sposóbu, aby robot szybko znalazł bezpieczne miejsce do lądowania. |
|
|
|
|
Berserker
Dark Ness
Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy Wiek: 24 Dołączył: 24 Mar 2009 Posty: 496 Skąd: Bigos
|
Wysłany: 23-12-2009, 09:02
|
|
|
Jak to nie ma? Sa przynajmniej 2, wystarczy troche pomyslec... |
_________________
|
|
|
|
|
FE4R
Twoja ulubiona misja: Saari - Inwazja
Pomógł: 4 razy Wiek: 24 Dołączył: 21 Paź 2009 Posty: 144
|
Wysłany: 23-12-2009, 12:49
|
|
|
A jakiś szybki? Ja wymyśliłem, że robot sprawdzi 9 punktów wokół siebie w zasięgu mocy reaktora, ale zanim to zrobił, chlup do wody.
W ogóle uderzyłeś w najczulszy punkt tego programu. Czuję się zgwałcony. D: |
|
|
|
|
adiblol
Administrator forum FLOSS FTW!
Twoja ulubiona misja: porównywanie formatów audio
Pomógł: 18 razy Dołączył: 21 Kwi 2008 Posty: 1313 Skąd: pokój odsłuchowy
|
Wysłany: 23-12-2009, 12:56
|
|
|
FE4R napisał/a: | Ja wymyśliłem, że robot sprawdzi 9 punktów wokół siebie w zasięgu mocy reaktora, ale zanim to zrobił, chlup do wody. |
Jest taka funkcji ipf ... |
_________________ 1Tbps Project && Telecomix Network
|
|
|
|
|
Berserker
Dark Ness
Twoja ulubiona misja: Ofrenia
Pomógł: 16 razy Wiek: 24 Dołączył: 24 Mar 2009 Posty: 496 Skąd: Bigos
|
Wysłany: 23-12-2009, 13:44
|
|
|
Pierwszy sposob: sprawdzasz punkty po kolei w 4 kierunkach: do przodu, do tylu, na lewo i prawo.
Drugi: co kilka sekund sprawdzasz, czy pozycja w jakiej sie znajdujesz ma grunt nad poziomem morza i jesli tak to ja zapisujesz. Pozniej do niej wracasz.
Zreszta wydaje mi sie, ze space() powinno znalezc takie miejsce. |
_________________
|
|
|
|
|
Bartek c++
Twoja ulubiona misja: Tropica - Czas na atak
Pomógł: 6 razy Wiek: 20 Dołączył: 07 Lip 2009 Posty: 390
|
Wysłany: 01-01-2010, 13:20
|
|
|
FE4R napisał/a: | Tak tak Bartek. Wciąż jest kilka problemów do rozwiązania.
Kod:
errmode(0);
Niepotrzebne kompletnie. Robot to nie owad, a błędy pomogą Ci udoskonalić program. |
Dzięki za zauwarznie zapomniałem tego usunąć. |
_________________
|
|
|
|
|
|
Nie możesz pisać nowych tematów Możesz odpowiadać w tematach Nie możesz zmieniać swoich postów Nie możesz usuwać swoich postów Nie możesz głosować w ankietach Nie możesz załączać plików na tym forum Możesz ściągać załączniki na tym forum
|
Wersja do druku
|
|
| |
|
|
|
|
Polski Portal COLOBOTa © 2008 - 2012 |
|
|