Click here to Skip to main content
15,867,895 members
Articles / Programming Languages / C++

Bowling Calculator

Rate me:
Please Sign up or sign in to vote.
3.75/5 (11 votes)
14 Jan 2018GPL32 min read 30.8K   400   4   20
An application to keep score of a bowling game with a hand-written looking score card

The Bowlers Name dialog

Image 1

The Bowling Calculator dialog

Image 2

The Bowlers score card

Image 3

https://en.wikipedia.org/wiki/Automatic_scorer

An automatic scorer is the computerized scoring system introduced into bowling alleys in the 1970s. The use of automatic scorers took away the task of keeping score by hand. This also introduced new bowlers to the game that otherwise would not participate. Most modern systems not only tally the score of a game, but also keep track of handicaps and the scores of league players. Brunswick Bowling & Billiards and QubicaAMF Worldwide are leaders in the research and development of computer systems for bowling alleys for score keeping and other related business (i.e. finance bookkeeping, payrolls, account receivables, account payables).[1]

Automatic scoring equipment is considered as a cornerstone of the bowling center and is marketed as such by capital equipment manufacturers. Today's systems offer advanced graphics, advertising, and marketing features and can also support scoring non-traditional games such as no-tap.

Automatic scorers detect electronically a bowling pin with a wood core and an ionomer cladding. The pin has a fluorescent coating on the outer surface usually in the neck portion. The reason for this is so that electronically it can be detected if still standing or it has been knocked down. This is done with an ultraviolet light detecting system.[2]

Many bowlers didn't trust automatic scorers when they were introduced in the 1970s. Many continued to keep score using the traditional method on paper score sheets to verify the accuracy of the automatic scorers. Today, however, automatic scorers are found in most modern bowling centers. A 16-lane bowling center in Chicago installed the first Automatic Scorer in 1967 by Brunswick Corporation.[3]

In some installations, the automatic scoring is connected directly to the pinsetter circuitry with results sent electronically to the scorer. On string-based pin setting (used in five pin and some ten pin facilities) scores are determined by identifying which pin strings were tugged. Automatic scoring can also be directly connected to a Brunswick GS series pinsetter, which lowers the pin table after each ball.

The automatic scoring is directly connected to the foul detection unit so that foul line violations are automatically scored.

Scoring Code

C++
/*
Deceptively simple looking iterative functions with variability at the 10th iteration.
In reality it is a paradox b/c it looks to the future and to the past at the same time
This is because on a strike or spare the future holds the final score
But when the pin is dropped in the future it has no knowledge of any pins it affects in the past

X = 10 + next 2 shots
/ = 10 + next shot
1 - 10 = face value
10th frame possible 3rd throw
*/

BOOL CBCDlg::UpdateScore(int nP1, int nP2, int nP3, unsigned int & MyCurrentFrame, unsigned int & MyFrameScore, unsigned int & MyRunningTotal, unsigned int & MyTotalScore)
{
	CString cs;
	unsigned int iFrame = MyCurrentFrame;
	{
		unsigned int nFramePins = 10;
		unsigned int nShots = iFrame != 9 ? 2 : 3;

		for (unsigned int iShot = 0; iShot < nShots; ++iShot)
		{
			unsigned int nPins1 = 0;
			if (iShot == 0)
				nPins1 = nP1;
			else if (iShot == 1)
				nPins1 = nP2;
			else if (iShot == 2)
				nPins1 = nP3;

			// Update the pins in the scoring array
			unsigned int iPos = iFrame * 2;
			m_arrPoints[iPos + iShot] = nPins1;

			// Update the remaining number of pins
			nFramePins -= nPins1;

			// Update the remaining number of throws
			if (nFramePins == 0)
			{
				if (iFrame != 9)
					nShots--;
				nFramePins = 10;
			}
			else
			{
				if (iFrame == 9 && iShot == 1 && m_arrPoints[iPos] != 10)
					nShots--;
			}
		}

		// Tally the score and update the score card
		unsigned int iCurrentFrame = 0;
		unsigned int iTotalScore = 0;
		unsigned int iFrameScore = 0;

		unsigned int arrFrameScore[10];
		memset(&arrFrameScore[0], 0, 10 * sizeof(unsigned int));

		while (iCurrentFrame <= iFrame)
		{
			unsigned int iPos = iCurrentFrame * 2;
			unsigned int nPins = m_arrPoints[iPos];
			CString csTemp;

			if (iCurrentFrame != 9)
			{
				// Strike is 10 + sum of next 2 rolls
				if (nPins == 10)
				{
					// Next roll starts in next frame
					unsigned int nPins2 = m_arrPoints[iPos + 2];
					if (nPins2 == 10)
					{
						// Next roll starts in next frame if the next frame is not the last frame
						if ((iCurrentFrame + 1) != 9)
						{
							unsigned int nPins3 = m_arrPoints[iPos + 4];
							iFrameScore = 20 + nPins3;
						}
						else // Next roll starts in the middle shot of the last frame
						{
							unsigned int nPins3 = m_arrPoints[iPos + 3];
							iFrameScore = 20 + nPins3;
						}
					}
					else
					{
						// Next roll is the second shot of the next frame
						unsigned int nPins3 = m_arrPoints[iPos + 3];
						iFrameScore = 10 + nPins2 + nPins3;
					}
					csTemp.Format(_T("%3s"), _T("X"));
					cs += csTemp;
				}
				else
				{
					// Next roll is the next shot
					unsigned int nPins2 = m_arrPoints[iPos + 1];
					if ((nPins + nPins2) == 10)
					{
						// Next roll is the first shot of the next frame
						unsigned int nPins3 = m_arrPoints[iPos + 2];

						// Spare is 10 + sum of next roll
						iFrameScore = 10 + nPins3;

						if (nPins)
							csTemp.Format(_T("%2d%s"), nPins, _T("/"));
						else
							csTemp = _T(" -/");

						cs += csTemp;
					}
					else
					{
						// Open is sum of pins
						iFrameScore = nPins + nPins2;

						if (m_iCurrentThrow == 1 && iCurrentFrame == iFrame)
						{
							if (nPins)
								csTemp.Format(_T(" %d "), nPins);
							else
								csTemp = _T(" - ");
						}
						else
						{
							if (nPins && nPins2)
								csTemp.Format(_T(" %d%d"), nPins, nPins2);
							else if (nPins && !nPins2)
								csTemp.Format(_T(" %d-"), nPins);
							else if (!nPins && nPins2)
								csTemp.Format(_T(" -%d"), nPins2);
							else
								csTemp = _T(" --");
						}
						cs += csTemp;
					}
				}
				cs += _T(" ");
			}
			else
			{
				// Score is sum of pins'
				unsigned int nPins1 = m_arrPoints[iPos];
				unsigned int nPins2 = m_arrPoints[iPos + 1];
				unsigned int nPins3 = m_arrPoints[iPos + 2];
				iFrameScore = nPins1 + nPins2 + nPins3;

				// Generate the score card text
				if (m_iCurrentThrow == 1)
				{
					if (nPins1 == 10) // 1 strike
						csTemp = _T("X  ");
					else
					{
						if (nPins1)
							csTemp.Format(_T("%d  "), nPins1); // Pins
						else
							csTemp = _T("-  ");
					}
				}
				else if (m_iCurrentThrow == 2)
				{
					if (nPins1 == 10 && nPins2 == 10) // 2 strikes
						csTemp = _T("XX ");
					else if (nPins1 == 10 && nPins2 < 10) // 1 strike and pins
					{
						if (nPins2)
							csTemp.Format(_T("X%d "), nPins2);
						else
							csTemp = _T("X- ");
					}
					else if (nPins1 + nPins2 == 10) // 1 spare
					{
						if (nPins1)
							csTemp.Format(_T("%d/ "), nPins1);
						else
							csTemp = _T("-/ ");
					}
					else
					{
						if (nPins1 && nPins2)
							csTemp.Format(_T("%d%d "), nPins1, nPins2); // pins
						else if (nPins1 && !nPins2)
							csTemp.Format(_T("%d -"), nPins1); // pins
						else if (!nPins1 && nPins2)
							csTemp.Format(_T("- %d"), nPins2); // pins
						else
							csTemp = _T("- -");
					}
				}
				else
				{
					if (nPins1 == 10 && nPins2 == 10 && nPins3 == 10) // 3 strikes
						csTemp = _T("XXX");
					else if (nPins1 == 10 && nPins2 == 10 && nPins3 < 10) // 2 strikes and pins
					{
						if (nPins3)
							csTemp.Format(_T("XX%d"), nPins3);
						else
							csTemp = _T("XX-");
					}
					else if (nPins1 == 10 && (nPins2 + nPins3) == 10) // 1 strike and a spare
					{
						if (nPins2)
							csTemp.Format(_T("X%d/"), nPins2);
						else
							csTemp = _T("X-/");
					}
					else if ((nPins1 + nPins2) == 10 && nPins3 == 10) // 1 spare and a strike
					{
						if (nPins1)
							csTemp.Format(_T("%d/X"), nPins1);
						else
							csTemp = _T("-/X");
					}
					else if ((nPins1 + nPins2) == 10 && nPins3 < 10) // 1 spare and pins
					{
						if (nPins1 && nPins3)
							csTemp.Format(_T("%d/%d"), nPins1, nPins3);
						else if (nPins1 && !nPins3)
							csTemp.Format(_T("%d/-"), nPins1);
						else if (!nPins1 && nPins3)
							csTemp.Format(_T("-/%d"), nPins3);
						else
							csTemp = _T("-/-");
					}
					else
					{
						if (nPins1 && nPins2)
							csTemp.Format(_T("%d%d"), nPins1, nPins2);
						else if (nPins1 && !nPins2)
							csTemp.Format(_T("%d-"), nPins1);
						else if (!nPins1 && nPins2)
							csTemp.Format(_T("-%d"), nPins2);
						else
							csTemp = _T("--");
					}
				}

				// Append the score
				cs += csTemp;
			}

			// Update the frame and total score
			arrFrameScore[iCurrentFrame] = iFrameScore;
			iTotalScore += iFrameScore;

			++iCurrentFrame;
		}


		// Put the pins on the score card
		Text(cs, 1, 2);

		// Get the frame scores
		cs.Empty();
		for (iCurrentFrame = 0; iCurrentFrame <= iFrame; ++iCurrentFrame)
		{
			CString csTemp;
			csTemp.Format(_T("%3d"), arrFrameScore[iCurrentFrame]);
			cs += csTemp;
			if (iCurrentFrame != 9)
				cs += _T(" ");
		}

		// Put the frame score on the score card
		Text(cs, 1, 3);

		// Get the running total
		cs.Empty();
		unsigned int iRunningTotal = 0;
		for (iCurrentFrame = 0; iCurrentFrame <= iFrame; ++iCurrentFrame)
		{
			iRunningTotal += arrFrameScore[iCurrentFrame];
			CString csTemp;
			csTemp.Format(_T("%3d"), iRunningTotal);
			cs += csTemp;
			if (iCurrentFrame != 9)
				cs += _T(" ");
		}

		// Put the running total on the score card
		Text(cs, 1, 4);

		// Set the outparameters
		MyFrameScore = arrFrameScore[MyCurrentFrame];
		MyRunningTotal = iRunningTotal;
		MyTotalScore = iTotalScore;

		CString csTotalScore;
		csTotalScore.Format(_T("Score: %d"), MyTotalScore);
		Text(csTotalScore, 1, 5);
	}

	return 0;
}

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Founder
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionIndentation Pin
Nelek14-Jan-18 9:50
protectorNelek14-Jan-18 9:50 
AnswerRe: Indentation Pin
Andy Bantly14-Jan-18 11:22
Andy Bantly14-Jan-18 11:22 
GeneralRe: Indentation Pin
Nelek15-Jan-18 9:23
protectorNelek15-Jan-18 9:23 
BugReleased Exe works wrong Pin
MikeMSA27-Oct-17 5:24
professionalMikeMSA27-Oct-17 5:24 
GeneralRe: Released Exe works wrong Pin
Andy Bantly27-Oct-17 6:19
Andy Bantly27-Oct-17 6:19 
GeneralRe: Released Exe works wrong Pin
MikeMSA27-Oct-17 6:51
professionalMikeMSA27-Oct-17 6:51 
QuestionFormatting... Pin
OriginalGriff24-Oct-17 20:23
mveOriginalGriff24-Oct-17 20:23 
AnswerRe: Formatting... Pin
Andy Bantly25-Oct-17 6:56
Andy Bantly25-Oct-17 6:56 
Suggestion[My vote of 2] My vote of 2 Pin
BillW3324-Oct-17 9:32
professionalBillW3324-Oct-17 9:32 
GeneralRe: [My vote of 2] My vote of 2 Pin
Andy Bantly24-Oct-17 11:17
Andy Bantly24-Oct-17 11:17 
PraiseRe: [My vote of 2] My vote of 2 Pin
BillW3326-Oct-17 4:12
professionalBillW3326-Oct-17 4:12 
GeneralRe: [My vote of 2] My vote of 2 Pin
Andy Bantly26-Oct-17 5:05
Andy Bantly26-Oct-17 5:05 
GeneralRe: [My vote of 2] My vote of 2 Pin
Southmountain1-Nov-17 4:29
Southmountain1-Nov-17 4:29 
QuestionScoring Pin
Andy Bantly24-Oct-17 6:53
Andy Bantly24-Oct-17 6:53 
SuggestionRe: Scoring Pin
Rick York24-Oct-17 7:25
mveRick York24-Oct-17 7:25 
GeneralRe: Scoring Pin
Andy Bantly24-Oct-17 7:56
Andy Bantly24-Oct-17 7:56 
The code is attached. Perhaps you can shed some light on what you expect. I posted the algorithm and then the code. I can't spell out the code b/c in my opinion people don't look at it. I can answer any questions but I refuse to be called out since almost every line of code is documented in clear and easy terms.

GeneralRe: Scoring Pin
Rick York24-Oct-17 10:14
mveRick York24-Oct-17 10:14 
GeneralRe: Scoring Pin
Andy Bantly24-Oct-17 11:12
Andy Bantly24-Oct-17 11:12 
AnswerRe: Scoring Pin
jgakenhe24-Oct-17 8:07
professionaljgakenhe24-Oct-17 8:07 
GeneralRe: Scoring Pin
Andy Bantly24-Oct-17 11:14
Andy Bantly24-Oct-17 11:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.