Matlab 保龄球成绩计算器

Matlab 保龄球成绩计算器,matlab,Matlab,我的保龄球成绩计算器有点问题。我只是有点偏离这里,我很确定这与最后一帧有关。不过我不知道。 有一点关于加载的变量。 bowling.xls包含50场保龄球比赛的数据,因此比赛是一个50x21矩阵。 这21列对应每个投出的球。 谢谢你们的帮助。如果您不懂Matlab,欢迎您使用通用代码进行响应 编辑:这是我的最新代码。正如你们所看到的,“current”变量现在被预设为显示我试图计算的游戏,所以你们可以看到它用于调试目的。我从这个程序得到的输出是158。应该是194 i = 1; gamescor

我的保龄球成绩计算器有点问题。我只是有点偏离这里,我很确定这与最后一帧有关。不过我不知道。 有一点关于加载的变量。 bowling.xls包含50场保龄球比赛的数据,因此比赛是一个50x21矩阵。 这21列对应每个投出的球。 谢谢你们的帮助。如果您不懂Matlab,欢迎您使用通用代码进行响应

编辑:这是我的最新代码。正如你们所看到的,“current”变量现在被预设为显示我试图计算的游戏,所以你们可以看到它用于调试目的。我从这个程序得到的输出是158。应该是194

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)