Commit 9700c026 authored by sphexoo's avatar sphexoo

Added RealPlayer class which can be controlled by a real player via console input.

parent 3931667b
......@@ -91,38 +91,38 @@
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="468" height="466" key="DebuggerActiveHint/0.0.1920.1040@0.0.1920.1040" timestamp="1589460391739" />
<state width="1877" height="385" key="GridCell.Tab.0.bottom" timestamp="1589461662507">
<state width="1373" height="394" key="GridCell.Tab.0.bottom" timestamp="1589467439116">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="385" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1589461662507" />
<state width="1877" height="385" key="GridCell.Tab.0.center" timestamp="1589461662507">
<state width="1373" height="394" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1589467439116" />
<state width="1373" height="394" key="GridCell.Tab.0.center" timestamp="1589467439115">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="385" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1589461662507" />
<state width="1877" height="385" key="GridCell.Tab.0.left" timestamp="1589461662506">
<state width="1373" height="394" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1589467439115" />
<state width="1373" height="394" key="GridCell.Tab.0.left" timestamp="1589467439115">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="385" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1589461662506" />
<state width="1877" height="385" key="GridCell.Tab.0.right" timestamp="1589461662507">
<state width="1373" height="394" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1589467439115" />
<state width="1373" height="394" key="GridCell.Tab.0.right" timestamp="1589467439116">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="385" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1589461662507" />
<state width="1877" height="352" key="GridCell.Tab.1.bottom" timestamp="1589460582021">
<state width="1373" height="394" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1589467439116" />
<state width="914" height="351" key="GridCell.Tab.1.bottom" timestamp="1589467439112">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="352" key="GridCell.Tab.1.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1589460582021" />
<state width="1877" height="352" key="GridCell.Tab.1.center" timestamp="1589460582021">
<state width="914" height="351" key="GridCell.Tab.1.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1589467439112" />
<state width="914" height="351" key="GridCell.Tab.1.center" timestamp="1589467439112">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="352" key="GridCell.Tab.1.center/0.0.1920.1040@0.0.1920.1040" timestamp="1589460582021" />
<state width="1877" height="352" key="GridCell.Tab.1.left" timestamp="1589460582021">
<state width="914" height="351" key="GridCell.Tab.1.center/0.0.1920.1040@0.0.1920.1040" timestamp="1589467439112" />
<state width="914" height="351" key="GridCell.Tab.1.left" timestamp="1589467439112">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="352" key="GridCell.Tab.1.left/0.0.1920.1040@0.0.1920.1040" timestamp="1589460582021" />
<state width="1877" height="352" key="GridCell.Tab.1.right" timestamp="1589460582021">
<state width="914" height="351" key="GridCell.Tab.1.left/0.0.1920.1040@0.0.1920.1040" timestamp="1589467439112" />
<state width="914" height="351" key="GridCell.Tab.1.right" timestamp="1589467439112">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="352" key="GridCell.Tab.1.right/0.0.1920.1040@0.0.1920.1040" timestamp="1589460582021" />
<state width="914" height="351" key="GridCell.Tab.1.right/0.0.1920.1040@0.0.1920.1040" timestamp="1589467439112" />
<state x="623" y="225" width="672" height="678" key="search.everywhere.popup" timestamp="1589461615549">
<screen x="0" y="0" width="1920" height="1040" />
</state>
......
import de.upb.isml.thegamef2f.engine.GameHistory;
import de.upb.isml.thegamef2f.engine.board.Game;
import de.upb.isml.thegamef2f.engine.player.Player;
import players.BasicPlayer;
import players.BasicPlayerV0;
import players.OptimizeTurnPlayer;
import players.RandomPlayer;
import players.*;
import util.Extensions.Statistics;
import java.util.Random;
......@@ -15,7 +12,7 @@ public class MainClass {
// USER INPUT
var numGames = 100000;
Player p1 = new BasicPlayer();
Player p2 = new BasicPlayerV0();
Player p2 = new RealPlayer();
Statistics stats = new Statistics(p1, p2);
Random rand = new Random();
......
package players;
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;
import de.upb.isml.thegamef2f.engine.player.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
/**
* Real Player Interface
* based on RandomPlayer from Alexander Tornede
* @author fjsauer
*
* Functionality:
* gives real player the ability to choose move from random moves.
*/
public class RealPlayer implements Player {
private Random random;
Scanner sc = new Scanner(System.in);
@Override
public void initialize(long randomSeed) {
this.random = new Random(randomSeed);
}
private Placement ChoosePlacement(GameState currentGameState, List<Placement> validPlacements)
{
while (true)
{
System.out.println("________ Enemy: ________");
System.out.println("ASC [ID:0]: "+ currentGameState.getTopCardOnOpponentsAscendingDiscardPile().getNumber() + " (Number of cards: "+ currentGameState.getCardsOnOpponentsAscendingDiscardPile().size()+")");
System.out.println("DES [ID:1]: "+ currentGameState.getTopCardOnOpponentsDescendingDiscardPile().getNumber() + " (Number of cards: "+ currentGameState.getCardsOnOpponentsDescendingDiscardPile().size()+")");
System.out.println("________ You: ________");
System.out.println("DES [ID:2]: "+ currentGameState.getTopCardOnOwnDescendingDiscardPile().getNumber() + " (Number of cards: "+ currentGameState.getCardsOnOwnDescendingDiscardPile().size()+")");
System.out.println("ASC [ID:3]: "+ currentGameState.getTopCardOnOwnAscendingDiscardPile().getNumber() + " (Number of cards: "+ currentGameState.getCardsOnOwnAscendingDiscardPile().size()+")");
System.out.println("Hand cards: " + currentGameState.getHandCards());
System.out.println("______________________\nChoose placement:\n Card:");
int cardNumber = sc.nextInt();
if (cardNumber == 0)
{
return null;
}
System.out.println("Discard pile ID: ");
int pileID = sc.nextInt();
CardPosition chosenCardPosition = null;
if (pileID == 0)
{
chosenCardPosition = CardPosition.OPPONENTS_ASCENDING_DISCARD_PILE;
}
else if (pileID == 1)
{
chosenCardPosition = CardPosition.OPPONENTS_DESCENDING_DISCARD_PILE;
}
else if (pileID == 2)
{
chosenCardPosition = CardPosition.OWN_DESCENDING_DISCARD_PILE;
}
else if (pileID == 3)
{
chosenCardPosition = CardPosition.OWN_ASCENDING_DISCARD_PILE;
}
else
{
System.out.println("Invalid CardPosition ID specified. Valid options are 0, 1, 2, 3.");
}
for (Placement placement : validPlacements)
{
if (placement.getCard().getNumber() == cardNumber && placement.getPosition() == chosenCardPosition)
{
return placement;
}
}
System.out.println("No valid placement matches specified card number and Pile ID. Try again.");
}
}
@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 chosenPlacement = ChoosePlacement(currentGameState, validPlacements);
// break from while loop if no further placement is chosen
if (chosenPlacement == null)
{
break;
}
if (chosenPlacement.getPosition() == CardPosition.OPPONENTS_ASCENDING_DISCARD_PILE
|| chosenPlacement.getPosition() == CardPosition.OPPONENTS_DESCENDING_DISCARD_PILE) {
placedOnOpponentsPiles = true;
}
// add this random placement to the placements for our move
placementsOfMove.add(chosenPlacement);
// update the view we have on the game to make sure that the next set of valid
// placements is indeed valid
currentGameState = computeNewGameStateAfterPlacement(currentGameState, chosenPlacement);
}
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
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