Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class ActionMaster {
- public enum Action {Tidy, EndTurn, EndGame, Reset};
- private int currentFrame = 1;
- private int currentPlayerIndex = 0;
- private string currentPlayer;
- private SortedList<string, Frame[]> scoreCard;
- // requires a list of player names
- public ActionMaster(string[] newPlayers) {
- scoreCard = new SortedList<string, Frame[]>();
- foreach (string player in newPlayers) {
- Frame[] frames = new Frame[10];
- for (int i = 0; i < 9; i++) {
- frames[i] = new Frame(Frame.FrameType.Normal, (i+1));
- }
- frames[9] = new Frame(Frame.FrameType.Last, 10);
- scoreCard[player] = frames;
- }
- //set the current player name to first player
- currentPlayer = scoreCard.Keys[currentPlayerIndex];
- }
- public string GetCurrentPlayer() {
- return currentPlayer;
- }
- //return the score
- public int GetPlayerScore(string playerName) {
- Frame[] frames = scoreCard[playerName];
- int score = 0;
- for (int i = 0; i < currentFrame; i++) {
- Frame nextFrame = null, twoAfterFrame = null;
- if ((i + 1) < currentFrame) nextFrame = frames[i+1];
- if ((i + 2) < currentFrame) twoAfterFrame = frames[i+2];
- int frameScore = frames[i].GetScore(nextFrame, twoAfterFrame);
- if (frameScore > 0) {
- //int frameON = i + 1;
- //Debug.Log ("score for player: " + playerName + ", on frame: " + frameON + ": " + frameScore);
- score += frameScore;
- }
- }
- return score;
- }
- protected bool IsLastPlayer() {
- int playerNum = currentPlayerIndex + 1;
- if (playerNum < scoreCard.Count) return false;
- else return true;
- }
- protected void StartNewRound() {
- currentPlayerIndex = 0;
- currentPlayer = scoreCard.Keys[currentPlayerIndex];
- currentFrame += 1;
- }
- protected void AdvanceToNextPlayer() {
- currentPlayerIndex++;
- currentPlayer = scoreCard.Keys[currentPlayerIndex];
- }
- public Action Bowl (int pins) {
- if ((pins < 0) || (pins > 10)) throw new UnityException ("Pin count is invalid!");
- int frameIndex = currentFrame - 1;
- Frame[] frames = scoreCard[currentPlayer];
- Frame currentPlayerFrame = frames[frameIndex];
- currentPlayerFrame.AddBowl(pins);
- // check to see if the player's frame is finished
- if (currentPlayerFrame.IsFrameFinished()) {
- //check to see if this is the last player
- if (IsLastPlayer()) {
- //if it is the last frame, end the game
- if (currentFrame == 10) return Action.EndGame;
- // otherwise advance the current frame and player
- StartNewRound();
- } else {
- AdvanceToNextPlayer();
- }
- return Action.EndTurn;
- } else {
- // handle the special case of a strike or spare on the last frame
- if (currentFrame == 10) {
- if (currentPlayerFrame.IsSpare()) return Action.Reset;
- else if (currentPlayerFrame.IsStrike()) {
- if(currentPlayerFrame.GetBowlCount() == 2) return Action.Tidy;
- else if (currentPlayerFrame.GetBowlCount() == 1) return Action.Reset;
- }
- }
- // frame is not finished so tidy
- return Action.Tidy;
- }
- }
- // protected inner class to hold frame data
- protected class Frame {
- public enum FrameType {Normal, Last};
- // will include 3 on last frame
- private int[] bowls;
- //private int frameNumber;
- private int bowlsTaken = 0;
- private FrameType type;
- public Frame(FrameType type, int number) {
- if (type.Equals(FrameType.Last)) bowls = new int[3];
- else bowls = new int[2];
- // initialize array to zero values
- for (int i = 0; i < bowls.Length; i++) {
- bowls[i] = 0;
- }
- //frameNumber = number;
- this.type = type;
- }
- // clean up the code in other calls
- public bool IsStrikeOrSpare() {
- return (IsStrike() || IsSpare());
- }
- // ok to pass a null next frame on last frame
- // if the score cannot yet be calculated, -1 is
- // returned
- public int GetScore(Frame nextFrame, Frame secondNextFrame) {
- if (IsStrike()) return CalculateStrikeScore(nextFrame, secondNextFrame);
- else if (IsSpare()) return CalculateSpareScore(nextFrame);
- else return CalculateNormalScore();
- }
- /**
- * If two bowls have been taken, a score is returned. Otherwise, -1 is returned.
- */
- private int CalculateNormalScore() {
- if (bowlsTaken < 2) return -1;
- else return (bowls[0] + bowls[1]);
- }
- /**
- * Calculates the score for a spare. If there has not been a next frame bowled yet,
- * this method is null safe so just pass in null. Will return -1 if there has not
- * been enough bowls to calculate
- */
- private int CalculateSpareScore(Frame nextFrame) {
- if (type.Equals(FrameType.Last)) {
- // last frame we use the 3 bowls to calculate
- if (bowlsTaken < 3) return -1;
- else return (bowls[0] + bowls[1] + bowls[2]);
- } else {
- if ((nextFrame == null) || (nextFrame.GetBowlCount() < 1)) return -1;
- else return (10 + nextFrame.GetFirstBowl());
- }
- }
- /**
- * Use this to calculate the score for a strike. It is ok to pass null values in
- * for input frames if they have not yet occured. A return of -1 indicates that
- * there is not enough data to calculate a score
- */
- private int CalculateStrikeScore(Frame nextFrame, Frame secondNextFrame) {
- if (type.Equals(FrameType.Last)) {
- // have to bowl 3 times on the last frame for a strike
- if (bowlsTaken < 3) return -1;
- else {
- return (bowls[0] + bowls[1] + bowls[2]);
- }
- } else {
- if (nextFrame == null) return -1;
- // case of a strike with the next bowl being normal
- if ((nextFrame.GetBowlCount() > 1) && (!nextFrame.IsStrike())) return (10 + nextFrame.GetFirstBowl() + nextFrame.GetSecondBowl());
- // ninth round special case
- if (nextFrame.type.Equals(FrameType.Last) && (nextFrame.bowlsTaken > 1)) {
- return (10 + nextFrame.GetFirstBowl() + nextFrame.GetSecondBowl());
- }
- // case of a strike and another strike
- if (nextFrame.IsStrike()) {
- //need the next frame to calculate
- if ((secondNextFrame == null) || (secondNextFrame.GetBowlCount() < 1)) return -1;
- else return (20 + secondNextFrame.GetFirstBowl());
- }
- //not enough frames to calculate yet
- return -1;
- }
- }
- // true if all the bowls associated with this frame are completed.
- // note that in the case of a strike or spare a score may not yet be available
- public bool IsFrameFinished() {
- // deal with special cases first
- if (type.Equals(FrameType.Last)) {
- if (!IsStrikeOrSpare() && (GetBowlCount() > 1)) return true;
- else if (GetBowlCount() > 2) return true;
- else return false;
- } else {
- //normal frame
- if (IsStrike() || (GetBowlCount() > 1)) return true;
- else return false;
- }
- }
- public void AddBowl(int pinCount) {
- bowls[bowlsTaken] = pinCount;
- //index by 1
- bowlsTaken++;
- }
- public int GetFirstBowl() {
- return bowls[0];
- }
- public int GetSecondBowl() {
- return bowls[1];
- }
- public int GetBowlCount() {
- return bowlsTaken;
- }
- public bool IsStrike() {
- if (bowls[0] == 10) return true;
- else return false;
- }
- public bool IsSpare() {
- if (bowls[0] == 10) return false;
- int total = bowls[0] + bowls[1];
- if (total == 10) return true;
- return false;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement