Last active
March 25, 2023 10:39
-
-
Save CamKem/81ae338d3e96888f5f74d8f33392fe9e to your computer and use it in GitHub Desktop.
Class: Tennis Match Kata
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Tests\Feature\Katas; | |
use PhpParser\Node\Expr\Cast\Object_; | |
class TennisMatch | |
{ | |
protected Player $playerOne; | |
protected Player $playerTwo; | |
public function __construct(Player $playerOne, Player $playerTwo) | |
{ | |
$this->playerOne = $playerOne; | |
$this->playerTwo = $playerTwo; | |
} | |
/** | |
* @return string | |
*/ | |
public function score(): string | |
{ | |
if ($this->isDeuce()) { | |
return 'deuce'; | |
} | |
if ($this->isTie()) { | |
return $this->playerOne->toScore() . '-all'; | |
} | |
if ($this->hasWinner()) { | |
return 'Winner: ' . $this->leader()->name; | |
} | |
if ($this->hasAdvantage()) { | |
return 'Advantage: ' . $this->leader()->name; | |
} | |
if ($this->isTieBreak()) { | |
return 'Tie-Breaker'; | |
} | |
if ($this->isTieBreakWinner()) { | |
return 'Winner: ' . $this->leader()->name; | |
} | |
return $this->defaultScore(); | |
} | |
/** | |
* @return bool | |
*/ | |
private function hasWinner(): bool | |
{ | |
if ( | |
$this->hasPointsInRange($this->playerOne->points, 4, 6) && | |
$this->leadsBy($this->playerOne->points, $this->playerTwo->points, 2) | |
) { | |
return true; | |
} else if ( | |
$this->hasPointsInRange($this->playerTwo->points, 4, 6) && | |
$this->leadsBy($this->playerTwo->points, $this->playerOne->points, 2) | |
) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* @return bool | |
*/ | |
private function hasAdvantage(): bool | |
{ | |
if ( | |
$this->hasPointsInRange($this->playerOne->points, 4, 5) && | |
!$this->isDeuce() | |
) { | |
return true; | |
} else if ( | |
$this->hasPointsInRange($this->playerTwo->points, 4, 5) && | |
!$this->isDeuce() | |
) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* @return Player | |
*/ | |
private function leader(): Player | |
{ | |
return $this->greaterThan($this->playerOne->points, $this->playerTwo->points) | |
? $this->playerOne | |
: $this->playerTwo; | |
} | |
/** | |
* @return bool | |
*/ | |
private function isTie(): bool | |
{ | |
return $this->playerOne->points < 3 && $this->scoresAreEqual(); | |
} | |
/** | |
* @return bool | |
*/ | |
private function isDeuce(): bool | |
{ | |
return $this->hasPointsInRange($this->playerOne->points, 3, 5) && $this->scoresAreEqual(); | |
} | |
/** | |
* @return bool | |
*/ | |
private function isTieBreak(): bool | |
{ | |
return $this->playerOne->points === 6 && $this->scoresAreEqual(); | |
} | |
/** | |
* @return bool | |
*/ | |
private function isTieBreakWinner(): bool | |
{ | |
if ($this->playerOne->points === 7 && $this->greaterThan($this->playerOne->points, $this->playerTwo->points)) { | |
return true; | |
} | |
if ($this->playerTwo->points === 7 && $this->greaterThan($this->playerTwo->points, $this->playerOne->points)) { | |
return true; | |
} | |
return false; | |
} | |
private function greaterThan($a, $b): bool | |
{ | |
return $a > $b; | |
} | |
/** | |
* @return string | |
*/ | |
public function defaultScore(): string | |
{ | |
return $this->playerOne->toScore() . '-' . $this->playerTwo->toScore(); | |
} | |
/** | |
* @param $winning | |
* @param $loosing | |
* @param $points | |
* @return bool | |
*/ | |
public function leadsBy($winning, $loosing, $points): bool | |
{ | |
return $winning >= $loosing + $points; | |
} | |
/** | |
* @param $player | |
* @param $greaterThan | |
* @param $lessThan | |
* @return bool | |
*/ | |
function hasPointsInRange($player, $equalOrGreaterThan, $equalOrLessThan): bool | |
{ | |
return $player >= $equalOrGreaterThan && $player <= $equalOrLessThan; | |
} | |
/** | |
* @return bool | |
*/ | |
public function scoresAreEqual(): bool | |
{ | |
return $this->playerOne->points === $this->playerTwo->points; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment