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, 13:41
Sentry
Autor Wiadomość
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: 19-01-2010, 18:31   Sentry

Ten program to bardziej prezentacja, jak dokladnie mozna w cokolwiek wycelowac. Za bardzo komentowac go nie musze, jest nawet jak na mnie czytelny.
Kod:
extern void object::Sentry()
{
    object p, rep, station;
    float speed, maxSpeed, angle, spin;
    float time, dist, dir, delay, r;
    point dest, center;
    int i;
    int list[];
    bool clear;
    i = 0;
    list[i++] = AlienAnt;
    list[i++] = AlienWorm;
    list[i++] = AlienSpider;
    list[i++] = AlienWasp;
    center = position;
    time = abstime();
    maxSpeed = 0.5;
    rep = radar(RepairCenter);
    station = radar(PowerStation);
    while(true)
    {
        aim(0);
        motor(0, 0);
        check("energy", 0.2, station);
        check("shield", 0.5, rep);
        if(distance(center, position) > 2)
        {
            errmode(0);
            goto(center);
            errmode(1);
        }
        while(radar(list, 0, 360, 0, 60) != null)
        {
            p = radar(list);
            dest = Dest(p);
            dir = Dir(dest);
            angle = Aim(dest);
            spin = dir/90;
            if(abs(spin) > maxSpeed) spin = spin/abs(spin)*maxSpeed;
            motor(-spin, spin);
            dist = distance(dest, position);
            delay = dist/45+0.2;
            if(p.category == AlienWasp) delay = 0.2;
            aim(angle);
            if(dist < 45)
            {
                aim(angle);
                if(abs(spin) < 0.1 and abs(angle) <= 20)
                {
                    if(abstime()-time > delay)
                    {
                        fire(0.2);
                        time = abstime();
                    }
                }
            }
        }
    }
}
float object::Angle(point dest)
{
    float dist, deltaH;
    float angle;
    dist = distance(position, dest);
    deltaH = dest.z - (position.z+1);
    angle = asin(deltaH/dist);
    return angle;
}
float object::Aim(point dest)
{
    float angle;
    angle = Angle(dest) * abs(cos(roll)) - pitch  * abs(cos(roll));
    return angle;
}
float object::Dir(point dest)
{
    float dir, angle;
    dir = direction(dest);
    angle = dir - (Angle(dest)-pitch) * sin(roll);
    return angle;
}
point object::Dest(object p)
{
    ipf(1000);
    float len, alfa;
    float vo, vb, dist, deltaH;
    float a, b, c, delta;
    point dest;
    vo = velocity(p);
    vb = 53;
    if(vo == 0)
    {
        dest = p.position;
        return dest;
    }
    deltaH = p.altitude;
    dist = distance2d(position, p.position);
    alfa = abs(p.orientation-(direction(p.position)+orientation));
    a = 1-pow(vb/vo, 2);
    b = cos(alfa)*dist;
    c = pow(dist, 2);
    delta = pow(b, 2)-4*a*c;
    if(delta >= 0) len = (-b-sqrt(delta))/(2*a);
    else len = -b*0.5/a;
    dest.x = p.position.x+cos(p.orientation)*len;
    dest.y = p.position.y+sin(p.orientation)*len;
    dest.z = topo(dest)+deltaH;
    return dest;
}
float velocity(object p)
{
    point start;
    float time, dtime, dist;
    start = p.position;
    time = abstime();
    wait(0.01);
    dist = distance2d(start, p.position);
    dtime = abstime()-time;
    return dist/dtime;
}
void object::check(string type, float level, object p)
{
    if(p == null) return;
    int r;
    if(strfind(type, "energy") != nan)
    {
        if(energyCell != null and energyCell.category == PowerCell and energyCell.energyLevel < level)
        {
            if(p.category == PowerStation)
            {
                errmode(0);
                r = goto(p.position);
                if(r != 0)
                {
                    errmode(1);
                    return;
                }
                errmode(1);
                while(energyCell.energyLevel < 1);
            }
        }
        return;
    }
    if(strfind(type, "shield") != nan)
    {
        if(shieldLevel < level)
        {
            if(p.category == RepairCenter)
            {
                errmode(0);
                r = goto(p.position);
                if(r != 0)
                {
                    errmode(1);
                    return;
                }
                errmode(1);
                while(shieldLevel < 1);
            }
        }
    }
   
}


- Program jest bardzo skuteczny, a przy tym niesamowicie energooszczedny. Jakby ktos sie jeszcze niedomyslil - program jest dla robotow stojacych w miejscu.
Mile widziana konstruktywna krytyka.
@edit
Zmienilem sposob obliczania kata miedzy linia przecinajaca robota oraz cel i plaszczyzna pozioma (czyli po prostu kata do celowania :P ), a dokladniej arcus tangens na arcus sinus. Powodem jest teoretycznie blad, a w praktyce przesladowania Feara ktory mi chyba nie dalby spokoju z tym :P Tangens kata 90/270/-90/-3690/n*180+90° nie istnieje, wiec jesli sprobuje sie go uzyskac za pomoca funkcji atan() to wywala dzielenie przez 0.
Ostatnio zmieniony przez Berserker 22-02-2010, 01:12, w całości zmieniany 1 raz  
 
 
     
Bartek c++ 


Twoja ulubiona misja: Tropica - Czas na atak
Pomógł: 6 razy
Wiek: 20
Dołączył: 07 Lip 2009
Posty: 390
Wysłany: 19-01-2010, 21:07   

A moze fire(0.1); zamiast 0.2 bedzie mniaj energi zurzywac.

// Ty patrzysz na swojego posta po napisaniu? - colobotwymiiata
_________________

Ostatnio zmieniony przez colobotwymiiata 31-05-2010, 11:18, w całości zmieniany 2 razy  
 
     
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: 19-01-2010, 22:05   

Cytat:
A moze fire(0.1); zamiast 0.2 bedzie mniaj energi zurzywac.

Im dluzsza salwa tym wieksza szansa na trafienie - istnieje zawsze ryzyko, ze jakas stala pomylilem (np predkosc pocisku), 0.2 ma wieksza gwarancje, ze taka osa przetnie strumien.

Audiotele:
Kto zgadnie, gdzie i jakie 2 bledy matematyczne popelnilem w programie, ktore 'niweluja" sie nawzajem i sprawiaja, ze program dziala tak jak to bylo zamierzone, ten dostanie dedykacje w postaci losowo wybranej emotki w nieokreslonym poscie po uplynieciu nieustalonego terminu.
 
 
     
FE4R 


Twoja ulubiona misja: Saari - Inwazja
Pomógł: 4 razy
Wiek: 24
Dołączył: 21 Paź 2009
Posty: 144
Wysłany: 20-01-2010, 00:07   

Może moja wypowiedź nie będzie bardzo konstruktywna, ale przynajmniej będzie o czym gadać. :mrgreen:

Po pierwsze Twój cienki program przegrał z moim super ultra świetnym programem dla osy, która leci 50 metrów nad ziemią. XD


Mam jednak kilka pytań dotyczących samego kodu programu (w stylu pipoka 8-) )

Kod:
bool clear;
Zastanawia mnie deklaracja tej zmiennej, która, o ile mnie wzrok nie myli, nie została nigdzie użyta.

Kod:
list[i++] = AlienAnt;
list[i++] = AlienWorm;
list[i++] = AlienSpider;
list[i++] = AlienWasp;

Możnaby AlienEgg dodać do listy.

Kod:
maxSpeed = 0.5;
Czy mam to interpretować jako maksymalna prędkość obrotu? o_o; Za bardzo nie wiem, do czego ta stała służy i skąd się wzięła.

Kod:
aim(0);
motor(0, 0);

Nie wiem, czy umieszczanie tego wewnątrz pętli while(true) jest dobrym rozwiązaniem, szczególnie dla programu obronnego.

Kod:
if(distance(center, position) > 2)
        {
            errmode(0);
            goto(center);
            errmode(1);
        }

Rozumiem, że to ma trzymać robota w jednej pozycji, gdy działające na niego siły są zbalansowane? Znaczy się - to jest raczej pewne, że robot będzie stał w miejscu, chyba, że umieści się go na tak pochyłym terenie, że będzie zjeżdżał. Wtedy bez sensu używać instrukcji goto(); W ogóle bez sensu umieszczać robota na tak pochyłym terenie. :)

Kod:
while(radar(list, 0, 360, 0, 60) != null)

60 metrów to za mało. Według mnie. Zrobiłem eksperyment, w którym osa potrafi pokonać 45 metrów, zanim robot Osłaniacz włączy osłonę (a wykrył osę na 70 metrze). 60 metrów strefy wykrywania to ograniczanie możliwości robota i jego zasięgu ~40 metrów. Na Twoim miejscu stworzyłbym pętlę wykrywającą wszystkie obiekty oraz if() filtrujące dystans do wroga.

Kod:
delay = dist/45+0.2;
No comprende. Te stałe need to be explained.

Kod:
aim(angle);
if(dist < 45) aim(angle)

Po co aimować 2 razy?

Kod:
vo = velocity(p);
vb = 53;

delta = pow(b, 2)-4*a*c;
if(delta >= 0) len = (-b-sqrt(delta))/(2*a);
else len = -b*0.5/a;

Skąd wziąłeś stałe 53, 4 oraz 0.5?

Kod:
void object::check(string type, float level, object p)
...

Bardzo spodobał mi się sposób z łańcuchami, co jednak możnaby ulepszyć. Jak na razie funkcja ma do wprowadzenia 3 argumenty. Łańcuch mógłby działać na zasadzie słowa kluczowego, automatycznie sprawdzającego poziom czegokolwiek(temperature, energyLevel, shieldLevel). Mam na myśli np.:
Kod:
void object::Recharge(string key)
{
    if(strfind(key, "") == nan) return;
    else
    {
        if(key == "energy")
        {
            if(energyCell == null || energyCell.energyLevel < 0.3)
            {
                /* instrukcje */
            }
        }
       
        if(key == "shield")
        {
            /* instrukcje */
        }
    }
}



Berserker napisał/a:
Kto zgadnie, gdzie i jakie 2 bledy matematyczne popelnilem w programie, ktore 'niweluja" sie nawzajem i sprawiaja, ze program dziala tak jak to bylo zamierzone, ten dostanie dedykacje w postaci losowo wybranej emotki w nieokreslonym poscie po uplynieciu nieustalonego terminu.

Słaby jestem z geometrii, to nawet nie spróbuję. :)

Bardzo miło 'podzielony' program na moduły. Wszystko jest przez to czytelniejsze, pomimo, że wolniej chodzi(w CBOT nie ma zmiennych globalnych, a każda deklaracja / definicja funkcji i inicjowane tam zmienne zjadają dużo pamięci). Tak jak w jednej funkcji użyłeś ipf(); tylko dlatego, że zadeklarowałeś dużo zmiennych, mimo, że nie zajmują one pamięci, aż do nadania im wartości, natomiast w funkcji liczącej dystans już ipf(); nie użyłeś. :P
 
     
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: 20-01-2010, 14:46   

Cytat:
Zastanawia mnie deklaracja tej zmiennej, która, o ile mnie wzrok nie myli, nie została nigdzie użyta.

Pozostalosc po sam nie pamietam czym. Pewnie ten program to przerobka programu do zabijania obcych na gorzystym terenie, ktory kiedys napisalem, a przez lenistwo nie usunalem wszystkich pozostalosci po sprawdzaniu widocznosci celu.
Cytat:
Możnaby AlienEgg dodać do listy.

Moznaby, ale ten program zostal napisany uwzgledniajac wszelkie ograniczenia fabularne - zalozylem, ze jajo rzadko spada z nieba tuz przed dzialo robota.
Cytat:
Czy mam to interpretować jako maksymalna prędkość obrotu? o_o; Za bardzo nie wiem, do czego ta stała służy i skąd się wzięła.

Przyjemnie sie oglada takiego powoli obracajacego sie robota, podczas gdy mrowki sraja ze strachu przed czekajaca je zaglada :)
Cytat:
Nie wiem, czy umieszczanie tego wewnątrz pętli while(true) jest dobrym rozwiązaniem, szczególnie dla programu obronnego.

Znaczy co, robot ma sie nonstop obracac?
Cytat:
Rozumiem, że to ma trzymać robota w jednej pozycji, gdy działające na niego siły są zbalansowane?

Nie, to jest polecenie powrotu do ustalonej pozycji po naprawieniu/naladowaniu sie.
Cytat:
60 metrów to za mało. Według mnie. Zrobiłem eksperyment, w którym osa potrafi pokonać 45 metrów, zanim robot Osłaniacz włączy osłonę (a wykrył osę na 70 metrze). 60 metrów strefy wykrywania to ograniczanie możliwości robota i jego zasięgu ~40 metrów. Na Twoim miejscu stworzyłbym pętlę wykrywającą wszystkie obiekty oraz if() filtrujące dystans do wroga.

Oslaniacz oslaniaczem, zanim oslaniacz wlaczy oslone dzialo obroci sie 2 razy.
A uzywajac petli while() unikam chociazby sprawdzenia, czy obcy sa na mapie.
Cytat:
No comprende. Te stałe need to be explained.

Bazowy czas 0.2s+czas wynikajacy ze stosunku odleglosci do maksymalnego zasiegu dziala. Proste jak drut.
Cytat:
Po co aimować 2 razy?

Zanim z poziomu 0 lufa podniesie sie o 20°, bedzie potrzebny np kat 15°.
Cytat:
Skąd wziąłeś stałe 53, 4 oraz 0.5?

Jesli chodzi o 53 - predkosc pocisku, ktora liczylem na biednych pajaczkach z cwiczen. Jesli chodzi o dwie pozostale "stale" - wlasnie skompromitowales sie jesli chodzi o twoja znajomosc matematyki :P
Cytat:
Bardzo spodobał mi się sposób z łańcuchami, co jednak możnaby ulepszyć. Jak na razie funkcja ma do wprowadzenia 3 argumenty. Łańcuch mógłby działać na zasadzie słowa kluczowego, automatycznie sprawdzającego poziom czegokolwiek(temperature, energyLevel, shieldLevel)

Program zostal napisany pod moje potrzeby, nie by uszczesliwic ludzkosc :P Ja jak buduje sobie baze np podczas misji, to przypisuje kazdemu robotowi jedna stacje energetyczna. Dlatego np nie aktualizuje zmiennej zawierajacej info dot stacji energetycznej. Jesli chodzi o poziom - o wiele latwiej zmienia sie jesli jest na poczatku programu, a nie gdzies w funkcjach.
Cytat:
Słaby jestem z geometrii, to nawet nie spróbuję.

Ja sam nie rozumiem na czym polega ten blad ani jakim cudem on nie psuje dzialania programu. Ale sprawdze, kto ma gotowe wzory na liczenie wszystkiego co tu jest badz postara sie sam policzyc :P
@screen
Dzielenie przez 0? O_O Trzeba bedzie przerzucic sie na sinusy - tangens nie ma wartosci dla kata 90/270° i wywala wlasnie dzielenie przez 0 :P
Cytat:
Tak jak w jednej funkcji użyłeś ipf(); tylko dlatego, że zadeklarowałeś dużo zmiennych, mimo, że nie zajmują one pamięci, aż do nadania im wartości, natomiast w funkcji liczącej dystans już ipf(); nie użyłeś.

1) Gdzie jest jakas funkcja liczaca dystans? O_O
2) W funkcji liczacej pozycje jest duzo obliczen - Zawsze to troche pamieci i czasu zajmuje.
 
 
     
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: 20-01-2010, 15:29   

Jeśli chcesz szybsze skręcanie, skorzystaj z buga w funkcji turn :)
http://www.colobot.yoyo.p...topic.php?t=138
_________________
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: 20-01-2010, 16:07   

@up
Ta funkcja jest strasznie niedokladna :P
_________________
 
 
     
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: 20-01-2010, 16:22   

To można najpierw zgrubnie funkcją szybkiego skrętu, a później dokładnie normalnym turn :)
_________________
1Tbps Project && Telecomix Network

 
 
     
FE4R 


Twoja ulubiona misja: Saari - Inwazja
Pomógł: 4 razy
Wiek: 24
Dołączył: 21 Paź 2009
Posty: 144
Wysłany: 20-01-2010, 18:13   

Berserker napisał/a:
jajo rzadko spada z nieba tuz przed dzialo robota.

Dziwną masz wersję gry w takim razie...


Cytat:
Znaczy co, robot ma sie nonstop obracac?

Wystarczy, że non-stop liczy kąt potrzebny do obrotu. Reszta powinna pójść gładko, nawet z użyciem motor();

Cytat:
Oslaniacz oslaniaczem, zanim oslaniacz wlaczy oslone dzialo obroci sie 2 razy.
A uzywajac petli while() unikam chociazby sprawdzenia, czy obcy sa na mapie.

Nie wiem, czy tak szybko się obróci o 180 stopni?
A sprawdzenie, czy obcy są na mapie byłoby dobrym pomysłem, chociażby dlatego, że wtedy możnaby wyłączyć program.

Cytat:
Zanim z poziomu 0 lufa podniesie sie o 20°, bedzie potrzebny np kat 15°.

Ale najpierw się musi podnieść o 20 stopni, bo tak rozkazała instrukcja, a dopiero potem się obniży do 15 stopni. Na jedno wyjdzie.

Cytat:
Jesli chodzi o 53 - predkosc pocisku, ktora liczylem na biednych pajaczkach z cwiczen. Jesli chodzi o dwie pozostale "stale" - wlasnie skompromitowales sie jesli chodzi o twoja znajomosc matematyki :P

Zamiast (pośrednio) krytykować mój sposób Zakuj Zdaj Zapomnij, to powiedz, co to jest. ^_^ W końcu to Twój program! :P

Cytat:
1) Gdzie jest jakas funkcja liczaca dystans? O_O

Pomyłka. Prędkość. Funkcja 'velocity'. O nią mi chodziło. W innym programie narzekałem, że nie da się prędkości dokładnie obliczyć.
 
     
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: 20-01-2010, 18:27   

Od gory do dolu:
Cytat:
W innym programie narzekałem, że nie da się prędkości dokładnie obliczyć.

Widzisz jednak, ze sie da.
Cytat:
Zamiast (pośrednio) krytykować mój sposób Zakuj Zdaj Zapomnij, to powiedz, co to jest. ^_^ W końcu to Twój program!

Trojmian kwadratowy... jeszcze jakies pytania? :)
Cytat:
Ale najpierw się musi podnieść o 20 stopni, bo tak rozkazała instrukcja, a dopiero potem się obniży do 15 stopni. Na jedno wyjdzie.

Ale jesli dam 1x ustawienie wysokosci lufy, to jednak robot wykona strzal jesli cel bedzie w zasiegu. Wykonanie niecelnego strzalu to badz co badz 0.2s straty. A wiele razy takie 0.2s uratowalo mi robota :)
Cytat:
Nie wiem, czy tak szybko się obróci o 180 stopni?
A sprawdzenie, czy obcy są na mapie byłoby dobrym pomysłem, chociażby dlatego, że wtedy możnaby wyłączyć program.

Robot na kolach bez probemu sie obroci o 180°.
Program z zalozenia ma byc taki, ze wlaczasz i nie obchodzi cie co sie stanie z tym robotem. Jesli obcych nie ma na mapie to po cholere budowac dzialo?
Cytat:
Wystarczy, że non-stop liczy kąt potrzebny do obrotu. Reszta powinna pójść gładko, nawet z użyciem motor();

No patrz, efekt ten sam, a pare obliczen mniej... :)
Cytat:
Dziwną masz wersję gry w takim razie...

To bylo takie eufemistyczne wyrazenie, ze sytuacja w ktorej jaja obcych pojawiaja sie w srodku bazy jest conajmniej glupia.
 
 
     
Bartek c++ 


Twoja ulubiona misja: Tropica - Czas na atak
Pomógł: 6 razy
Wiek: 20
Dołączył: 07 Lip 2009
Posty: 390
Wysłany: 27-01-2010, 21:07   

zrobilem kiedys prostszy program i tak samo skuteczny o nazwie "robotobronny".
_________________

 
     
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: 27-01-2010, 23:43   

@up
Faktycznie, nazwa najlepiej definiuje skutecznosc programu...

Jesli chodzi o skutecznosc to niewiele mozna poprawic w wiekszosci programow, tutaj jedynie dodalem porzadny system celowania zeby osy zestrzeliwywac. Za to marnuje tak malo energii, ze uzyty w dziale organicznym idzie do stacji energetycznej srednio co 0.5h przy ciaglym nadchodzeniu mrowek.
_________________
 
 
     
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