Skip to content

Game complete - testing phase#1

Open
Rogalek wants to merge 1 commit intomasterfrom
develop
Open

Game complete - testing phase#1
Rogalek wants to merge 1 commit intomasterfrom
develop

Conversation

@Rogalek
Copy link
Copy Markdown
Owner

@Rogalek Rogalek commented Aug 13, 2019

Game is complete now - some testing needed in the future.

@Rogalek Rogalek added the enhancement New feature or request label Aug 13, 2019
@Rogalek Rogalek requested a review from SkySurferOne August 13, 2019 12:20
@Rogalek Rogalek self-assigned this Aug 13, 2019
Copy link
Copy Markdown
Collaborator

@SkySurferOne SkySurferOne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generalnie widać, że masz problem z samym programowaniem obiektowym i z tym jak definiować klasy i ich zachowanie. Poczytaj sobie czym jest abstrakcja w programowaniu obiektowym i enkapsulacja. Warto też znać i stosować takie zasady jak SOLID, DRY, KISS itp. Jak tworzysz klasy to dobrze jakby były w osobnych plikach, które nazywają się tak jak klasa. Jeśli chodzi o styl pisania w samym pythonie to warto kierować się https://www.python.org/dev/peps/pep-0008/



class TicTacToeGame:
class GameOn:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GameOn to niezbyt dobra nazwa dla klasy. Klasa powinna być rzeczownikiem i powinna być abstrakcją jakiejś rzeczy nie czynności. To metody opisują czynności wykonywane na obiekcie klasy. Dobrym przykładem klasy mogłaby być np. Game, Board, Player. Gdzie Game startuje nową grę i najprawdopodobniej jest singletonem, bo raczej nie chcemy tworzyć kliku gier na raz. Game tworzy planszę i dodaje do niej graczy.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

W tym przypadku zrobiłeś coś co się nazywa God object.

@@ -39,45 +27,41 @@ def __init__(self):
'7': ' ', '8': ' ', '9': ' '
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rozumiem, że to ma być plansza? Czemu nie jest to zwykła dwuwymiarowa tablica? Czy nie czytelniejsze jest board[0][1]? Wgle najlepiej jakby to była klasa, która przykrywa implementację planszy. Co jak nagle chciałbyś zrobić planszę 9x9? Musiałbyś zmieniać całą klasę GameOn? Swoją drogą tutaj naruszasz SRP. Board to też lepsza nazwa niż moves. I o ile mi wiadomo chociaż w pythonie nie ma czegoś takiego jak zmienne prywatne to stosuje się konwencję z podkreśleniami __foo https://stackoverflow.com/questions/1641219/does-python-have-private-variables-in-classes

print('-----------')
print(f' 7 | 8 | 9 \n')

def current_battlefield(self):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ta metoda powinna się zaleźć w klasie Board. Lepsza nazwa to np. show_board.

print(f' 7 | 8 | 9 \n')

def current_battlefield(self):
print(f"\n {self.moves['1']} | {self.moves['2']} | {self.moves['3']} ")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jakby to była tablica wystarczyłoby zrobić podwójną pętlę lub jedną pętle z warunkiem. To by też pozwoliło Ci na zrobienie generycznego printa - działałby jeśli zmieniłby Ci się rozmiar planszy. Byłoby to też bardziej zwięzłe, bo powtarzasz tutaj kod - DRY.

def play_round(self, player_symbol):
move = (input("Please select position for next move, from 1 to 9, don't use number "
"which is already taken: "))
if move not in self.p_moves or len(move) != 1:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ta logika powinna się znaleźć w klasie Board. Można by zrobić np. metodę set_sign(coord, player), która by rzucała exception gdyby coordynaty były złe. Można łapać wyjątek i logować błąd lub wystawić też metodę is_coord_valid()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wgle jest możliwe że warunek move not in self.p_moves jest prawdziwy, a len(move) != 1 nie? Chyba nie? A faktycznie może być właśnie zdałem sobie sprawę z pomysłowości rozwiązania xD a co jeśli plansza byłaby rozmiaru 9x9? Dodałbyś liczby od 1 do 81? A co z liczbami z dwoma cyframi? Poza tym złożoność tej operacji jest liniowa. Można do zastąpić zwykłym porównaniem, które wykonamy w czasie stałym. - Przy tym rozwiązaniu wystarczy że zapamiętamy maksymalną wartość pola.

['1', '4', '7'], ['2', '5', '8'], ['3', '6', '9'],
['1', '5', '8'], ['3', '5', '7']
]
keys = [k for k, v in self.moves.items() if v == symbol]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jakbyś wykorzystał tablicę nie musiałbyś robić takich rzeczy.

print('Welcome to my game! Let\'s start with some rules.')
self.battlefield()

def win(self, symbol):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To nie jest dobra nazwa dla tej metody.


if self.win(player_now):
print(f"Winner is player with '{player_now}' symbol!!!")
GameOff().start(True)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Przeczytaj to i zastanów się czy to jest zrozumiałe :D żeby podkreślić kuriozum te linijki napiszę co tu się dzieje: tworzysz nowy obiekt GameOff (wyłącz grę) na którym wykonujesz metodę START i podajesz parametr boolowski True (hmm a co jak podam False? Start zakończenia gry się nie wykona? Nie, nie zrestartujemy gry.)


def game_off(self):
# tutaj może coś w stylu czy chcesz zagrać czy zobaczyć zasady najpierw?
class GameOff:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ta logika powinna być w klasie Game.

self.rules()
GameOff().start()
else:
GameOn().game()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To nie może tak być. Po prostu nie. :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants