1010class Game
1111{
1212 const MAX_FIELDS = 9 ;
13+
1314 const HORIZONTAL_1 = [1 , 2 , 3 ];
1415 const HORIZONTAL_2 = [4 , 5 , 6 ];
1516 const HORIZONTAL_3 = [7 , 8 , 9 ];
@@ -31,49 +32,37 @@ class Game
3132 ];
3233
3334 private string $ id ;
35+ private User $ firstUser ;
36+ private User $ secondUser ;
3437 private array $ board ;
3538 private int $ fieldsFilled ;
3639 private bool $ isFinished ;
3740 private ?string $ winnerId ;
38- private User $ firstUser ;
39- private User $ secondUser ;
4041 private ?string $ lastMovementUserId ;
4142
4243
43- private function __construct ()
44+ private function __construct (User $ firstUser , User $ secondUser )
4445 {
4546 $ this ->id = Uuid::uuid4 ()->toString ();
47+ $ this ->firstUser = $ firstUser ;
48+ $ this ->secondUser = $ secondUser ;
4649 $ this ->isFinished = false ;
50+ $ this ->fieldsFilled = 0 ;
4751 $ this ->winnerId = null ;
4852 $ this ->lastMovementUserId = null ;
49- $ this ->fieldsFilled = 0 ;
50- for ($ i = 1 ; $ i < 10 ; $ i ++) {
53+ for ($ i = 1 ; $ i <= self ::MAX_FIELDS ; $ i ++) {
5154 $ this ->board [$ i ] = null ;
5255 }
5356 }
5457
55- public function id (): string
56- {
57- return $ this ->id ;
58- }
59-
6058 /**
6159 * @param User $firstUser
6260 * @param User $secondUser
6361 * @return Game
6462 */
6563 public static function start (User $ firstUser , User $ secondUser ): self
6664 {
67- $ self = new self ();
68- $ self ->firstUser = $ firstUser ;
69- $ self ->secondUser = $ secondUser ;
70-
71- return $ self ;
72- }
73-
74- public function isFinished (): bool
75- {
76- return $ this ->isFinished ;
65+ return new self ($ firstUser , $ secondUser );
7766 }
7867
7968 /**
@@ -89,9 +78,9 @@ public function isFinished(): bool
8978 public function userMoves (string $ userId , int $ field ): void
9079 {
9180 $ this ->assertIsNotFinished ();
92- $ this ->assertValidField ($ field );
9381 $ this ->assertUserIsPlaying ($ userId );
9482 $ this ->assertUserTurn ($ userId );
83+ $ this ->assertValidField ($ field );
9584 $ this ->assertFieldIsNotFilled ($ field );
9685
9786 $ this ->board [$ field ] = $ userId ;
@@ -126,6 +115,11 @@ private function getWinnerByLine(array $line): ?string
126115 return null ;
127116 }
128117
118+ private function gameCanHaveWinner (): bool
119+ {
120+ return $ this ->fieldsFilled >= 5 ;
121+ }
122+
129123 /**
130124 * @param string $userId
131125 * @throws UserNotPlayingException
@@ -139,33 +133,42 @@ private function assertUserIsPlaying(string $userId): void
139133 throw new UserNotPlayingException ('USER IS NOT PLAYING THIS GAME ' );
140134 }
141135
142- private function assertIsNotFinished (): void
136+ /**
137+ * @param string $userId
138+ * @throws UserTurnException
139+ */
140+ private function assertUserTurn (string $ userId ): void
143141 {
144- if ($ this ->isFinished ) {
145- throw new GameIsFinishedException ( ' GAME IS ENDED ' );
142+ if ($ this ->lastMovementUserId == $ userId ) {
143+ throw new UserTurnException ( ' IS NOT YOUR TURN ' );
146144 }
147145
148146 return ;
149147 }
150148
151- public function winner (): ?User
149+ /**
150+ * @throws GameIsFinishedException
151+ */
152+ private function assertIsNotFinished (): void
152153 {
153- if ($ this ->winnerId == $ this ->firstUser ->id ()) {
154- return $ this ->firstUser ;
155- }
156-
157- if ($ this ->winnerId == $ this ->secondUser ->id ()) {
158- return $ this ->secondUser ;
154+ if ($ this ->isFinished ) {
155+ throw new GameIsFinishedException ('GAME IS ENDED ' );
159156 }
160157
161- return null ;
158+ return ;
162159 }
163160
164- private function assertUserTurn (string $ userId )
161+ /**
162+ * @param int $field
163+ * @throws InvalidFieldException
164+ */
165+ private function assertValidField (int $ field ): void
165166 {
166- if ($ this -> lastMovementUserId == $ userId ) {
167- throw new UserTurnException ( ' IS NOT YOUR TURN ' );
167+ if ($ field < 1 || $ field > self :: MAX_FIELDS ) {
168+ throw new InvalidFieldException ( ' INVALID BOARD FIELD, ONLY FROM 1 TO 9 : ' . $ field );
168169 }
170+
171+ return ;
169172 }
170173
171174 /**
@@ -181,19 +184,27 @@ private function assertFieldIsNotFilled(int $field): void
181184 return ;
182185 }
183186
184- /**
185- * @return bool
186- */
187- private function gameCanHaveWinner (): bool
187+ public function id (): string
188188 {
189- return $ this ->fieldsFilled >= 5 ;
189+ return $ this ->id ;
190190 }
191191
192- private function assertValidField ( int $ field )
192+ public function isFinished (): bool
193193 {
194- if ($ field < 1 || $ field > self ::MAX_FIELDS ) {
195- throw new InvalidFieldException ('INVALID BOARD FIELD, ONLY FROM 1 TO 9 : ' . $ field );
194+ return $ this ->isFinished ;
195+ }
196+
197+ public function winner (): ?User
198+ {
199+ if ($ this ->winnerId == $ this ->firstUser ->id ()) {
200+ return $ this ->firstUser ;
201+ }
202+
203+ if ($ this ->winnerId == $ this ->secondUser ->id ()) {
204+ return $ this ->secondUser ;
196205 }
206+
207+ return null ;
197208 }
198209
199210 public function board (): array
0 commit comments