Skocz do zawartości

Floodnik

Użytkownicy
  • Postów

    188
  • Dołączył

  • Ostatnia wizyta

Odpowiedzi opublikowane przez Floodnik

  1. No to napotykamy problem: "co autor miał na myśli" :)

    Pierwsze, co mi przychodzi do głowy, to przed wywołaniem rekurencyjnym sprawdzić, czy dany podciąg(lewa, prawa połówka) jest już posortowany, zwyczajnie przebiegając przez niego. Jeśli tak, nie robić wywołania.

    Czy to rozwiązuje nasze zadanie?

    Nie wiem. JAKIEŚ usprawnienie to jest - w przypadku niektórych ciągów(np. dla już posortowanego ciągu zrobisz tylko jedną pętlę, wyjdzie liniowy czas, normalny mergesort by standardowo jechał wszystkie wywołania). Więc teoretycznie zadanie zostało wykonane. Choć nie znajdujemy wszystkich podciągów rosnących... To by było imo bez sensu, mogłoby nawet zwiększyć złożoność.

     

    PS. Pisząc poprzedni post nie zwróciłem uwagi na to, że to miało być usprawnienie MergeSorta, a nie dodatkowa funkcjonalność(dlatego łapałem się za głowę o co chodzi). Przepraszam :P

  2. Pierwszy pomysł, korzystający z wiedzy licealnej :P Być może da się szybciej, być może po poskracaniu wyjdzie to co napisał @adam014(a być może co innego), ale przedstawię swój tok rozumowania.

    Nie zraź się do kiepskiego rysunku, powoli wszystko opiszę!

    bazgroly.png

    1) Mamy dane:

    x1, y1, x2, y2 - początek i koniec ściany,

    x0, y0 - punkt zderzenia ze ścianą,

    wektor v = [vx, vy] (a początek 0, 0 - początek układu współrzędnych) - prędkość kulki

    2) Przeskalowuję sobie mój wektor, umieszczając go tak, by jego koniec znajdował się w miejscu zderzenia kulki ze ścianą.

    początek wektora: x0 - vx; y0 - vy, koniec: x0, y0.

    3) Korzystamy ze wzoru na prostą, na której leżą dwa punkty(licealne, do poszukania w internecie jeśli nie znasz), otrzymujemy prostą, na której leżą x1, y1, x2, y2. Potem, korzystając z kolejnego wzoru, otrzymujemy prostą prostopadłą do niej przechodzącą przez punkt zderzenia.

    4) Teraz odbijamy symetrycznie początek wektora względem naszej prostej prostopadłej - kolejny wzór licealny, może być przydatne wcześniejsze poprowadzenie prostej równoległej do naszej początkowej prostej zawierającej ścianę, bo na tej nowej prostej znajduje się docelowy koniec wektora(rysunek).

    Otrzymane współrzędne to koniec wektora. Początek wektora zaś to punkt zderzenia.

    5) Przeskalowujemy wektor spowrotem, by jego początek pokrywał się z początkiem układu współrzędnych.

     

    To wszystko. Proponuję nie robić obliczeń na bieżąco zgodnie z powyższym planem działania, tylko wyprowadzić sobie algebraicznie ostateczne wzory na Vx, Vy(ostateczne współrzędne wektora prędkości, które nas interesują) i zobaczyć co się stanie. Unikniemy dużo niepotrzebnych obliczeń.

     

    Pozdrawiam

  3. A zasadę ich działania doskonale rozumiem(póki co),

    Wygląda na to, że jednak nie - gdybyś doskonale rozumiał zasadę ich działania, nie zadawałbyś powyższych pytań. ;)

    Ja Ci powiem jedno - to jest Twoja decyzja! Ty tworzysz grę, Ty wybierasz. Możesz oczywiście żywcem skopiować czyjąś pracę ale w ten sposób wstrzymujesz swój rozwój, nic kreatywnego nie zrobisz.

    Jeśli wiesz, jak działają TCP/UDP, to pomyśl, do jakich czynności zastosować jedno, a do jakich drugie. I zrób tak, a jeśli po testach uznasz, że lepiej byłoby inaczej, zrób inaczej :)

  4. Przyjrzałem się nieco bliżej temu rozwiązaniu i nie ma ono zbytniego sensu.

    Popatrz przykładowo na to:

    void Delete(size_t el)
        {
            zmienna[el] = NULL;
        }

    Dane pole nie jest usuwane, "wycinane", a jedynie zerowane. Co, jeśli użytkownik struktury chciałby mieć element o wartości zero? Wtedy metoda Add(type var) rozumiałaby to tak, że to pole nie istnieje(== NULL). Oprócz tego "zmienna[el] = NULL" nie powinno się skompilować w przypadku klasy takiej jak Player.

    Ja użyłbym tablicy wskaźników:

    private:
        Type** zmienna;

    Dzięki temu będziemy w stanie odróżnić "stan" pola(istnieje bądź nie) od jego wartości.

  5. Jeśli masz tylko jednego NPC, to tak jak gnysek mówił.

    Na samym początku definiujesz zmienną np. bool isbroken=0; W ifach dajesz break; isbroken=1; za wewnętrznym forem dajesz if(isbroken) break;

     

    Jeśli jedna globalna funkcja steruje większą ilością NPC, to sprawa jest bardziej skomplikowana. Ja bym zrobił klasę dla NPC a każdy z nich byłby obiektem, który "myśli" samodzielnie.

    Skoro jednak chcesz zostawić obecny sposób poruszania się, to trzeba pokombinować. Przykładowo, zrób sobię tablicę bool zmienna[][] o wielkości takiej samej, jak mapa. Wartości są ustawiane na false na początku wykonywania setmove(). W ifach dajesz dodatkowy warunek - !zmienna[a], co oznacza, że NPC stojący w tym miejscu jeszcze się nie poruszył. W momencie ruchu ustawiasz dane miejsce w zmienna[][] o współrzędnej docelowej na true. Przykładowo w pierwszym ifie dopisujesz zmienna[a-1]=true; i tak dalej.

  6. Zakładam, że x, y to współrzędne gracza?

     

    Oddalają się, bo tak ich zaprogramowałeś. Na przykładzie pierwszego ifa:

    if (a==y+1 or a==y+2 or a==y+3 or a==y+4)
    ...
    lvl[a][b]=0;
    lvl[a+1][b]=2;

     

    Jeśli npc jest przesunięty od gracza o 1/2/3/4 poziomy w dół(a==y+1 itd.), to npc przesuwa się o 1 poziom w dół(lvl[a+1]=2)... Czyli jeszcze bardziej się oddala.

    A teleportują się dlatego, że wykonujesz pętlę. Za każdym razem, kiedy powyższe warunki są spełnione, npc porusza się. Dajesz im taką możliwość kilka razy w ciągu wykonywania funkcji setmove()...

  7. Nie mam porównania, bo uczyłem się tylko z jednego kursu - http://xion.org.pl/productions/texts/coding/megatutorial/

    Od strony technicznej. Potem pozostaje nauka poszczególnych bibliotek(które będą Ci potrzebne) i różnych informatycznych zagadnień, już luźno związanych z samym językiem. Materiałów na internecie jest pełno, gdy zobaczysz w czyimś kodzie słówko, z którym się nie spotkałeś, po prostu wklepujesz je w google.

  8. struct a;
    struct b {
        a* parent;
        void bla( a* p );
    };
    struct a {
        int val;
        b* son;
    };
    
    void b::bla(a* p)
    {
        p->val = 4;
    };

     

    Jeśli chcesz, żeby "bla" była funkcją inline(a taką jest, kiedy definiujesz ją w środku klasy/struktury), to dopisz z przodu inline.

    inline void b::bla(a* p)
    {
        p->val = 4;
    };

  9. asddd.png

    Kompilacja przebiega pomyślnie. Jedyne, co zrobiłem, to dodanie funkcji main.

    Jaka jest treść tego błędu?

     

     

    PS. Jeszcze coś, do czego bym się przyczepił:

    void push_street( stStreet * p ) {

    street.push_back( p );

    street.back()->parent = this;

    }

    Po co tak? :P Trochę naokoło. Nie lepiej zrobić

    p->parent = this;
    street.push_back(p);

    ?

     

    No i kolejna sprawa, tak jak mówił Tymon - używaj klas. Oczywiście na upartego możesz używać struktur, tylko w odpowiednich miejscach wstaw specyfikatory private/public/protected. Chodzi o bezpieczeństwo - wszystkie elementy klasy, które mogą być prywatne, powinny takie być. Dostęp do nich udzielaj metodami.

  10. Używam Code::Blocks z kompilatorem GCC i nie ma problemów.

    Jeszcze przykładowy kod prezentujący, że powyższa metoda działa:

    //bla bla
    #include <iostream>
    using namespace std;
    //bla bla
    
    int main()
    {
        town a;
        cout << &a << endl;
        a.push_street(new street);
        cout << a.streets.back()->parent << endl;
    };

     

    Konsola pokaże dwa takie same adresy.

  11. Jedyną różnicą między klasą a strukturą w c++ jest domyślny specyfikator dostępu, więc różnicy nie ma.

    Struct ma też wskaźnik this, tak samo jak class, więc w czym problem?

    #include <vector>
    
    struct town;
    
    struct street {
        town* parent;
    };
    
    struct town
    {
        std::vector<street*> streets;
        void push_street(street* p)
        {
            streets.push_back(p);
            p->parent = this;
        }
    };

  12. A gdy przykładowo Twoje view_y/view_x znajduje się w rogu mapy... To czy przypadkiem w pewnym momencie nie próbujesz wykroczyć poza zakres pole_gry[]?

    Poza tym, tak jak CrackGM zauważył - bez sensu :P Albo użyj dwuwymiarowej tablicy, albo, jeśli chcesz koniecznie "spakować" mapę do jednowymiarowej tablicy, to: pole_gry[w*y+x], gdzie w - szerokość Twojej mapy, x, y - współrzędne, które aktualnie badasz.

  13. (przeciążenie funkcji przypisania dla każdego typu i sprawdzenie jego poprawności z ustalonym). A pobranie? C++ nie wybierze odpowiedniej funkcji według zmiennej wewnątrz klasy.

    1. Szablony

    2. rtti(typeid), potem switch Palnąłem głupotę, przecież dla void* to nie zadziała. Ale wystarczy podczas stworzenia zapisać sobie typ do zmiennej(tak jak u Ciebie - eType), potem użyć instrukcji switch i rzutować to na wskaźnik innego typu. Wtedy już da się skorzystać z RTTI czy innego mechanizmu.

     

    Można jeszcze inaczej: oddzielna struktura dla każdego typu(żeby za dużo nie pisać - szablony), chociaż rozwiązanie mało optymalne.

     

    po co?

    Program, który sam się przeprogramowuje? :P (pytanie do obeznanych: czy tak nie działają wirusy polimorficzne?)

  14. Ehh...nie lubię C++ :<

    Na szczęście jest na tyle elastyczne, że rozwiązanie zawsze znajdziesz.

    a na "zewnątrz" możesz sobie po prostu dodać string to tej zmiennej i wyświetlać ją jako nazwę.

    To jest myśl. Możesz zrobić sobie dynamiczną tablicę struktur. Struktury te będą się składać ze zmiennej właściwej o typie jaki sobie zażyczysz oraz z napisu który będzie tak jakby nazwą tej zmiennej.

    Tablica ta będzie opakowana w obiekt narzędziowy, który pozwoli Ci dowolnie zwiększać i zmniejszać wielkość tablicy(poprzez tworzenie nowej o większej/mniejszej wielkości, kopiowanie pamięci i usuwanie starej).

    I problem rozwiązany.

  15. To by się mijało z celem O_o

    Po to jest kasacja kont, żeby ludzie grali od nowa. Z tym że będzie trudniej.

    Osobiście nie będę grał w Almorę z jakimś małym exp i drop rate, bo wtedy zrobi się po prostu nudno. Nie byłoby co robić, tylko przez cały dzień bić bugi(ale chyba aż tak drastycznie expa nie zmniejszysz :P)

  16. Wszedłem z ciekawości na serwer. Gram obecnie magiem, 30 lvl. Admin powiedział o evencie "Kto zabije DarkGoda dostanie 10mln", akurat przechodziłem obok niego, a że postacie nie mają żadnej odporności na magie(nawet jeśli ma się lvl 60) to zabiłem go bez problemu, wystarczyło zaskoczenie. Jednak nie dostałem 10mln jak dotąd, jedyne co zarobiłem to wściekłość DarkGoda(pewnie jakaś zedytowana postać, admin dał dużo defa czy coś, nie spodziewali się tak szybkiej śmierci) :D Oszuści. Możliwe, że po prostu zbyt wcześnie wyszedłem z serwera, będę się jeszcze kłócił :P

  17. @Gnysek

    Nie wiem co powiedzieć. Wydaje mi się, że ekranem tak "rzuca"(kiedy się poruszam) niczym za dawnych projektorów. Trochę mnie oczy od tego bolą. Ale nie wiem, czy to może wina mojej karty graficznej, chociaż nigdzie indziej tak nie mam.

×
×
  • Dodaj nową pozycję...