Dzień dobry,
W ramach treningu Pythona, Gita i myślenia postanowiłem napisać prostą grę w statki używając Pythona, gra jest rozgrywana w oknie konsoli. Mój problem jest bardziej z tematu planowania klas, interakcji i ich czytelności.
Na ten moment mam trzy klasy: Users, Board i Battleship. Jestem w trakcie pisania metody do umieszczenia statku na planszy, i tutaj pojawiają się wątpliwości. Stworzyłem w klasie Board metodę put_ship która na ten moment sprawdza czy wprowadzone wartości są poprawne.
Chciałem dodać kolejny warunek, mianowicie czy statek o danym rozmiarze umieszczony na danym polu w danym kierunku zmieści się na planszy. W tym momencie zacząłem myśleć czy moje podejście jest właściwe, czy obiekt Board powinien faktycznie to sprawdzać, umieszczać i obliczać, czy nie lepiej byłoby to rozdzielić na coś dodatkowego? Z jednej strony, widzę planszę jako coś co może się wyświetlać pod różnymi postaciami i ewentualnie zmieniać dane na danym polu, ale chyba niezbyt czytelne i poprawne jest to żeby plansza obliczała czy Statek o rozmiarze 4 może zostać umieszczony na polu A2 w kierunku W czy już "wychodzi" z ram. Umieszczając tą logikę w tej klasie sprawiam że wtedy obiekt Plansza nie wykonuje tylko jednej rzeczy, wyświetlanie stanu gry, tylko ma dodatkowe zadania, a przez to więcej powodów aby ją zmodyfikować.
Umieszczam kod poniżej, znajduję się również na moim GitHubie wraz z klasą z testami poszczególnych funkcji:
import numpy as np
import Battleship as bs
class Board:
def __init__(self):
self.grid = np.array([['.' for i in range(10)] for j in range(10)])
def __str__(self):
return "Gameboard"
def show_board(self):
for i in range(10):
print(" {} ".format(chr(i+65)), end="")
print(' /')
for i in range(10):
for j in range(10):
print("[{}]".format(self.grid[i][j]), sep="", end="")
print('', i + 1, end="")
print()
print()
def check_field(self, x, y):
if x is not str:
return False;
return self.grid[ord(x.upper())-65][int(y)]
def put_ship(self, x: bs, field: str, direction: str = "E"):
alert = "";
if field[0].upper() not in "ABCDEFGHIJ":
alert += "\nInvalid column letter. Enter letter from \"A\" to \"J\"."
if not 0 < int(field[1]) < 11:
alert += "\nInvalid row number. Enter number from \"1\" to \"10\"."
if not alert and self.check_field(field[0], field[1]) != ".":
alert += "\nField {} is not empty.".format(field)
if direction not in ("N", "E", "S", "W"):
alert += "\nWrong direction. Enter one of: {}.".format(("N", "E", "S", "W"))
if alert is "":
return True
else:
print(alert)
return False
import Board as b
import Battleship as bs
import numpy as np
class User:
def __init__(self, name = ""):
self.name = "User"
self.boards = {b.Board(), b.Board()}
self.battleships = np.array([])
def __str__(self):
return self.name
def create_ships(self):
sizes = {4, 3, 3, 2, 2, 2, 1, 1, 1, 1}
for size in sizes:
bs.Battleship(size)
class Battleship:
def __init__(self, size, place):
self.size = size
self.place = place # Ex. A3A4A5A6
self.swims = True