public class Game
{
private IOutputProvider _outputProvider;
private List<Frame> frames = new List<Frame>();
private int currentRoll = 0;
public Game(IOutputProvider outputProvider)
{
_outputProvider = outputProvider;
for (int i = 0; i < 10; i++)
{
frames.Add(new Frame());
}
}
public void StarteSpiel()
{
while (!Over())
{
_outputProvider.Write("Geben Sie die Anzahl der umgeworfenen Pins ein: ");
string input = _outputProvider.Read();
int pins;
while (!int.TryParse(input, out pins) || pins < 0 || pins > 10)
{
_outputProvider.Write("Ungültige Eingabe! Bitte geben Sie eine Zahl zwischen 0 und 10 ein: ");
input = _outputProvider.Read();
}
AddRoll(pins);
}
_outputProvider.Write("Spiel beendet! Endpunktzahl: " + TotalScore());
}
private void AddRoll(int pins)
{
if (Over())
{
throw new IndexOutOfRangeException("Das Spiel ist beendet!");
}
int frameIndex = GetCurrentFrameIndex();
if (pins == 10 && currentRoll % 2 == 0 && frameIndex < 9)
{
_outputProvider.Write("Herzlichen Glückwunsch, Sie haben einen Strike geworfen!");
frames[frameIndex].PinsRolled[0] = pins;
frames[frameIndex].IsComplete = true;
currentRoll += 2;
}
else
{
if (frames[frameIndex].PinsRolled[0] + pins > 10 && frameIndex < 9)
{
_outputProvider.Write("Die Summe der beiden Würfe in einem Frame darf nicht mehr als 10 betragen. Bitte geben Sie eine gültige Anzahl Pins ein: ");
return;
}
// Den Wurf zum aktuellen Frame hinzufügen
if (frames[frameIndex].PinsRolled[0] == 0)
{
frames[frameIndex].PinsRolled[0] = pins;
}
else
{
frames[frameIndex].PinsRolled[1] = pins;
frames[frameIndex].IsComplete = true; // Frame ist vollständig
}
currentRoll++;
}
CalculateScores();
_outputProvider.Write($"Aktuelle Punktzahl: {TotalScore()}");
}
private int GetCurrentFrameIndex()
{
return currentRoll / 2;
}
private int TotalScore()
{
int totalScore = 0;
foreach (var frame in frames)
{
totalScore += frame.Score;
}
return totalScore;
}
private bool Over()
{
// Stelle sicher, dass das Spiel 10 Frames hat
if (frames.Count < 10)
{
return false;
}
var lastFrame = frames[9];
if (lastFrame.PinsRolled[0] == 10)
{
return lastFrame.PinsRolled.Length == 3 && currentRoll >= 12;
}
if (lastFrame.PinsRolled[0] + lastFrame.PinsRolled[1] == 10)
{
return currentRoll >= 11;
}
return currentRoll >= 20;
}
private void CalculateScores()
{
for (int i = 0; i < frames.Count; i++)
{
var frame = frames[i];
if (frame.IsComplete)
{
if (IsStrike(i))
{
CalculateStrikeScore(frame, i);
}
else if (IsSpare(i))
{
CalculateSpareScore(frame, i);
}
else
{
frame.Score = frame.PinsRolled[0] + frame.PinsRolled[1];
}
}
}
}
private void CalculateStrikeScore(Frame frame, int frameIndex)
{
frame.Score = 10 + StrikeBonus(frameIndex);
}
private void CalculateSpareScore(Frame frame, int frameIndex)
{
frame.Score = 10 + SpareBonus(frameIndex);
}
private bool IsStrike(int frameIndex)
{
return frames[frameIndex].PinsRolled[0] == 10;
}
private bool IsSpare(int frameIndex)
{
return frames[frameIndex].PinsRolled[0] + frames[frameIndex].PinsRolled[1] == 10;
}
private int StrikeBonus(int frameIndex)
{
if (frameIndex + 1 < frames.Count)
{
var nextFrame = frames[frameIndex + 1];
return nextFrame.PinsRolled[0] + (nextFrame.PinsRolled[1] != 0 ? nextFrame.PinsRolled[1] : (frameIndex + 2 < frames.Count ? frames[frameIndex + 2].PinsRolled[0] : 0));
}
return 0;
}
private int SpareBonus(int frameIndex)
{
if (frameIndex + 1 < frames.Count)
{
return frames[frameIndex + 1].PinsRolled[0];
}
return 0;
}
}
所以大家正在写一个小游戏来计算我在保龄球比赛中打倒了多少瓶。我已经为基本上所有可能发生的情况编写了许多测试,但我无法修复我的测试在仅投掷罢工时失败的问题。
最终目标是生12窝,总分300分。我很困难,如果有人能帮助我那就太好了
这是我的框架类:
public class Frame
{
public int[] PinsRolled { get; set; }
public int Score { get; set; }
public bool IsComplete { get; set; }
public Frame()
{
PinsRolled = new int[2];
IsComplete = false;
}
}
错误发生在
行if (frames[frameIndex].PinsRolled[0] + pins > 10 && frameIndex < 9)
因为
frameIndex
是 10,frames.Count()
也是 10。由于索引从 0 开始,这意味着有效索引是 0、1、2、3、4、5、6、7、8、9,而不是 10。
摆脱索引越界问题的快速解决方案是
int frameIndex = GetCurrentFrameIndex();
if (frameIndex >= frames.Count()) {
return;
}
结果可能会解决这个问题。但是,这将是一种解决方法,您应该更深入地了解为什么要尝试引用
frames
范围之外的框架。使用调试器修改 Over
。