[PHP] Zadanie z talia kart


(system) #1

Znalazłem w internecie pewne zadanie z PHP.

<?php

/* Zbuduj PROTOTYP klasy "karta" która będzie symbolizować kartę do gry. 

Z kartą można zrobić następujące rzeczy:

-położyć kartę na stół.

-wsiąść kartę ze stołu.


Powołaj potem nową kartę (obiekt) - Dama Kier i połóż ją na stół.

Pamiętaj przy tym że różne karty mają różne właściwości.

*/




class Karta {


	private $WybiezKarte;

	private $Stol = array();

	private $TaliaKart = array();


	private $aKarty = array('Kolor' => array('Kier' , 'Pik' , 'Serce' , 'Trefl') ,

							'Oznaczenie' => array('As','2','3','4','5','6','7','8','9','10','Jupek','Dama','Krol') );



	public function Karta (){

		$this->WybiezKarte = '';

		$this->SortujTalieKart();

	}


	private function SortujTalieKart(){

		if(is_array($this->aKarty)){

			foreach ($this->aKarty['Kolor'] as $TKolor){

				foreach($this->aKarty['Oznaczenie'] as $TOznacznie){

					$this->TaliaKart[] = $TOznacznie." ".$TKolor;

				}

			}

			asort($this->TaliaKart);

			return true;

		}

		return false;

	}


	private function StanKarty(){

		if(in_array($this->WybiezKarte , $this->TaliaKart)){

			print("Karta ".$this->WybiezKarte." znajduje w talli.
");

		}else{

			if(in_array($this->WybiezKarte , $this->Stol)){

				print("Karta ".$this->WybiezKarte." znajduje sie na stole
");

			}else{

				print("Karta ".$this->WybiezKarte." nie znajduje sie w talli.
");

			}

		}

	}


	public function PolozKarteNaStol($NowaKarta = ''){

		$this->WybiezKarte = $NowaKarta;

		if(in_array($this->WybiezKarte , $this->TaliaKart)){

			$klucz_tablicy_TK = array_search($this->WybiezKarte , $this->TaliaKart);

			$this->Stol[$klucz_tablicy_TK] = $this->WybiezKarte;

			unset($this->TaliaKart[$klucz_tablicy_TK]);

			$this->StanKarty();

			return true;

		}else{

			return false;

		}

	}


	public function WezKarteZeStolu($BranaKarta = ''){

		$this->WybiezKarte = $BranaKarta;

		if(in_array($this->WybiezKarte , $this->Stol)){

			$klucz_tablicy_S = array_search($this->WybiezKarte , $this->Stol);

			$this->TaliaKart[$klucz_tablicy_S] = $this->WybiezKarte;

			unset($this->Stol[$klucz_tablicy_S]);

			$this->StanKarty();

			return true;

		}else{

			return false;

		}

	}


	public function Pokaz_Stol_z_Kartami(){

		$txt = "
Stol z Kartami";

		$txt .= "
  • "; foreach ($this->Stol as $TK){ $txt .= "
  • ".$TK.""; } $txt .= "
    "; $txt .= "----------------"; print($txt); } } $NowaTaliaKart = new Karta(); $NowaTaliaKart->PolozKarteNaStol('As Pik'); $NowaTaliaKart->WezKarteZeStolu('As Pik'); $NowaTaliaKart->PolozKarteNaStol('5 Pik'); $NowaTaliaKart->PolozKarteNaStol('8 Serce'); $NowaTaliaKart->PolozKarteNaStol('As2 Pik2'); //Wynik nie jest pokazywane ponieważ karta nie występuje w tablicy "TaliaKart" $NowaTaliaKart->PolozKarteNaStol('8 Trefl'); $NowaTaliaKart->PolozKarteNaStol('9 Kier'); $NowaTaliaKart->PolozKarteNaStol('2 Serce'); $NowaTaliaKart->WezKarteZeStolu('2 Serce'); $NowaTaliaKart->Pokaz_Stol_z_Kartami(); ?>[/code] Oto wynik :
    [code]Karta As Pik znajduje sie na stole Karta As Pik znajduje w talli. Karta 5 Pik znajduje sie na stole Karta 8 Serce znajduje sie na stole Karta 8 Trefl znajduje sie na stole Karta 9 Kier znajduje sie na stole Karta 2 Serce znajduje sie na stole Karta 2 Serce znajduje w talli. Stol z Kartami * 5 Pik * 8 Serce * 8 Trefl * 9 Kier ----------------

Nie wiem czy dobrze zadanie interpretowałem , czy dało by się to zrobić nieco zgrabniej i prościej?

Jak coś źle zrobiłem to przepraszam >.< .


(Airborn) #2

Ogólnie sporo rzeczy jest nie tak jak być powinno. Zaczynając od pojęć takich jak enkapsulacja, czy tedlaczego konstruktor zwraca cokolwiek. Klasa jest też zupełnie bezsensownie zaprojektowana, dlaczego ma pola takie jak stół, czy talia?


(system) #3

Poprawiłem Skrypt , wygląda teraz nieco wyraźniej , lecz nie wiem czy coś nadal jest nieprawidłowo napisane.

//Edytowałem pierwszy post.


([alex]) #4

Nadał wszystkie zarzuty od Airborn , są aktualne.

Jest tego o wiele więcej tylko że pewnie Airborn nie podał wszystkiego z racji tego, że jak poradzisz sobie z tymi wadami - resztę już sam zauważysz :smiley: A może dla tego że lista wad byłaby zbyt długa.


(system) #5

Kolejna próba zmiany klasy : http://wklej.org/hash/00635d02b2/.


(Grzegorz Kwiatek) #6

No niestety nie o to chodzi. Klasa jest źle zaprojektowana jak słusznie zauważyli przedmówcy. Przede wszystkim zwróć uwagę na to co napisał Airborn na samym początku. Pomyśl o karcie jako rzeczywistym obiekcie. Tak na zdrowy rozum, karta nie zawiera w sobie talii kart, nie zawiera też w sobie stołu.

Talia, jako tablica, powinna być prawdopodobnie na zewnątrz klasy. Z kolei jeśli chodzi ci o znacznik, czy dana karta jest na stole czy w ręce, to pewnie powinieneś wrzucić w klasę np. bool NaStole; i odwoływać się do tej zmiennej poprzez funkcje klasy "PolozNaStol(...),PodniesZeStolu(...)", które by zmieniały znacznik (jeśli to w ogóle konieczne).


(matiit) #7

Ogólnie to może znasz składnie, ale nie wiesz jak "projektować" klasę.

Ma być jak najprostsza i jak najbardziej przypominać rzeczywistą rzecz. Wyobrażasz sobie kartę i "co może ona robić i co można robić z nią"... i już masz metody, "jakie ma właściwości" i już masz pola.

http://xion.org.pl/files/texts/mgt/html/1_7.html


(Tomipik) #8

Zgadzam sie z przedmowcami. Ja tu widze 3 rozwiazania odnosnie danego stanu karty. Jezeli karta moze byc tylko na stole albo w talii to rozwiazanie gregusa jest jak najbardziej odpowiednie i optymalne w tym przypadku. Jezeli moga byc jeszcze jakies inne stany, to mozna miejsce polozenia koarty oznaczac enumem. Kolejne rozwiazanie w miare opymalne, jakie mi przychodzi na mysl w tym przypadku, to 2 listy - kart na stole i kart w talii i tam mozesz przechoywac obiekty kart. Dwa pierwsze rozwiania gwarantuja Ci ze karta nie bedzie na stole i w talii na raz, a w 3 musisz sam to zabezpieczyc.


(system) #9

Aż mi głupio , może teraz będzie prawidłowo (lecz w to wątpię...) może za "x" razem uda mi się to zrobić jak należy :frowning:

http://wklej.org/hash/eed348fb02/


(Airborn) #10

Ja bym się nadal nie zgodził z wieloma rzeczami. Takie szczegóły jak chociażby zmiana koloru. Widziałeś kiedyś, żeby ktoś przemalowywał kartę sobie? :clever:

Może podrzucę swoją przykładową implementację klasa talia, klasa karta, przykładowe wykorzystanie. To wciąż wersja którą można dalej rozbudować, ale moim zdaniem budowa tego na jednej karcie jest trochę bez sensu.


(system) #11

Dzięki Airborn za przykładową implementacje teraz już wiem czemu każdy mówił , że klasa jest źle zaprojektowana. W gruncie rzeczy wszystko co napisałem nie miało mieć prawa nazwania tego klasą , muszę więcej takich przykładów przerobić abym miał lepsze pojęcie na temat projektowania , lecz trudno znaleźć w necie takie przykładowe zadanka. To co matiit podał jest przydatne.