Wpis z mikrobloga

Mam pytanie o projektowanie klas. Piszę sobie szachy w javie i zastanawiam nad klasami.
Klasa Game ma pole Piece[] board, oraz jest klasa Piece która ma pola PieceType (enumy 'K', 'Q' itd) oraz Color oraz Square (pole na jakim stoi)
Teraz zastanawiam się czy implementować szczegółowe klasy figur i czy sprawdzanie ich możliwych ruchów powinno odbywać się w silniku czy nie, rozpatruję następujące opcje

1. Klasa Game sprawdza czy ruch dla Piece jest możliwy, typ Piece jest stosowany jest dla wszystkich figur (ponieważ każda ma pole type i color a to co je odróżnia jest robione w silniku Game)

2. Piece jest abstrakcyjna, tworzę podklasy Knight, Queen itd. Konkretne klasy miałyby np. metodę availableSquares() która zwraca dostępne pola na jakie może się ruszyć z pola na którym stoi
a) availableSquares() zwraca dostępne pola, ale przy założeniu, jakby ta figura stała samotnie na szachownicy a silnik Game ogranicza te ruchy zależnie od stanu board
b) do konkretnych klas Knight, Queen itd. wstrzykuje board, by mogły one orientować się jaka jest pozycja i same uwzględnić na jakie pola mogą iść w metodzie availableSquares() (uwzględniając inne figury stojące na drodze itd)

Wydaje mi się, ze opcja 2a jest okej, wygląda logicznie, ale jest więcej roboty bo najpierw w klasie Piece liczę dostępne pola a mógłbym od razu dostępne pola przy uwzględnieniu innych figur na szachownicy (potem silnik i tak ogranicza te pola i musi on "symulować" linię po jakiej idzie figura przy sprawdzić czy stoi coś na linii)

#szachy #naukaprogramowania #java
  • 11
  • Odpowiedz
jeszcze jedno pytanie jakie mi się nasuwa - to czy używać typów najmniejszych które na pewno pomieszczą zakres danych. bo np. do współrzędnych szachownicy wystarczy typ byte, ale nie wiem czy nie użyć int, który jest domyślnym całkowitoliczbowym i będzie wymagał mniej operacji np. przy parsowaniu tekstu z notację na współrzędne
  • Odpowiedz
@JakTamCoTam: może dwuznacznie brzmi silnik - mi chodzi o "kontroler" który sprawdza poprawność ruchu i aktualizuje stan szachownicy i figur na niej. Sprawdza zasady (czy koniec gry, jak czas leci). I tego znaczenia słowa "silnik" dotyczy moje pytanie.

Później zamierzam dodać gracza komputerowego , czyli po prostu klasę która będzie analizowała dostępne ruchy (dostanie z metody obecnego kontrolera, klasy Game), będzie miała swoją funkcję oceniającą, drzewo min-max itd. (wtedy to będzie silnik stricte szachowy, coś jak Stockfish)

Aktualnie nie wiem czy sprawdzanie czy ruch jest poprawny robić w kontrolerze (klasa Game) czy hierarchię klas Piece-> KonkretneFigury i KonkretneFigury aby ocenić czy ruch jest możliwy musiałyby znać stan gry (Game musiałby wstrzykiwać do "modelu" stan szachownicy). Druga opcja to KonkretneFigury pokazują tylko możliwe ruchy figury (jakby nie stało nic innego na planszy) a kontroler analizuje (tylko tak naprawdę podczas analizy i tak kontroler rozróżnia czy analizuje dla pionka czy skoczka, dlatego nie wiem czy jest sens robić klasę KonkretneFigury, czy dać ogólną Piece która ma tylko pole name które mówi co to za figura, ale o jej możliwe ruchy dba
  • Odpowiedz
@Ragnarokk: nie rozumiem trochę Rubiego, ale masz tam
piece.rb gdzie jest metoda clearpath która potrzebuje board (czyli to ogólna klasa figur sprawdza czy inne figury z szachownicy nie przeszkadzają w wykonaniu ruchu).
Zastanawiam się czy dobrze jest jak piece zna stan szachownicy.
bo już konkretniejsze klasy typu bishop.rb mają can
movetofield gdzie tak naprawdę jak dobrze rozumiem korzystają z metody nadklasy oraz swojej specyfiki ruchu.

Sam board.rb jak widze rozpoznaje sytuacje "specjalne" (bicie w przelocie, ruch podczas szacha, promocja,
  • Odpowiedz
@Lewo: Piece jako abstrakcyjna i logika w klasach figur (przechowują zasady - jak w rozwiązaniu @Ragnarokk a) + dokładasz wyjątek (może on być w klasach umieszczony) dla skoczka i do bicia w przelocie. Umieszczanie pewnych rzeczy w klasach jest nadmiarowe chyba, że chcesz dodatkowe reguły dodawać (inne warianty szachów). Ponadto jeszcze jest kwestia, czy chcesz podpowiadać ruchy po naciśnięciu figury, czy tylko sprawdzać wykonane ruchy. Tyle jest decyzji do
  • Odpowiedz
@piotrb: chciałem całą logikę mieć w jednej klasie - Game. A Piece mieć jako model na którym jest kolor i współrzędne gdzie stoi. Tak to figury muszą dostać szachownicę żeby sprawdzić czy mogą taki ruch wykonać (czy nie "przelatują" nad innymi figurami). Chciałem zrobić trochę jak wzorzec MVC i żeby figury nie musiały pracować na stanie szachownicy (która jest polem w Game). Tylko kontroler (Game) znałby stan szachownicy i na
  • Odpowiedz
@Lewo:
Sorry, nie mam chwilowo czasu by usiąść i zrozumieć (a też przypominać sobie jak i po co to robiłem), jutro spróbuję w pracy (w końcu tę bibliotekę robiłem też w ramach pracy :P)
  • Odpowiedz
@Lewo:
W sumie powiem to co mówisz nie różni się tak bardzo od tego, co ja zrobiłem - ja te metody z klasy Piece przeniosłem z Boarda bardziej w celach organizacyjnych:

z
  • Odpowiedz
@Ragnarokk: narazie nie wiem czy mam zgodność z pgn, póki co z palca wpisuje ruchy (preprealpha :D)
A masz jakis pomysł jak sprawdzać czy wykonanie ruchu ustawia naszego króla pod szacha?

Bo mam Piece[][] board i chętnie zrobiłbym ruch, sprawdził czy nie dostaje po nim szacha.
Tylko wykonanie ruchu to: przesunięcie figur i usunięcie innych (np po biciu), cofanie takiego ruchu musiałoby pamiętać co zostało zbite, co się ruszło, przy promocji pionka pamiętać by pionka odmienić
  • Odpowiedz
A masz jakis pomysł jak sprawdzać czy wykonanie ruchu ustawia naszego króla pod szacha?

I myślałem o zrobieniu głebokiej kopii board (razem z kopiami Piece) i mieć taki preview board i za każdym razem robić na niej najpierw ruch, sprawdzić czy odsłaniam się na szacha po ruchu - jeśli tak, to do preview przywrócić poprzedni stan (zrobić głęboką kopię głównej szachownicy) a jak nie, to jest okej i ten ruch wykonuje też
  • Odpowiedz