3

Yatzy ボットを開発しているときに「保留」機能に行き詰まっています。他のすべては機能しますが、この関数のロジックは場合によっては失敗するようです。基本的には、与えられたすべての数字を保持し、与えられた数字と一致しないサイコロを振るという考え方です。

[00:04] @Dessimat0r: .roll
[00:04] YatzyBot: #1: dice: [2, 5, 3, 4, 1], scores: [ 1 2 3 4 5 6 1P 2P 3K 4K SS LS H Y C ]
[00:04] @Dessimat0r: .hold 2 1
[00:04] YatzyBot: #2: dice: [2, 5, 3, 4, 1], scores: [ 1 2 3 4 5 6 1P 2P 3K 4K SS LS H Y C ]
[00:04] @Dessimat0r: .hold 2 1
[00:04] YatzyBot: #3: dice: [2, 5, 3, 4, 1], scores: [ 1 2 3 4 5 6 1P 2P 3K 4K SS LS H Y C ]

ご覧のように、選択されたいくつかの数字だけでなく、すべての数字が保持されています (これはサイコロの出目による偶然ではありません)。コードは以下のとおりです。

} else if (event.getMessage().startsWith(".hold")) {
    if (y.getTurn() != null && event.getUser().getNick().equals(y.getTurn().getPlayer().getName())) {
        String[] tokens = event.getMessage().split(" ");
        if (tokens[0].equals(".hold")) {
            boolean failed = false;
            try {
                if (tokens.length == 1) {
                    bot.sendMessage(CHANNEL, "Must choose some dice to hold!");
                    return;
                }
                ArrayList<Integer> dice = new ArrayList<Integer>();
                ArrayList<Integer> holdnums = new ArrayList<Integer>();
                ArrayList<Integer> rollnums = new ArrayList<Integer>();

                for (Die d : y.getDice()) {
                    dice.add(d.getFaceValue());
                }

                // parse other numbers
                for (int i = 1; i < tokens.length; i++) {
                    int num = Integer.parseInt(tokens[i]);
                    holdnums.add(num);
                }
                ListIterator<Integer> diter = dice.listIterator();
                dice: while (diter.hasNext()) {
                    Integer d = diter.next();

                    if (holdnums.isEmpty()) {
                        rollnums.add(d);
                        diter.remove();
                        continue;
                    }
                    ListIterator<Integer> iter = holdnums.listIterator();
                    while (iter.hasNext()) {
                        int holdnum = iter.next().intValue();
                        if (holdnum == d) {
                            iter.remove();
                            diter.remove();
                            continue dice;
                        }
                    }

                }

                if (!holdnums.isEmpty()) {
                    bot.sendMessage(CHANNEL, "Hold nums not found: " + holdnums);
                    failed = true;
                }

                if (!failed) {
                    y.getTurn().rollNumbers(convertIntegers(rollnums));

                    Map<Scoring, Integer> scores = y.getRollScores();

                    Map<Scoring, Integer> unchosen = new EnumMap<Scoring, Integer>(Scoring.class);
                    Map<Scoring, Integer> chosen = new EnumMap<Scoring, Integer>(Scoring.class);

                    for (Entry<Scoring, Integer> entry : scores.entrySet()) {
                        if (y.getTurn().getPlayer().getTotals().get(entry.getKey()) == -1) {
                            unchosen.put(entry.getKey(), entry.getValue());
                        } else {
                            chosen.put(entry.getKey(), entry.getValue());
                        }
                    }
                    bot.sendMessage(CHANNEL, "#" + y.getTurn().getRolls() + ": dice: " + y.getDiceStr() + ", scores: " + getDiceStr(y.getTurn().getPlayer().getTotals(), scores));
                }
            } catch (TurnException e1) {
                bot.sendMessage(CHANNEL, e1.getMessage());
            } catch (RollException e2) {
                bot.sendMessage(CHANNEL, e2.getMessage());
            } catch (YahtzyException e3) {
                bot.sendMessage(CHANNEL, e3.getMessage());
            } catch (NumberFormatException e4) {
                bot.sendMessage(CHANNEL, e4.getMessage());
            }
        }
    }
}

編集:すべて修正しました。更新されたコード:

} else if (event.getMessage().startsWith(".hold")) {
    if (y.getTurn() != null && event.getUser().getNick().equals(y.getTurn().getPlayer().getName())) {
        String[] tokens = event.getMessage().split(" ");
        if (tokens[0].equals(".hold")) {
            boolean failed = false;
            try {
                if (tokens.length == 1) {
                    bot.sendMessage(channel, "Must choose some dice to hold!");
                    return;
                }
                ArrayList<Integer> holdnums = new ArrayList<Integer>();
                ArrayList<Integer> rollnums = new ArrayList<Integer>();

                // parse other numbers
                for (int i = 1; i < tokens.length; i++) {
                    int num = Integer.parseInt(tokens[i]);
                    holdnums.add(num);
                }
                for (int i = 0; i < y.getDice().length; i++) {
                    int d = y.getDice()[i].getFaceValue();

                    if (holdnums.isEmpty()) {
                        rollnums.add(d);
                        continue;
                    }

                    ListIterator<Integer> iter = holdnums.listIterator();

                    boolean found = false;
                    while (iter.hasNext()) {
                        int holdnum = iter.next().intValue();
                        if (holdnum == d) {
                            iter.remove();
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        rollnums.add(d);
                    }
                }

                if (!holdnums.isEmpty()) {
                    bot.sendMessage(channel, "Hold nums not found: " + holdnums);
                    failed = true;
                }

                if (!failed) {
                    boolean[] rolled = y.getTurn().rollNumbers(convertIntegers(rollnums));

                    Map<Scoring, Integer> scores = y.getRollScores();

                    Map<Scoring, Integer> unchosen = new EnumMap<Scoring, Integer>(Scoring.class);
                    Map<Scoring, Integer> chosen = new EnumMap<Scoring, Integer>(Scoring.class);

                    for (Entry<Scoring, Integer> entry : scores.entrySet()) {
                        if (y.getTurn().getPlayer().getTotals().get(entry.getKey()) == -1) {
                            unchosen.put(entry.getKey(), entry.getValue());
                        } else {
                            chosen.put(entry.getKey(), entry.getValue());
                        }
                    }
                    bot.sendMessage(channel, "#" + y.getTurn().getRolls() + ": dice: " + diceToString(rolled) + ", scores: " + getDiceStr(y.getTurn().getPlayer().getTotals(), scores));
                }
            } catch (TurnException e1) {
                bot.sendMessage(channel, e1.getMessage());
            } catch (RollException e2) {
                bot.sendMessage(channel, e2.getMessage());
            } catch (YahtzyException e3) {
                bot.sendMessage(channel, e3.getMessage());
            } catch (NumberFormatException e4) {
                bot.sendMessage(channel, e4.getMessage());
            }
        }
    }
}
4

1 に答える 1

2

すべて問題ないように見えますが、このチェックholdnumは適切な場所にありません。

    if (absent) {
      bot.sendMessage(CHANNEL, "Hold num not found: " + holdnum);
      failed = true;
      break dice;
    }

与えられた保留番号が正しいか間違っているかをここで言うのは時期尚早なので、このコードを削除することをお勧めします。有効性を確認するholdnumsには、「サイコロ」ループの終了後にこのリストを確認しますholdnums。が空でない場合は、見つからなかったアイテムがいくつか含まれています。


更新された質問の場合:

同じ値を何度も追加しrollnums.add(d)ないように、ネストして呼び出すべきではないという問題が1つあります。while代わりに、このループが完了した後、一度呼び出す必要があります。

于 2012-10-27T17:37:22.617 に答える