Rozwiązywanie problemów metodą zachłanną – gra „Zbieranie monet”

Wstęp

Gra, którą omówimy, to prosty skrypt w Pythonie, który pozwala graczowi poruszać się po planszy i zbierać monety. Plansza ma wymiar 5×5 i zawiera losowo rozmieszczone monety. Gracz startuje w lewym górnym rogu planszy i może poruszać się tylko w dół lub w prawo. Celem gry jest zebranie jak największej liczby monet, a gra kończy się, gdy gracz dotrze do prawego dolnego rogu planszy. W grze należy stosować metodę zachłanną.

Zasady Gry

  • Gra toczy się na planszy o wymiarach 5×5, która jest wczytywana z pliku tekstowego.
  • Gracz rozpoczyna w lewym górnym rogu planszy i porusza się, wybierając ruch w prawo lub w dół.
  • Każde pole na planszy zawiera pewną liczbę monet, które gracz zbiera, przechodząc przez to pole.
  • Gracz nie może się cofnąć ani poruszać w innych kierunkach niż prawo i dół.
  • Gra kończy się, gdy gracz dotrze do prawego dolnego rogu planszy (pozycja (4, 4)).
  • Po zakończeniu gry wyświetlane jest podsumowanie liczby ruchów i zebranych monet.

Implementacja

Skrypt gry został napisany w Pythonie i wykorzystuje proste podejście do sterowania ruchem oraz zbierania monet. Plansza jest wczytywana z pliku tekstowego, a po każdym ruchu gracza wyświetlana jest jej aktualna wersja, z zaznaczoną pozycją gracza.

W skrypcie zastosowano funkcję generacja, która odpowiada za wyświetlanie planszy. Funkcja ta minimalizuje redundancję kodu i zwiększa czytelność skryptu. Oto kluczowe fragmenty skryptu:

Wyjaśnienie linii kodu:

  • Deklaracja zmiennej plansza – linia 2: Tworzymy pustą listę o nazwie plansza, która będzie przechowywać wszystkie wiersze planszy. Każdy wiersz będzie listą liczb (monet).
  • Otwieranie pliku – linia 3: Otwieramy plik o nazwie plansza.txt w trybie odczytu ("r" – read). Słowo kluczowe with automatycznie zamyka plik po zakończeniu pracy. Zmienna file to uchwyt do otwartego pliku, dzięki czemu możemy go użyć do odczytu danych.
  • Pętla for – linie 4-5: Pętla iteruje po każdej linii tekstu w pliku file. Każda linia zawiera liczby (monety), które musimy przekształcić z tekstu na liczby całkowite.
  • Linia 5:
    • line.split() dzieli każdą linię tekstu na osobne elementy (liczby), bazując na separatorze, którym jest spacja (domyślne zachowanie metody split()).
    • Następnie każda wartość z line.split() jest zamieniana na liczbę całkowitą za pomocą int(x) i całość jest zapisywana jako lista liczb w plansza.
    • append() dodaje tę listę (wiersz planszy) do listy plansza, tworząc tym samym tablicę 5×5.

Co robi ten fragment:

  • Wczytuje dane z pliku plansza.txt, gdzie każda linia to wiersz planszy. Każda liczba w pliku to liczba monet na polu planszy.
  • Lista plansza będzie miała postać:


Wyjaśnienie linii kodu:

  • Linia 13: Definiujemy funkcję generacja(x, y). Funkcja ta przyjmuje dwie wartości: xy, które reprezentują współrzędne gracza na planszy. Funkcja ta zostanie użyta do generowania graficznej reprezentacji planszy i zaznaczenia na niej aktualnej pozycji gracza.
  • Linia 14: Funkcja rozpoczyna pętlę for, która iteruje przez indeksy wierszy planszy. Pętla ta przechodzi przez każdy wiersz (5 wierszy).
  • Linia 15: Druga pętla for wewnątrz pierwszej iteruje przez indeksy kolumn. W ten sposób odwiedzamy każdą komórkę w danym wierszu, aby ją wyświetlić.
  • Linia 16: Instrukcja warunkowa if sprawdza, czy aktualnie odwiedzane współrzędne (i, j) są takie same jak współrzędne gracza (x, y). Jeśli tak, oznacza to, że gracz znajduje się na tym polu, więc wartość w tej komórce planszy zostaje otoczona nawiasami kwadratowymi, aby wizualnie wyróżnić pozycję gracza.
  • Linia 17: Jeśli współrzędne i, j nie odpowiadają pozycji gracza, wyświetlana jest po prostu liczba monet na danym polu. Każda wartość zostaje „justowana” (wyrównana) przy użyciu funkcji ljust(), aby zapewnić równy odstęp między polami.
  • Linia 18: Zakończenie pętli for dla kolumn – każda linia (wiersz) kończy się wyświetleniem wszystkich komórek w danym wierszu.
  • Linia 19: Zakończenie pętli for dla wierszy – każda iteracja odwiedza i wyświetla kolejne wiersze planszy.
  • Linia 20: Zakończenie definicji funkcji generacja. Funkcja ta zostanie wywołana kilkukrotnie w grze, aby pokazać aktualny stan planszy z zaznaczoną pozycją gracza po każdym jego ruchu.


Wyjaśnienie linii kodu:

  • Linia 29: Pętla while zaczyna się od warunku x < 4 or y < 4. Warunek ten sprawia, że pętla działa tak długo, jak długo gracz nie znajduje się w prawym dolnym rogu planszy (pozycja (4, 4)). Dopóki któraś z wartości x (pozycja w wierszach) lub y (pozycja w kolumnach) jest mniejsza niż 4, pętla się powtarza.
  • Linia 30: Wyświetla aktualną pozycję gracza na planszy oraz liczbę monet, które gracz zebrał do tej pory. To informacja dla gracza, aby wiedział, gdzie znajduje się na planszy i ile już uzbierał monet.
  • Linia 31: Program prosi gracza o podanie kierunku ruchu. Wyświetlany jest komunikat: „Wybierz kierunek (prawo – 'p’, dół – 'd’)”. Gracz musi wpisać jedną z dwóch liter – p (dla ruchu w prawo) lub d (dla ruchu w dół). Wynik jest przechowywany w zmiennej ruch.
  • Linia 33: Instrukcja warunkowa sprawdza, czy gracz wybrał ruch w dół (ruch == 'd') oraz czy można jeszcze poruszyć się w dół (x < 4). Jeśli oba warunki są spełnione, zmienna x zostaje zwiększona o 1, co oznacza przemieszczenie gracza o jeden wiersz w dół.
  • Linia 34: Jeśli warunki z linii 33 są spełnione, również zwiększana jest zmienna liczba_ruchow o 1. Ta zmienna przechowuje liczbę wszystkich ruchów wykonanych przez gracza.
  • Linia 35: Instrukcja elif sprawdza, czy gracz wybrał ruch w prawo (ruch == 'p') oraz czy gracz może jeszcze poruszać się w prawo (y < 4). Jeśli oba warunki są spełnione, zmienna y zostaje zwiększona o 1, co oznacza przemieszczenie gracza o jedną kolumnę w prawo.
  • Linia 36: Tak samo jak w przypadku ruchu w dół, zmienna liczba_ruchow zostaje zwiększona o 1, jeśli warunki w linii 35 są spełnione.
  • Linia 38: Jeśli gracz wprowadził niepoprawny ruch (np. wybrał ruch w prawo, będąc na skraju planszy lub wpisał coś innego niż p lub d), wyświetlany jest komunikat: „Niepoprawny ruch, spróbuj ponownie”. Program przechodzi do następnej iteracji pętli while dzięki instrukcji continue, co oznacza, że program wraca na początek pętli i prosi gracza o ponowny wybór.
  • Linia 42: Po poprawnym ruchu gracza, wartość zmiennej zebrane_monety zostaje zaktualizowana o liczbę monet z nowego pola, na które przesunął się gracz. Zmienna ta przechowuje całkowitą liczbę monet zebranych przez gracza w trakcie gry.
  • Linie 45–47: Funkcja generacja(x, y) jest wywoływana ponownie, aby zaktualizować i wyświetlić planszę z zaznaczoną nową pozycją gracza po ruchu. Następnie program wraca do początku pętli, gdzie ponownie sprawdzane są warunki gry i wprowadzane kolejne ruchy gracza.


Przykład Pliku Planszy

Plansza jest wczytywana z pliku tekstowego, który zawiera pięć wierszy po pięć liczb (monet w polach). Oto przykładowy plik plansza.txt:


Po wczytaniu, gra rozpoczyna się w lewym górnym rogu planszy, a gracz może poruszać się, wybierając ruch w prawo (p) lub w dół (d).

Opis Rozwiązania Opartego o Metodę Zachłanną

Metoda zachłanna to podejście, w którym na każdym etapie decyzji wybieramy najbardziej opłacalną opcję (lokalnie najlepszą). W kontekście tej gry metoda zachłanna mogłaby być wykorzystana do wybrania ścieżki, która na każdym kroku maksymalizuje liczbę zebranych monet. W tym przypadku gracz na każdym ruchu wybiera, czy pójść w dół czy w prawo, wybierając ruch do pola, które zawiera więcej monet.

Jednak w grze, którą realizuje ten skrypt, metoda zachłanna nie jest wprost zastosowana przez gracza – gracz sam decyduje, który ruch wykona, na podstawie własnej strategii. Natomiast metoda zachłanna mogłaby być zaimplementowana w algorytmie, który automatycznie wybierałby kierunek, aby zebrać jak najwięcej monet. W tym przypadku algorytm porównywałby liczbę monet na polu na prawo i polu poniżej, a następnie wybierałby kierunek, który prowadzi do większej liczby monet.

W naszym skrypcie metoda zachłanna została wspomniana w kontekście obliczania optymalnej liczby monet, choć nie pokazujemy jej bezpośrednio w grze. Gracz jednak może samodzielnie zastosować strategię zachłanną, obserwując liczby na sąsiednich polach.

Podsumowanie

Gra ta jest prostym projektem, który pozwala na trenowanie podstaw programowania w Pythonie oraz pracy z plikami. Skrypt pokazuje, jak można wykorzystać proste funkcje do generowania planszy i wyświetlania jej stanu po każdym ruchu. Mimo że gra nie wymaga zaawansowanych technik, jest dobrym przykładem zastosowania algorytmów i metod, takich jak metoda zachłanna, w prostych problemach.

Zachęcam do eksperymentowania z kodem – możesz zmienić zasady gry, powiększyć planszę, a nawet wprowadzić elementy sztucznej inteligencji, które same będą wybierały najlepsze ruchy.

Przykładowy kod: link

 

Was this helpful?

0 / 0