Bowling Calculator






3.75/5 (10 votes)
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;
}