Thursday, September 29, 2011

The Bowling Game Kata in PHP

I did the famous Bowling Game Kata and converted it from Java to PHP, and used PHPUnit for unit tests, and thought I'd share my code for anyone who wants to see it.

If you run the tests like:
 $ phpunit --testdox BowlingTest.php
you should see the tests all pass like:

    Bowling
       [x] Should roll gutter game
       [x] Should roll all ones
       [x] Should roll one spare
       [x] Should roll one strike
       [x] Should roll perfect game
 <?php 
      
 class Game
 { 
   private $rolls = array();
  
   public function roll($pins) {
     $this->rolls[] = $pins;
   } 
  
   public function score() {
     $score = 0;
     $rollsMax = count($this->rolls);
     $firstInFrame = 0;
  
     for ($frame = 0; $frame < 10; $frame++) {
       if ($this->isStrike($firstInFrame)) {
         $score += 10 + $this->nextTwoBallsForStrike($firstInFrame);
         $firstInFrame++;
       } else if ($this->isSpare($firstInFrame)) {
           $score += 10 + $this->nextBallForSpare($firstInFrame);
           $firstInFrame += 2;
       } else {
         $score += $this->twoBallsInFrame($firstInFrame);
         $firstInFrame += 2;
       }
     }
  
     return $score; 
   } 
  
   public function nextTwoBallsForStrike($firstInFrame) {
     return $this->rolls[$firstInFrame + 1] + $this->rolls[$firstInFrame + 2];
   }

   public function nextBallForSpare($firstInFrame) {
     return $this->rolls[$firstInFrame + 2];
   } 
  
   public function twoBallsInFrame($firstInFrame) {
     return $this->rolls[$firstInFrame] + $this->rolls[$firstInFrame + 1];
   }

  
   public function isStrike($firstInFrame) {
     return $this->rolls[$firstInFrame] == 10;
   }

   public function isSpare($firstInFrame) {
     return $this->rolls[$firstInFrame] + $this->rolls[$firstInFrame+1] == 10;
   }

   public function rollSpare() {
     $this->roll(5);
     $this->roll(5);
   }
 }


 class BowlingTest extends PHPUnit_Framework_TestCase {
   private $g;

   public function setUp() {
     $this->g = new Game;
   }

   /**
    * @test
    */
   public function Should_roll_gutter_game() {
     $this->rollMany(20, 0);
     $this->assertEquals(0, $this->g->score());
   }

   /**
    * @test
    */
   public function Should_roll_all_ones() {
     $this->rollMany(20, 1);
     $this->assertEquals(20, $this->g->score());
   }

   /**
    * @test
    */
   public function Should_roll_one_spare() {
     $this->g->rollSpare();
     $this->g->roll(3);
     $this->rollMany(17, 0);
     $this->assertEquals(16, $this->g->score());
   }

   /**
     * @test
    **/
   public function Should_roll_one_strike() {
     $this->rollStrike();
     $this->g->roll(3);
     $this->g->roll(4);
     $this->rollMany(16, 0);
     $this->assertEquals(24, $this->g->score());
   }

   /**
    * @test
    **/
   public function Should_roll_perfect_game() {
      $this->rollMany(12, 10);
      $this->assertEquals(300, $this->g->score());
   }

   public function rollMany($n, $pins) {
     for ($i = 0; $i < $n; $i++) {
         $this->g->roll($pins);
     }
   }

   public function rollStrike() {
     $this->g->roll(10);
   }
 }
 

1 comment:

About Me

Followers