Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplified announcement processing + async calls #24

Merged
merged 1 commit into from
Aug 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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