Skocz do zawartości

Definiowanie zmiennych...


CuB3

Rekomendowane odpowiedzi

Witam! B)

 

To juz moje drugie pytanie dzisiaj. Chyba schodze na psy :boxed:

 

No ale przejdzmy do rzeczy. Otoz zainteresowala mnie dzisiaj jedna pewna rzecz. Mianowicie jak sprowadzic kilka obiektow do jednej zmiennej ale tak by byla ona zgodna z argumentem jednego obiektu. Istnieje taka mozliwosc?

 

Przykladowo:

zmienna = o1,o2,o3;

 

I jakas funkcja np:

instance_create(x,y,zmienna)

 

Jest jakas mozliwosc dokonania tak wielkiego czynu xD?

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chodzi o przechowywanie indeksów kilku obiektów w zmiennej i ich tworzenie GM nie oferuje czegoś takiego. Praktycznie jest to wykonalne, tak więc zapis:

objects = power( 2, object3 ) | power( 2, object5 ) | power( 2, object1 );

Odczyt:

n = 0;
while( objects != 0 )
{
     if( objects & 1 )
          instance_create( 0, 0, n );

     objects = objects >> 1;
     n += 1;
}

 

Wytłumaczyć zasadę działania?

Odnośnik do komentarza
Udostępnij na innych stronach

To wyjątkowo proste, potęgi liczby 2 mają swoje odpowiedniki w kodzie binarnym jako pojedyncza jedynka w określonej pozycji między zerami.

1 - 0000001
2 - 0000010
4 - 0000100
8 - 0001000

Tutaj tę pozycję określa wykładnik potęgi liczby 2, więc też wartość takiej liczby. Widzisz to?

 

Jak już wcześniej tłumaczyłem zasadę działania binarnego xor ( ^ ), tak też tutaj podobną zasadę można wykorzystać tylko, że z użyciem binarnego or ( | ). Pozwoli to nam wstawić jedynkę w określone miejsce i przypadkiem się jej nie pozbyć ( np. gdy będziemy przypadkowo używać dwóch takich samych indeksów obiektów - pamiętaj, że or mówi "jeśli jedna z dwóch liczb", a xor dodatkowo dokłada warunek "jeśli te liczby nie są równe" co nam jest kompletnie niepotrzebne ).

 

Teraz jeśli użyjemy binarnego or na dwóch lub kilku liczbach to otrzymamy coś takiego:

00000100 | 00010000 = 00010100
10000000 | 00000001 = 10000001
10000000 | 00000001 | 00010000 = 10010001

Rozumiesz?

 

Teraz, jeśli indeks obiektu jest liczbą to potraktujmy go jako wykładnik potęgi! Wtedy te 0 i 1 będą mówić jakie indeksy są w zmiennej, a ich pozycja powie nam jaki to indeks. :D

 

Dla przykładu:

/*
Obiekty i ich wartości indeksów:
obj_1 = 1
obj_2 = 2
obj_3 = 3
*/

zmienna1 = power( 2, obj_1 ) | power( 2, obj_3 );
Tłumacząc na nasze:
( 2 do potęgi 1 ) | ( 2 do potęgi 3 )
Czyli: 
2 | 8 = 10
Na bitach:
00000010 | 00001000 = 00001010

 

Teraz przydało by się zanalizować to co mamy. Musimy sprawdzić każdy z zapisanych bitów w zmiennej czy jest równy 1 i znaleźć też same pozycje jedynek. Jak sprawdzić czy w danej pozycji jest jedynka? Przyda nam się operator binarny and który pozwoli sprawdzić czy dana jedynka jest w zmiennej i oczywiście potęgi liczby 2. Zasadę działania and przedstawię tylko na przykładzie:

( 2 do 2 | 2 do 0 | 2 do 3 ) & ( 2 do 2 ) = ( 2 do 2 )
Co znaczy:
( 4 | 1 | 8 ) & 4 = 4
Co w binarnych wygląda:
( 00000100 | 00000001 | 00001000 ) & 00000100 = 00000100

Rozumiemy? Jeśli wskazanej jedynki by nie było to byśmy uzyskali po prostu 0.

Teraz potrzeba nam sprawdzić w jakiej pozycji są jedynki. Możemy generować każdą potęgę liczby 2:

for( n = 0; n < ilość_zapisanych_indeksów; n += 1 )
{
    p = power( 2, n );
    if( zmienna & p )
    {
        //Ta jedynka jest w zmiennej
    }
}

Ale dodajemy sobie dodatkową niewiadomą, czyli ilość_zapisanych_indeksów - chyba wiadomo co oznacza. Jakby ją znaleźć? Najlepiej jej w ogóle się pozbyć. Wiemy, że jeśli nie ma już żadnych jedynek w zmiennych to wartość zmiennej jest równa 0. To teraz jakby tak likwidować kolejno każdą z jedynek/zer na początku? Przyda się operator przesunięcia bitów oznaczany >> dla przesunięcia w prawo, oraz << dla przesunięcia w lewo. Ogólna zasada ich działania wygląda tak:

01010101 >> 1 = 00101010
01010101 >> 4 = 00000101
01010101 << 2 = 01010100

Rozumiemy?

Nam potrzebny jest tylko ten prawy by pozbywać się pierwszej 0/1 i musimy przesuwać tylko o 1. Tak więc kod wygląda następująco:

while( zmienna != 0 ) //Powtarzaj póki jest coś w zmiennej
{
    if( zmienna & 1 ) //Sprawdzamy zawsze tylko pierwszą jedynkę
    {
        //Ta jedynka jest w zmiennej
    }

     zmienna = zmienna >> 1; //Przesuwamy o 1
}

I tyle. Do określenia pozycji jedynki czyli i indeksu obiektu potrzeba nam tylko jednej zmiennej która będzie zwiększała swoją wartość co jeden krok. Czyli:

pozycja = 0; //Zaczynamy od 0
while( zmienna != 0 ) //Powtarzaj póki jest coś w zmiennej
{
    if( zmienna & 1 ) //Sprawdzamy zawsze tylko pierwszą jedynkę
    {
        //Ta jedynka jest w zmiennej
    }

     zmienna = zmienna >> 1; //Przesuwamy o 1
     pozycja += 1; //Zwiększamy też wartość zmiennej przechowującej pozycję
}

To wszystko czego nam potrzeba. Jak mówiłem pozycja określa indeks obiektu, tak więc patrząc na podany w moim powyższym poście przykład stwierdzamy, że jest poprawny. ;)

 

Pisałem najprościej jak umiałem i na szybko. :P

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...