From 5821db29a06d2de62e8e9013935df6e57ab51cee Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 9 Oct 2026 17:56:05 +0200
Subject: [PATCH 01/27] refactor: run CI only on pull requests with specifics
conditions
---
.github/workflows/ci.yml | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 76d1a63..1f59613 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,8 +1,15 @@
name: CI
on:
- push:
pull_request:
+ paths-ignore:
+ - '.idea/**'
+ - '.gitignore'
+ - 'README.md'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
jobs:
test:
From 97566d95f3383a69055115407337c780b792b155 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 9 Oct 2026 18:03:16 +0200
Subject: [PATCH 02/27] feat: activate PAIR category
---
src/main/java/io/github/vbetsch/yams/CategoryEnum.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main/java/io/github/vbetsch/yams/CategoryEnum.java b/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
index 3ac7db2..ce64a55 100644
--- a/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
+++ b/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
@@ -7,6 +7,7 @@ public enum CategoryEnum {
FOURS,
FIVES,
SIXES,
+ PAIR,
THREE_OF_A_KIND,
FOUR_OF_A_KIND,
// FULL_HOUSE,
From 115a6ccec14e8370e30aab1e0f24f72a642b3f34 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 9 Oct 2026 18:03:44 +0200
Subject: [PATCH 03/27] refactor: split categories with chapters
---
src/main/java/io/github/vbetsch/yams/CategoryEnum.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/main/java/io/github/vbetsch/yams/CategoryEnum.java b/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
index ce64a55..fe7e074 100644
--- a/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
+++ b/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
@@ -1,13 +1,17 @@
package io.github.vbetsch.yams;
public enum CategoryEnum {
+ // --- TOP PART ---
ACES,
TWOS,
THREES,
FOURS,
FIVES,
SIXES,
+ // --- BONUS PART (kata) ---
PAIR,
+// TWO_PAIRS,
+ // --- BOTTOM PART ---
THREE_OF_A_KIND,
FOUR_OF_A_KIND,
// FULL_HOUSE,
From b06342ebbc778f7ff3194908f628174489e53b81 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 9 Oct 2026 19:34:54 +0200
Subject: [PATCH 04/27] feat: create occurrencesByValue hashmap for
handlePairScore
---
pom.xml | 6 ++++++
src/main/java/io/github/vbetsch/yams/Yams.java | 16 ++++++++++++++++
.../java/io/github/vbetsch/yams/YamsTest.java | 12 ++++++++++++
3 files changed, 34 insertions(+)
diff --git a/pom.xml b/pom.xml
index c54c7ce..9082ba0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,6 +21,12 @@
5.11.0
test
+
+ org.jetbrains
+ annotations
+ RELEASE
+ compile
+
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 765f539..54dfef5 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -1,6 +1,8 @@
package io.github.vbetsch.yams;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.stream.IntStream;
public class Yams {
@@ -46,6 +48,19 @@ private boolean containsDuplicatesNth(List roll, int duplicatesNumber)
return reducedRoll.count() == (Yams.DICES_COUNT - duplicatesNumber + 1);
}
+ private int handlePairScore(List roll) throws IllegalArgumentException {
+ if (!this.containsDuplicatesNth(roll, 2)) {
+ throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.PAIR);
+ }
+ Map occurrencesByValue = new HashMap<>();
+ for (int i = 0; i < roll.size(); i++) {
+ int diceValue = roll.get(i);
+ occurrencesByValue.merge(diceValue, 1, Integer::sum);
+ }
+ IO.println(occurrencesByValue);
+ return 4;
+ }
+
private int handleThreeOfAKindScore(List roll) throws IllegalArgumentException {
if (!this.containsDuplicatesNth(roll, 3)) {
throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.THREE_OF_A_KIND);
@@ -73,6 +88,7 @@ public int computeScore(List roll, CategoryEnum category) throws Invali
case CategoryEnum.FOURS -> this.handleTopPartScores(roll, 4);
case CategoryEnum.FIVES -> this.handleTopPartScores(roll, 5);
case CategoryEnum.SIXES -> this.handleTopPartScores(roll, 6);
+ case CategoryEnum.PAIR -> this.handlePairScore(roll);
case CategoryEnum.THREE_OF_A_KIND -> this.handleThreeOfAKindScore(roll);
case CategoryEnum.FOUR_OF_A_KIND -> this.handleFourOfAKindScore(roll);
default -> 1000;
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 9683c49..06f523b 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -152,6 +152,18 @@ void sixes_return18Points_whenGivenRollWithThreeDicesSixes() {
assertEquals(18, result);
}
+ @Test
+ void pair_return4Points_whenGivenRollWithOnlyOnePair() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(2, 2, 3, 4, 5), CategoryEnum.PAIR);
+
+ // Assert
+ assertEquals(4, result);
+ }
+
@Test
void threeOfAKind_return3Points_whenGivenThreeDicesOnes() {
// Arrange
From 1f77b6134d93b0272519c48aed5b8901f052fea1 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 9 Oct 2026 20:00:33 +0200
Subject: [PATCH 05/27] feat: create method getOccurrencesByValue and return
sum of pairs
---
.../java/io/github/vbetsch/yams/Yams.java | 21 ++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 54dfef5..2e3ebf8 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -48,17 +48,28 @@ private boolean containsDuplicatesNth(List roll, int duplicatesNumber)
return reducedRoll.count() == (Yams.DICES_COUNT - duplicatesNumber + 1);
}
- private int handlePairScore(List roll) throws IllegalArgumentException {
- if (!this.containsDuplicatesNth(roll, 2)) {
- throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.PAIR);
- }
+ private Map getOccurrencesByValue(List roll) {
Map occurrencesByValue = new HashMap<>();
for (int i = 0; i < roll.size(); i++) {
int diceValue = roll.get(i);
occurrencesByValue.merge(diceValue, 1, Integer::sum);
}
IO.println(occurrencesByValue);
- return 4;
+ return occurrencesByValue;
+ }
+
+ private int handlePairScore(List roll) throws IllegalArgumentException {
+ if (!this.containsDuplicatesNth(roll, 2)) {
+ throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.PAIR);
+ }
+ Map occurrencesByValue = this.getOccurrencesByValue(roll);
+ return occurrencesByValue
+ .entrySet()
+ .stream()
+ .filter(occurrenceByValue -> occurrenceByValue.getValue() == 2)
+ .map(Map.Entry::getKey)
+ .max(Integer::compare)
+ .orElse(0) * 2;
}
private int handleThreeOfAKindScore(List roll) throws IllegalArgumentException {
From cde45ebeaef6140b048feb03637ff521b7aad15b Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 17:19:21 +0200
Subject: [PATCH 06/27] refactor: use the right exception to throw in tests
---
.../java/io/github/vbetsch/yams/YamsTest.java | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 06f523b..a64cbb2 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -152,6 +152,15 @@ void sixes_return18Points_whenGivenRollWithThreeDicesSixes() {
assertEquals(18, result);
}
+// @Test
+// void pair_throwIllegalArgumentException_whenGivenNotPair() {
+// // Arrange
+// Yams yams = new Yams();
+//
+// // Act
+// int result = yams.computeScore(List.of(6, 6, 6, 2, 3), CategoryEnum.SIXES);
+// }
+
@Test
void pair_return4Points_whenGivenRollWithOnlyOnePair() {
// Arrange
@@ -245,7 +254,7 @@ void throwIllegalArgumentException_whenGivenLessThanFiveDices() {
// Act & Assert
assertThrows(
- InvalidRollSizeError.class,
+ IllegalArgumentException.class,
() -> yams.computeScore(List.of(1, 2, 3, 4), CategoryEnum.CHANCE),
"Roll must contain exactly 5 dices"
);
@@ -258,7 +267,7 @@ void throwIllegalArgumentException_whenGivenMoreThanFiveDices() {
// Act & Assert
assertThrows(
- InvalidRollSizeError.class,
+ IllegalArgumentException.class,
() -> yams.computeScore(List.of(1, 2, 3, 4, 5, 6), CategoryEnum.CHANCE),
"Roll must contain exactly 5 dices"
);
@@ -271,7 +280,7 @@ void throwIllegalArgumentException_whenGivenNoDice() {
// Act & Assert
assertThrows(
- InvalidRollSizeError.class,
+ IllegalArgumentException.class,
() -> yams.computeScore(List.of(), CategoryEnum.CHANCE),
"Roll must contain exactly 5 dices"
);
From 1ed9d6869b3bce31ff1216691d39bd0882921ea0 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 17:22:36 +0200
Subject: [PATCH 07/27] style: add chapters
---
src/test/java/io/github/vbetsch/yams/YamsTest.java | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index a64cbb2..5a38659 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -8,6 +8,7 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
class YamsTest {
+ // --- CHANCE ---
@Test
void chance_return15Points_whenGivenLargeStraight() {
// Arrange
@@ -32,6 +33,7 @@ void chance_return16Points_whenGivenSmallStraight() {
assertEquals(16, result);
}
+ // --- YAMS ---
@Test
void yams_return50Points_whenGivenFiveDicesSix() {
// Arrange
@@ -80,6 +82,7 @@ void yams_return0Points_whenGivenRollWithoutDuplicates() {
assertEquals(0, result);
}
+ // --- ACES ---
@Test
void aces_return3Points_whenGivenRollWithThreeDicesAces() {
// Arrange
@@ -92,6 +95,7 @@ void aces_return3Points_whenGivenRollWithThreeDicesAces() {
assertEquals(3, result);
}
+ // --- TOP PARTS ---
@Test
void twos_return6Points_whenGivenRollWithThreeDicesTwos() {
// Arrange
@@ -173,6 +177,7 @@ void pair_return4Points_whenGivenRollWithOnlyOnePair() {
assertEquals(4, result);
}
+ // --- THREE OF A KIND ---
@Test
void threeOfAKind_return3Points_whenGivenThreeDicesOnes() {
// Arrange
@@ -210,6 +215,7 @@ void threeOfAKind_throwIllegalArgumentException_whenGivenLargeStraight() {
);
}
+ // --- FOUR OF A KIND ---
@Test
void fourOfAKind_return7Points_whenGivenFourDicesOnes() {
// Arrange
@@ -247,6 +253,7 @@ void fourOfAKind_throwIllegalArgumentException_whenGivenLargeStraight() {
);
}
+ // --- CHECKS ---
@Test
void throwIllegalArgumentException_whenGivenLessThanFiveDices() {
// Arrange
From d9a2dc70b0b61974ba23dfa1175ab442c5a89569 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 17:23:46 +0200
Subject: [PATCH 08/27] test: add
pair_throwIllegalArgumentException_whenGivenNotPair
---
.../java/io/github/vbetsch/yams/YamsTest.java | 21 ++++++++++++-------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 5a38659..3d19833 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -156,14 +156,19 @@ void sixes_return18Points_whenGivenRollWithThreeDicesSixes() {
assertEquals(18, result);
}
-// @Test
-// void pair_throwIllegalArgumentException_whenGivenNotPair() {
-// // Arrange
-// Yams yams = new Yams();
-//
-// // Act
-// int result = yams.computeScore(List.of(6, 6, 6, 2, 3), CategoryEnum.SIXES);
-// }
+ // --- PAIRS ---
+ @Test
+ void pair_throwIllegalArgumentException_whenGivenNotPair() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act & Assert
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.PAIR),
+ "We cannot compute score with category PAIR for this roll"
+ );
+ }
@Test
void pair_return4Points_whenGivenRollWithOnlyOnePair() {
From 291fe25ebfb79e5e78a76664bfcb0db3fdf9b571 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 17:37:05 +0200
Subject: [PATCH 09/27] test:
pair_return4Points_whenGivenRollWithOnlyOnePairOfThree
---
.../java/io/github/vbetsch/yams/YamsTest.java | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 3d19833..b4a5cb1 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -171,7 +171,7 @@ void pair_throwIllegalArgumentException_whenGivenNotPair() {
}
@Test
- void pair_return4Points_whenGivenRollWithOnlyOnePair() {
+ void pair_return4Points_whenGivenRollWithOnlyOnePairOfTwo() {
// Arrange
Yams yams = new Yams();
@@ -182,6 +182,19 @@ void pair_return4Points_whenGivenRollWithOnlyOnePair() {
assertEquals(4, result);
}
+ @Test
+ void pair_return4Points_whenGivenRollWithOnlyOnePairOfThree() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(3, 3, 4, 5, 1), CategoryEnum.PAIR);
+
+ // Assert
+ assertEquals(6, result);
+ }
+
+
// --- THREE OF A KIND ---
@Test
void threeOfAKind_return3Points_whenGivenThreeDicesOnes() {
From 841754453df0021b3087f176ff36a19fcba62228 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 17:38:51 +0200
Subject: [PATCH 10/27] refactor: remove points numbers in tests names
---
.../java/io/github/vbetsch/yams/YamsTest.java | 36 +++++++++----------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index b4a5cb1..38978cb 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -10,7 +10,7 @@
class YamsTest {
// --- CHANCE ---
@Test
- void chance_return15Points_whenGivenLargeStraight() {
+ void chance_returnPoints_whenGivenLargeStraight() {
// Arrange
Yams yams = new Yams();
@@ -22,7 +22,7 @@ void chance_return15Points_whenGivenLargeStraight() {
}
@Test
- void chance_return16Points_whenGivenSmallStraight() {
+ void chance_returnPoints_whenGivenSmallStraight() {
// Arrange
Yams yams = new Yams();
@@ -35,7 +35,7 @@ void chance_return16Points_whenGivenSmallStraight() {
// --- YAMS ---
@Test
- void yams_return50Points_whenGivenFiveDicesSix() {
+ void yams_returnPoints_whenGivenFiveDicesSix() {
// Arrange
Yams yams = new Yams();
@@ -47,7 +47,7 @@ void yams_return50Points_whenGivenFiveDicesSix() {
}
@Test
- void yams_return50Points_whenGivenFiveDicesThree() {
+ void yams_returnPoints_whenGivenFiveDicesThree() {
// Arrange
Yams yams = new Yams();
@@ -59,7 +59,7 @@ void yams_return50Points_whenGivenFiveDicesThree() {
}
@Test
- void yams_return0Points_whenGivenRollWithDuplicates() {
+ void yams_returnPoints_whenGivenRollWithDuplicates() {
// Arrange
Yams yams = new Yams();
@@ -71,7 +71,7 @@ void yams_return0Points_whenGivenRollWithDuplicates() {
}
@Test
- void yams_return0Points_whenGivenRollWithoutDuplicates() {
+ void yams_returnPoints_whenGivenRollWithoutDuplicates() {
// Arrange
Yams yams = new Yams();
@@ -84,7 +84,7 @@ void yams_return0Points_whenGivenRollWithoutDuplicates() {
// --- ACES ---
@Test
- void aces_return3Points_whenGivenRollWithThreeDicesAces() {
+ void aces_returnPoints_whenGivenRollWithThreeDicesAces() {
// Arrange
Yams yams = new Yams();
@@ -97,7 +97,7 @@ void aces_return3Points_whenGivenRollWithThreeDicesAces() {
// --- TOP PARTS ---
@Test
- void twos_return6Points_whenGivenRollWithThreeDicesTwos() {
+ void twos_returnPoints_whenGivenRollWithThreeDicesTwos() {
// Arrange
Yams yams = new Yams();
@@ -109,7 +109,7 @@ void twos_return6Points_whenGivenRollWithThreeDicesTwos() {
}
@Test
- void three_return9Points_whenGivenRollWithThreeDicesThrees() {
+ void three_returnPoints_whenGivenRollWithThreeDicesThrees() {
// Arrange
Yams yams = new Yams();
@@ -121,7 +121,7 @@ void three_return9Points_whenGivenRollWithThreeDicesThrees() {
}
@Test
- void four_return12Points_whenGivenRollWithThreeDicesFours() {
+ void four_returnPoints_whenGivenRollWithThreeDicesFours() {
// Arrange
Yams yams = new Yams();
@@ -133,7 +133,7 @@ void four_return12Points_whenGivenRollWithThreeDicesFours() {
}
@Test
- void five_return15Points_whenGivenRollWithThreeDicesFives() {
+ void five_returnPoints_whenGivenRollWithThreeDicesFives() {
// Arrange
Yams yams = new Yams();
@@ -145,7 +145,7 @@ void five_return15Points_whenGivenRollWithThreeDicesFives() {
}
@Test
- void sixes_return18Points_whenGivenRollWithThreeDicesSixes() {
+ void sixes_returnPoints_whenGivenRollWithThreeDicesSixes() {
// Arrange
Yams yams = new Yams();
@@ -171,7 +171,7 @@ void pair_throwIllegalArgumentException_whenGivenNotPair() {
}
@Test
- void pair_return4Points_whenGivenRollWithOnlyOnePairOfTwo() {
+ void pair_returnPoints_whenGivenRollWithOnlyOnePairOfTwo() {
// Arrange
Yams yams = new Yams();
@@ -183,7 +183,7 @@ void pair_return4Points_whenGivenRollWithOnlyOnePairOfTwo() {
}
@Test
- void pair_return4Points_whenGivenRollWithOnlyOnePairOfThree() {
+ void pair_returnPoints_whenGivenRollWithOnlyOnePairOfThree() {
// Arrange
Yams yams = new Yams();
@@ -197,7 +197,7 @@ void pair_return4Points_whenGivenRollWithOnlyOnePairOfThree() {
// --- THREE OF A KIND ---
@Test
- void threeOfAKind_return3Points_whenGivenThreeDicesOnes() {
+ void threeOfAKind_returnPoints_whenGivenThreeDicesOnes() {
// Arrange
Yams yams = new Yams();
@@ -209,7 +209,7 @@ void threeOfAKind_return3Points_whenGivenThreeDicesOnes() {
}
@Test
- void threeOfAKind_return10Points_whenGivenThreeDicesTwos() {
+ void threeOfAKind_returnPoints_whenGivenThreeDicesTwos() {
// Arrange
Yams yams = new Yams();
@@ -235,7 +235,7 @@ void threeOfAKind_throwIllegalArgumentException_whenGivenLargeStraight() {
// --- FOUR OF A KIND ---
@Test
- void fourOfAKind_return7Points_whenGivenFourDicesOnes() {
+ void fourOfAKind_returnPoints_whenGivenFourDicesOnes() {
// Arrange
Yams yams = new Yams();
@@ -247,7 +247,7 @@ void fourOfAKind_return7Points_whenGivenFourDicesOnes() {
}
@Test
- void fourOfAKind_return11Points_whenGivenFourDicesTwos() {
+ void fourOfAKind_returnPoints_whenGivenFourDicesTwos() {
// Arrange
Yams yams = new Yams();
From 5149fa050d32ae6c4d29f342bffbb5136445548b Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 17:46:09 +0200
Subject: [PATCH 11/27] style: format Yams class
---
.../java/io/github/vbetsch/yams/Yams.java | 41 ++++++++++---------
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 2e3ebf8..41d4045 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -8,6 +8,25 @@
public class Yams {
static final int DICES_COUNT = 5;
+ // Utils
+ private Map getOccurrencesByValue(List roll) {
+ Map occurrencesByValue = new HashMap<>();
+ for (int i = 0; i < roll.size(); i++) {
+ int diceValue = roll.get(i);
+ occurrencesByValue.merge(diceValue, 1, Integer::sum);
+ }
+ IO.println(occurrencesByValue);
+ return occurrencesByValue;
+ }
+
+ private boolean containsDuplicatesNth(List roll, int duplicatesNumber) {
+ IntStream reducedRoll = roll
+ .stream()
+ .mapToInt(Integer::intValue)
+ .distinct();
+ return reducedRoll.count() == (Yams.DICES_COUNT - duplicatesNumber + 1);
+ }
+
private int calculateSumOfDices(List roll) {
return roll
.stream()
@@ -15,6 +34,7 @@ private int calculateSumOfDices(List roll) {
.sum();
}
+ // Handlers
private int handleChanceScore(List roll) {
return this.calculateSumOfDices(roll);
}
@@ -40,24 +60,6 @@ private int handleTopPartScores(List roll, int target) {
.sum();
}
- private boolean containsDuplicatesNth(List roll, int duplicatesNumber) {
- IntStream reducedRoll = roll
- .stream()
- .mapToInt(Integer::intValue)
- .distinct();
- return reducedRoll.count() == (Yams.DICES_COUNT - duplicatesNumber + 1);
- }
-
- private Map getOccurrencesByValue(List roll) {
- Map occurrencesByValue = new HashMap<>();
- for (int i = 0; i < roll.size(); i++) {
- int diceValue = roll.get(i);
- occurrencesByValue.merge(diceValue, 1, Integer::sum);
- }
- IO.println(occurrencesByValue);
- return occurrencesByValue;
- }
-
private int handlePairScore(List roll) throws IllegalArgumentException {
if (!this.containsDuplicatesNth(roll, 2)) {
throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.PAIR);
@@ -86,8 +88,9 @@ private int handleFourOfAKindScore(List roll) throws IllegalArgumentExc
return this.calculateSumOfDices(roll);
}
+ // Public method
public int computeScore(List roll, CategoryEnum category) throws InvalidRollSizeError {
- if(roll.size() != Yams.DICES_COUNT) {
+ if (roll.size() != Yams.DICES_COUNT) {
throw new InvalidRollSizeError(roll.size());
}
return switch (category) {
From 44ff3fa6029553186ac25f5e58f1fb8eb5aee92f Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:04:20 +0200
Subject: [PATCH 12/27] feat: migrate containsDuplicatesNth to
containsAtLeastDuplicatesNth using occurrencesByValue
---
.../java/io/github/vbetsch/yams/Yams.java | 19 ++++++++++---------
.../java/io/github/vbetsch/yams/YamsTest.java | 12 ++++++++++++
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 41d4045..012842c 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -19,12 +19,11 @@ private Map getOccurrencesByValue(List roll) {
return occurrencesByValue;
}
- private boolean containsDuplicatesNth(List roll, int duplicatesNumber) {
- IntStream reducedRoll = roll
+ private boolean containsAtLeastDuplicatesNth(Map occurrencesByValue, int duplicatesNumber) {
+ return occurrencesByValue
+ .entrySet()
.stream()
- .mapToInt(Integer::intValue)
- .distinct();
- return reducedRoll.count() == (Yams.DICES_COUNT - duplicatesNumber + 1);
+ .anyMatch(occurrenceByValue -> occurrenceByValue.getValue() >= duplicatesNumber);
}
private int calculateSumOfDices(List roll) {
@@ -61,10 +60,10 @@ private int handleTopPartScores(List roll, int target) {
}
private int handlePairScore(List roll) throws IllegalArgumentException {
- if (!this.containsDuplicatesNth(roll, 2)) {
+ Map occurrencesByValue = this.getOccurrencesByValue(roll);
+ if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 2)) {
throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.PAIR);
}
- Map occurrencesByValue = this.getOccurrencesByValue(roll);
return occurrencesByValue
.entrySet()
.stream()
@@ -75,14 +74,16 @@ private int handlePairScore(List roll) throws IllegalArgumentException
}
private int handleThreeOfAKindScore(List roll) throws IllegalArgumentException {
- if (!this.containsDuplicatesNth(roll, 3)) {
+ Map occurrencesByValue = this.getOccurrencesByValue(roll);
+ if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 3)) {
throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.THREE_OF_A_KIND);
}
return this.calculateSumOfDices(roll);
}
private int handleFourOfAKindScore(List roll) throws IllegalArgumentException {
- if (!this.containsDuplicatesNth(roll, 4)) {
+ Map occurrencesByValue = this.getOccurrencesByValue(roll);
+ if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 4)) {
throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.FOUR_OF_A_KIND);
}
return this.calculateSumOfDices(roll);
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 38978cb..6e263dc 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -194,6 +194,18 @@ void pair_returnPoints_whenGivenRollWithOnlyOnePairOfThree() {
assertEquals(6, result);
}
+ @Test
+ void pair_returnPoints_whenGivenRollWithTwoPairs() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(3, 3, 4, 4, 1), CategoryEnum.PAIR);
+
+ // Assert
+ assertEquals(8, result);
+ }
+
// --- THREE OF A KIND ---
@Test
From 287d5ab13b1d52c20f6be7b254fd567f3a49e6d3 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:08:20 +0200
Subject: [PATCH 13/27] test: if we have more than expected
---
.../java/io/github/vbetsch/yams/YamsTest.java | 25 ++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 6e263dc..20ac9a6 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -206,7 +206,6 @@ void pair_returnPoints_whenGivenRollWithTwoPairs() {
assertEquals(8, result);
}
-
// --- THREE OF A KIND ---
@Test
void threeOfAKind_returnPoints_whenGivenThreeDicesOnes() {
@@ -232,6 +231,18 @@ void threeOfAKind_returnPoints_whenGivenThreeDicesTwos() {
assertEquals(10, result);
}
+ @Test
+ void threeOfAKind_returnPoints_whenGivenMoreThanThreeDicesTwos() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(2, 2, 2, 2, 3), CategoryEnum.THREE_OF_A_KIND);
+
+ // Assert
+ assertEquals(11, result);
+ }
+
@Test
void threeOfAKind_throwIllegalArgumentException_whenGivenLargeStraight() {
// Arrange
@@ -270,6 +281,18 @@ void fourOfAKind_returnPoints_whenGivenFourDicesTwos() {
assertEquals(11, result);
}
+ @Test
+ void fourOfAKind_returnPoints_whenGivenMoreThanFourDicesTwos() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(2, 2, 2, 2, 2), CategoryEnum.FOUR_OF_A_KIND);
+
+ // Assert
+ assertEquals(10, result);
+ }
+
@Test
void fourOfAKind_throwIllegalArgumentException_whenGivenLargeStraight() {
// Arrange
From 9999ad51f5c73c27d92e053c3b9ad46e7f03aec0 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:10:19 +0200
Subject: [PATCH 14/27] fix: filter in pair handler
---
src/main/java/io/github/vbetsch/yams/Yams.java | 2 +-
src/test/java/io/github/vbetsch/yams/YamsTest.java | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 012842c..3f48db5 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -67,7 +67,7 @@ private int handlePairScore(List roll) throws IllegalArgumentException
return occurrencesByValue
.entrySet()
.stream()
- .filter(occurrenceByValue -> occurrenceByValue.getValue() == 2)
+ .filter(occurrenceByValue -> occurrenceByValue.getValue() >= 2)
.map(Map.Entry::getKey)
.max(Integer::compare)
.orElse(0) * 2;
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 20ac9a6..685fd7a 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -194,6 +194,18 @@ void pair_returnPoints_whenGivenRollWithOnlyOnePairOfThree() {
assertEquals(6, result);
}
+ @Test
+ void pair_returnPoints_whenGivenRollWithMoreThanTwoDices() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(3, 3, 3, 5, 1), CategoryEnum.PAIR);
+
+ // Assert
+ assertEquals(6, result);
+ }
+
@Test
void pair_returnPoints_whenGivenRollWithTwoPairs() {
// Arrange
From 3af76084bce74c4492212878428287da4759cdad Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:13:04 +0200
Subject: [PATCH 15/27] docs: update checklist
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 0af2dba..4467b2c 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ The following categories exists:
- [x] Ones, Twos, Threes, Fours, Fives, Sixes: The player scores the sum of the dice that reads one, two, three, four,
five or six, respectively. For example, 1, 1, 2, 4, 4 placed on “fours” gives 8 points.
-- [ ] Pair: The player scores the sum of the two highest matching dice. For example, 3, 3, 3, 4, 4 placed on “pair”
+- [x] Pair: The player scores the sum of the two highest matching dice. For example, 3, 3, 3, 4, 4 placed on “pair”
gives 8.
- [ ] Two pairs: If there are two pairs of dice with the same number, the player scores the sum of these dice. If not,
the player scores 0. For example, 1, 1, 2, 3, 3 placed on “two pairs” gives 8.
From 6ee2138bd73210835423573c1f172366bc11b062 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:17:25 +0200
Subject: [PATCH 16/27] refactor: rename zero points tests
---
src/test/java/io/github/vbetsch/yams/YamsTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 685fd7a..feaae5e 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -59,7 +59,7 @@ void yams_returnPoints_whenGivenFiveDicesThree() {
}
@Test
- void yams_returnPoints_whenGivenRollWithDuplicates() {
+ void yams_returnZeroPoints_whenGivenRollWithDuplicates() {
// Arrange
Yams yams = new Yams();
@@ -71,7 +71,7 @@ void yams_returnPoints_whenGivenRollWithDuplicates() {
}
@Test
- void yams_returnPoints_whenGivenRollWithoutDuplicates() {
+ void yams_returnZeroPoints_whenGivenRollWithoutDuplicates() {
// Arrange
Yams yams = new Yams();
From 25e288991bec72aaa08e8335bf90b7a83cdff1a5 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:20:30 +0200
Subject: [PATCH 17/27] fix: return zero points if duplicates check failed
---
...CategoryNotAuthorizedForThisRollError.java | 7 ----
.../java/io/github/vbetsch/yams/Yams.java | 6 +--
.../java/io/github/vbetsch/yams/YamsTest.java | 39 +++++++++----------
3 files changed, 21 insertions(+), 31 deletions(-)
delete mode 100644 src/main/java/io/github/vbetsch/yams/CategoryNotAuthorizedForThisRollError.java
diff --git a/src/main/java/io/github/vbetsch/yams/CategoryNotAuthorizedForThisRollError.java b/src/main/java/io/github/vbetsch/yams/CategoryNotAuthorizedForThisRollError.java
deleted file mode 100644
index 6b01ff4..0000000
--- a/src/main/java/io/github/vbetsch/yams/CategoryNotAuthorizedForThisRollError.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package io.github.vbetsch.yams;
-
-public class CategoryNotAuthorizedForThisRollError extends IllegalArgumentException {
- public CategoryNotAuthorizedForThisRollError(CategoryEnum category) {
- super("We cannot compute score with category " + category + " for this roll");
- }
-}
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 3f48db5..c89c344 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -62,7 +62,7 @@ private int handleTopPartScores(List roll, int target) {
private int handlePairScore(List roll) throws IllegalArgumentException {
Map occurrencesByValue = this.getOccurrencesByValue(roll);
if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 2)) {
- throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.PAIR);
+ return 0;
}
return occurrencesByValue
.entrySet()
@@ -76,7 +76,7 @@ private int handlePairScore(List roll) throws IllegalArgumentException
private int handleThreeOfAKindScore(List roll) throws IllegalArgumentException {
Map occurrencesByValue = this.getOccurrencesByValue(roll);
if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 3)) {
- throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.THREE_OF_A_KIND);
+ return 0;
}
return this.calculateSumOfDices(roll);
}
@@ -84,7 +84,7 @@ private int handleThreeOfAKindScore(List roll) throws IllegalArgumentEx
private int handleFourOfAKindScore(List roll) throws IllegalArgumentException {
Map occurrencesByValue = this.getOccurrencesByValue(roll);
if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 4)) {
- throw new CategoryNotAuthorizedForThisRollError(CategoryEnum.FOUR_OF_A_KIND);
+ return 0;
}
return this.calculateSumOfDices(roll);
}
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index feaae5e..0fb02a0 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -158,16 +158,15 @@ void sixes_returnPoints_whenGivenRollWithThreeDicesSixes() {
// --- PAIRS ---
@Test
- void pair_throwIllegalArgumentException_whenGivenNotPair() {
+ void pair_returnZeroPoints_whenGivenNotPair() {
// Arrange
Yams yams = new Yams();
- // Act & Assert
- assertThrows(
- IllegalArgumentException.class,
- () -> yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.PAIR),
- "We cannot compute score with category PAIR for this roll"
- );
+ // Act
+ int result = yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.FOUR_OF_A_KIND);
+
+ // Assert
+ assertEquals(0, result);
}
@Test
@@ -256,16 +255,15 @@ void threeOfAKind_returnPoints_whenGivenMoreThanThreeDicesTwos() {
}
@Test
- void threeOfAKind_throwIllegalArgumentException_whenGivenLargeStraight() {
+ void threeOfAKind_returnZeroPoints_whenGivenLargeStraight() {
// Arrange
Yams yams = new Yams();
- // Act & Assert
- assertThrows(
- IllegalArgumentException.class,
- () -> yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.THREE_OF_A_KIND),
- "We cannot compute score with category ThreeOfAKind for this roll"
- );
+ // Act
+ int result = yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.FOUR_OF_A_KIND);
+
+ // Assert
+ assertEquals(0, result);
}
// --- FOUR OF A KIND ---
@@ -306,16 +304,15 @@ void fourOfAKind_returnPoints_whenGivenMoreThanFourDicesTwos() {
}
@Test
- void fourOfAKind_throwIllegalArgumentException_whenGivenLargeStraight() {
+ void fourOfAKind_returnZeroPoints_whenGivenLargeStraight() {
// Arrange
Yams yams = new Yams();
- // Act & Assert
- assertThrows(
- IllegalArgumentException.class,
- () -> yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.FOUR_OF_A_KIND),
- "We cannot compute score with category FourOfAKind for this roll"
- );
+ // Act
+ int result = yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.FOUR_OF_A_KIND);
+
+ // Assert
+ assertEquals(0, result);
}
// --- CHECKS ---
From eb46f5cac5fc2c15c7e393be7e98f1b4b94be8a3 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:24:39 +0200
Subject: [PATCH 18/27] fix: categories in tests
---
src/test/java/io/github/vbetsch/yams/YamsTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 0fb02a0..3d864df 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -163,7 +163,7 @@ void pair_returnZeroPoints_whenGivenNotPair() {
Yams yams = new Yams();
// Act
- int result = yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.FOUR_OF_A_KIND);
+ int result = yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.PAIR);
// Assert
assertEquals(0, result);
@@ -260,7 +260,7 @@ void threeOfAKind_returnZeroPoints_whenGivenLargeStraight() {
Yams yams = new Yams();
// Act
- int result = yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.FOUR_OF_A_KIND);
+ int result = yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.THREE_OF_A_KIND);
// Assert
assertEquals(0, result);
From bd8dbffb1195d6b196e046a63997d19795527e96 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:25:53 +0200
Subject: [PATCH 19/27] feat: handle two pairs
---
.../java/io/github/vbetsch/yams/CategoryEnum.java | 2 +-
src/main/java/io/github/vbetsch/yams/Yams.java | 1 +
src/test/java/io/github/vbetsch/yams/YamsTest.java | 13 +++++++++++++
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/main/java/io/github/vbetsch/yams/CategoryEnum.java b/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
index fe7e074..0738fcc 100644
--- a/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
+++ b/src/main/java/io/github/vbetsch/yams/CategoryEnum.java
@@ -10,7 +10,7 @@ public enum CategoryEnum {
SIXES,
// --- BONUS PART (kata) ---
PAIR,
-// TWO_PAIRS,
+ TWO_PAIRS,
// --- BOTTOM PART ---
THREE_OF_A_KIND,
FOUR_OF_A_KIND,
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index c89c344..dc20017 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -104,6 +104,7 @@ public int computeScore(List roll, CategoryEnum category) throws Invali
case CategoryEnum.FIVES -> this.handleTopPartScores(roll, 5);
case CategoryEnum.SIXES -> this.handleTopPartScores(roll, 6);
case CategoryEnum.PAIR -> this.handlePairScore(roll);
+ case CategoryEnum.TWO_PAIRS -> this.handlePairScore(roll);
case CategoryEnum.THREE_OF_A_KIND -> this.handleThreeOfAKindScore(roll);
case CategoryEnum.FOUR_OF_A_KIND -> this.handleFourOfAKindScore(roll);
default -> 1000;
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 3d864df..7bb7e2a 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -217,6 +217,19 @@ void pair_returnPoints_whenGivenRollWithTwoPairs() {
assertEquals(8, result);
}
+ // --- TWO PAIRS ---
+ @Test
+ void twopairs_returnZeroPoints_whenGivenNotPair() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(1, 2, 3, 4, 5), CategoryEnum.TWO_PAIRS);
+
+ // Assert
+ assertEquals(0, result);
+ }
+
// --- THREE OF A KIND ---
@Test
void threeOfAKind_returnPoints_whenGivenThreeDicesOnes() {
From 6e6c1e176a966c5175e32c42980d5be157fe0c5c Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:37:07 +0200
Subject: [PATCH 20/27] feat: create
containsAtLeastXDuplicatesOnYDifferentDices
---
.../java/io/github/vbetsch/yams/Yams.java | 25 +++++++++++++++++-
.../java/io/github/vbetsch/yams/YamsTest.java | 26 ++++++++++++++++++-
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index dc20017..9f2ad04 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -4,6 +4,7 @@
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
+import java.util.stream.Stream;
public class Yams {
static final int DICES_COUNT = 5;
@@ -26,6 +27,14 @@ private boolean containsAtLeastDuplicatesNth(Map occurrencesBy
.anyMatch(occurrenceByValue -> occurrenceByValue.getValue() >= duplicatesNumber);
}
+ private boolean containsAtLeastXDuplicatesOnYDifferentDices(Map occurrencesByValue, int duplicatesNumber, int differentDices) {
+ Stream> matchingOccurrences = occurrencesByValue
+ .entrySet()
+ .stream()
+ .filter(occurrenceByValue -> occurrenceByValue.getValue() >= duplicatesNumber);
+ return matchingOccurrences.count() == differentDices;
+ }
+
private int calculateSumOfDices(List roll) {
return roll
.stream()
@@ -73,6 +82,20 @@ private int handlePairScore(List roll) throws IllegalArgumentException
.orElse(0) * 2;
}
+ private int handleTwoPairsScore(List roll) throws IllegalArgumentException {
+ Map occurrencesByValue = this.getOccurrencesByValue(roll);
+ if (!this.containsAtLeastXDuplicatesOnYDifferentDices(occurrencesByValue, 2, 2)) {
+ return 0;
+ }
+ return occurrencesByValue
+ .entrySet()
+ .stream()
+ .filter(occurrenceByValue -> occurrenceByValue.getValue() >= 2)
+ .map(Map.Entry::getKey)
+ .max(Integer::compare)
+ .orElse(0) * 2;
+ }
+
private int handleThreeOfAKindScore(List roll) throws IllegalArgumentException {
Map occurrencesByValue = this.getOccurrencesByValue(roll);
if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 3)) {
@@ -104,7 +127,7 @@ public int computeScore(List roll, CategoryEnum category) throws Invali
case CategoryEnum.FIVES -> this.handleTopPartScores(roll, 5);
case CategoryEnum.SIXES -> this.handleTopPartScores(roll, 6);
case CategoryEnum.PAIR -> this.handlePairScore(roll);
- case CategoryEnum.TWO_PAIRS -> this.handlePairScore(roll);
+ case CategoryEnum.TWO_PAIRS -> this.handleTwoPairsScore(roll);
case CategoryEnum.THREE_OF_A_KIND -> this.handleThreeOfAKindScore(roll);
case CategoryEnum.FOUR_OF_A_KIND -> this.handleFourOfAKindScore(roll);
default -> 1000;
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 7bb7e2a..5dac3cc 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -219,7 +219,7 @@ void pair_returnPoints_whenGivenRollWithTwoPairs() {
// --- TWO PAIRS ---
@Test
- void twopairs_returnZeroPoints_whenGivenNotPair() {
+ void two_pairs_returnZeroPoints_whenGivenNotPair() {
// Arrange
Yams yams = new Yams();
@@ -230,6 +230,30 @@ void twopairs_returnZeroPoints_whenGivenNotPair() {
assertEquals(0, result);
}
+ @Test
+ void two_pairs_returnZeroPoints_whenGivenRollWithOnlyOnePair() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(2, 2, 3, 4, 5), CategoryEnum.TWO_PAIRS);
+
+ // Assert
+ assertEquals(0, result);
+ }
+
+ @Test
+ void two_pairs_returnPoints_whenGivenRollWithTwoPairs() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(3, 3, 4, 4, 1), CategoryEnum.TWO_PAIRS);
+
+ // Assert
+ assertEquals(14, result);
+ }
+
// --- THREE OF A KIND ---
@Test
void threeOfAKind_returnPoints_whenGivenThreeDicesOnes() {
From 8fb00da405492d892c6f88b62db954671b5264ed Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:41:33 +0200
Subject: [PATCH 21/27] refactor: merge contains duplicates methods
---
.../java/io/github/vbetsch/yams/Yams.java | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 9f2ad04..8072efe 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -20,19 +20,12 @@ private Map getOccurrencesByValue(List roll) {
return occurrencesByValue;
}
- private boolean containsAtLeastDuplicatesNth(Map occurrencesByValue, int duplicatesNumber) {
- return occurrencesByValue
- .entrySet()
- .stream()
- .anyMatch(occurrenceByValue -> occurrenceByValue.getValue() >= duplicatesNumber);
- }
-
- private boolean containsAtLeastXDuplicatesOnYDifferentDices(Map occurrencesByValue, int duplicatesNumber, int differentDices) {
+ private boolean containsAtLeastXDuplicatesOnAtLeastYDifferentDices(Map occurrencesByValue, int duplicatesNumber, int differentDices) {
Stream> matchingOccurrences = occurrencesByValue
.entrySet()
.stream()
.filter(occurrenceByValue -> occurrenceByValue.getValue() >= duplicatesNumber);
- return matchingOccurrences.count() == differentDices;
+ return matchingOccurrences.count() >= differentDices;
}
private int calculateSumOfDices(List roll) {
@@ -70,7 +63,7 @@ private int handleTopPartScores(List roll, int target) {
private int handlePairScore(List roll) throws IllegalArgumentException {
Map occurrencesByValue = this.getOccurrencesByValue(roll);
- if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 2)) {
+ if (!this.containsAtLeastXDuplicatesOnAtLeastYDifferentDices(occurrencesByValue, 2, 1)) {
return 0;
}
return occurrencesByValue
@@ -84,7 +77,7 @@ private int handlePairScore(List roll) throws IllegalArgumentException
private int handleTwoPairsScore(List roll) throws IllegalArgumentException {
Map occurrencesByValue = this.getOccurrencesByValue(roll);
- if (!this.containsAtLeastXDuplicatesOnYDifferentDices(occurrencesByValue, 2, 2)) {
+ if (!this.containsAtLeastXDuplicatesOnAtLeastYDifferentDices(occurrencesByValue, 2, 2)) {
return 0;
}
return occurrencesByValue
@@ -98,7 +91,7 @@ private int handleTwoPairsScore(List roll) throws IllegalArgumentExcept
private int handleThreeOfAKindScore(List roll) throws IllegalArgumentException {
Map occurrencesByValue = this.getOccurrencesByValue(roll);
- if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 3)) {
+ if (!this.containsAtLeastXDuplicatesOnAtLeastYDifferentDices(occurrencesByValue, 3, 1)) {
return 0;
}
return this.calculateSumOfDices(roll);
@@ -106,7 +99,7 @@ private int handleThreeOfAKindScore(List roll) throws IllegalArgumentEx
private int handleFourOfAKindScore(List roll) throws IllegalArgumentException {
Map occurrencesByValue = this.getOccurrencesByValue(roll);
- if (!this.containsAtLeastDuplicatesNth(occurrencesByValue, 4)) {
+ if (!this.containsAtLeastXDuplicatesOnAtLeastYDifferentDices(occurrencesByValue, 4, 1)) {
return 0;
}
return this.calculateSumOfDices(roll);
From 6a675ea372cf84f301c7905dadab16ddc504666b Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:54:08 +0200
Subject: [PATCH 22/27] fix: compute score for two pairs
---
src/main/java/io/github/vbetsch/yams/Yams.java | 6 +++---
src/test/java/io/github/vbetsch/yams/YamsTest.java | 12 ++++++++++++
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 8072efe..dbb0cd0 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -84,9 +84,9 @@ private int handleTwoPairsScore(List roll) throws IllegalArgumentExcept
.entrySet()
.stream()
.filter(occurrenceByValue -> occurrenceByValue.getValue() >= 2)
- .map(Map.Entry::getKey)
- .max(Integer::compare)
- .orElse(0) * 2;
+ .map(occurrenceByValue -> occurrenceByValue.getKey() * 2)
+ .mapToInt(Integer::intValue)
+ .sum();
}
private int handleThreeOfAKindScore(List roll) throws IllegalArgumentException {
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index 5dac3cc..b0c9eca 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -254,6 +254,18 @@ void two_pairs_returnPoints_whenGivenRollWithTwoPairs() {
assertEquals(14, result);
}
+ @Test
+ void two_pairs_returnPoints_whenGivenRollWithFull() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(3, 3, 4, 4, 4), CategoryEnum.TWO_PAIRS);
+
+ // Assert
+ assertEquals(14, result);
+ }
+
// --- THREE OF A KIND ---
@Test
void threeOfAKind_returnPoints_whenGivenThreeDicesOnes() {
From 4f9b50904d9a48f4e9f405c9870cbbec04151a56 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:56:28 +0200
Subject: [PATCH 23/27] test:
two_pairs_returnPoints_whenGivenRollWithTwoPairsOfFourAndFive
---
src/test/java/io/github/vbetsch/yams/YamsTest.java | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/test/java/io/github/vbetsch/yams/YamsTest.java b/src/test/java/io/github/vbetsch/yams/YamsTest.java
index b0c9eca..44a175d 100644
--- a/src/test/java/io/github/vbetsch/yams/YamsTest.java
+++ b/src/test/java/io/github/vbetsch/yams/YamsTest.java
@@ -243,7 +243,7 @@ void two_pairs_returnZeroPoints_whenGivenRollWithOnlyOnePair() {
}
@Test
- void two_pairs_returnPoints_whenGivenRollWithTwoPairs() {
+ void two_pairs_returnPoints_whenGivenRollWithTwoPairsOfThreeAndFour() {
// Arrange
Yams yams = new Yams();
@@ -254,6 +254,18 @@ void two_pairs_returnPoints_whenGivenRollWithTwoPairs() {
assertEquals(14, result);
}
+ @Test
+ void two_pairs_returnPoints_whenGivenRollWithTwoPairsOfFourAndFive() {
+ // Arrange
+ Yams yams = new Yams();
+
+ // Act
+ int result = yams.computeScore(List.of(4, 4, 5, 5, 1), CategoryEnum.TWO_PAIRS);
+
+ // Assert
+ assertEquals(18, result);
+ }
+
@Test
void two_pairs_returnPoints_whenGivenRollWithFull() {
// Arrange
From a0575903ebb2f1c19e8bbd1ce7b9c6edd7ba0e12 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 18:56:45 +0200
Subject: [PATCH 24/27] docs: update checklist
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 4467b2c..a2449b6 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ The following categories exists:
five or six, respectively. For example, 1, 1, 2, 4, 4 placed on “fours” gives 8 points.
- [x] Pair: The player scores the sum of the two highest matching dice. For example, 3, 3, 3, 4, 4 placed on “pair”
gives 8.
-- [ ] Two pairs: If there are two pairs of dice with the same number, the player scores the sum of these dice. If not,
+- [x] Two pairs: If there are two pairs of dice with the same number, the player scores the sum of these dice. If not,
the player scores 0. For example, 1, 1, 2, 3, 3 placed on “two pairs” gives 8.
- [x] Three of a kind: If there are three dice with the same number, the player scores the sum of these dice. Otherwise,
the player scores 0. For example, 3, 3, 3, 4, 5 places on “three of a kind” gives 9.
From a2a117629c831bf641e4e5dc3a3388178f621ef3 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 19:04:32 +0200
Subject: [PATCH 25/27] refactor: create getAllPairsOccurrences
---
src/main/java/io/github/vbetsch/yams/Yams.java | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index dbb0cd0..5d2bbe1 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -35,6 +35,13 @@ private int calculateSumOfDices(List roll) {
.sum();
}
+ private Stream> getAllPairsOccurrences(Map occurrencesByValue) {
+ return occurrencesByValue
+ .entrySet()
+ .stream()
+ .filter(occurrenceByValue -> occurrenceByValue.getValue() >= 2);
+ }
+
// Handlers
private int handleChanceScore(List roll) {
return this.calculateSumOfDices(roll);
@@ -66,10 +73,7 @@ private int handlePairScore(List roll) throws IllegalArgumentException
if (!this.containsAtLeastXDuplicatesOnAtLeastYDifferentDices(occurrencesByValue, 2, 1)) {
return 0;
}
- return occurrencesByValue
- .entrySet()
- .stream()
- .filter(occurrenceByValue -> occurrenceByValue.getValue() >= 2)
+ return this.getAllPairsOccurrences(occurrencesByValue)
.map(Map.Entry::getKey)
.max(Integer::compare)
.orElse(0) * 2;
@@ -80,10 +84,7 @@ private int handleTwoPairsScore(List roll) throws IllegalArgumentExcept
if (!this.containsAtLeastXDuplicatesOnAtLeastYDifferentDices(occurrencesByValue, 2, 2)) {
return 0;
}
- return occurrencesByValue
- .entrySet()
- .stream()
- .filter(occurrenceByValue -> occurrenceByValue.getValue() >= 2)
+ return this.getAllPairsOccurrences(occurrencesByValue)
.map(occurrenceByValue -> occurrenceByValue.getKey() * 2)
.mapToInt(Integer::intValue)
.sum();
From 952dc1852fe384fbb58ed7451650a09a40c28395 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 19:07:09 +0200
Subject: [PATCH 26/27] refactor: rename i to index
---
src/main/java/io/github/vbetsch/yams/Yams.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/io/github/vbetsch/yams/Yams.java b/src/main/java/io/github/vbetsch/yams/Yams.java
index 5d2bbe1..e1e904f 100644
--- a/src/main/java/io/github/vbetsch/yams/Yams.java
+++ b/src/main/java/io/github/vbetsch/yams/Yams.java
@@ -12,8 +12,8 @@ public class Yams {
// Utils
private Map getOccurrencesByValue(List roll) {
Map occurrencesByValue = new HashMap<>();
- for (int i = 0; i < roll.size(); i++) {
- int diceValue = roll.get(i);
+ for (int index = 0; index < roll.size(); index++) {
+ int diceValue = roll.get(index);
occurrencesByValue.merge(diceValue, 1, Integer::sum);
}
IO.println(occurrencesByValue);
From 5a9f4a69ad9b4f9196bf13673afe970f78b576f3 Mon Sep 17 00:00:00 2001
From: vbetsch <71458556+vbetsch@users.noreply.github.com>
Date: Fri, 16 Oct 2026 19:12:50 +0200
Subject: [PATCH 27/27] revert: annotations config
---
pom.xml | 6 ------
1 file changed, 6 deletions(-)
diff --git a/pom.xml b/pom.xml
index 9082ba0..c54c7ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,12 +21,6 @@
5.11.0
test
-
- org.jetbrains
- annotations
- RELEASE
- compile
-