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
Podstawy programowania
Autor Wiadomość
bonzaii 
Ja


Twoja ulubiona misja: Moja Własna :D
Wiek: 26
Dołączył: 21 Lip 2009
Posty: 16
Skąd: Bydgoszcz
Wysłany: 21-07-2009, 15:09   Podstawy programowania

Witam.

Jestem nowy, więc witam wszystkich ;)

Dawno temu grałem w colobota. Jakieś 3-4 lata temu. Większość zapomniałem, ale nadal programuje w innych językach. Chciałbym się nauczyć jak najwięcej wyciągnąć z programowania w tej grze bo to fajna zabawa - a ostatnio mi się nudzi :D
Kiedyś zrobiłem wszystkie wyzwania (prawie wszystkie :( ) ale sprawiały mi trudności.
Mam do was parę pytań.

1. Jak mogę zacząć współpracę 2 botów w trybie Master/Slave (matki i robola)? Chciałbym tylko prosty przykład, np: Matka wydaje rozkaz, żeby robot szedł w punkt A, a jak dojedzie to w pkt B, jak tam dojedzie to spowrotem pkt A (chodzi mi tylko o to, że nie wiem jak można wpływać programem jednego robota na program innego).

2. Czy istnieje możliwość napisania funkcji zwracającej parametry? Dla przykładu chciałbym napisać funkcję, która zwraca poziom naładowania baterii robota (wiem, że można inaczej - to przykład).

3. Czy jest możliwość wprowadzenia jakiś zmiennych (stałych?), które zapisywał by jeden robot, a inne mogłby by z nich korzystać? (np jeden robot podaje miejsce zbiórki, a inne korzystają z niego i szukają w pobliżu wolnego miejsca i się tam udają).

Nie proszę o gotowe kody bo i tak mi są nie potrzebne. Prosiłbym tylko o wyjaśnienie działania :)

W ogóle jestem pod wrażeniem umiejętności niektórych, a ten pomysł z Colobot RPG to już na prawdę szokuje :D Cieszę się, że powstało to forum, kilka lat temu nie mogłem nic takiego znaleźć w naszym ojczystym języku :)

Pozdrawiam
 
 
     
Schocker 
Wants cookies!


Twoja ulubiona misja: Hmm... All.
Pomógł: 3 razy
Wiek: 22
Dołączył: 31 Maj 2009
Posty: 177
Skąd: Wadowice
Wysłany: 21-07-2009, 20:42   

Jeśli chodzi o pytanie nr 1, to mi się wydaje, że można by to robić przez pliki. Master zapisuje coś do pliku, a slave z niego to odczytuje. Ale takich programów master/slave nie pisałem, więc jest to taki mój pierwszy pomysł. ^^;

Hm. To może być skomplikowane, nie mam aż takiej wiedzy, niemniej jednak ja bym to zrobił tak:
Kod:

if (whatever >,<,== null, 0, 1, 0.1 whatever)
{
message(whatever);
}

I następny if, ale jest z tym dużo roboty. Może ktoś bardziej wtajemniczony zna prostszy sposób. ;)
_________________
But there's no sense crying over every mistake, you just keep on trying 'till you ran out of cake -GlaDOS
 
 
     
pipok
Gość


Wysłany: 22-07-2009, 06:58   Re: Podstawy programowania

bonzaii napisał/a:
2. Czy istnieje możliwość napisania funkcji zwracającej parametry?
Chyba nie zrozumiałem pytania, bo odpowiedź jest oczywista i zawarta w pomocy Colobota.
Cytat:
Funkcja może również zwrócić wynik przy użyciu instrukcji return. Jednakże powinna być wówczas zadeklarowana nie jako void, ale powinna mieć określony typ:
Kod:
float Średnia( float a, float b )
{
  return (a+b)/2;
}
 
     
pipok 


Dołączył: 24 Cze 2009
Posty: 53
Wysłany: 22-07-2009, 08:37   Re: Podstawy programowania

bonzaii napisał/a:
1. Jak mogę zacząć współpracę 2 botów w trybie Master/Slave (matki i robola)? Chciałbym tylko prosty przykład, np: Matka wydaje rozkaz, żeby robot szedł w punkt A, a jak dojedzie to w pkt B, jak tam dojedzie to spowrotem pkt A (chodzi mi tylko o to, że nie wiem jak można wpływać programem jednego robota na program innego).
To też jest omówione w Colobocie, w dziale "Wyzwania". Przykład żywcem z "Wyzwań", bot odbierający rozkazy rozumie tylko komunikaty move(N) oraz turn(N).
Bot-Master:
Kod:
extern void object::Remote( )
{
  SendOrder("move(10)");
  SendOrder("turn(90)");
  SendOrder("move(20)");
}

void object::SendOrder(string order)
{
  exchange list();
  while ( list.put(order) == false )
  {
    wait(1);
  }
}

public class exchange
{
static private string m_order = "";

  synchronized bool put(string order)
  {
    if ( m_order == "" )
    {
      m_order = order;
      return true;
    }
    else { return false; }
  }

  synchronized string get()
  {
    string ret = m_order;
    m_order = "";
    return ret;
  }
}

Bot-Slave:
Kod:
extern void object::Slave( )
{
  exchange list();
  string   todo;

  while ( true )
  {
    while ( true )
    {
      todo = list.get();
      if ( todo != "" )  break;
      wait(1);
    }
    if ( strfind(todo, "move") == 0 )
    {
      move(strval(strmid(todo,5)));
    }
    if ( strfind(todo, "turn") == 0 )
    {
      turn(strval(strmid(todo,5)));
    }
  }
}


Cytat:
3. Czy jest możliwość wprowadzenia jakiś zmiennych (stałych?), które zapisywał by jeden robot, a inne mogłby by z nich korzystać?
Za pośrednictwem zapisu-odczytu pliku lub wymiany komunikatów, jak wyżej.
 
     
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: 22-07-2009, 11:32   

Coś takiego wymyśliłem: http://www.colobot.yoyo.p...php?p=6042#6042
_________________
1Tbps Project && Telecomix Network

 
 
     
bonzaii 
Ja


Twoja ulubiona misja: Moja Własna :D
Wiek: 26
Dołączył: 21 Lip 2009
Posty: 16
Skąd: Bydgoszcz
Wysłany: 22-07-2009, 11:47   

Widziałem to i na podstawie tego uczę się klas i innych ciekawych rzeczy. Wykonałem wszystkie ćwiczenia, ale żadnych wyzwań bo widzę, że to te same co ćwiczenia. Czy jakbym wykonał te wszystkie wyzwania to by się pojawiły jakieś nowe? Trudniejsze? Pytanie nr 2 już nie aktualne :P Prostą komunikację między botami na razie opanowałem za pomocą klasy publicznej z wartościami STATIC :) Zapisywanie informacji na wypadek "padnięcia programu" zrobiłem w najprostszy dla mnie sposób - Stacja Przekaźnikowa :D hehe. Sporo się od wczoraj nauczyłem. Dziękuję za waszą pomoc!

PS: pipok: Twojej pomocy nie kumam :D Tzn ten kod co napisałeś to na dzień dzisiejszy jeszcze dla mnie czarna magia, ale kto wie, może dzisiaj się coś zmieni :)
 
 
     
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: 22-07-2009, 14:37   

Te wyzwania z klasami to są w patchu od Epsiteca bodajże, ale może są w patchu nieoficjalnym (nie pamiętam).
_________________
1Tbps Project && Telecomix Network

 
 
     
pipok 


Dołączył: 24 Cze 2009
Posty: 53
Wysłany: 22-07-2009, 16:56   

bonzaii napisał/a:
PS: pipok: Twojej pomocy nie kumam :D Tzn ten kod co napisałeś to na dzień dzisiejszy jeszcze dla mnie czarna magia, ale kto wie, może dzisiaj się coś zmieni :)
To nie jest bardzo trudne.
Bot Wykonawca powinien robić trzy rzeczy:
    1. Odbiór. Pobrać komunikat "z zewnątrz" do zmiennej łańcuchowej todo:
    Kod:
    todo = list.get();
    2. Interpretacja. Przeanalizować otrzymany łańcuch znaków:
    Kod:
    if ( strfind(todo, "move") == 0 )  // komunikat to instrukcja przemieszczenia sie
    {
      parametr = strval(strmid(todo,5)); // od 5 znaku zaczyna się liczba, o ile sie przemiescic
    3. Reakcja. Podjąć odpowiednie działanie:
    Kod:
      move(parametr);
    }
Mam nadzieję, że to jest proste?

Teraz część dla bota Rozkazodawcy. Robi tylko jedną rzecz: wydaje rozkazy, w postaci dopasowanej do tego, co potrafi "zrozumieć" Wykonawca.
Kod:
SendOrder("move(10)");
Wydanie rozkazu zawartego w zmiennej łańcuchowej order realizuje funkcja
Kod:
void object::SendOrder(string order)
{
  exchange list();
  while ( list.put(order) == false )
  {
    wait(1);
  }
}
Pierwsza linijka tworzy obiekt o nazwie list, klasy exchange. Zwróć uwagę, że Wykonawca także korzysta z obiektu tej klasy! To jest ich wspólny "kanał komunikacyjny".
Następnie Rozkazodawca próbuje w pętli, do skutku, umieścić w obiekcie swój rozkaz. Dlaczego próbuje do skutku? Bo klasa, która jest "nośnikiem rozkazów", pozwala na przechowanie tylko jednego rozkazu. Można więc wydać rozkaz tylko wtedy, kiedy poprzedni zostanie odczytany i wymazany z nośnika.

Na koniec "kanał komunikacyjny", czyli publiczna klasa służąca do wymiany komunikatów. Na początku mamy w niej statyczną zmienną prywatną.
Kod:
static private string m_order = "";
Dzięki temu, że klasa jest publiczna, jest dostępna dla wszystkich botów, dzięki temu, że zmienna wewnątrz klasy jest statyczna, jej wartość pozostaje wspólna dla botów, które posłużą się tą klasą - to jest sedno rozwiązania. Każdy bot (i obcy ;) ) ma dostęp do tej zmiennej, tej samej zmiennej, do tego samego miejsca w pamięci. Z kolei dzięki temu, że zmienna jest prywatna dla klasy, unikamy ryzyka manipulowania nią przez kod spoza klasy.
Prócz zmiennej klasa zawiera dwie metody (funkcje), jedną do umieszczania rozkazu (łańcucha znakowego) w zmiennej m_order, a drugą do pobierania rozkazu ze zmiennej m_order (i usuwania go).
Umieszczenie rozkazu
Kod:
synchronized bool put(string order)
  {
    if ( m_order == "" )
    {
      m_order = order;
      return true;
    }
    else { return false; }
  }
to po prostu wpisanie jego wartości do naszej statycznej zmiennej m_order. Zauważ, , że jest wykonywane tylko wtedy, kiedy m_order nie jest łańcuchem pustym. Jeśli jest inaczej, to znaczy, że m_order przechowuje nadal poprzedni rozkaz, wciąż nie odczytany. Wówczas funkcja zwraca fałsz, sygnalizując w ten sposób niepowodzenie.

Pobranie rozkazu:
Kod:
synchronized string get()
  {
    string ret = m_order;
    m_order = "";
    return ret;
  }
}
jest jeszcze prostsze: funkcja zwraca dotychczasową zawartość m_order, ale jednocześnie ją "czyści" (przypisuje zmiennej łańcuch pusty). Rozkaz został odebrany, dotarł do odbiorcy, więc znika.

Obie metody, put() i get, występują w klasie jako "synchronized", co zapewnia, że w danym momencie tylko jeden bot na raz może je wykonywać. Zapobiega się w ten sposób równoczesnemu wykonywaniu tych funkcji przez dwa różne boty, co miałoby trudne do przewidzenia skutki (oba dobierałyby się do zmiany wartości tej samej zmiennej).
 
     
bonzaii 
Ja


Twoja ulubiona misja: Moja Własna :D
Wiek: 26
Dołączył: 21 Lip 2009
Posty: 16
Skąd: Bydgoszcz
Wysłany: 22-07-2009, 17:16   

Z tego wszystkiego nie rozumiem 'exchange' ?

@Edit:
I dlaczego skoro cyfra to dopiero 6 znak w stringu o wartości:
Kod:
move(5)

mimo to jest odbierana przez strval jako znak 5 ?

@Edit2:
Czyżby znak 'm' w tym stringu jest znakiem 0? Zapomniałem, że w programowaniu listy są liczone od 0 :P
 
 
     
pipok 


Dołączył: 24 Cze 2009
Posty: 53
Wysłany: 22-07-2009, 19:30   

bonzaii napisał/a:
Z tego wszystkiego nie rozumiem 'exchange' ?
To po prostu nazwa utwozronej klasy. Tutaj jest użyte w definicji klasy:
Kod:
public class exchange
{
  static private string m_order = "";
  ...
}
A tutaj w utworzeniu instancji tej klasy (o nazwie list):
Kod:
exchange list();
Po angielsku "exchange" oznacza "wymiana". Bez znaczenia, jak nazwiesz. Słowo "exchange" możesz w obu programach zamienić na np. "komunikaty".

bonzaii napisał/a:
Czyżby znak 'm' w tym stringu jest znakiem 0? Zapomniałem, że w programowaniu listy są liczone od 0 :P
Owszem. W języku Colobota znaki w łańcuchu są numerowane od zera, tak samo, jak elementy tablicy (łańcuch jest tablicą znaków). Sporo języków programowania tak ma, między innymi C++ i Java, do których język botów jest najbardziej podobny.
 
     
Wyświetl posty z ostatnich:   

Wersja do druku

Skocz do:  

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