Skip to content

Instantly share code, notes, and snippets.

@pixels4nickels
Last active December 10, 2015 11:49
Show Gist options
  • Save pixels4nickels/4430039 to your computer and use it in GitHub Desktop.
Save pixels4nickels/4430039 to your computer and use it in GitHub Desktop.
Kata bowling excercise. create a bowling game using 1 game class with 2 methods: roll(pins:int) and score():int . call score() after all rolls are completed.
package {
import flash.utils.Dictionary;
import spark.components.TextArea;
public class Game {
private const TOTAL_LABEL:String = "Total: ";
private const GUTTER_LABEL:String = "Gutter!";
private const OPEN_FRAME:String = "You got ";
private const FRAME_LABEL:String = "Frame: ";
private const STRIKE_LABEL:String = "Strike!";
private const SPARE_LABEL:String = "Spare!";
private const FRAMES_TOTAL:uint = 10;
private const PINS_TOTAL:uint = 10;
private var display:Function = function (frame:uint, roll:uint, result:String):void {
output.text += FRAME_LABEL + frame + " - roll " + roll + ": " + result + "\n";
}
private var currentRoll:uint = 1;
private var currentFrame:uint = 1;
private var scoreData:Dictionary = new Dictionary();
private var finalScore:uint = 0;
private var output:TextArea;
public var currentPinsRemaining:uint = 10;
public function Game(output:TextArea) {
this.output = output;
}
public function roll(pins:int):void {
if (currentFrame < FRAMES_TOTAL){ // Normal frame logic
if (currentRoll == 1) { // 1st roll for the current frame.
scoreData[currentFrame] = []; // create a score node for the frame
currentPinsRemaining = PINS_TOTAL - pins;
scoreData[currentFrame][0] = pins
if (currentPinsRemaining == 0){ // STRIKE!!
display(currentFrame, currentRoll, STRIKE_LABEL);
scoreData[currentFrame][0] = pins; // store roll result
currentFrame++; //increment current frame.
currentRoll = 1;
currentPinsRemaining = PINS_TOTAL; // reset pins
}else if (scoreData[currentFrame][0] == 0){ // gutter
display(currentFrame, currentRoll, GUTTER_LABEL);
currentRoll++;
}else {
display(currentFrame, currentRoll, OPEN_FRAME + pins);
currentRoll++;
}
}else{ // 2nd roll
currentPinsRemaining -= pins;
scoreData[currentFrame][1] = pins; // store roll result
if (currentPinsRemaining == 0) { // spare
display(currentFrame, currentRoll, SPARE_LABEL);
}else if (pins == 0){ // gutter
display(currentFrame, currentRoll, GUTTER_LABEL);
}else {
display(currentFrame, currentRoll, OPEN_FRAME + pins);
}
currentRoll = 1; // reset roll
currentPinsRemaining = PINS_TOTAL; // reset pins
currentFrame++;//increment current frame.
}
}
else if (currentFrame == 10) // 10th frame logic
{
if (currentRoll == 1) {
scoreData[currentFrame] = []; // create a score node for the 10th frame
currentPinsRemaining = PINS_TOTAL - pins;
scoreData[currentFrame][0] = pins; // store roll result
if (pins == 10){ // STRIKE!!
currentPinsRemaining = PINS_TOTAL; // Strike in the 10 frame, 1st ball. Reset pins.
display(currentFrame, currentRoll, STRIKE_LABEL);
}else if (pins == 0) {
display(currentFrame, currentRoll, GUTTER_LABEL);
}else {
display(currentFrame, currentRoll, OPEN_FRAME + pins);
}
currentRoll++;
}
else if (currentRoll == 2) // 2nd roll
{
scoreData[currentFrame][1] = pins; // store roll result
if (scoreData[currentFrame][0] != 10){ // if no strike on 1st roll
currentPinsRemaining -= pins;
if (currentPinsRemaining == 0) {// we cleaned up a spare from 1st frame
currentPinsRemaining = PINS_TOTAL; // Reset pins.
display(currentFrame, currentRoll, SPARE_LABEL);
currentRoll++; // allow another roll
} else {
// did not cleanup spare, no 3rd roll!
display(currentFrame, currentRoll, OPEN_FRAME + pins);
currentFrame++; // kill game by setting frame to 11
output.text += TOTAL_LABEL + score().toString();
}
} else { // "clean" 2nd roll
if (pins == 10){ // Strike again!
currentPinsRemaining = PINS_TOTAL; // Reset pins.
display(currentFrame, currentRoll, STRIKE_LABEL);
} else {
currentPinsRemaining -= pins; // update remaining pins
display(currentFrame, currentRoll, OPEN_FRAME + pins);
}
currentRoll++; // allow 3rd roll
}
}
else // 3rd roll
{
scoreData[currentFrame][2] = pins; // store roll result
if (scoreData[currentFrame][1] != 10 && scoreData[currentFrame][0] + scoreData[currentFrame][1] != 10) // if no strike or spare on 2nd roll
{
currentPinsRemaining -= pins;
if (currentPinsRemaining == 0) {// we cleaned up a spare from 2nd frame
display(currentFrame, currentRoll, SPARE_LABEL);
} else {// did not cleanup spare, no 3rd roll!
display(currentFrame, currentRoll, OPEN_FRAME + pins);
}
} else { // "clean" 3rd roll
if (pins == 10){ // Strike again!!
display(currentFrame, currentRoll, STRIKE_LABEL);
} else {
display(currentFrame, currentRoll, OPEN_FRAME + pins);
}
}
currentFrame++; // kill game by setting frame to 11
output.text += TOTAL_LABEL + score().toString();
}
}
}
public function score():int {
var clearedLastFrame:Boolean = false;
for each(var node:Array in scoreData) {
var frameScore:uint = 0;
if (clearedLastFrame) {
frameScore += node[0];
}
if (node[0] != 10) {
frameScore += node[0] + node[1];
} else {
frameScore += node[0];
}
finalScore += frameScore;
if (frameScore == 10) {
clearedLastFrame = true;
} else {
clearedLastFrame = false;
}
}
return finalScore;
}
}
}
<?xml version="1.0"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
applicationComplete="init()">
<fx:Script><![CDATA[
import mx.controls.Alert;
private var game:Game;
protected function init():void {
output.text = "";
game = new Game(output);
}
]]></fx:Script>
<s:layout><s:VerticalLayout></s:VerticalLayout></s:layout>
<s:TextArea id="output" width="400" height="300" />
<s:Button label="Roll Random" click="game.roll(Math.random()*(game.currentPinsRemaining+1))" />
<s:Button label="Roll Perfect" click="game.roll(game.currentPinsRemaining)" />
<s:Button label="New Game" click="init()" />
</s:WindowedApplication>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment