Content of file EvolutionStrategiesTest.java
package de.fhdw.gaming.ipspiel21.dilemmaOriginal.strategy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.Map;
import java.util.Optional;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import de.fhdw.gaming.core.domain.GameException;
import de.fhdw.gaming.core.domain.PlayerState;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.domain.DilemmaGame;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.domain.DilemmaGameBuilder;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.domain.DilemmaPlayer;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.domain.DilemmaPlayerBuilder;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.domain.DilemmaState;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.domain.factory.DilemmaStrategyFactory;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.domain.impl.DilemmaGameBuilderImpl;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.moves.DilemmaMove;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.moves.impl.AbstractDilemmaMove;
import de.fhdw.gaming.ipspiel21.dilemmaOriginal.moves.impl.DilemmaDefaultMoveFactory;
import de.fhdw.gaming.ipspiel21.evolution.GameHistoryCollection;
import de.fhdw.gaming.ipspiel21.evolution.MemoryObserver;
/**
* Testing all Evolution Strategies.
*
* @author Robby Rabbitman
*
*/
@TestInstance(Lifecycle.PER_CLASS)
class EvolutionStrategiesTest {
/**
* Game Builder.
*/
private DilemmaGameBuilder gameBuilder;
/**
* CurrentGameId.
*/
private int gameId;
/**
* Current Player Builder for Player 1.
*/
private SamePlayerBuilder pb1;
/**
* Current Player Builder for Player 2.
*/
private SamePlayerBuilder pb2;
/**
* Player 1 Name.
*/
private String p1;
/**
* Player 2 Name.
*/
private String p2;
/**
* DefaultMoves for a Dilemma Game.
*/
private DilemmaDefaultMoveFactory mf;
/**
* initialize the Test data. Given new Objects.
*
* @throws InterruptedException
* @throws GameException
*/
@BeforeEach
public void initTest() throws GameException, InterruptedException {
this.gameBuilder = new DilemmaGameBuilderImpl();
this.pb1 = new SamePlayerBuilder(this.gameBuilder.createPlayerBuilder());
this.pb1.defaultPlayerBuilder().changeName(this.p1);
this.pb2 = new SamePlayerBuilder(this.gameBuilder.createPlayerBuilder());
this.pb2.defaultPlayerBuilder().changeName(this.p2);
}
/**
* Initierung der Spieler, MoveFactory and setting GameId to 0.
*/
@BeforeAll
public void init() {
this.mf = new DilemmaDefaultMoveFactory();
this.gameId = 0;
this.p1 = "Hugo";
this.p2 = "Hans";
}
/**
* Creates a DilemmaGame for the tests.
*
* @param f1
* @param f2
* @return
* @throws GameException
* @throws InterruptedException
*/
private DilemmaGame createGame(final DilemmaStrategyFactory f1, final DilemmaStrategyFactory f2)
throws GameException, InterruptedException {
this.gameBuilder = new DilemmaGameBuilderImpl();
this.gameBuilder.addPlayerBuilder(this.pb1, f1.create(this.mf));
this.gameBuilder.addPlayerBuilder(this.pb2, f2.create(this.mf));
final DilemmaGame game = this.gameBuilder.build(this.gameId++);
game.addObserver(MemoryObserver.INSTANCE);
return game;
}
/**
* Get the Move from a player out of his memory for a given game.
*
* @param player
* @param game
* @param move
* @return
*/
private DilemmaMove getMove(final DilemmaPlayer player, final int game, final int move) {
return (DilemmaMove) player.getGameHistoryCollection().getSpecificGameHistory(game).getMove(move);
}
/**
* Execute a game.
*
* @param games
* @param f1
* @param f2
* @param cb
*/
private void execute(final int games, final DilemmaStrategyFactory f1, final DilemmaStrategyFactory f2,
final GameFinishedCallback cb) {
for (int i = 1; i <= games; i++) {
DilemmaGame game = null;
try {
game = this.createGame(f1, f2);
game.start();
game.makeMove();
game.makeMove();
game.close();
cb.execute(i, this.pb1.getPlayer(), this.pb2.getPlayer(), this.getMove(this.pb1.getPlayer(), 0, 0),
this.getMove(this.pb2.getPlayer(), 0, 0));
} catch (GameException | InterruptedException e) {
fail(e.getMessage());
} finally {
if (game != null) {
game.close();
}
}
}
}
/**
* The logger for a Dilemma Game.
*
* @param game
* @param player1
* @param player2
*/
@SuppressWarnings("unused")
private void log(final int game, final DilemmaPlayer player1, final DilemmaPlayer player2) {
System.out.println(String.format("\n%s = %s\n%s = %s", player1.getName(),
this.collectionAsString(player1.getGameHistoryCollection()), player2.getName(),
this.collectionAsString(player2.getGameHistoryCollection())));
}
/**
* To String method for a Collection.
*
* @param collection
* @return
*/
private String collectionAsString(final GameHistoryCollection collection) {
return collection.getGameHistories().stream().map(h -> h.getMove(0).toString())
.reduce((a, b) -> a + ", " + b).orElse("");
}
/**
* Testing the Mistrust Strategy.
*/
@Test
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
Code containing duplicate String literals can usually be improved by declaring the String as a constant field.
private void bar() {
buz("Howdy");
buz("Howdy");
buz("Howdy");
buz("Howdy");
}
private void buz(String x) {}
See PMD documentation.
void testMistrustStrategy() {
this.execute(1, new DilemmaMistrustStrategyFactory(), new DilemmaAlwaysConfessStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(this.mf.createNoMove(), m1));
this.execute(9, new DilemmaMistrustStrategyFactory(), new DilemmaAlwaysConfessStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(this.getMove(player2, 1, 0), m1));
}
/**
* Testing the Nasty Strategy.
*/
@Test
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
void testNastyStrategy() {
this.execute(10, new DilemmaNastyStrategyFactory(), new DilemmaStaySilentStrategyFactory(),
(game, player1, player2, m1, m2) -> {
assertEquals(game % 3 == 0 ? this.mf.createYesMove() : this.mf.createNoMove(), m1);
});
}
/**
* Game Test for the pavlov strategy.
*/
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
@Test
void testPavlovStrategy() {
this.execute(10, new DilemmaPavlovStrategyFactory(), new DilemmaStaySilentStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(
game == 1 ? this.mf.createYesMove() : this.getMove(player2, 1, 0), m1));
}
/**
* Game Test for the pavlov strategy.
*/
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
@Test
void testPavlovAgainstKindStrategy() {
this.execute(10, new DilemmaPavlovStrategyFactory(), new DilemmaAlwaysConfessStrategyFactory(),
(game, player1, player2, m1, m2) -> {
if (game == 1) {
assertEquals(this.mf.createYesMove(), m1);
}
if (game == 2) {
assertEquals(this.mf.createNoMove(), m1);
}
});
}
/**
* Game Test for the periodically kind strategy.
*/
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
@Test
void testPeriodicallyKindStrategy() {
this.execute(10, new DilemmaPeriodicallyKindStrategyFactory(), new DilemmaStaySilentStrategyFactory(),
(game, player1, player2, m1,
m2) -> assertEquals(game % 3 == 0 ? this.mf.createNoMove() : this.mf.createYesMove(), m1));
}
/**
* Game Test for the prober strategy.
*/
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
@Test
void testProberStrategy() {
this.execute(1, new DilemmaProberStrategyFactory(), new DilemmaStaySilentStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(this.mf.createYesMove(), m1));
this.execute(2, new DilemmaProberStrategyFactory(), new DilemmaStaySilentStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(this.mf.createNoMove(), m1));
this.execute(7, new DilemmaProberStrategyFactory(), new DilemmaStaySilentStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(this.mf.createNoMove(), m1));
}
/**
* Game Test for the punisher strategy.
*/
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
@Test
void testPunisherStrategy() {
// TODO Implement
}
/**
* Testing the Spite Strategy against the Always Silent Strategy.
*/
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
@Test
void testSpiteVsStaySilentStrategy() {
this.execute(10, new DilemmaSpiteStrategyFactory(), new DilemmaStaySilentStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(this.mf.createYesMove(), m1));
}
/**
* Testing the Spite Strategy against the Always Confess Strategy.
*/
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
@Test
void testSpiteVsAlwaysConfessStrategy() {
this.execute(1, new DilemmaSpiteStrategyFactory(), new DilemmaAlwaysConfessStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(this.mf.createYesMove(), m1));
this.execute(9, new DilemmaSpiteStrategyFactory(), new DilemmaAlwaysConfessStrategyFactory(),
(game, player1, player2, m1, m2) -> assertEquals(this.mf.createNoMove(), m1));
}
/**
* Create a PlayerBuilder which uses the same inputs then before. It stays the same object.
*
* @author Robby Rabbitman
*
*/
private class SamePlayerBuilder implements DilemmaPlayerBuilder {
/**
* proxied pb.
*/
private DilemmaPlayerBuilder pb;
/**
* proxied p.
*/
private ModifiablePlayer player;
/**
* The Constructor.
*
* @param pb
*/
public SamePlayerBuilder(final DilemmaPlayerBuilder pb) {
this.pb = pb;
}
@Override
public DilemmaPlayerBuilder changeName(final String newName) {
return this.pb.changeName(newName);
}
@Override
public DilemmaPlayerBuilder changePossibleOutcomes(
final Map<AbstractDilemmaMove, Map<AbstractDilemmaMove, Double>> possibleOutcomes) {
return this.pb.changePossibleOutcomes(possibleOutcomes);
}
@Override
public DilemmaPlayer build(final DilemmaState state) throws GameException {
if (this.player == null) {
this.player = new ModifiablePlayer(this.pb.build(state), state);
}
this.player.setState(state);
return this.player;
}
@Override
public DilemmaPlayerBuilder defaultPlayerBuilder() {
this.pb = this.pb.defaultPlayerBuilder();
return this;
}
/**
* The Player of the PlayerBuilder.
*
* @return
*/
public DilemmaPlayer getPlayer() {
return this.player;
}
/**
* Testcase to clear pmd violation. Class should be moved into own file!
*/
@Test
void test() {
assertEquals(1, 1);
}
}
/**
* A Modifiable Player for tests.
*
* @author Robby Rabbitman
*
*/
private static class ModifiablePlayer implements DilemmaPlayer {
/**
* proxied p.
*/
private DilemmaPlayer player;
/**
* The GameHistory of a Player.
*/
private final GameHistoryCollection collection;
/**
* The Constructor.
*
* @param player
* @param state
*/
public ModifiablePlayer(final DilemmaPlayer player, final DilemmaState state) {
this.collection = player.getGameHistoryCollection();
this.player = player;
this.player = this.deepCopy(state);
}
@Override
public GameHistoryCollection getGameHistoryCollection() {
return this.collection;
}
@Override
public void setGameHistoryCollection(final GameHistoryCollection gameHistoryCollection) {
this.player.setGameHistoryCollection(gameHistoryCollection);
}
@Override
public String getName() {
return this.player.getName();
}
@Override
public PlayerState getState() {
return this.player.getState();
}
@Override
public Optional<Double> getOutcome() {
return this.player.getOutcome();
}
@Override
public Map<AbstractDilemmaMove, Map<AbstractDilemmaMove, Double>> getPossibleOutcomes() {
return this.player.getPossibleOutcomes();
}
@Override
public final DilemmaPlayer deepCopy(final DilemmaState newGameState) {
return this.player.deepCopy(newGameState);
}
@Override
public void setMove(final AbstractDilemmaMove abstractMove) {
this.player.setMove(abstractMove);
}
@Override
public AbstractDilemmaMove getMove() {
return this.player.getMove();
}
/**
* Set a game state to this player.
*
* @param state
*/
public void setState(final DilemmaState state) {
this.player = this.deepCopy(state);
}
/**
* Testcase to clear pmd violation. Class should be moved into own file!
*/
@Test
void test() {
assertEquals(1, 1);
}
}
/**
* Callback for writing tests, after a Game is finished.
*
* @author Robby Rabbitman
*
*/
@FunctionalInterface
private interface GameFinishedCallback {
/**
* A Callback can execute a Game(DilemmaGame).
* After this game is finished the Callback will hold all players and there moves.
*
* @param game
* @param p1
* @param p2
* @param m1
* @param m2
*/
void execute(int game, DilemmaPlayer p1, DilemmaPlayer p2, DilemmaMove m1, DilemmaMove m2);
}
}