Skip to content

Instantly share code, notes, and snippets.

@CamKem
Last active March 25, 2023 10:39
Show Gist options
  • Save CamKem/81ae338d3e96888f5f74d8f33392fe9e to your computer and use it in GitHub Desktop.
Save CamKem/81ae338d3e96888f5f74d8f33392fe9e to your computer and use it in GitHub Desktop.
Class: Tennis Match Kata
<?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