Oryginalna strona colobot.cba.pl umarła, gdy cba.pl przestało oferować darmowy hosting. To jest statyczny mirror, pobrany w 2018. ~krzys_h
 Polski Portal COLOBOTa - COLOBOT Polish Portal
Forum - Polski Portal COLOBOTa
Strona głównaStrona główna UżytkownicyUżytkownicy GrupyGrupy StatystykiStatystyki


Poprzedni temat «» Następny temat
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.

Kod:
errmode(0);

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. :lol:
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ąć.
_________________

 
     
Wyświetl posty z ostatnich:   
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

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group
Polski Portal COLOBOTa © 2008 - 2012