Commit e5d3abce authored by Fabian Jakob Sauer's avatar Fabian Jakob Sauer

Added BasicPlayer class to modifiy and test against RandomPlayer.

parent c2b4493d
......@@ -22,6 +22,7 @@
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="ignore.virus.scanning.warn.message" value="true" />
<property name="project.structure.last.edited" value="Modules" />
<property name="project.structure.proportion" value="0.0" />
<property name="project.structure.side.proportion" value="0.0" />
......@@ -68,21 +69,37 @@
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state x="322" y="93" key="#Project_Structure/0.0.1920.1040@0.0.1920.1040" timestamp="1588687390551" />
<state width="1877" height="242" key="GridCell.Tab.0.bottom" timestamp="1588688336055">
<state width="1877" height="365" key="GridCell.Tab.0.bottom" timestamp="1588706839348">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="242" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1588688336055" />
<state width="1877" height="242" key="GridCell.Tab.0.center" timestamp="1588688336055">
<state width="1877" height="365" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1588706839348" />
<state width="1877" height="365" key="GridCell.Tab.0.center" timestamp="1588706839348">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="242" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1588688336055" />
<state width="1877" height="242" key="GridCell.Tab.0.left" timestamp="1588688336055">
<state width="1877" height="365" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1588706839348" />
<state width="1877" height="365" key="GridCell.Tab.0.left" timestamp="1588706839348">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="242" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1588688336055" />
<state width="1877" height="242" key="GridCell.Tab.0.right" timestamp="1588688336055">
<state width="1877" height="365" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1588706839348" />
<state width="1877" height="365" key="GridCell.Tab.0.right" timestamp="1588706839348">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="242" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1588688336055" />
<state width="1877" height="365" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1588706839348" />
<state width="1877" height="365" key="GridCell.Tab.1.bottom" timestamp="1588706839348">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="365" key="GridCell.Tab.1.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1588706839348" />
<state width="1877" height="365" key="GridCell.Tab.1.center" timestamp="1588706839348">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="365" key="GridCell.Tab.1.center/0.0.1920.1040@0.0.1920.1040" timestamp="1588706839348" />
<state width="1877" height="365" key="GridCell.Tab.1.left" timestamp="1588706839348">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="365" key="GridCell.Tab.1.left/0.0.1920.1040@0.0.1920.1040" timestamp="1588706839348" />
<state width="1877" height="365" key="GridCell.Tab.1.right" timestamp="1588706839348">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="365" key="GridCell.Tab.1.right/0.0.1920.1040@0.0.1920.1040" timestamp="1588706839348" />
</component>
</project>
\ No newline at end of file
package de.upb.isml.thegamef2f.engine.player;
import java.util.*;
import de.upb.isml.thegamef2f.engine.CardPosition;
import de.upb.isml.thegamef2f.engine.GameState;
import de.upb.isml.thegamef2f.engine.Move;
import de.upb.isml.thegamef2f.engine.Placement;
import de.upb.isml.thegamef2f.engine.board.Card;
/**
* Basic Player AI
* @author fjsauer
*/
public class BasicPlayer implements Player {
private Random random;
@Override
public void initialize(long randomSeed) {
this.random = new Random(randomSeed);
}
@Override
public Move computeMove(GameState gameState) {
GameState currentGameState = gameState;
boolean placedOnOpponentsPiles = false;
List<Placement> placementsOfMove = new ArrayList<>();
// as long as we still have hand cards
while (!currentGameState.getHandCards().isEmpty()) {
List<Placement> validPlacements = new ArrayList<>();
// compute all valid placements
for (Card card : currentGameState.getHandCards()) {
for (CardPosition position : CardPosition.values()) {
Placement placement = new Placement(card, position);
if (isPlacementValid(placement, currentGameState, !placedOnOpponentsPiles)) {
validPlacements.add(placement);
}
}
}
// if we cannot find a valid placement anymore, we can stop here and return the
// ones we have so far
if (validPlacements.isEmpty()) {
return new Move(placementsOfMove);
}
// pick a random placement out of the valid ones
Placement randomPlacement = validPlacements.get(random.nextInt(validPlacements.size()));
if (randomPlacement.getPosition() == CardPosition.OPPONENTS_ASCENDING_DISCARD_PILE
|| randomPlacement.getPosition() == CardPosition.OPPONENTS_DESCENDING_DISCARD_PILE) {
placedOnOpponentsPiles = true;
}
// add this random placement to the placements for our move
placementsOfMove.add(randomPlacement);
// update the view we have on the game to make sure that the next set of valid
// placements is indeed valid
currentGameState = computeNewGameStateAfterPlacement(currentGameState, randomPlacement);
}
return new Move(placementsOfMove);
}
private GameState computeNewGameStateAfterPlacement(GameState gameStatePriorToPlacement, Placement placement) {
List<Card> handCards = new ArrayList<>(gameStatePriorToPlacement.getHandCards());
handCards.remove(placement.getCard());
List<Card> cardsOnOwnAscendingDiscardPile = new ArrayList<>(
gameStatePriorToPlacement.getCardsOnOwnAscendingDiscardPile());
if (placement.getPosition() == CardPosition.OWN_ASCENDING_DISCARD_PILE) {
cardsOnOwnAscendingDiscardPile.add(placement.getCard());
}
List<Card> cardsOnOwnDescendingDiscardPile = new ArrayList<>(
gameStatePriorToPlacement.getCardsOnOwnDescendingDiscardPile());
if (placement.getPosition() == CardPosition.OWN_DESCENDING_DISCARD_PILE) {
cardsOnOwnDescendingDiscardPile.add(placement.getCard());
}
List<Card> cardsOnOpponentsAscendingDiscardPile = new ArrayList<>(
gameStatePriorToPlacement.getCardsOnOpponentsAscendingDiscardPile());
if (placement.getPosition() == CardPosition.OPPONENTS_ASCENDING_DISCARD_PILE) {
cardsOnOpponentsAscendingDiscardPile.add(placement.getCard());
}
List<Card> cardsOnOpponentsDescendingDiscardPile = new ArrayList<>(
gameStatePriorToPlacement.getCardsOnOpponentsDescendingDiscardPile());
if (placement.getPosition() == CardPosition.OPPONENTS_ASCENDING_DISCARD_PILE) {
cardsOnOpponentsDescendingDiscardPile.add(placement.getCard());
}
return new GameState(handCards, cardsOnOwnAscendingDiscardPile, cardsOnOwnDescendingDiscardPile,
cardsOnOpponentsAscendingDiscardPile, cardsOnOpponentsDescendingDiscardPile);
}
private boolean isPlacementValid(Placement placement, GameState gameState, boolean placingOnOpponentPilesAllowed) {
switch (placement.getPosition()) {
case OPPONENTS_ASCENDING_DISCARD_PILE:
return placingOnOpponentPilesAllowed
? canPlaceCardOnOpponentsAscendingDiscardPile(placement.getCard(), gameState)
: false;
case OPPONENTS_DESCENDING_DISCARD_PILE:
return placingOnOpponentPilesAllowed
? canPlaceCardOnOpponentsDescendingDiscardPile(placement.getCard(), gameState)
: false;
case OWN_ASCENDING_DISCARD_PILE:
return canPlaceCardOnOwnAscendingDiscardPile(placement.getCard(), gameState);
case OWN_DESCENDING_DISCARD_PILE:
return canPlaceCardOnOwnDescendingDiscardPile(placement.getCard(), gameState);
}
return false;
}
private boolean canPlaceCardOnOwnAscendingDiscardPile(Card card, GameState gameState) {
return gameState.getTopCardOnOwnAscendingDiscardPile().isSmallerThan(card)
|| gameState.getTopCardOnOwnAscendingDiscardPile().is10LargerThan(card);
}
private boolean canPlaceCardOnOwnDescendingDiscardPile(Card card, GameState gameState) {
return card.isSmallerThan(gameState.getTopCardOnOwnDescendingDiscardPile())
|| card.is10LargerThan(gameState.getTopCardOnOwnDescendingDiscardPile());
}
private boolean canPlaceCardOnOpponentsAscendingDiscardPile(Card card, GameState gameState) {
return card.isSmallerThan(gameState.getTopCardOnOpponentsAscendingDiscardPile());
}
private boolean canPlaceCardOnOpponentsDescendingDiscardPile(Card card, GameState gameState) {
return gameState.getTopCardOnOpponentsDescendingDiscardPile().isSmallerThan(card);
}
@Override
public String toString() {
return getName();
}
}
\ No newline at end of file
import de.upb.isml.thegamef2f.engine.board.Game;
import de.upb.isml.thegamef2f.engine.player.BasicPlayer;
import de.upb.isml.thegamef2f.engine.player.Player;
import de.upb.isml.thegamef2f.engine.player.RandomPlayer;
public class main {
public static void main(String[] args) {
Game game = new Game(new RandomPlayer(), new RandomPlayer(), 2147953);
Game game = new Game(new RandomPlayer(), new BasicPlayer(), 2147953);
Player winner = game.simulate();
game.getHistory().printHistory();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment