Commit 4a9b5f30 authored by Fabian Jakob Sauer's avatar Fabian Jakob Sauer

Added calculation of win percentage for every move.

parent 9c262019
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
......@@ -27,6 +27,11 @@
<property name="project.structure.proportion" value="0.0" />
<property name="project.structure.side.proportion" value="0.0" />
</component>
<component name="RecentsManager">
<key name="CreateClassDialog.RecentsKey">
<recent name="" />
</key>
</component>
<component name="RunManager" selected="Application.MainClass">
<configuration name="MainClass" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="MainClass" />
......@@ -77,41 +82,41 @@
<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="468" height="466" key="DebuggerActiveHint" timestamp="1588857735419">
<state width="468" height="466" key="DebuggerActiveHint" timestamp="1588936167247">
<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="1588857735419" />
<state width="1877" height="344" key="GridCell.Tab.0.bottom" timestamp="1588860569824">
<state width="468" height="466" key="DebuggerActiveHint/0.0.1920.1040@0.0.1920.1040" timestamp="1588936167247" />
<state width="1877" height="310" key="GridCell.Tab.0.bottom" timestamp="1588936544380">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="344" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1588860569824" />
<state width="1877" height="344" key="GridCell.Tab.0.center" timestamp="1588860569823">
<state width="1877" height="310" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1588936544380" />
<state width="1877" height="310" key="GridCell.Tab.0.center" timestamp="1588936544380">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="344" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1588860569823" />
<state width="1877" height="344" key="GridCell.Tab.0.left" timestamp="1588860569823">
<state width="1877" height="310" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1588936544380" />
<state width="1877" height="310" key="GridCell.Tab.0.left" timestamp="1588936544380">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="344" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1588860569823" />
<state width="1877" height="344" key="GridCell.Tab.0.right" timestamp="1588860569823">
<state width="1877" height="310" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1588936544380" />
<state width="1877" height="310" key="GridCell.Tab.0.right" timestamp="1588936544380">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="344" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1588860569823" />
<state width="1877" height="344" key="GridCell.Tab.1.bottom" timestamp="1588860569824">
<state width="1877" height="310" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1588936544380" />
<state width="1073" height="173" key="GridCell.Tab.1.bottom" timestamp="1588936180713">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="344" key="GridCell.Tab.1.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1588860569824" />
<state width="1877" height="344" key="GridCell.Tab.1.center" timestamp="1588860569824">
<state width="1073" height="173" key="GridCell.Tab.1.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1588936180713" />
<state width="1073" height="173" key="GridCell.Tab.1.center" timestamp="1588936180713">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="344" key="GridCell.Tab.1.center/0.0.1920.1040@0.0.1920.1040" timestamp="1588860569824" />
<state width="1877" height="344" key="GridCell.Tab.1.left" timestamp="1588860569824">
<state width="1073" height="173" key="GridCell.Tab.1.center/0.0.1920.1040@0.0.1920.1040" timestamp="1588936180713" />
<state width="1073" height="173" key="GridCell.Tab.1.left" timestamp="1588936180713">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="344" key="GridCell.Tab.1.left/0.0.1920.1040@0.0.1920.1040" timestamp="1588860569824" />
<state width="1877" height="344" key="GridCell.Tab.1.right" timestamp="1588860569824">
<state width="1073" height="173" key="GridCell.Tab.1.left/0.0.1920.1040@0.0.1920.1040" timestamp="1588936180713" />
<state width="1073" height="173" key="GridCell.Tab.1.right" timestamp="1588936180713">
<screen x="0" y="0" width="1920" height="1040" />
</state>
<state width="1877" height="344" key="GridCell.Tab.1.right/0.0.1920.1040@0.0.1920.1040" timestamp="1588860569824" />
<state width="1073" height="173" key="GridCell.Tab.1.right/0.0.1920.1040@0.0.1920.1040" timestamp="1588936180713" />
</component>
</project>
\ No newline at end of file
......@@ -7,27 +7,118 @@ 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 util.StackValue.ExtendedPlacement;
import util.StackValue.StackValue;
/**
* Basic Player AI
* based on RandomPlayer from Alexander Tornede
* @author fjsauer
*/
public class BasicPlayer implements Player {
private Random random;
private StackValue stackValue = new StackValue();
private double winPercentage = 0.5;
private GameState latestGameState;
@Override
public void initialize(long randomSeed) {
this.random = new Random(randomSeed);
}
private List<ExtendedPlacement> ComputePlacements(List<Card> pile, Card lastKnownCard, CardPosition pos)
{
/* Generates a list of ExtendedPlacements
(containing information about last card on given pile)
given a card pile and the last known card */
List<ExtendedPlacement> placements = new ArrayList<ExtendedPlacement>();
boolean isNewCard = false;
for (Card card : pile)
{
if(isNewCard)
{
placements.add(new ExtendedPlacement(card, pos, lastKnownCard));
lastKnownCard = card;
}
if (!isNewCard && card == lastKnownCard) // find start of new cards on given pile
{
isNewCard = true;
}
}
return placements;
}
private List<ExtendedPlacement> ReconstructPlacements(GameState newGameState)
{
/* Checks if any piles top card has changed compared to last saved gamestate.
If yes new moves are generated and added to list.
This list is returned.
*/
List<ExtendedPlacement> reconstructedPlacements = new ArrayList<ExtendedPlacement>();
if (newGameState.getTopCardOnOwnDescendingDiscardPile() != latestGameState.getTopCardOnOwnDescendingDiscardPile())
{
List<Card> pile = newGameState.getCardsOnOwnDescendingDiscardPile();
Card lastKnownCard = latestGameState.getTopCardOnOwnDescendingDiscardPile();
reconstructedPlacements.addAll(ComputePlacements(pile, lastKnownCard, CardPosition.OWN_DESCENDING_DISCARD_PILE));
}
if (newGameState.getTopCardOnOwnAscendingDiscardPile() != latestGameState.getTopCardOnOwnAscendingDiscardPile())
{
List<Card> pile = newGameState.getCardsOnOwnAscendingDiscardPile();
Card lastKnownCard = latestGameState.getTopCardOnOwnAscendingDiscardPile();
reconstructedPlacements.addAll(ComputePlacements(pile, lastKnownCard, CardPosition.OWN_ASCENDING_DISCARD_PILE));
}
if (newGameState.getTopCardOnOpponentsDescendingDiscardPile() != latestGameState.getTopCardOnOpponentsDescendingDiscardPile())
{
List<Card> pile = newGameState.getCardsOnOpponentsDescendingDiscardPile();
Card lastKnownCard = latestGameState.getTopCardOnOpponentsDescendingDiscardPile();
reconstructedPlacements.addAll(ComputePlacements(pile, lastKnownCard, CardPosition.OPPONENTS_DESCENDING_DISCARD_PILE));
}
if (newGameState.getTopCardOnOpponentsAscendingDiscardPile() != latestGameState.getTopCardOnOpponentsAscendingDiscardPile())
{
List<Card> pile = newGameState.getCardsOnOpponentsAscendingDiscardPile();
Card lastKnownCard = latestGameState.getTopCardOnOpponentsAscendingDiscardPile();
reconstructedPlacements.addAll(ComputePlacements(pile, lastKnownCard, CardPosition.OPPONENTS_ASCENDING_DISCARD_PILE));
}
return reconstructedPlacements;
}
private double EvaluateState(List<ExtendedPlacement> reconstructedPlacements)
{
for (ExtendedPlacement placement : reconstructedPlacements)
{
if (placement.getPosition() == CardPosition.OWN_ASCENDING_DISCARD_PILE)
{
stackValue.OWN_ASCENDING_DISCARD_PILE += placement.getCard().getNumber() - placement.GetPrevTopCard().getNumber() - 1;
}
else if (placement.getPosition() == CardPosition.OPPONENTS_ASCENDING_DISCARD_PILE)
{
stackValue.OPPONENTS_ASCENDING_DISCARD_PILE += placement.getCard().getNumber() - placement.GetPrevTopCard().getNumber() - 1;;
}
else if (placement.getPosition() == CardPosition.OWN_DESCENDING_DISCARD_PILE)
{
stackValue.OWN_DESCENDING_DISCARD_PILE += placement.GetPrevTopCard().getNumber() - placement.getCard().getNumber() + 1;
}
else if (placement.getPosition() == CardPosition.OPPONENTS_DESCENDING_DISCARD_PILE)
{
stackValue.OPPONENTS_DESCENDING_DISCARD_PILE += placement.GetPrevTopCard().getNumber() - placement.getCard().getNumber() + 1;
}
}
return 0.5 +
((stackValue.OPPONENTS_ASCENDING_DISCARD_PILE - stackValue.OWN_ASCENDING_DISCARD_PILE) / 60.0 * 0.25) +
((stackValue.OPPONENTS_DESCENDING_DISCARD_PILE - stackValue.OWN_DESCENDING_DISCARD_PILE) / 60.0 * 0.25);
}
private Placement IsBackwardsTrick(GameState currentGameState, List<Placement> validPlacements)
{
for (Placement placement : validPlacements)
{
if( currentGameState.getTopCardOnOwnAscendingDiscardPile().getNumber() == placement.getCard().getNumber() + 10 ||
currentGameState.getTopCardOnOwnDescendingDiscardPile().getNumber() == placement.getCard().getNumber() - 10 )
if( (currentGameState.getTopCardOnOwnAscendingDiscardPile().getNumber() == placement.getCard().getNumber() + 10 && placement.getPosition() == CardPosition.OWN_ASCENDING_DISCARD_PILE) ||
(currentGameState.getTopCardOnOwnDescendingDiscardPile().getNumber() == placement.getCard().getNumber() - 10 && placement.getPosition() == CardPosition.OWN_DESCENDING_DISCARD_PILE) )
{
return placement;
}
......@@ -36,21 +127,30 @@ public class BasicPlayer implements Player {
}
@Override
public Move computeMove(GameState gameState) {
GameState currentGameState = gameState;
public Move computeMove(GameState newGameState) {
if (latestGameState == null)
{
latestGameState = newGameState;
}
List<ExtendedPlacement> reconstructedPlacements = ReconstructPlacements(newGameState);
winPercentage = EvaluateState(reconstructedPlacements);
// System.out.println("Win Percentage: " + winPercentage);
latestGameState = newGameState;
boolean placedOnOpponentsPiles = false;
List<Placement> placementsOfMove = new ArrayList<>();
// as long as we still have hand cards
while (!currentGameState.getHandCards().isEmpty()) {
while (!latestGameState.getHandCards().isEmpty()) {
List<Placement> validPlacements = new ArrayList<>();
// compute all valid placements
for (Card card : currentGameState.getHandCards()) {
for (Card card : latestGameState.getHandCards()) {
for (CardPosition position : CardPosition.values()) {
Placement placement = new Placement(card, position);
if (isPlacementValid(placement, currentGameState, !placedOnOpponentsPiles)) {
if (isPlacementValid(placement, latestGameState, !placedOnOpponentsPiles)) {
validPlacements.add(placement);
}
}
......@@ -64,7 +164,7 @@ public class BasicPlayer implements Player {
//Pick next placement
Placement nextPlacement = null;
nextPlacement = IsBackwardsTrick(currentGameState, validPlacements); // perform backwards trick if available
nextPlacement = IsBackwardsTrick(latestGameState, validPlacements); // perform backwards trick if available
if (nextPlacement == null)
{
nextPlacement = validPlacements.get(random.nextInt(validPlacements.size())); // pick random move if no special rule applied
......@@ -80,9 +180,8 @@ public class BasicPlayer implements Player {
// update the view we have on the game to make sure that the next set of valid
// placements is indeed valid
currentGameState = computeNewGameStateAfterPlacement(currentGameState, nextPlacement);
latestGameState = computeNewGameStateAfterPlacement(latestGameState, nextPlacement);
}
return new Move(placementsOfMove);
}
......
package util.StackValue;
import de.upb.isml.thegamef2f.engine.CardPosition;
import de.upb.isml.thegamef2f.engine.Placement;
import de.upb.isml.thegamef2f.engine.board.Card;
public class ExtendedPlacement extends Placement {
private Card prevTopCard;
public ExtendedPlacement(Card card, CardPosition position, Card prevTopCard) {
super(card, position);
this.prevTopCard = prevTopCard;
}
public Card GetPrevTopCard()
{
return prevTopCard;
}
}
package util.StackValue;
public class StackValue {
public int OWN_ASCENDING_DISCARD_PILE = 0;
public int OWN_DESCENDING_DISCARD_PILE = 0;
public int OPPONENTS_ASCENDING_DISCARD_PILE = 0;
public int OPPONENTS_DESCENDING_DISCARD_PILE = 0;
public int GetOwnAscendingDiscardPile()
{
return OWN_ASCENDING_DISCARD_PILE;
}
public int GetOwnDescendingDiscardPile()
{
return OWN_DESCENDING_DISCARD_PILE;
}
public int GetOpponentsAscendingDiscardPile()
{
return OPPONENTS_ASCENDING_DISCARD_PILE;
}
public int GetOpponentsDescendingDiscardPile()
{
return OPPONENTS_DESCENDING_DISCARD_PILE;
}
}
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