Skip to content

Commit

Permalink
Simplified announcement processing (#24)
Browse files Browse the repository at this point in the history
Added more async functions
Added unit tests
  • Loading branch information
jberclaz authored Aug 23, 2020
1 parent f06bfb7 commit e6a6f94
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/leflat/jass/common/Team.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void addPlayer(BasePlayer p) {
p.setTeam(this);
}

public void addAnnoucementScore(List<Announcement> anouncements) {
public void addAnnouncementScore(List<Announcement> anouncements) {
for (var a : anouncements) {
currentScore += Card.atout == Card.COLOR_SPADE ? 2 * a.getValue() : a.getValue();
}
Expand Down
116 changes: 81 additions & 35 deletions src/main/java/com/leflat/jass/server/GameController.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,55 +196,50 @@ Plie playPlie(int startingPlayer) throws PlayerLeftExpection, BrokenRuleExceptio
}

boolean processAnnouncements() throws PlayerLeftExpection {
boolean validAnnoucements = false;
Map<Integer, List<Announcement>> annoucements = new HashMap<>();
boolean validAnnouncements = false;
BasePlayer playerWithStoeck = null;
Announcement highestAnnouncement = null;
Team announcingTeam = null; // joueur qui a la plus grosse annonce
for (var p : players) {
var a = p.getAnnouncements();
for (var player : players) {
var a = player.getAnnouncements();
if (a.isEmpty()) {
continue;
}
annoucements.put(p.getId(), a);
for (var announcement : a) {
LOGGER.info(p + " announces : " + announcement);
LOGGER.info(player + " announces : " + announcement);
if (announcement.getType() == Announcement.STOECK) {
playerWithStoeck = p;
playerWithStoeck = player;
continue;
}
if (highestAnnouncement == null || announcement.compareTo(highestAnnouncement) > 0) {
highestAnnouncement = announcement;
announcingTeam = p.getTeam();
announcingTeam = player.getTeam();
}
}
}

if (announcingTeam != null) { // there are announces
for (var p : players) {
if (!annoucements.containsKey(p.getId())) {
for (var player : players) {
var a = player.getAnnouncements();
if (a.isEmpty()) {
continue;
}
if ((p.getTeam() == announcingTeam)) {
announcingTeam.addAnnoucementScore(annoucements.get(p.getId()));
for (var p2 : players) {
p2.setAnnouncements(p, annoucements.get(p.getId()));
}
validAnnoucements = true;
if ((player.getTeam() == announcingTeam)) {
announcingTeam.addAnnouncementScore(a);
setAnnoucementsAsync(player, a);
validAnnouncements = true;
}
p.clearAnnouncements();
player.clearAnnouncements();
}
} else if (playerWithStoeck != null) { // no announce but stock
for (var p : players) {
p.setAnnouncements(playerWithStoeck, Collections.singletonList(new Announcement(Announcement.STOECK, null)));
}
int stoeckScore = Card.atout == Card.COLOR_SPADE ? Announcement.VALUES[Announcement.STOECK] * 2 : Announcement.VALUES[Announcement.STOECK];
} else if (playerWithStoeck != null) { // no announce but stoeck
setAnnoucementsAsync(playerWithStoeck, Collections.singletonList(new Announcement(Announcement.STOECK, null)));
// add stock points
int stoeckScore = Card.atout == Card.COLOR_SPADE ? Announcement.VALUES[Announcement.STOECK] * 2 : Announcement.VALUES[Announcement.STOECK];
playerWithStoeck.getTeam().addScore(stoeckScore);
playerWithStoeck.clearAnnouncements();
validAnnoucements = true;
validAnnouncements = true;
}
return validAnnoucements;
return validAnnouncements;
}

int chooseAtout(int playerNumber) throws PlayerLeftExpection {
Expand Down Expand Up @@ -287,16 +282,12 @@ void chooseTeam() throws PlayerLeftExpection {
reorderPlayers();

var order = players.stream().map(BasePlayer::getId).collect(Collectors.toList());
for (var p : players) {
p.setPlayersOrder(order);
}
setPlayersOrderAsync(order);
}

void chooseTeamsRandomly() throws PlayerLeftExpection {
// préparation du tirage des équipes
for (var player : players) {
player.prepareTeamDrawing(true);
}
prepareTeamDrawingAsync(true);

boolean drawingSuccessful;
do {
Expand All @@ -315,9 +306,7 @@ void chooseTeamsRandomly() throws PlayerLeftExpection {
// détermine les équipes
drawingSuccessful = calculateTeam(cardsDrawn);
if (!drawingSuccessful) {
for (var p : players) {
p.prepareTeamDrawing(false);
}
prepareTeamDrawingAsync(false);
waitSec(2);
}
} while (!drawingSuccessful);
Expand Down Expand Up @@ -505,7 +494,7 @@ void setDrawnCardAsync(BasePlayer player, int position, Card card) throws Player
}
}

void collectPlieAsync(BasePlayer player) throws PlayerLeftExpection {
void collectPlieAsync(BasePlayer player) throws PlayerLeftExpection {
var answers = players.stream()
.map(p -> CompletableFuture.supplyAsync(() -> {
try {
Expand All @@ -524,7 +513,7 @@ void collectPlieAsync(BasePlayer player) throws PlayerLeftExpection {
}
}

void setAtoutAsync(int color, BasePlayer player) throws PlayerLeftExpection {
void setAtoutAsync(int color, BasePlayer player) throws PlayerLeftExpection {
var answers = players.stream()
.map(p -> CompletableFuture.supplyAsync(() -> {
try {
Expand All @@ -542,4 +531,61 @@ void setAtoutAsync(int color, BasePlayer player) throws PlayerLeftExpection {
throw (PlayerLeftExpection) ex.getCause();
}
}

void setAnnoucementsAsync(BasePlayer player, List<Announcement> announcements) throws PlayerLeftExpection {
var answers = players.stream()
.map(p -> CompletableFuture.supplyAsync(() -> {
try {
p.setAnnouncements(player, announcements);
} catch (PlayerLeftExpection playerLeftExpection) {
throw new CompletionException(playerLeftExpection);
}
return 0;
}))
.collect(Collectors.toList());

try {
answers.stream().map(CompletableFuture::join).collect(Collectors.toList());
} catch (CompletionException ex) {
throw (PlayerLeftExpection) ex.getCause();
}
}

void setPlayersOrderAsync(List<Integer> order) throws PlayerLeftExpection {
var answers = players.stream()
.map(p -> CompletableFuture.supplyAsync(() -> {
try {
p.setPlayersOrder(order);
} catch (PlayerLeftExpection playerLeftExpection) {
throw new CompletionException(playerLeftExpection);
}
return 0;
}))
.collect(Collectors.toList());

try {
answers.stream().map(CompletableFuture::join).collect(Collectors.toList());
} catch (CompletionException ex) {
throw (PlayerLeftExpection) ex.getCause();
}
}

void prepareTeamDrawingAsync(boolean firstAttempt) throws PlayerLeftExpection {
var answers = players.stream()
.map(p -> CompletableFuture.supplyAsync(() -> {
try {
p.prepareTeamDrawing(firstAttempt);
} catch (PlayerLeftExpection playerLeftExpection) {
throw new CompletionException(playerLeftExpection);
}
return 0;
}))
.collect(Collectors.toList());

try {
answers.stream().map(CompletableFuture::join).collect(Collectors.toList());
} catch (CompletionException ex) {
throw (PlayerLeftExpection) ex.getCause();
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/leflat/jass/test/MockUi.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class MockUi implements IJassUi {
private List<Card> hand;
private IRemotePlayer player;
private float delaySeconds = 0;
private boolean hasAskedForNewGame = false;

public MockUi(IRemotePlayer player, float delaySeconds) {
this.player = player;
Expand Down Expand Up @@ -149,6 +150,10 @@ public void displayGameResult(Team winningTeam, boolean won) {

@Override
public boolean getNewGame() {
if (!hasAskedForNewGame) {
hasAskedForNewGame = true;
return true;
}
return false;
}

Expand Down
37 changes: 36 additions & 1 deletion src/test/java/com/leflat/jass/server/AsyncTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

public class AsyncTests {
@Test
void async_tests() throws PlayerLeftExpection {
void async_error_test() throws PlayerLeftExpection {
Card.atout = Card.COLOR_SPADE;
RemotePlayer player1 = mock(RemotePlayer.class);
RemotePlayer player2 = mock(RemotePlayer.class);
Expand All @@ -37,4 +37,39 @@ void async_tests() throws PlayerLeftExpection {
game.setHandScoreAsync(new int[]{10, 20}, null);
});
}

@Test
void async_test() throws PlayerLeftExpection {
Card.atout = Card.COLOR_SPADE;
RemotePlayer player1 = mock(RemotePlayer.class);
RemotePlayer player2 = mock(RemotePlayer.class);
RemotePlayer player3 = mock(RemotePlayer.class);
RemotePlayer player4 = mock(RemotePlayer.class);
when(player1.getId()).thenReturn(0);
when(player2.getId()).thenReturn(1);
when(player3.getId()).thenReturn(2);
when(player4.getId()).thenReturn(3);
var t1 = new Team(0);
var t2 = new Team(1);
t1.addScore(100);
t2.addScore(200);
when(player1.getTeam()).thenReturn(t1);
when(player2.getTeam()).thenReturn(t1);
when(player3.getTeam()).thenReturn(t2);
when(player4.getTeam()).thenReturn(t2);

var game = new GameController(0);
game.setNoWait(true);
game.addPlayer(player1);
game.addPlayer(player2);
game.addPlayer(player3);
game.addPlayer(player4);

game.setTeamsScoreAsync(false);

verify(player1).setScores(100, 0);
verify(player2).setScores(100, 0);
verify(player3).setScores(200, 0);
verify(player4).setScores(200, 0);
}
}
4 changes: 2 additions & 2 deletions src/test/java/com/leflat/jass/server/CommonTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ public void team_score_test() {
ans.add(new Announcement(Announcement.THREE_CARDS, new Card(12)));

Card.atout = Card.COLOR_HEART;
team.addAnnoucementScore(ans);
team.addAnnouncementScore(ans);
assertEquals(170, team.getScore());

team.resetScore();
Card.atout = Card.COLOR_SPADE;
team.addAnnoucementScore(ans);
team.addAnnouncementScore(ans);
assertEquals(340, team.getScore());

assertFalse(team.hasWon());
Expand Down

0 comments on commit e6a6f94

Please sign in to comment.