Article View: pl.comp.lang.tcl
Article #131Temat akademicki
From: Wojciech Kocjan
Date: Sun, 17 Jul 2005 10:55
Date: Sun, 17 Jul 2005 10:55
144 lines
6582 bytes
6582 bytes
Hej,
W związku z tym, że tu jest za cicho, postanowiłem podrzucić temat do
dyskusji. Mianowicie chciałbym w ramach nadmiaru luzu w pracy stworzyć
gierkę strategiczną. Pomijam narazie jaką, bo pewnie się poddam i
pomyślę o czymś znacznie prostszym (chyba, że są chętni do robienia
razem :-).
Jednakże najbardziej podobał mi się kiedyś pomysł takiej gierki "When 2
Worlds War" z Amigi (ostatnio widzialem "Pocket War" na pocketpc, ale
nie sprawdzałem jak to wygląda tam). Mianowicie gra polegała na
napisaniu poleceń dla jednostek, potem dla baz i bardzo często potem
piło się piwo/wino/kawę/herbatę/whatever, a one same sobie walczyły. Tam
trzeba było głównie dzielić produkcję nowych na "squads" i sprawdzać na
ile tam jest problemów z tym. Ale pomysł miodny i na mocnej Amidze
(czyli 40MHz :) nieraz miało się tysiące jednostek. Tradycyjny klikacz
myszką by sobie nie dał rady - chociaż można je było ręcznie też
obsługiwać. No ale sytuacja, gdzie trzeba było spaceshipami
transportował lądowe/lotnicze/morskie, eskortować je innymi spaceshipami
etc to byłoby sadyzmem robić to ręcznie.
W każdym razie bardzo korci mnie napisanie jakiejkolwiek gierki
napędzanej skryptami. No i myślałem sobie jak do tego Tcl wykorzystać.
Jedyny myk jest taki, że nie chciałbym żeby jeden skrypt był w stanie
wykorzystywać za dużo czasu (taki mini RTOS :), a też nie chciałbym
odpalać milionów wątków dla każdej jednostki z osobna. Aha, skoro
miałaby to być gra dla siedzących w pracy, zakładam, że tura byłaby i
tak proporcjonalna do średniej ilości jednostki/gracz - z początku
krótko, jak już się każdy rozwinie to dużo dłużej (co sprzyja czasowi
wyznaczania działań).
Przyszło mi do głowy kilka pomysłow, ale może ktoś ma inny:
1/ Podmiana funkcji pętlowych - for, foreach, while i inne
To zaproponowali goście z comp.lang.tcl, ale ma duży minus - jak już
przerwę pętlę to do niej nie wrócę. Nawet jeśli zapamiętam stan i
wykonam później iterację, to sprawdza się to w:
for {set i 0} {$i < 30} {incr i} {
puts X
}
ale nie sprawdzi się w:
for {set i 0} {$i < 3} {incr i} {
for {set j 0} {$j < 10} {incr j} {
puts X
}
}
nie mógłbym przerwać wewn. pętli i jakoś wrócić do głównej. A może
mógłbym, ale ilość magii przekraczałaby pisanie debuggera do Tcl chyba.
2/ Każdy gracz to jeden wątek
To daje w miare sprawiedliwy podział czasu, raczej załatwiany przez
system (nie wiem co z tzw userspace threads, chyba BSD ma/miał takie).
Ale jest jeden minus - jeden infinite loop pozwoli zabić całą ekipę. Co
byłoby ciekawe, bo znając błędy w skryptach można byłoby exploitować
wroga ;-)
Można połączyć 1/ z 2/ i np żaden loop nie mógłby trwać więcej niż
określony czas.
3/ Napisanie od nowa
To jest najciekawsze, ale nie wiem ile niesie ze sobą babraniny.
Stworzyłbym safe interpreter, w którym zdefiniowałbym pętle i wszystko
jako własne polecenia. To wiąże się z kilkoma obejściami, na przykład
nie można byłoby bezpośrednio wykonywać poleceń i wyliczać, ale w znośny
sposób dałoby się to obejść. Pozbyłbym się części poleceń Tcl, a
stosował prostsze (np for/foreach/while), ale trudno.
Większość można zrobić parsując [info complete], natomiast nie mam
pojęcia ile jest z tym zabawy. Na pewno parsowanie szukając ";" oraz \n
i sprawdzanie [info complete] działa dobrze, ale potem każda
pętla/warunek musi sobie rozbijać swoje polecenia i boję się o czas tego.
4/ Zdarzenia
To z kolei da największy hardcore dla piszących skrypty.
Teoretycznie to najbardziej pasuje do Tcla, ale bardziej naturalne
wydaje się zapisanie:
while {1} {
while {[damage] < 0.6} {
set pos [me nearest_enemy]
move_to_weapons_range $pos
attack $pos
}
go_to_base
}
Eventami:
proc repairmode {} {
on newturn {}
on idle {repairmode2}
}
proc repairmode2 {} {
start_repair
on newturn {}
on idle {sop}
}
proc sop {} {
on newturn {
if {[damage] >= 0.6} {repairmode}
}
on idle {
set pos [me nearest_enemy]
move_to_weapons_range $pos
attack $pos
}
}
Chociaż to drugie jest faktycznie ciekawe :) No i prostsze do
zaimplementowania. Plus nie wyrzuciłbym na śmietnik optymalizacji do
bytecode.
Analizowałem też problem interpretatorów. Stworzenie 10000
interpretatorów ([interp create -safe] + 50 interp alias) zżera 400MB
pamięci. Natomiast interp dla każdej kombinacji gracz,rodzaj_obiektu
plus namespace dla każdej instancji (dla zmiennych lokalnych etc) to już
dobre rozwiązanie. 20000 jednostek + 10 zmiennych lokalnych każda (i 50
interp alias dla każdego interpa) zajmuje 30MB. To jest do
zaakceptowania bez problemu.
Oczywiście każdy team musi mieć innego interpa, żeby nie czytać sobie
wzajemnie zmiennych :-) To by był dopiero hardcore - mimo, że [info] nie
będzie ;-)
Czy ktoś chciałby podyskutować co tu można ciekawego wymyślić? Albo ktoś
chciałby się dołączyć?
ps. Na studiach miałem "najkrótszą drogę", ale tu już za dużo nie
pamiętam, a też podręcznikowe metody pewnie mają się kiepsko do realiów
i optymalizacji kodu. Ma ktoś dobry algorytm na to? Chodzi głównie o
mapy np 160x80, gdzie podane są "koszty" ścieżki (wolę nie bawić się w
drogi jak w civ/freeciv, bo to utrudnia alrogytm AFAIR). Tu akurat
chętnie wsparłbym się kodem w C, żeby było szybciej.
--
WK
Technical Details
Message-ID:
<dbddek$9qb$1@atlantis.news.tpi.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!news.onet.pl!newsfeed.tpinternet.pl!nemesis.news.tpi.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mailShow Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!news.onet.pl!newsfeed.tpinternet.pl!nemesis.news.tpi.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail From: Wojciech Kocjan <hceicjow.backward@kocjan.org> Newsgroups: pl.comp.lang.tcl Subject: Temat akademicki Date: Sun, 17 Jul 2005 12:55:14 +0200 Organization: tp.internet - http://www.tpi.pl/ Lines: 144 Message-ID: <dbddek$9qb$1@atlantis.news.tpi.pl> NNTP-Posting-Host: bpi135.neoplus.adsl.tpnet.pl Mime-Version: 1.0 X-Trace: atlantis.news.tpi.pl 1121597717 10059 83.29.50.135 (17 Jul 2005 10:55:17 GMT) X-Complaints-To: usenet@tpi.pl NNTP-Posting-Date: Sun, 17 Jul 2005 10:55:17 +0000 (UTC) User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) X-Accept-Language: pl, en-us, en Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit