Matlab 保龄球成绩计算器
我的保龄球成绩计算器有点问题。我只是有点偏离这里,我很确定这与最后一帧有关。不过我不知道。 有一点关于加载的变量。 bowling.xls包含50场保龄球比赛的数据,因此比赛是一个50x21矩阵。 这21列对应每个投出的球。 谢谢你们的帮助。如果您不懂Matlab,欢迎您使用通用代码进行响应 编辑:这是我的最新代码。正如你们所看到的,“current”变量现在被预设为显示我试图计算的游戏,所以你们可以看到它用于调试目的。我从这个程序得到的输出是158。应该是194Matlab 保龄球成绩计算器,matlab,Matlab,我的保龄球成绩计算器有点问题。我只是有点偏离这里,我很确定这与最后一帧有关。不过我不知道。 有一点关于加载的变量。 bowling.xls包含50场保龄球比赛的数据,因此比赛是一个50x21矩阵。 这21列对应每个投出的球。 谢谢你们的帮助。如果您不懂Matlab,欢迎您使用通用代码进行响应 编辑:这是我的最新代码。正如你们所看到的,“current”变量现在被预设为显示我试图计算的游戏,所以你们可以看到它用于调试目的。我从这个程序得到的输出是158。应该是194 i = 1; gamescor
i = 1;
gamescore = 0;
current = [10 0 6 0 9 1 10 0 10 0 8 2 8 2 8 0 10 0 10 10 10]
strikes = zeros(1,10);
spares = zeros(1,10);
% Check for strikes
for j=1:10
if current(2*j-1) == 10
strikes(j) = 1;
end
end
% Check for spares
for j=1:10
if (current(2*j-1) + current(2*j) == 10) && (current(2*j-1)~=10)
spares(j) = 1;
end
end
% Calculate score
for j=1:10
if strikes(j) == 1
gamescore = gamescore + 10 + current(2*j) + current(2*j+1);
elseif spares(j) == 1
gamescore = gamescore + 10 + current(2*j);
else
gamescore = gamescore + current(2*j-1) + current(2*j);
end
end
fprintf('Game score: %d \n',gamescore)
让我们考虑这个代码:
else
score(1,j) = current(1,j) + current(1,j+1);
如果在第5帧,j=5
中没有罢工或备战,分数是多少?从代码来看,它将是
= current(1,j) + current(1,j+1);
= 5th Ball + 6th Ball
= Score of frame 3
由此可以清楚地看出,代码需要更改为
else
score(1,j) = current(1,2*j-1) + current(1,2*j);
编辑:
测试后,如果连续发生两次攻击,代码也会失败。为此添加检查很简单,只需更改:
if strikes(1,j) == 1
score(1,j) = 10 + current(1,2*j+1) + current(1,2*j+2);
到
你的代码没有很好地为matlab矢量化 您应该需要的唯一for循环应该是在每次攻击后添加到虚拟零轮中的循环(以便区分攻击和0-10个备用。我假设数据是21列,而不是22列,数据还没有排列到帧中,而是在末尾进行了零填充。如果您可以更改输入格式,使其以帧形式给出,那么您可以在没有hav的情况下同时获得所有游戏的所有分数向量。)(我想绕着它们转一圈)。 否则,其他一切都可以矢量化,例如
for idx = 1 : 2 : 19
if game(idx) == 10
game = [game(1 : idx), 0, game(idx : 21)]
end
end
因为保龄球可能是完美的300场比赛,我不相信有任何方法可以将其矢量化。在你处理完之前的所有帧之前,你无法确定0-10是一个一击还是一个空挡
但现在很容易获得备用和罢工指数以及分数
startscore = sum(game(1 : 20));
game = reshape(game,11,2);
spares = game(1 : 10, 1) + game(1 : 10, 2) == 10;
sparescore = sum(game(2 : 11, 1)(spares));
strikes = game(1 : 10, 1) == 10;
strikescore = sum(game(2 : 11, 2)(strikes));
score = startscore + sparescore + strikescore
只是想说明如果数据已经排列成帧,如何解决它 在这种情况下,我假设除最后一帧外,敲击后的虚拟零已经存在
function [scores] = getscores(games)
[n, m] = size(games);
assert(m == 21);
games = [games, zeros(n, 1)];
lastwasstrike = games(:, 19) == 10;
games(lastwasstrike, 21 : 22) = games(lastwasstrike, 20 : 21);
games(lastwasstrike, 20) = 0;
startscores = sum(games(:, 1:20), 2);
isspare = games(:, 1:2:19) + games(:, 2:2:20) == 10
sparescores = sum((games(:, 3:2:21).*isspare), 2)
isstrike = games(:, 1:2:19) == 10
strikescores = sum((games(:, 4:2:22).*isstrike), 2)
isdoublestrike = games(:, 1:2:17) == 10 & games(:, 3:2:19) == 10
doublestrikescores = sum((games(:, 5:2:21).*isdoublestrike), 2)
scores = startscores+sparescores+strikescores+doublestrikescores
endfunction
下面是我如何将所有分数矢量化在一起
编辑:
请注意,我在这里把一次击球算为一次备球,所以sparescores实际上只是对任何一帧之后的第一次投掷进行求和,在有一次备球或一次击球之后
然后为了平衡它,strikescores只是在一次打击之后在任何一帧上的第二次投掷
再次编辑:
我必须解释一下连续两次打击的原因。现在我认为这很好,我做到了!!经过一系列的胡闹,使用了你们的方法和我自己的方法,我终于能够找到代码了。就是这样!如果你们对我为什么要做某事有任何疑问,我很乐意解释,因为你们也对我做了同样的事情e
i = 1;
gamescore = 0;
current = games(i,:);
strikes = zeros(1,12);
spares = zeros(1,10);
% Check for strikes
for j=1:9
if current(2*j-1) == 10
strikes(j) = 1;
end
end
for j=1:3
if current(18+j)==10
strikes(9+j) = 1;
end
end
% Check for spares
for j=1:10
if (current(2*j-1) + current(2*j) == 10) && (current(2*j-1)~=10)
spares(j) = 1;
end
end
% Calculate score
for j=1:10
if strikes(j) == 1
if strikes(j+1)==1
gamescore = gamescore + 20 + current(2*j+1);
else
gamescore = gamescore + 10 + current(2*j) + current(2*j+1);
end
elseif spares(j) == 1
gamescore = gamescore + 10 + current(2*j+1);
else
gamescore = gamescore + current(2*j-1) + current(2*j);
end
end
fprintf('Game score: %d \n',gamescore)
此外,还有一些调试建议:让数据告诉你漏洞在哪里!一场全击的游戏能给你300分吗?这会显示出一个漏洞在击数上。一场在第二个球上全10分的游戏能给你100分吗?这会显示出一个漏洞在备用数上。一场除第一帧外全击的游戏能给你预期的结果吗?这将表明吃了一个计算开放式框架分数的数学错误也
strikespot
和sparespot
让我很困惑,因为它们在各自的循环中与j
没有什么不同,但是你想要这些的原因可能有你自己的。你能用你得到的分数和你期望的分数发布一个示例游戏吗?好主意!它通过将current(1,
的所有实例替换为games,应该很容易对所有游戏进行矢量化(:,
。此外,make打击
,备用
,和得分
有许多行,如游戏
。在我看来,数据已经在帧中,因为第10帧中有21=9帧2个球+3个球,而编写的代码取决于当前中的jth
帧(1,2*j-1:2*j)
在这种情况下,您可以同时对所有游戏进行矢量化。我将发布另一个答案。您是否测试了代码?games=10*One(1,21)是否给出300分?除非您在罢工框架中为第二项设置虚拟零,否则这是不正确的。因此,在这种情况下,完美的游戏应该是[repmat([10,0],1,10),10,10].哦,那是210。我忘了如果连续两次击球,你必须先投一次,然后再投一次,这会让事情变得更棘手。我会解决它。等一下,onOkay,现在它给出300。有22列,因为我把最后一帧中的最后两次投掷作为虚拟的第11帧,当第一次投掷是一次击球时。这样就少了要处理的边缘案例很抱歉,我明白你的要求。作为函数的输入,一个完美的游戏应该是[repmat([10,0],1,9),10,10,10]这部分min(2*j+3,20)
是为了确保第10帧的前两个球被计算在内,如果第9帧有进球,第10帧的第1个球也有进球。谢谢你的回答。起初我在船上,但似乎我仍然没有得到我应该得到的分数。我更新了我的分数计算部分,使之成为现在的样子。现在有什么想法吗?我想ss我将尝试使用一个整数变量“gamescore”,并在每次迭代中添加到它,而不是将它们添加到向量中并求和。但不确定这是否会产生差异。您是否试图在所有51个游戏中找到最大分数?这似乎是您的注释所指示的,但不是您的代码所做的。要做到这一点,您需要添加一个for循环来迭代游戏,而不是仅仅声明i=1
,设置gamescore(i)=sum(score)
,并返回gamescore
的最大值以及50个游戏,是的。我有我的for循环,从I=1:50;我已经注释了它,但只是为了测试目的。此代码适用于我和我的游戏。你能发布错误是什么吗?输入和输出是什么?
i = 1;
gamescore = 0;
current = games(i,:);
strikes = zeros(1,12);
spares = zeros(1,10);
% Check for strikes
for j=1:9
if current(2*j-1) == 10
strikes(j) = 1;
end
end
for j=1:3
if current(18+j)==10
strikes(9+j) = 1;
end
end
% Check for spares
for j=1:10
if (current(2*j-1) + current(2*j) == 10) && (current(2*j-1)~=10)
spares(j) = 1;
end
end
% Calculate score
for j=1:10
if strikes(j) == 1
if strikes(j+1)==1
gamescore = gamescore + 20 + current(2*j+1);
else
gamescore = gamescore + 10 + current(2*j) + current(2*j+1);
end
elseif spares(j) == 1
gamescore = gamescore + 10 + current(2*j+1);
else
gamescore = gamescore + current(2*j-1) + current(2*j);
end
end
fprintf('Game score: %d \n',gamescore)