1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

C++ Bowling Score for class

Discussion in 'Mac Programming' started by slooksterPSV, Jan 21, 2007.

  1. macrumors 68030

    slooksterPSV

    #1
    We have to make a program that calculates the score of a bowling game, here's my code, but it isn't working right here's an input that was given to us along with the scores, my code is at the bottom:
    1----2----3----4----5----6----7----8----9----10
    9\__-\___X___X__62__7\__8\___X___9-__9\X
    10--30---56---74---82--100-120-139-148-168

    Code:
    //Frame.h
    #ifndef __FRAME_H_
    #define __FRAME_H_
    
    #include <iostream>
    using namespace std;
    
    struct Score
    {
    	int amount;
    	char symbol;
    };
    
    Score score[16] = {
    {0, '0'},
    {1, '1'},
    {2, '2'},
    {3, '3'},
    {4, '4'},
    {5, '5'},
    {6, '6'},
    {7, '7'},
    {8, '8'},
    {9, '9'},
    {10, 'X'},
    {10, 'T'},
    {0, 'F'},
    {0, 'G'},
    {0, '-'},
    {10, '\\'} };
    
    class Frame
    {
    	private:
    		int numBowls;
    		char bowl[3];
    		int scoreBowl;
    	public:
    		Frame(int nBowls) { numBowls = nBowls; scoreBowl = 0; };
    		void calculateScore(Frame aFrame, Frame bFrame);
    		void setBowls(char, char, char);
    		int getScore();
    };
    
    void Frame::calculateScore(Frame aFrame, Frame bFrame)
    {
    	Frame tempFrame = Frame(2);
    	tempFrame.setBowls('0','0', '0');
    	int x = 0;
    	int y = 0;
    	for(x = 0; x <= 15; x++)
    	{
    		for(y = 0; y < numBowls; y++)
    		{
    			if((bowl[y] == score[x].symbol) && (bowl[y+1] != '\\'))
    			{
    				scoreBowl = score[x].amount;
    			}else if(bowl[y+1] == '\\')
    			{
    				scoreBowl = 10;
    				aFrame.calculateScore(tempFrame, tempFrame);
    				scoreBowl += aFrame.getScore();
    			//	cout << scoreBowl << "\t\t";
    				y = numBowls;
    				x = 15;
    			}
    			else if((bowl[y] == score[x].symbol) && (score[x].symbol == 'X') )
    			{
    				aFrame.calculateScore(tempFrame, tempFrame);
    				bFrame.calculateScore(tempFrame, tempFrame);
    				//cout << bFrame.bowl << endl;
    				scoreBowl += aFrame.getScore();
    				scoreBowl += bFrame.getScore();
    				y = numBowls;
    				x = 15;
    			}
    			else if((bowl[y] == score[x].symbol) && (score[x].symbol == '\\'))
    			{
    				aFrame.calculateScore(tempFrame, tempFrame);
    				scoreBowl += aFrame.getScore();
    				y = numBowls;
    				x = 15;
    			}
    		}
    	}
    }
    
    void Frame::setBowls(char a, char b, char c)
    {
    	if(numBowls == 2)
    	{
    		bowl[0] = a;
    		bowl[1] = b;
    	}
    	if(numBowls == 3)
    	{
    		bowl[0] = a;
    		bowl[1] = b;
    		bowl[2] = c;
    	}
    }
    
    int Frame::getScore()
    {
    	return scoreBowl;
    }
    
    #endif
    
    Code:
    //main.cpp
    #include <iostream>
    #include "frame.h"
    
    using namespace std;
    
    int main (int argc, char * const argv[]) {
    	char bowling[22];
    	int score = 0;
    	cout << "Please enter bowling scores without spaces in the form of 0-9, T, F, X, \, -: ";
    	cin >> bowling;
    	Frame frm[9] = Frame(2);
    	int y = 0;
    	for(int x = 0; x < 22; x++)
    	{
    		if(y < 9){
    		for(y = 0; y < 10; y++)
    		{
    			if(bowling[x] == 'X')
    			{
    				frm[y].setBowls(bowling[x], '0', '0');
    				//cout << bowling[x]<< "\t" << bowling[x+1] << "\t" << y << endl;
    				x += 1;
    			}else
    			{
    				//cout << bowling[x] << "\t" << bowling[x+1] << "\t" << y << endl;
    				frm[y].setBowls(bowling[x], bowling[x+1], '0');
    				x += 1;
    			}
    		}
    		}
    	}
    //	frm[0].calculateScore(frm[1], frm[2]);
    	for(int z = 0; z < 9; z++)
    	{
    		if(z <= 6)
    		{
    			frm[z].calculateScore(frm[z+1], frm[z+2]);
    		}else if(z == 7)
    		{
    			frm[z].calculateScore(frm[z+1], NULL);
    		}else
    		{
    			frm[z].calculateScore(NULL, NULL);
    		}
    	}
    //	frm[1].calculateScore(frm[2], NULL);
    //	frm[2].calculateScore(NULL, NULL);
    	for(int a = 0; a < 9; a++)
    	{
    		score += frm[a].getScore();
    		cout << score << "\t";
    	}
        return 0;
    }
    
    What do I need to do to fix it or that?

    EDIT: No I don't have the 10th frame setup yet, I wanna get these 9 frames working, numbers 0 to 9 work but X \ - don't
     
  2. macrumors 6502

    #2
    First off, I would like to say I'm no C++ expert but I can give you some suggestions, but I'm still trying to decipher your code. In the meantime, try commenting your code so people reading it know what are your intentions with a block or what a method does.

    You should also probably shorten the main and leave the work to be done in the object's methods or functions if you want to go about this problem in a more procedural way. Your main coudl probably looks something like:

    main():
    contruct bowlingGameObject bgo
    bgo.getsInput(); //populars the scores of the game into a 2d array (maybe?)
    bgo.calcScore(); //calculates the final score

    thats pretty much it. As you can see your main is really messy and shouldn't do that. You are straying from the OOP principal, which you can get away with, but thats not good code.

    if i get the time i'll try to do this in java but i'm at work right now.
     
  3. macrumors 6502

    #3
    Ok just did this after my lunch break. It is in Java but I'm sure you can convert it. Don't mind the mess. I also just hard coded the scores. Cheers.

    class BowlingGame:
    Code:
    import java.util.ArrayList;
    
    public class BowlingGame {
    	//variables
    	//9\__-\___X___X__62__7\__8\___X___9-__9\X
    	//10--30---56---74---82--100-120-139-148-168
    	private ArrayList gameFrame = new ArrayList();
    	private int score = 0;
    	
    	public BowlingGame()
    	{										//index; frame points	
    		gameFrame.add(new Frame('9','/'));	//0; 10
    		gameFrame.add(new Frame('-','/')); 	//1; 20
    		gameFrame.add(new Frame('X',' ')); 	//2; 26
    		gameFrame.add(new Frame('X',' '));	//3; 18
    		gameFrame.add(new Frame('6','2'));	//4; 8
    		gameFrame.add(new Frame('7','/')); 	//5; 18
    		gameFrame.add(new Frame('8','/')); 	//6; 20
    		gameFrame.add(new Frame('X',' ')); 	//7; 19
    		gameFrame.add(new Frame('9','-')); 	//8; 9
    		gameFrame.add(new TenthFrame('9','/','X')); //9; 20
    	}
    	
    	
    	public int calcScore()
    	{
    		Frame nextFrame;
    				
    		for (int i=0; i < 10; i++)
    		{	
    			//if last frame
    			if(i==9) 
    			{
    				System.out.println("Frame #" + (i+1) + "\n" 
    						+ ((TenthFrame)gameFrame.get(i)).getBall1() 
    						+ ", " + ((TenthFrame)gameFrame.get(i)).getBall2()
    						+ ", " + ((TenthFrame)gameFrame.get(i)).getBall3());
    				score += calcTenthFrame((TenthFrame)gameFrame.get(i));
    				System.out.println("running score is " + score);
    			}
    			else
    			{
    				System.out.println("Frame #" + (i+1) + "\n" 
    						+ ((Frame)gameFrame.get(i)).getBall1() 
    						+ ", " + ((Frame)gameFrame.get(i)).getBall2());
    								
    				if( ((Frame)gameFrame.get(i)).isSpare() )
    				{
    					nextFrame = (Frame)gameFrame.get(i+1);
    					score += 10 + intVal(nextFrame.getBall1());
    				}
    				//if next ball is a strike, add the next frame's first ball.
    				else if( ((Frame)gameFrame.get(i)).isStrike() && (i+1)!=9)
    				{
    					nextFrame = (Frame)gameFrame.get(i+1);
    					score += 10;
    					if (nextFrame.getBall1() == 'X')					
    					{	
    						score+=10;
    						nextFrame = (Frame)gameFrame.get(i+2);
    						score+=intVal(nextFrame.getBall1());
    					}
    					else
    						score += calcFrameScore(nextFrame);
    				}
    				else if( ((Frame)gameFrame.get(i)).isStrike() && (i+1)==9)
    				{
    					nextFrame = (TenthFrame)gameFrame.get(i+1);
    					score += 10;
    					if (nextFrame.getBall1() == 'X')					
    					{	
    						score += 10 + intVal(nextFrame.getBall2());
    					}
    					score += intVal(nextFrame.getBall1()) + intVal(nextFrame.getBall2());
    				}
    				else
    					score += calcFrameScore((Frame)gameFrame.get(i));
    				
    				System.out.println("running score is " + score);
    			}
    		
    		}
    		return score;		
    	}
    	
    	public int intVal(char a)
    	{
    		switch(a)
    		{
    		case '1': return 1;
    		case '2': return 2;
    		case '3': return 3;
    		case '4': return 4; 
    		case '5': return 5; 
    		case '6': return 6; 		
    		case '7': return 7; 
    		case '8': return 8; 
    		case '9': return 9;
    		case 'X':
    		case '/':
    			return 10;
    		default: return 0;
    		}
    	}
    	
    	public int calcTenthFrame(TenthFrame frame)
    	{
    		if (frame.getBall2() == '/')
    			return 10 + intVal(frame.getBall3());		
    		else if (frame.getBall3() == '/')
    			return 10 + intVal(frame.getBall1());
    		else
    			return intVal(frame.getBall1()) + intVal(frame.getBall2()) + intVal(frame.getBall3());
    	}
    	public int calcFrameScore(Frame frame)
    	{
    			return intVal(frame.getBall1()) + intVal(frame.getBall2());	
    	}
    	
    }	
    
    
    Frame class:
    Code:
    public class Frame {
    	
    	private char ball1;
    	private char ball2;
    
    	
    	public Frame(char ball1, char ball2)
    	{
    		this.ball1=ball1;
    		this.ball2=ball2;
    	}
    	public char getBall1()
    	{
    		return ball1;
    	}
    	
    	public char getBall2()
    	{
    		return ball2;
    	}
    	public boolean isStrike()
    	{
    		return this.getBall1() == 'X';
    	}
    	public boolean isSpare()
    	{
    		return (this.getBall2() == '/' || this.getBall2() == '/');
    	}
    		
    }
    
    TenthFrame class

    Code:
    public class TenthFrame extends Frame {
    	private char ball3;
    	
    	public TenthFrame(char ball1, char ball2, char ball3)
    	{
    		super(ball1,ball2);
    		this.ball3=ball3;		
    	}
    	
    	public char getBall3()
    	{
    		return ball3;
    	}
    	
    	
    }
    
    Main-Class: GameTest class

    Code:
    public class GameTest {
    
    	public static void main(String[] args) {
    		BowlingGame bg = new BowlingGame();
    		System.out.println("Your score is " + bg.calcScore());
    
    	}
    
    }
    
     
  4. macrumors regular

    #4
    An alternative way to do it.

    You might want to have a look here to get a good idea of how the pros do this sort of thing.
    Bowling Kata
     
  5. macrumors 6502a

    #5
    Ruby. Works.

    Code:
    # Todd Burch  Jan 27, 2007  www.smustard.com 
    
    class Frame ; 
     
    attr_accessor :strike, :spare, :ball ; 
    
      def initialize(fnumber) ; 
        @ball = Array.new(2,0) ; # allow a frame to keep 2 scores.  Init to zero. 
        @spare  = false ;        # assume no spare 
        @strike = false ;        # assume no strike 
        #puts "Frame # = #{fnumber}; scores=#{$scores}" ;    # diagnostic  
        return if (fnumber==11 and $scores.length==0) ;      # there is no 3rd ball in the tenth 
    
        # BALL NUMBER 1  
    
        val = $scores.shift ;          # remove the first character 
        #puts "...BALL 1=>#{val}<" ;   # diagnostic 
        @ball[0] = case val ;          # through the case statement, assign a value to the score. 
          when "X" then @strike = true ;  10 ; 
          when "-" then 0 ; 
          else val.to_i ; 
        end ; 
    
        return if @strike ;            # if a strike was thrown, we're done with this frame. 
        return if $scores.length==0 ;  # if not more scores, we're done.  
    
        # BALL NUMBER 2 
        
        val = $scores.shift  # get next character 
        #puts "...BALL 2=>#{val}<" ;    # diagnostic 
        @ball[1] = case val  ;          # through the case, assign a value to the score. 
          when "X" then 10 ;            # can only occur in the 10th frame. 
          when "\\" then @spare = true ; (10 - @ball[0].to_i) ;   # make both throws add up to 10 
          when "-" then 0 ;             # gutter ball baby.  Get the bumpers. 
          else val.to_i ; 
        end ; 
      end ; 
     
      def total 
        return self.ball[0] + self.ball[1] ;   # add both throws together for this frame. 
      end ;                                    # def total 
    end ;                                      # class Frame ; 
    
    class Game  ; 
    attr_accessor :frame, :score  
    @@frames = 12 ;              # for ease of calculations, pretend there are 12 frames, not ten. 
      def initialize ;           # called for a "new"
        @score = 0 ;             # cumulative score for the game. 
        @frame = Array.new ;     # array to keep track of every frames rolls 
        frame_number = 1 ; 
        @@frames.times do ;      # init the frames array. 
          @frame.push(Frame.new(frame_number)) ; 
          frame_number += 1 ; 
        end ;  # @frames.times  
      end ;                      # initialize 
     
      def calc(frames)           # add up the scores for however many frames. 
      self.frame.each_index {|f| 
        break if f>([frames,9].min) ;       # only count 10 frames 
        j = f + 1 ;                         # next frame index 
        k = f + 2 ;                         # frame + 2 index 
        if self.frame[f].strike then        # if a strike was thrown in this frame... 
           if self.frame[j].strike then     # and the next frame was a strike too... 
              @score += (self.frame[f].total + self.frame[j].total + self.frame[k].ball[0]) ; # add next 2 frame's balls 
           else @score += (self.frame[f].total + self.frame[j].total) ;                       # add next frame's 2 balls    
           end ; 
        elsif self.frame[f].spare then                                  # otherwise, if a spare thrown?  
           @score += (self.frame[j].total + self.frame[j].ball[0])  ;   # add next frame's 1st ball 
        else @score += self.frame[f].total  ;                           # just add this frame's balls 
        end ;                                                           # if strike 
      } 
      @score ;           # return the score 
      end ;   # def calc  
    end ;     # class Game 
    
    DATA.each_line do |d|    # read the data at the "__END__" of the file. 
      $scores = d.strip.split(//) ;           # turn the string into an array 
      g = Game.new ;                          # new up a Game class and all it's frames. 
      puts "The game marking was #{d}" ;      # report the score keeper's notes.  
      i = 0 ; 
      g.frame.each {|f|                      # uncomment out the "puts" for a verbose answer. 
         #puts "frame:#{i+1} balls=#{f.ball[0]},#{f.ball[1]}; spare=#{f.spare}, strike=#{f.strike}: score=#{g.calc(i)}" ; 
         i += 1 ; 
         g.score = 0 ;                       # reset for each iteration  
      }
      puts "The score is #{g.calc(10)}" ;    # Give the total score, count 10 frames worth of scores.  
    end ;    # DATA loop 
    
    __END__
    11223344556677889900
    11121314151617181911
      XXXXXXXXXXXX
    --------------------
    1\2\3\4\5\6\7\8\9\0\9
    -\-\-\-\-\-\-\-\-\-\X
    9\-\XX627\8\X9-9\X
    
     

Share This Page