Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

slooksterPSV

macrumors 68040
Original poster
Apr 17, 2004
3,544
306
Nowheresville
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
 

scan

macrumors 6502
Oct 24, 2005
344
0
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.
 

scan

macrumors 6502
Oct 24, 2005
344
0
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());

	}

}
 

toddburch

macrumors 6502a
Dec 4, 2006
748
0
Katy, Texas
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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.