Strona główna Polish Python Coders Group
   Strona główna   Pomoc Zaloguj się Rejestracja  
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji

Aktualności: PyStok #42 - wystąpią Łukasz Langa i Dominik Kozaczko
Szukaj Szukaj
Strony: [1]   Do dołu
Drukuj
Wątek: Wyznaczenie drogi do bramki  (Przeczytany 128 razy)
« : 02:30 14/06/19 »
venxx Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 3


Witam.
Próbuję stworzyć prostego bota do gry paper soccer, lecz stanąłem na problemie dotyczącym określeniem czy w następnym ruchu będzie opcja strzelenia gola czyli czy będzie dostępna droga do bramki przykładowo:

Nie mam nawet na celu szukania najkrótszej drogi tylko aby potrafił określić jest dostępna droga czy nie.
Szukałem informacji takich jak szukanie w labiryncie, aczkolwiek nie mam pomysłu jakbym mógł to użyć w moim kodzie ponieważ nie opieram się na grafach.
PS. Czy pygame gdy jest uruchomione musi pobierać 100% procesora?
Mój kod:
https://github.com/8371/Paper-soccer/blob/master/paper_soccer.py
Zapisane
« Odpowiedz #1 : 06:35 14/06/19 »
sig Offline
Professional Python User

Zobacz profil
***

Reputacja: 89
Wiadomości: 431


Skoro starczy wiedzieć że droga jest, możesz "zalać" boisko. Generalnie koncepcja jest taka: Spod bramki wydobywa się woda, która rozlewa się w te strony w które można wykonać ruch. Jak dojdzie do piłki, to znaczy że jest droga (a jak nie będzie możliwości jej dalszego rozlania a piłka dalej sucha to niema).
Zapisane
« Odpowiedz #2 : 07:57 14/06/19 »
Guaz Offline
Expert Python User

Zobacz profil
****

Reputacja: 69
Płeć: Mężczyzna
Wiadomości: 513


Jak powiedział wyżej @sig Uśmiech

Dodam tylko jak określa się to bardziej informatycznie:
Tworzysz strukturę drzewa, korzeniem jest bramka. I teraz zależnie od możliwości z danego punktu, przeszukujesz w szerz (nie do najgłębszego wyczerpania) możliwości dojścia do bramki. Czyli sprawdzasz kolejno pierwszy poziom, drugi, trzeci itd. każdy poziom reprezentuje ilość kresek. Reszta jak u kolegi wyżej.

Co do pyGame. Niestety, nie nadaje się on w praktyce do tworzenia gier, ogólnie python i jego 'silniki' jak pygame nie są do tego przeznaczone, przez brak sztywnego typowania między innymi. Przez co ilość pamięci jest kolosalna, a renderowanie grafiki daleko odbiega od wydajności innych języków. Dlatego jeśli chcesz tworzyć gry, niestety python mnie mocno zawiódł, więc polecam skierować spojrzenie w bardziej powszechne narzędzia jak choćby unity Uśmiech
Zapisane

Python 3.5+ / Mint

Daje wędkę zamiast ryby. Chyba że ktoś się chce czegoś nauczyć, wtedy chętnie pomogę każdemu.
Za rybę niestety trzeba zapłacić Z politowaniem.
« Odpowiedz #3 : 18:29 14/06/19 »
Ameise Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Wiadomości: 7


Zalogowałem się tylko dlatego, że kiedyś uwielbiałem tę grę Chichot Jeszcze nie widziałem dobrego bota do tej gry, zazwyczaj słaby mini-max, którego potrafi ograć gracz 1300 na kurniku Uśmiech Od 2-3 lat niektórzy próbują coś z MCTS, może trochę lepiej, tak powiedzmy wygrywa z graczami 1500, ale to wciąż słabo. mini-max czy mcts są dobre, ale przydałyby się też dodatkowe założenia przy pisaniu bota (np. wybieraj jedne z najdłuższych sekwencji ruchów - im więcej zapełnienia planszy, tym mniej możliwych ruchów w przyszłości - nie potrafię tego dokładnie wytłumaczyć, każdy kto gra w piłkę wie o co mi chodzi) + np. wbudowanie 'schematów' w pamięci bota. Jakieś pół roku temu przeglądałem githuba w poszukiwaniu projektów dot. piłki i moim zwycięzcą jest:

- https://github.com/slunzok/papersoccer (strona internetowa)
- https://github.com/slunzok/papersoccer-scripts (jakieś skrypty w pythonie, jest jeden nawet w pygame, ale tylko przeglądanie partii)

Fajny projekt, szczególnie ta strona internetowa - wydaje mi się, że możesz przejrzeć plik .js dot. 'orlika treningowego' i przerobic na pythona - ten mazak Gmocha wyznacza wszystkie możliwe sekwencje dla kolejnego ruchu, dodałbyś dodatkowego ifa, jeśli piłka jest w bramce i chyba masz o to o co ci chodzi Uśmiech Szkoda tylko, że autor chyba porzucił rozwijanie strony.

