1

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

编辑:这是我的最新代码。正如您所看到的,“当前”变量现在被预设以显示我正在尝试计算的游戏,所以你们可以看到它以进行调试。我从这个程序得到的输出是 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)
4

4 回答 4

1

让我们考虑这段代码:

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);

编辑:经过测试,如果有 2 次连续罢工,代码也会失败。为此添加检查很简单,只需更改:

if strikes(1,j) == 1
    score(1,j) = 10 + current(1,2*j+1) + current(1,2*j+2);

if strikes(1,j) == 1
    if strikes(1,j+1) == 1
        score(1,j) = 10 + current(1,2*j+1) + current(1,min(2*j+3,20));
    else
        score(1,j) = 10 + current(1,2*j+1) + current(1,2*j+2);
    end
于 2013-03-18T18:25:49.403 回答
1

您的代码对于 matlab 没有很好的矢量化。

您应该需要的唯一for循环应该是在每次打击后添加虚拟零轮的循环(以便将打击与0-10个备件区分开来。我假设它是21列而不是22列数据尚未为您安排到帧中,而是在末尾填充了零。如果您可以更改输入格式以使其以帧为单位,那么您可以同时获得所有游戏的所有分数的向量,而无需循环它们)。否则,其他所有内容都可以矢量化,例如。

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
于 2013-03-18T18:42:58.407 回答
1

只是想展示如果数据已经排列成帧如何解决它。

在这种情况下,我假设罢工后的虚拟零已经存在,除了最后一帧。

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

这是我如何矢量化一起获取所有分数

编辑:请注意,我在这里将罢工算作备用,因此备用分数实际上只是在有备用或罢工后的任何帧之后的第一次投掷相加然后为了平衡它,罢工分数只是在任何帧之后的第二次投掷罢工再次编辑:我不得不连续两次罢工。现在我觉得很好

于 2013-03-18T19:13:31.243 回答
0

我做到了!!经过一堆乱七八糟的方法,使用一堆你们的方法和我自己的方法,我终于能够找到代码。这里是!如果您对我为什么做某事有任何疑问,我会很乐意解释,因为你们对我做同样的事情非常好。

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)
于 2013-03-21T05:15:54.900 回答