Click here to Skip to main content
13,701,517 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

10.9K views
203 downloads
4 bookmarked
Posted 24 Oct 2017
Licenced GPL3

Bowling Calculator

, 14 Jan 2018
Rate this:
Please Sign up or sign in to vote.
An application to keep score of a bowling game with a hand-written looking score card

The Bowlers Name dialog

The Bowling Calculator dialog

The Bowlers score card

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

/*
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)

Share

About the Author

Andy Bantly
Founder
United States United States
Working as a software developer since 1989. Started out with Basic, FORTRAN and JCL, moved into Visual Basic 1.0, C, then C++, and now I work mainly in C++ using MFC, Win32, and ATL/COM. I use Microsoft Products only because that is what gives me gainful employment. Through work, I have a lot of experience with HTML, JavaScript, XSL transformations, the XMLHTTP object, PHP 4.x, and simple COM object integrations.

I've worked for the University of Oklahoma in the school of meteorology (Go SOONERS!), consulting, and now as a Senior Software Engineer. These things keep my lights on and electricity going. My dream job is to own a bowling alley and rub elbows with pro-bowlers! I'm also an avid pedicab driver and have my own cab. I like the hustle of picking up people in downtown and biking them to their destination.

You may also be interested in...

Comments and Discussions

 
QuestionIndentation Pin
Nelek14-Jan-18 9:50
protectorNelek14-Jan-18 9:50 
AnswerRe: Indentation Pin
Andy Bantly14-Jan-18 11:22
memberAndy 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
memberAndy 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
protectorOriginalGriff24-Oct-17 20:23 
AnswerRe: Formatting... Pin
Andy Bantly25-Oct-17 6:56
memberAndy 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
memberAndy 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
memberAndy Bantly26-Oct-17 5:05 
GeneralRe: [My vote of 2] My vote of 2 Pin
Southmountain1-Nov-17 4:29
memberSouthmountain1-Nov-17 4:29 
QuestionScoring Pin
Andy Bantly24-Oct-17 6:53
memberAndy Bantly24-Oct-17 6:53 
SuggestionRe: Scoring Pin
Rick York24-Oct-17 7:25
memberRick York24-Oct-17 7:25 
GeneralRe: Scoring Pin
Andy Bantly24-Oct-17 7:56
memberAndy Bantly24-Oct-17 7:56 
GeneralRe: Scoring Pin
Rick York24-Oct-17 10:14
memberRick York24-Oct-17 10:14 
GeneralRe: Scoring Pin
Andy Bantly24-Oct-17 11:12
memberAndy 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
memberAndy 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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04-2016 | 2.8.180910.1 | Last Updated 14 Jan 2018
Article Copyright 2017 by Andy Bantly
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid