2011-06-26 15 views
6

Stworzyłem prostą konsolową grę Scrabble z wykorzystaniem Pythona. Starałem się hermetyzować model gry z I/O tak bardzo, jak to możliwe, co oznacza, że ​​stworzyłem kilka klas, aby opisać grę z jej regułami i aktualnym stanem. Zasadniczo wymyśliłem tych klasach:Połączyć autonomiczny model gry z interfejsem opartym na Qt

  • LetterSet: Aby opisać płytek w grze (punktacja łączna kwota, itp)
  • Board: Reprezentacja Zarządu z jego funkcji płytek i auxiliry
  • Player: wirtualna klasa podklasy rzeczywiste Classes jak istota ludzka lub BOT, dostał jedną z metod, które powinny powrócić play() gracze poruszać
  • Game: Cóż ...

Wszystko działa dobrze dzięki prostemu, liniowemu i synchronicznemu przepływowi z moją aplikacją konsolową.

Ale okazuje się, że nie jest łatwo przenieść tę koncepcję do Qt. Stworzyłem wszystkie potrzebne widżety, takie jak tablica Dragable, ogólne elementy wizualne opisujące stan gry i proste przyciski, takie jak "Pass", "Continue", "Exchange".

Problem polega na tym, że nie jestem pewien, jak postępować z metodą play(), która może korzystać z interfejsu Qt utworzonego w celu wygenerowania prawidłowego ruchu. Nie jest to jednak problemem dla Bot, który po prostu wyszukuje ruch bez żadnej interakcji.

Mój obecny pomysł to utworzenie lokalnej pętli zdarzeń, jak opisano here i oczekiwanie na kliknięcie przycisków w mojej metodzie play() zdefiniowanej w Human(Bot). Jest to trochę brzydkie, więc zastanawiam się, czy istnieje lepszy sposób na zrobienie tego.

Chciałbym, aby główna logika była taka sama, np. klasa Player obsługuje metodę play(), która generuje ruch i zwraca go. W ten sposób powinno być możliwe utworzenie dowolnego typu urządzeń typu Player, takich jak odtwarzacze sieciowe lub boty. Ten synchroniczny sposób robienia tego nie działa dobrze z działaniem Qt na zasadzie sygnału/gniazda. Mam nadzieję, że ktoś ma pomysł na rozwiązanie mojego problemu.

Podsumowując:Jak wygenerować Przesuń Player „s wewnątrz jego metody play() i odsyłając je jak zwykłą move = player.play(game) rozmowy?

Edit: Migawka, aby zorientować się, co mówię: snapshot http://reaktor42.de/~b52/shots/2011-06-26-235749_972x729_scrot.png

Edit2: jest to raczej stary i zakończyła zadanie o dwa lata temu z powodzeniem. Niemniej jednak pomyślałem, że może to być przydatne dla innych, jeśli opublikuję results through github.

Dzięki z góry, Oli

Odpowiedz

2

Co można zrobić w funkcji Odtwarzacz play jest:

  1. Włączone przyciski i podłączyć je do gniazd (jeden za działania)
  2. poczekać, aż ruch gracz ma potwierdzić (lub jakiegokolwiek innego powodu, aby zamknij)
  3. sygnały Disconnect, aby rozciąć gdy ruch gracz został odebrany (lub jest weryfikowany)

jest to jeden ze sposobów, ale należy go zmodyfikować, aby pasowały do ​​modelu grę

+0

Ale jak zachować to wszystko w metodzie 'play()' i zwróć ruch dopiero po tym, jak gracz naprawdę coś zrobił. Nie rozumiem, jak mogę to zrobić za pomocą sygnałów i gniazd. –

1

Mój obecny pomysł jest utworzenie lokalnej pętli zdarzeń, takich jak opisane tutaj i czekać na przyciski, aby kliknął w moim metody play() zdefiniowana w ludzkiej (BOT). Jest to trochę brzydkie, więc zastanawiam się, czy istnieje lepszy sposób na zrobienie tego.

Nie rozumiem, dlaczego uważasz, że to jest brzydkie. W ten sposób praktycznie działa dowolny program GUI: zainicjuj zestaw kontrolek (przycisków itp.), Poczekaj, aż użytkownik wejdzie w interakcję z kontrolkami, odpowiedz na interakcję i powtórz.

Polecam mieć przycisk, aby gracz mógł przesłać ruch. Klikają to, zdarzenie jest uruchamiane, program obsługi zdarzeń informuje, że obiekt został wykonany i przekazuje go do obsługi zdarzenia logiki gry. Logika gry sprawdza, czy ruch jest legalny (powinieneś umieścić tutaj kod zamiast w klasach GUI) i przekazuje kontrolę do następnego obiektu Player, jeśli ruch był legalny.

+0

Wygląda na to, że nie wyjaśniłem niezbędnej metody 'play()' i nie wpadłeś na pomysł. Ponownie sformułuję mój problem później. –

1

Myślę, że masz rację, że istnieje pewna rozbieżność między modelem opartym na zdarzeniach w środowisku GUI i oryginalnym projektem aplikacji. Za pomocą aplikacji konsolowej piszesz pętlę zdarzeń, ale w aplikacji GUI w którejkolwiek z frameworków, które znam, framework ma jedną z własnych.

Chciałbym, aby obiekt odtwarzacza wysłał ruch za pomocą sygnału do obiektu gry. Konieczne będzie uporządkowanie podstawowej klasy odtwarzacza wokół tego projektu. Nie powinno to być trudne, ponieważ masz już opracowaną rzeczywistą logikę, po prostu ponownie ją podłączasz.

Należy zauważyć, że obiekty odtwarzacza są w rzeczywistości tylko interfejsami między grą a faktycznym odtwarzaczem, którym może być ktoś klikający przyciski w interfejsie użytkownika lub zdalny odtwarzacz przez połączenie sieciowe. Tylko w przypadku bota obiekt gracza może być w rzeczywistości odtwarzany przez gracza, a nawet w takim przypadku najlepiej byłoby mieć oddzielne obiekty mechanizmu strategii. Myślenie w ten sposób może pomóc w uchwyceniu projektu.

Nie musisz tego robić w ten sposób. Możesz obejść to, np. według opisywanej metody, ale nie chciałbym zawracać sobie głowy własnymi pętlami zdarzeń wewnątrz aplikacji, która ma własną pętlę zdarzeń GUI. To walczy przeciwko strukturze GUI, zamiast pracować z nią. To nie jest po prostu Qt, to tak, problem będzie podobny do tego w każdym środowisku GUI. To inny sposób myślenia o tworzeniu aplikacji i polecam jej zaakceptowanie.

Powiązane problemy