Sam ci nie pomogę, bo napisanie **naprawdę dobrego** bota do tej gry wydaje mi się czasochłonne. Tak tylko wrzuciłem tu swoje 3 grosze na temat piłki, przejrzyj może jeszcze inne projekty na githubie i życzę ci powodzenia! Uśmiech
Zapisane
« Odpowiedz #4 : 01:48 15/06/19 »
venxx Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 3


@Sig wydaje mi się, że wiem co masz na myśli tylko w jaki sposób mógłbym to wykonać patrząc na mój kod?
@Guaz Mógłbyś trochę bardziej rozwinąć myśl tego drzewka?
@Ameise Znasz tę grę? Bardzo się ciesze bo jest mało popularna. Co do tych bardziej zaawansowanych opcji narazie się za nie nie porywam bo mam problem z tą prostą sprawą rok temu próbowałem to zrobić ale sam nie dam rady. Te linki które wysłałeś są mi dobrze znane nawet znam gościa który to zrobił. Czemu porzucił ten projekt nie mam pojęcia prawdopodobnie brak czasu i brak zysków z tego.
Jeśli ktoś miałby czas prosiłbym o bardziej szczegółową pomoc ponieważ piszę tutaj już w ostateczności ponieważ sam już mam problem cokolwiek dodać do mojego kodu i obawiam się, aby on miał sens trzeba by go napisać porządnie od nowa.
Zapisane
« Odpowiedz #5 : 21:00 15/06/19 »
Ameise Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Wiadomości: 7


Dwa przykłady ode mnie (opierając się na przeróbce skryptów ze strony papersoccer.pl):

1) Gole - gif --- Gole - download --- Tak jak już pisałem powyżej, wystarczy lekko przerobić kod z orlika treningowego np.:

- dodałem tablicę gmochGoals
- w funkcji prev() i next() zamiast gmochMoves dałem gmochGoals - żeby wyświetlał tylko gole, a nie wszystkie możliwe ruchy
- w funkcji setGmochMode() dodałem gmochGoals = [], żeby wyzerować tablicę - kiedy ktoś odklika mazak Gmocha
- w funkcji marker() dodałem ifa dla ruchów (0,1,3,4,5,7 - bez 2 i 6, bo w tych przypadkach nigdy nie nastąpi taka możliwość), czy piłka w bramce:

Kod
// gorna bramka
if (tmpCursorY-1 == 0) {
   gmochGoals.push(gmochMultiMoves[i] + "0");
}

lub                         

Kod
// dolna bramka
if (tmpCursorY+1 == 12) {
   gmochGoals.push(gmochMultiMoves[i] + "3");
}

- w funkcji drawGameState(), przy ifie, który sprawdza, czy gmochMode == 1, zamieniłem wszystkie gmochMoves na gmochGoals - żeby rysował tylko gole, nie wszystkie możliwe ruchy

I gotowe. Trochę wystarczy pogłówkować i naprawdę mając kod z tej strony można szybko dopisać sobie nowe funkcje (ale przyznaję, mi zajęło 3 dni, zanim zrozumiałem działanie Język)

2) Bot - gif --- Bot - download -  I kolejny przykład, jak zmodyfikować kod z orlika treningowego, żeby zrobić najprostszego bota (tzn. robisz ruch, a bot w odpowiedzi wykonuje najdłuższy możliwy - nie ma tu żadnej głębokości przeszukiwania minimax itp., po prostu okroiłem maksymalnie mazak Gmocha i ze wszystkich możliwych ruchów automatycznie wykonuje tylko jeden, ten o najdłuższej długości, a jeśli jest ich więcej, to losuje jeden z nich)

- dodałem zmienną botMode = 0
- w funkcji buttonPress() dodałem ifa:

Kod
// jesli uzytkownik wlaczyl tryb bota, po kazdym kliknietym, zakonczonym ruchu przeciwnika wywoluj okrojony mazak Gmocha (marker())
if (botMode == 1 && multiMove == 0) {
   marker();
}

- w funkcji marker() wywaliłem ( w "2. Dodanie do tymczasowej tablicy tmpBoard trwają ...") wszystkie tmpCursorList.push([tmpCursorX, tmpCursorY, "0"]); itp. bo nie mają znaczenia; w ("3. Na koniec sprawdzenie 8 ruchów. Jeśli można ...") dla każdego ruchu wywalam wyliczenia boardClicks, boardFingerprint, bo nie mają znaczenia, a dodaję:

Kod
// gmochMoves zawiera wszystkie najdluzsze ruchy, jesli aktualny ruch jest dluzszy, wyczysc tablice gmochMoves i dodaj ruch - to teraz on bedzie najdluzszy - i wszystkie kolejne o takiej samej dlugosci beda dodawane do gmochMoves
 
next_move = gmochMultiMoves[i] + "0";
if (gmochMoves.length != 0 && next_move.length > gmochMoves[0].length) {
   gmochMoves = [];
}
gmochMoves.push(gmochMultiMoves[i] + "0");


- w funkcji marker() przy końcowym ifie gmochMultiMoves.length == 0 dodałem (kod wziąłem z funkcji prevMove(), można powiedzieć, że to tak, jakbym na stronie papersoccer.pl w orliku treningowym uruchomił mazak Gmocha, a następnie kliknął 'zatwierdź ruch' - muszę tak zrobić, żeby teraz zaktulizować pozycję kursora itp.):

Kod
                var random_move = gmochMoves[Math.floor(Math.random()*gmochMoves.length)];
               moves.push(random_move);
 
               for (var m=0;m<random_move.length;m++) {
                   if (random_move[m] == "0") {
                       board[cursorX][cursorY] = board[cursorX][cursorY] + "0";
                       board[cursorX][cursorY-1] = board[cursorX][cursorY-1] + "4";  
 
                       cursorY = cursorY - 1;
                   } else if (random_move[m] == "1") {
                       board[cursorX][cursorY] = board[cursorX][cursorY] + "1";
                       board[cursorX+1][cursorY-1] = board[cursorX+1][cursorY-1] + "5";
 
                       cursorX = cursorX + 1;
                       cursorY = cursorY - 1;
                   } else if (random_move[m] == "2") {
                       board[cursorX][cursorY] = board[cursorX][cursorY] + "2";
                       board[cursorX+1][cursorY] = board[cursorX+1][cursorY] + "6";
 
                       cursorX = cursorX + 1;
                   } else if (random_move[m] == "3") {
                       board[cursorX][cursorY] = board[cursorX][cursorY] + "3";
                       board[cursorX+1][cursorY+1] = board[cursorX+1][cursorY+1] + "7";
 
                       cursorX = cursorX + 1;
                       cursorY = cursorY + 1;
                   } else if (random_move[m] == "4") {
                       board[cursorX][cursorY] = board[cursorX][cursorY] + "4";
                       board[cursorX][cursorY+1] = board[cursorX][cursorY+1] + "0";
 
                       cursorY = cursorY + 1;
                   } else if (random_move[m] == "5") {
                       board[cursorX][cursorY] = board[cursorX][cursorY] + "5";
                       board[cursorX-1][cursorY+1] = board[cursorX-1][cursorY+1] + "1";
 
                       cursorX = cursorX - 1;
                       cursorY = cursorY + 1;
                   } else if (random_move[m] == "6") {
                       board[cursorX][cursorY] = board[cursorX][cursorY] + "6";
                       board[cursorX-1][cursorY] = board[cursorX-1][cursorY] + "2";
 
                       cursorX = cursorX - 1;
                   } else if (random_move[m] == "7") {
                       board[cursorX][cursorY] = board[cursorX][cursorY] + "7";
                       board[cursorX-1][cursorY-1] = board[cursorX-1][cursorY-1] + "3";
 
                       cursorX = cursorX - 1;
                       cursorY = cursorY - 1;
                   }
               }
 
               xrange = [];
               yrange = [];
               for(var i=cursorX-1;i<cursorX+2;i++){xrange.push(i);}
               for(var i=cursorY-1;i<cursorY+2;i++){yrange.push(i);}
 
               gmochId = 0;
               gmochMoves = [];
               gmochBlocked = [];
               gmochPermutation = [];
 
               //marker();
               next();


Trochę więcej kombinowania, ale też w miarę proste, trzeba tylko dobrze pomyśleć Język To tyle ode mnie, i tak poświęciłem większość część soboty na zrobienie tych dwóch rzeczy (a tylko przerobiłem kod od kogoś i dodałem parę linijek, a co dopiero tłumaczyć wszystko od początku i napisać to w pythonie Chichot a gdzie minimax czy inne rzeczy Chichot) Według mnie olej pygame i spróbuj się wgłębić w ten kod z githuba, praktycznie logikę gry masz już napisaną, teraz tylko dopisać własne funkcje. Ja nie mam czasu nikogo uczyć/tłumaczyć, więc życzę ci wytrwałości w nauce i powodzenia! Uśmiech
Zapisane
« Odpowiedz #6 : Dzisiaj o 00:47 »
venxx Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 3


@Ameise dziękuję Ci bardzo za poświęcony czas i wyczerpującą odpowiedź.
Dołożę wszelkich starań w celu przeanalizowania tego co napisałeś i wgłębienia się w kod
ze strony papersoccer. Jeśli będę miał z czymś problem postaram się dać znać Uśmiech
Zapisane
Strony: [1]   Do góry
Drukuj
Skocz do:  

© 2007 - 2019 Polish Python Coders Group
Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines | Theme by PixelSlot