Gotrek - mój pierwszy większy projekt w moim własnym języku (chomik)

0

Cześć,

Jeśli macie ochotę możecie zerknąć na kod mojego programu "Gotrek":
link

Na razie nie ma go na githubie, to tylko taka wersja, żeby się zorientować jak się pisze w chomiku. Gotrek jest napisany w sdl_chomiku, żeby odpalić wystarczy go skonfigurować a potem wydać komendę "make". Nie jest przeznaczony do instalowania. Wymaga oczywiście chomika, dostępnego z link.

Jeśli pamiętacie w kwietniu tego roku rozpocząłem wątek "Protytyp ciekawego i minimalistycznego języka programowania". To jest język oparty na dwóch konstrukcjach - przypisaniu i wykonaniu kodu. W szczególności nie ma instrukcji pętli ani instrukcji warunkowej. To oczywiście tylko eksperyment. Ale ciekawy.

Po pojawieniu się strony tytułowej należy nacisnąć return, wówczas pojawi się coś takiego:

Screenshot_20220915_231649.png

Ta strzałka obok obrazka chomika służy do wyboru opcji, można nią sterować klawiszami "up" i "down", a "return" służy do jej aktywowania. Po rozpakowaniu zobaczycie kilka katalogów, m.in. "chomik" i "sdl_chomik" - tam znajduje się kod gry. Na razie ma ok. 21kB.

Najciekawsze są rekurencyjne typy wyliczeniowe. Można je znaleźć w pliku "chomik/user_defined_types.chomik". Tam jest m.in. taki kod:

type information={(X:person) is in (Y:place),
                    (X:person) has function (Y:function), 
                    (X:person) has a (Y:weapon),                 
                    (X:person) can see (Y:person),
                    (X:person) can hear (Y:person),
                    (X:person) has told (Y:person) that (Z:information),
                    (X:person) has asked (Y:person) to (Z:action),
                    (X:person) has asked (Y:person) what is his function,
                    (X:person) has asked (Y:person) what is his weapon,
                    (X:person) has asked (Y:person) whether he is a liar,
                    (X:person) thinks that (Y:information),                    
                    (X:person) is a liar};
                    
type action={no_action,                             # does not depend on anything
            goto (X:place),                         # depends on a place (that must be connected)
            tell (X:person) that (Y:information),   # depends on a person (that must be present)
            ask (X:person) to (Y:action),           # depends on a person (that must be present)
            ask (X:person) what is his function,    # ...
            ask (X:person) what is his weapon,
            ask (X:person) whether he is a liar,
            attack (X:person),
            propose (X:person) to exchange weapons
            };

Ważne jest to, że niektóre akcje zależą od informacji, a niektóre informacje od akcji. Czyli mamy cykl zależności.

2

Nic z tego nie rozumiem. ale gratuluję pomysłu i woli walki !

No i "chomik" brzmi dumnie ! :) :) :)

0

To jest jakiś pattern matching?

0
LukeJL napisał(a):

To jest jakiś pattern matching?

Wydaje mi się, że nie.

W chomiku centralnym pojęciem są rodziny zmiennych. Kod jest wbudowanym typem, można mieć zmienne typu kod. Pętle są implicite, np. taki kod powoduje utworzenie "atrybutów" obiektów klasy "person" (to najbliższe jak można to nazwać w C++):

type person={Gotrek, Gerrudir, Gwaigilion};
expand(1);
variable (X:person) strength:integer;

let variable (X:person) strength=value integer 10;  # wszyscy mają siłę 10, tu jest niejawna pętla
let variable Gotrek strength=value integer 5;       # a teraz Gotrek ma siłę 5, pozostali nadal 10

Dla dwóch i więcej placeholderów (tj. wyrażeń (X:nazwa_typu)) pętla chodzi po iloczynie kartezjańskim wszystkich typów, czyli mamy coś jakby atrybuty par albo innych krotek (tuples), np.:

variable (X:person) likes (Y:person):boolean;
let variable (X:person) likes (Y:person)=value boolean false;  # teraz nikt nikogo nie lubi
let variable Gotrek likes (A:person)=value boolean true;       # teraz Gotrek lubi wszystkich

Za pomocą analogicznej konstrukcji (rodziny zmiennych typu code) można uzyskać zachowanie jakby instrukcji warunkowej a nawet polimorfizm. Na przykład:

variable (X:person) say hello:code;
let variable (X:person) say hello = value code { execute <print "hello">; }; # teraz wszyscy umieją się przywitać
execute <(X:person) say hello>; # dostaniemy trzy razy "hello"
let variable Gotrek say hello = value code { execute <print "hi">; };        # teraz zmieniliśmy jak się wita Gotrek
execute <(X:person) say hello>; # dostaniemy raz "hi" i dwa razy "hello"

Piszę dokumentację chomika (po angielsku), jeszcze nie jest gotowa.

1

Gotrek jest już na Githubie, zawiera już 37kB kodu w chomiku/sdl_chomiku.
link

W związku z sugestią @obscurity minimalnie zmieniłem składnię chomika, teraz "variable" po "let" jest opcjonalne, "execute" też jest opcjonalne. Trochę łatwiej się pisze.

Gra nie jest jeszcze gotowa. Najbardziej mi zależy na pokazaniu tego, co jest unikalne w chomiku, a mianowicie zastosowania dla rekurencyjnych enumeracji. Znajdziecie je w pliku Gotreka: chomik/user_defined_types.chomik. Chodzi zwłaszcza o "information" i "action".

Nie ma w tym żadnego AI, każda postać dostaje do wyboru pięć opcji ruchu, użytkownik wybiera opcję dla Gotreka (górne okienko, strzałka), a NPC wybierają opcje losowo. Na razie działa tylko przechodzenie z miasta do miasta i zaatakowanie kogoś. Pod okienkiem z wyborem opcji jest prosta animacja.

Na dole jest okienko, w którym są informacje trybu "god mode", tj. takie, które docelowo nie będą dostępne dla gracza. To tylko do testowania. Usunę to kiedyś.

Bardzo by mnie zmotywowało, gdybyście napisali, że ktoś skompilował chomika i odpalił Gotreka. Może być krytyka, tylko bez przesady, bo ktoś napisał, że nie umiem pewnie nic poza C++, albo, że wymyśliłem na nowo Lispa. Ostrzegam, że wszystko sobie biorę do serca ;))))

Nie mówię, że musicie wszyscy przesiąść się na chomika, ale mam nadzieję Was przekonać do samej idei tego języka. Najpiękniejsze w nim są domyślne iteracje. Brak jest instrukcji warunkowej, brak instrukcji pętli, struktur/klas itp. Wszystkie zmienne są globalne (wiem, to okropne).

0

Gotrek (link) ma już 65kB kodu. Mogę powiedzieć, być może niezbyt bezstronnie, że w chomiku pisze się dość przyjemnie.

Mam już w głowie zarys fabuły gry. Akcja toczy się w XVII wieku, w Rzeczypospolitej. No, powiedzmy w alternatywnej rzeczywistości, bo Gdańsk, Poznań i Wrocław należą do nas. Nazwy miast da się łatwo zmienić, można też dodać nowe. W grze bierze udział czterech krasnoludów, tytułowym bohaterem steruje gracz, reszta to NPC. Krasnoludy mogą się nawzajem atakować, zadawać sobie pytania, odpowiadać na nie, składać propozycje, akceptować je lub nie. Za każdą udaną wymianę będą dostawać trochę punktów (zmienię to na "dukaty"). Na razie premiowany jest tylko wygrany pojedynek. Można być kłamcą - wtedy będzie premia za wciskanie rozmówcy fałszywych informacji, tylko trzeba uważać, żeby nie wpaść. Po uzbieraniu pewnej ilości dukatów (czy może lepiej liczyć to w tysięcach dukatów) można dać łapówkę (najlepiej w Warszawie), żeby dostać urząd. Urzędy to "cześnik", "krajczy", "kasztelan" itp. Takie staropolskie. Acha - po wręczeniu łapówki dostaje się losowy urząd (albo nie, przy czym jeśli jest za mała, to ryzykuje się grzywnę a może i odsiadkę w lochu). Po tym jak jeden z krasnoludów zaliczy wszystkie urzędy gra się kończy (i krasnolud zostaje mianowany królem).

Miasta są połączone (tworzą graf nieskierowany), każdy krasnolud wybiera z tego co mu przyjdzie do głowy (NPC wybierają losowo). Taka gra. Może dorzucę do sdl_chomika bibliotekę SDL2_mixer, żeby dodać muzykę do gry.

title.png

0

Na razie utknąłem na zbudowaniu "chomik"-a
Na MSYS2 taki błąd

configure checking for SDL2/SDL.h
configure result: yes
configure checking for IMG_Load in -lSDL2_image
configure gcc -o conftest.exe -g -O2 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/SDL2 -Dmain=SDL_main -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/SDL2 -Dmain=SDL_main conftest.c -lSDL2_image -lSDL2 >&5
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): in function main': C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to WinMain'
collect2.exe: error: ld returned 1 exit status
configure $? = 1
configure: failed program was:
| /* confdefs.h /
| #define PACKAGE_NAME "chomik"
| #define PACKAGE_TARNAME "chomik"
| #define PACKAGE_VERSION "0.0.6"
| #define PACKAGE_STRING "chomik 0.0.6"
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define PACKAGE "chomik"
| #define VERSION "0.0.6"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define LT_OBJDIR ".libs/"
| #define HAVE_LIBSDL2 1
| #define HAVE_SDL2_SDL_H 1
| /
end confdefs.h. /
|
| /
Override any GCC internal prototype to avoid an error.
| Use char because int might match the return type of a GCC
| builtin and then its argument prototype would still apply. */
| #ifdef __cplusplus
| extern "C"
| #endif
| char IMG_Load ();
| int
| main ()
| {
| return IMG_Load ();
| ;
| return 0;
| }
configure result: no
configure error:
The SDL2_image library not found. Check that it is installed on your system. If it is not, download and install it
(preferably using your configuration manager - i.e. the application called Add/Remove Programs or something like yum or dnf.)
Remember to install the DEVEL version. If it is installed elswehere you can run the script "configure" with the option --libdir=DIR.
Execute "configure -h" for more info.

A tu ten problem opisany w innym projekcie ktory uzywa SDL2
https://stackoverflow.com/questions/32342285/undefined-reference-to-winmain16-c-sdl-2#32343111
ale jak ustawić #define SDL_MAIN_HANDLED dla testujacego SDL2_image w configure to ja nie mam pojecia , uzywam tylko cmake

0
Adamek Adam napisał(a):

Na razie utknąłem na zbudowaniu "chomik"-a

Udało mi się zbudować na linuksie (przy użyciu mingw32). Tutaj jest archiwum zip link, zawiera trzy pliki:

chomik.exe
sdl_chomik.exe
README.txt

W README.txt jest lista potrzebnych DLLek (jest ich aż 11). Wszystkie powinny być pod 32 bity.

Sprawdziłem pod Windowsem i pod Wine na Linuksie, gotrek działa. Trzeba wejść do katalogu sdl_chomik w rozpakowanym archiwum gotreka i odpalić:

..\..\sdl_chomik.exe game.sdl_chomik

(Oczywiście założyłem, że dwa katalogi wyżej jest ten sdl_chomik.exe i DLLki).

0

Jestem bardzo wdzięczny za reakcje (rzadkie!). Dzięki Wam pojawił się chomik pod Windows i sandbox (link). Pomyślałem, że może odpowiem na pytanie dlaczego właściwie gotreka lepiej jest pisać w chomiku niż np. bezpośrednio w C++. Otóż w gotreku, w pliku chomik/user_defined_types.chomik są zdefiniowane akcje i informacje jak już o tym pisałem. Teraz je rozbudowałem, jeden z testów (odpalcie "make check") sprawdza ile jest akcji a drugi ile jest informacji. Obecnie akcji jest 1086, a informacji 2188. W tym samym pliku są zdefiniowane trzy wartości dla typu tense (past, present, future). Na przykład taki enum:

(X:person) is in (T:tense) in (Y:place)

jest rozwijany do informacji "Gotrek is in past in Krakow", "Gotrek is in future in Warszawa" itd. co w przełożeniu na polski oznacza "Gotrek był w Krakowie", "Gotrek będzie w Warszawie". To rozwijanie w C++ nie istnieje, trzeba by na piechotę dopisać kawałek kodu, który w chomiku produkuje iloczyn kartezjański możliwych zbiorów (person x tense x place).

W pliku chomik/persons_decisions_generate.chomik dla każdej osoby (person) jest generowane pięć możliwych decyzji. Każda z akcji wybrana jako decyzja nr.x należy do jakiejś klasy akcji. Chomik przywraca właściwe znaczenia wielu słowom. Np. słowo klasa akcji oznacza po prostu zbiór akcji, jest do tego specjalny enum:

type action_class={ actions that do not depend on anything, 
                    actions that depend on a place, 
                    actions that depend on a person proposals,
                    actions that depend on a person answers,
                    actions that depend on a person others};

Te enumy są tylko enumami, nie mają nic wspólnego z pojęciem klasy z OOP. Są one używane do generowania możliwych decyzji - najpierw generuje się losowo klasę, załóżmy że jest to - "actions that depend on place", Wówczas wybiera się tylko miejsca do których jest połączenie z miejsca, w którym znajduje się dana osoba, np. dla Krakowa będzie to Warszawa i Wrocław. No i możliwa decyzja może być "idź do Warszawy"/"idź do Wrocławia". Z kolei akcje zależne od osób mają trzy klasy - bo są trzy możliwe fazy gry:

game_phase_type={asking phase, answering phase, moving phase}

W fazie "asking phase" wybierane są tylko takie akcje, które należą do subklasy (subklasa do oddzielny enum), załóżmy, że wylosowaliśmy jako osobę Pregora - sprawdzamy czy dana osoba jest obecna tam gdzie postać, dla której generujemy możliwe decyzje. Ostatecznie możemy wpaść na pomysł, żeby wybrać akcję z rodziny:

ask (X:person) what is in (T:tense) (Y:person) function

Na przykład "ask Pregor what is in past Gerrudir function" - czyli "spytaj Pregora jaki urząd pełnił Gerrudir". Zauważcie, że taki chomikowy enum to zwykły ciąg identyfikatorów, na przykład "actions that do not depend on anything", i jako taki może nam posłużyć do wyboru kodu z rodziny o którą nam chodzi. Czyli zamiast ifa w pseudokodzie:

if (selected_class == "actions that do not depend on anything")
{
   <generate possible decisions for the current person and action class actions that do not depend on anything>;
}
else
if (selected_class == "actions that depend on a place")
{
   <generate possible decisions for the current person and action class actions that depend on a place>;
}
else
...

... możemy napisać po prostu:

<generate possible decisions for the current person and action class <selected_class>>;

Możecie sprawdzić, że tego rodzaju wybór kodu jest dokonywany w pliku chomik/persons_decisions_generate.chomik (linia 160):

<generate possible decisions for the current person and action class <current action class>>;

Za każdym razem jak wszystkie postaci wykonają ruch jest ustawiana kolejna faza, przy czym po "moving phase" następuje znowu "asking phase". W "asking phase" można zadawać pytania, lub składać propozycje. W drugiej fazie - answering phase - można reagować na złożone propozycje, odpowiadać na pytania. W trzeciej fazie można się przemieszczać do innych miast.

Następnie w pliku chomik/make_decisions.chomik decyzje są podejmowane - każdy NPC wybiera decyzję losowo (losując numer 1 do 5 - one nie są w ogóle inteligentne), tylko dla Gotreka nadpisuje się decyzję zgodnie z tym co wybrał gracz - w górnym okienku. To się dzieje w pliku chomik/decisions_make.chomik.

Generalnie ten sposób identyfikacji kodu lub jakichś wartości innych typów jest bardzo silny. Jest w ogóle możliwy dlatego, że w Chomiku nazwą mogą być nie tylko identyfikatory, ale ciągi identyfikatorów, poprzetykane literałami i placeholderami. W języku takim jak C++ żeby uzyskać tą samą funkcjonalność trzeba pisać ify, switche lub redefiniować wirtualne metody. I i tak jest słabszy. Chomik nadal jest tylko zabawką (nie ma w nim nawet mnożenia, czy otwierania plików do czytania), ale wydaje się, że ma bardzo duży potencjał. Wiążę duże nadzieje zwłaszcza z tymi rekurencyjnymi enumeracjami - np. gdy Gotrek powie Gerrudirowi, że Pregor był w Krakowie, to później może komuś innemu (Gwaigilionowi) powiedzieć o tym i sprawić, że Gwaigilion będzie myślał, że Gotrek powiedział Gerrudirowi, że ... Jest tu jawna rekurencja. Oczywiście Chomik nie dopuszcza nieskończonej rekurencji. Ale i tak jest fajny, Dawaliśmy się, że tak powiem, zbyt długo wodzić za nos matematykom, którzy mają mało fantazji. Mam na myśli kopiowanie zapisu matematycznego do programowania. Chomik zrobi z tym porządek ;)))

Jeszcze taka refleksja - wydawało mi się pierwotnie, że typy "range" czyli np. 1..10 są niepotrzebnie związane z tą samą składnią co zwykłe enumy. Ale już tak nie myślę. W istocie mają z enumami wiele wspólnego - tyle, że jest zadany z góry algorytm jak generować kolejne nazwy w takich enumeracjach. Bo w gruncie rzeczy literał 10 jest nazwą, nazwą liczby 10 w systemie dziesiątkowym, a jednocześnie nazwą liczby 2 w systemie dwójkowym itd. Jest nazwą i niczym więcej.

1

A dlaczego make a nie cmake ?
Projekt ma tyle lat że jak zaczynał to jeszcze nie było cmake ?

0
Adamek Adam napisał(a):

A dlaczego make a nie cmake ?
Projekt ma tyle lat że jak zaczynał to jeszcze nie było cmake ?

Nie rozważałem cmake'a, bo go nie znam. Używałem, owszem, ale jako konsument. Autotoolsy dają mi wszystko co potrzebuję - wiem jak skompilować bibliotekę, dodać ją do programu, zrobić testy, dystrybucję itd. Chętnie się nauczę cmake, poczytam sobie i poćwiczę. Zawsze coś nowego.

Chomika zacząłem 3 kwietnia 2022, czyli ma dopiero kilka miesięcy. Gotreka 13 września 2022. Pewne ficzery, które są w chomiku (rekurencyjne enumeracje) napisałem na potrzeby innego mojego projektu - z AI - trygława. Trygław nie jest jeszcze skończony, jego poprzednikami są Perkun i Svarog. Są oparte o pewien algorytm optymalizacji, moje odkrycie, tylko nie znam podstaw marketingu i popularyzacja tego mi ciężko idzie ;)))

1

Mam parę nowości w "Gotreku". Zauważyłem, że pewne obliczenia są niepotrzebnie robione w runtime, a mogłyby być robione tylko raz. Teraz w katalogu "generators" są skrypty, które generują dwa pliki w katalogu "generated". Te pliki to list_of_actions.chomik i list_of_informations.chomik. Są inkludowane z normalnym kodem, dzięki nim Gotrek jest trochę szybszy.

W sumie (razem z testami, dodatkowymi skryptami, generatorami i kodem wygenerowanym) Gotrek ma już 68kB,

W grze są trzy fazy - asking, answering i moving. Pierwsza faza umożliwia zadanie pytania, albo sformułowanie propozycji obecnym NPC. Druga faza jest przeznaczona do udzielania odpowiedzi, odmowy lub zgody na propozycje. Trzecia faza służy do ruchu. Po niej znowu następuje pierwsza. Atakować można w pierwszej i drugiej.

Najciekawsze w Gotreku (a zarazem w całym Chomiku) są, moim zdaniem, enumeracje. Mieszczą się w pliku chomik/user_defined_types.chomik. Na razie daleko jeszcze do końca, ale może kogoś zainspiruję do sięgnięcia po Chomika. Te enumeracje to jest największa, jak sądzę, zaleta Chomika. Przypomnę, że można je stosować rekurencyjnie i z cyklicznymi zależnościami (np. akcje zależą od informacji a informacje od akcji). To jest coś, czego nie ma w żadnym znanym mi języku programowania.

No i wszystkiego dobrego w Nowym Roku ;)))

1

Przepraszam, podałem błędną informację, źle liczyłem objętość kodu. Gotrek jest dużo większy, łącznie zawiera 936695 bajtów. Dorzuciłem nowy target make o nazwie "cloc", jeżeli ktoś ma cloc'a zainstalowanego może teraz odpalić "make cloc" w głównym katalogu. Aktualnie to daje wynik:

     187 text files.
     164 unique files.                                          
      69 files ignored.

github.com/AlDanial/cloc v 1.82  T=0.06 s (2043.1 files/s, 382204.3 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Chomik                          66           1301            276           8555
Bourne Shell                     5            588            752           3982
make                            18            551            153           3731
SDL_Chomik                      29            475             76           1241
m4                               2             80             21            666
-------------------------------------------------------------------------------
SUM:                           120           2995           1278          18175
-------------------------------------------------------------------------------

Definicje dla cloc'a do języków Chomik i SDL_Chomik są w pliku lang.txt (katalog główny).

Dzisiaj dorzuciłem jeszcze jeden plik generowany (generated/list_of_correctness_info,chomik). Dzięki niemu Gotrek jest jeszcze szybszy, mniej jest liczenia w runtimie.

2

Screenshot_20230107_012238.png
Wczoraj zrobiłem animowane figury w Blenderze, na razie tylko Gotreka. Teraz są trzy rodzaje broni - miecz, topór i młot. Animacje są dla wszystkich trzech broni. Zrobię tak, żeby każda broń miała swoje zalety i wady, zależnie od broni przeciwnika, trochę tak jak jest w grze "kamień, papier, nożyce".

Może zauważyliście, że każdy gracz ma pewien urząd - dzisiaj dodałem takie zachowanie, że jeżeli jesteśmy np. Skarbnikiem i atakujemy Gerrudira, który powiedzmy jest Cześnikiem, a przygląda się temu Pregor, to Pregor może wmieszać się do walki pomagając temu, kto ma taki urząd jak on. Czyli gdyby był Skarbnikiem to pomógłby Gotrekowi, a gdyby był Cześnikiem to pomógłby Gerrudirowi. Dzięki temu jest sens interesować się urzędami innych. Na razie urzędy się nie zmieniają, będzie można je "kupić" za łapówkę - w Warszawie. Na razie nie ma komunikatu kto komu pomagał, wypisuję to tylko na standardowe wyjście.

Można się już wymieniać bronią z innymi, jeden musi to zaproponować, a drugi musi się zgodzić. Na razie to nie ma większego znaczenia, ale zmienię to.

Dzisiaj dodałem ciekawą rzecz do samego chomika - taką wbudowaną rodzinę zmiennych typu code, która pozwala sprawdzić, czy dana zmienna jest reprezentowana w pamięci. Nie dotykałem struktury języka, to działa jako zwykła wbudowana rodzina (nazywa się <get is defined ...> i ustawia wbudowaną flagę 'the get is defined result' typu boolean). Ten feature jest potrzebny do nowego Gotreka. W chomiku jest specjalny test z przykładem jak stosować to 'get is defined ...' (tests/test20.chomik). Gotrek ma już 948392 bajtów.

0
Paweł Biernacki napisał(a):

Może zauważyliście, że każdy gracz ma pewien urząd - dzisiaj dodałem takie zachowanie, że jeżeli jesteśmy np. Skarbnikiem i atakujemy Gerrudira, który powiedzmy jest Cześnikiem, a przygląda się temu Pregor, to Pregor może wmieszać się do walki pomagając temu, kto ma taki urząd jak on. Czyli gdyby był Skarbnikiem to pomógłby Gotrekowi, a gdyby był Cześnikiem to pomógłby Gerrudirowi.

To by jaśniej wyglądało w postaci jakiegoś (najlepiej automatycznie generowanego) grafu, gdzie węzły grafu to Cześnik, Pregor, Gerrudir itp. i byłyby strzałki, kto komu pomaga.

0

Na stronie link jest do pobrania kolejna wersja "fantasy_chomik_demo" - to robocza nazwa. Zdecydowałem, że Gotreka usunę z Github'a, zamiast niego będę rozwijał w Chomiku (właściwie w SDL_Chomiku) ten projekt - fantasy. Po rozpakowaniu należy odpalić ./configure, a następnie "make run". Program jest duży i wprawdzie niewiele jeszcze umie (przynajmniej w warstwie wizualnej), ale uważam, że jest ciekawy.

Po uruchomieniu można nacisnąć parę razy ENTER - wówczas program wykonuje polecenie opisane na ekranie (jest na razie tylko po angielsku). Oprócz ENTER działa jeszcze:

BACKSPACE - wylosuj inną decyzję
ESCAPE - wylosuj inną decyzję (idź do innego miasta)
SPACE - wypisz na konsolę kim jesteś i co masz
strzałka w lewo - wypisz aktualne decyzje wszystkich postaci (są trzy)
strzałka do góry - wypisz na konsoli gdzie kto jest (w jakim mieście)
strzałka w dół - wypisz akcje dla postaci 1 (gracza) wraz z wartościami boolean "czy akcja ma sens TERAZ"
strzałka w prawo - wypisz wszystkie zmienne odpowiadające informacjom postaci 2 (Gerrudira)

Właściwie piszę po to, żeby się pochwalić pewnym subtelnym rozwiązaniem. W poniższym kodzie jest obsługa strzałki w prawo z pliku main/main.sdl_chomik - ciekawy jest kod "process on true". Jak może pamiętacie nawiasy trójkątne służą w Chomiku do pobrania wartości zmiennej. Otóż 'what person 2 thinks' jest zmienną typi information i w poniższym kodzie dokonujemy dwa razy pobrania jej wartości, z tym że za drugim razem używamy nawiasów trójkątnych DWA RAZY. Dzięki temu mamy dostęp do zmiennej, której nazwą jest informacja, a logicznie cała operacja przypomina trochę dwukrotne użycie operatora * w C (mam na myśli dereferencję wskaźnika). Ponadto (również w poniższym kodzie) używam wbudowanej rodziny zmiennych get is defined ..., która pozwala sprawdzić, czy zmienna o danej nazwie istnieje w pamięci.

W pliku common/common.sdl_chomik są definicje najważniejszych enumeracji - information i action. Poniżej iterujemy po wszystkich informacjach, dla każdej informacji 'current information' konstruujemy nową informację i umieszczamy ją w zmiennej 'what person 2 thinks'. Następnie sprawdzamy, czy ta zmienna jest zdefiniowana, i jeżeli tak - wypisujemy zarówno zawartość 'what person 2 thinks' jak i zawartość jej zawartości.

Mam nadzieję, że nie zagmatwałem po raz kolejny. Pewna bliska mi osoba, której wspomniałem o Chomiku powiedziała, że jak mnie zna to musi być potwornie skomplikowany. Broniłem się jak mogłem ;)))

variable process on (B:boolean):code;
let process on false = value code {};
let process on true = value code
{
    <print <what person 2 thinks> "=" <<what person 2 thinks>>>;    # here we "dereference" an information, i.e. a variable declared as:
                                                                    # variable (I:information):boolean;
};

variable process information (I:information):code;
let process information (I:information)=value code
{
    let current information = value information [(I:information)];
    let what person 2 thinks = value information person 2 thinks that <current information> is true;

    # we have no guarantee that the variable corresponding with the information built above really exists
    # so we check it here:
    let the get is defined result = value boolean true;
    <get is defined <what person 2 thinks>>;    # a cool feature, something like reflection
    <process on <the get is defined result>>;
};


let on key right = value code
{
    <process information (I:information)>;
};
0

Na Githubie jest nowy chomik, poprawiłem memory leak w parserze. Dodałem też parę ulepszeń żeby był mniej pamięciożerny.

Na link jest wersja Fantasy 0.0.4. Jest tam też opis gry, mam już mniej więcej wykrystalizowany pomysł jak będzie wyglądał świat.

Działa już coś takiego, że gdy rozmawiają dwie postacie a trzecia jest w tym samym miejscu, to ta trzecia postać dostaje informacje o tym co mówią. Czyli można podsłuchiwać.
Każde miejsce może wymagać klucza, lub nie. Miejsca, które nie wymagają klucza są zawsze "otwarte". Te, które wymagają klucza są zamknięte, chyba, że jedna ze znajdujących się tam postaci ma odpowiedni klucz. Komunikacja z innymi w miejscu, do którego żadna z będących tam postaci nie ma klucza jest niemożliwa.

Jeżeli znajdziecie jakiś klucz i podniesiecie go w obecności innej postaci, to ona dostaje informację, że Gotrek (wasza postać) ma ten klucz.

Marzy mi się, żeby było tak, że gdy kogoś zapytacie czy nie ma np. złotego klucza, to on pomyśli, że wy go nie macie. Bo gdybyście go mieli, to prawdopodobnie nie pytalibyście o ten klucz. Coś w rodzaju prostej logiki. I jeszcze chciałbym, żeby można było wprowadzać innych w błąd - z tym, że jeśli się zorientują mogą was za to nie lubić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1