야 트지 (Yatzy) 봇을 개발할 때 '보류'기능이 작동하지 않습니다. 다른 모든 것은 작동하지만이 기능의 논리가 실패하는 것처럼 보입니다. 기본적으로 아이디어는 주어진 모든 숫자를 유지 한 다음 주어진 숫자와 일치하지 않는 주사위를 굴리는 것입니다.야 트리 (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());
}
}
}
}
감사합니다. 그것은 정확하게 문제는 아니지만 어쨌든 도움이되었습니다. 주사위가 다시 반복되고 있으므로 처리 된 후 제거 할 수 있도록 다른 목록에 넣었습니다. 이것은 트릭을하는 것처럼 보였다. 수정 사항을 반영하도록 위 코드를 업데이트하겠습니다. 최적화 제안이 있다면 환영 할 것입니다. :) –
아직도 문제가 있습니다. 새 코드를 확인해 주시겠습니까? :) –
@ChrisDennett : 답변을 업데이트했습니다. 최적화에 관해서는, 내가 아는 한 Yatzy에는 5 개의 주사위 만 있기 때문에 코드의이 부분을 최적화하는 것이 효과가 없습니다. 당신은'dice'와'holdnums'리스트를 모두 정렬 할 수 있고, 작은 값으로 반복자를 앞 당김으로써 하나의 루프에서 둘 다 반복 할 수 있습니다. –