65.9K
CodeProject 正在变化。 阅读更多。
Home

保龄球计算器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.75/5 (10投票s)

2017年10月24日

GPL3

2分钟阅读

viewsIcon

33334

downloadIcon

452

一个用于记录保龄球比赛分数的应用程序, 带有手写风格的记分卡

保龄球选手姓名对话框

保龄球计算器对话框

保龄球选手得分卡

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

自动计分器是一种在20世纪70年代引入保龄球馆的计算机计分系统。自动计分器的使用消除了手动记分的工作。这也为那些原本不会参与游戏的新保龄球手提供了机会。大多数现代系统不仅可以计算比赛得分,还可以跟踪 handicap(等级分)和联赛选手的得分。Brunswick Bowling & BilliardsQubicaAMF 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;
}
© . All rights reserved.