保龄球计算器






3.75/5 (10投票s)
一个用于记录保龄球比赛分数的应用程序,
保龄球选手姓名对话框
保龄球计算器对话框
保龄球选手得分卡
https://en.wikipedia.org/wiki/Automatic_scorer
自动计分器是一种在20世纪70年代引入保龄球馆的计算机计分系统。自动计分器的使用消除了手动记分的工作。这也为那些原本不会参与游戏的新保龄球手提供了机会。大多数现代系统不仅可以计算比赛得分,还可以跟踪 handicap(等级分)和联赛选手的得分。Brunswick Bowling & Billiards和QubicaAMF Worldwide是保龄球馆计算机系统研发领域的领导者,用于计分和其他相关业务(例如财务簿记、工资单、应收账款、应付账款)。[1]
自动计分设备被认为是保龄球馆的基石,并由资本设备制造商以此进行营销。如今的系统提供先进的图形、广告和营销功能,并且还可以支持非传统游戏的计分,例如 no-tap(不倒球)。
自动计分器通过电子方式检测带有木质核心和离子体涂层的保龄球瓶。球瓶外表面通常在瓶颈部分涂有荧光涂层。这样做的原因是,通过电子方式可以检测它是否仍然站立或已被击倒。这是通过紫外线检测系统完成的。[2]
许多保龄球手在20世纪70年代自动计分器推出时并不信任它们。许多人继续使用传统方法在纸质计分卡上记分,以验证自动计分器的准确性。然而,如今,大多数现代保龄球馆都配备了自动计分器。1967年,芝加哥的一个16条球道的保龄球馆安装了 Brunswick Corporation 的第一台自动计分器。[3]
在某些安装中,自动计分器直接连接到 pinsetter(自动摆球机)电路,结果通过电子方式发送到计分器。在基于绳索的摆球机(用于五瓶式和一些十瓶式保龄球馆)中,得分是通过识别哪些绳索被拉动来确定的。自动计分器也可以直接连接到 Brunswick GS 系列摆球机,该摆球机在每次投球后都会降低球瓶台。
自动计分器直接连接到犯规检测单元,以便自动计分犯规线违规。
计分代码
/*
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;
}