mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Added support for AI vs AI matches
This commit is contained in:
@@ -840,9 +840,11 @@ public class GameAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ai's cannot finish their game without human yet - so terminate a game if human has left.
|
// ai's cannot finish their game without human yet - so terminate a game if human has left.
|
||||||
|
/*
|
||||||
if (reason == null && !Iterables.any(game.getPlayers(), Predicates.and(Player.Predicates.NOT_LOST, Player.Predicates.isType(PlayerType.HUMAN)))) {
|
if (reason == null && !Iterables.any(game.getPlayers(), Predicates.and(Player.Predicates.NOT_LOST, Player.Predicates.isType(PlayerType.HUMAN)))) {
|
||||||
reason = GameEndReason.AllHumansLost;
|
reason = GameEndReason.AllHumansLost;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return reason;
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ public final class GameOutcome implements Iterable<Entry<LobbyPlayer, PlayerStat
|
|||||||
*/
|
*/
|
||||||
public boolean isWinner(final LobbyPlayer who) {
|
public boolean isWinner(final LobbyPlayer who) {
|
||||||
PlayerStatistics stats = playerRating.get(who);
|
PlayerStatistics stats = playerRating.get(who);
|
||||||
|
if ( stats == null )
|
||||||
|
return false;
|
||||||
return stats.getOutcome().hasWon();
|
return stats.getOutcome().hasWon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,8 +171,6 @@ public class MatchController {
|
|||||||
localHuman = p;
|
localHuman = p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (null == localHuman)
|
|
||||||
throw new IllegalStateException("Cannot start a game without a human yet!");
|
|
||||||
|
|
||||||
FControl.SINGLETON_INSTANCE.setPlayer(localHuman);
|
FControl.SINGLETON_INSTANCE.setPlayer(localHuman);
|
||||||
|
|
||||||
|
|||||||
@@ -465,6 +465,9 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean LOG_AI_ATTACKS = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Getter for the field <code>attackers</code>.
|
* Getter for the field <code>attackers</code>.
|
||||||
@@ -522,6 +525,7 @@ public class AiAttackController {
|
|||||||
return combat;
|
return combat;
|
||||||
}
|
}
|
||||||
if (bAssault) {
|
if (bAssault) {
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println("Assault");
|
System.out.println("Assault");
|
||||||
CardLists.sortByPowerDesc(attackersLeft);
|
CardLists.sortByPowerDesc(attackersLeft);
|
||||||
for (Card attacker : attackersLeft) {
|
for (Card attacker : attackersLeft) {
|
||||||
@@ -556,6 +560,7 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
if (exalted) {
|
if (exalted) {
|
||||||
CardLists.sortByPowerDesc(this.attackers);
|
CardLists.sortByPowerDesc(this.attackers);
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println("Exalted");
|
System.out.println("Exalted");
|
||||||
this.aiAggression = 6;
|
this.aiAggression = 6;
|
||||||
for (Card attacker : this.attackers) {
|
for (Card attacker : this.attackers) {
|
||||||
@@ -752,12 +757,15 @@ public class AiAttackController {
|
|||||||
} else {
|
} else {
|
||||||
this.aiAggression = 0;
|
this.aiAggression = 0;
|
||||||
} // stay at home to block
|
} // stay at home to block
|
||||||
|
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println(String.valueOf(this.aiAggression) + " = ai aggression");
|
System.out.println(String.valueOf(this.aiAggression) + " = ai aggression");
|
||||||
|
|
||||||
// ****************
|
// ****************
|
||||||
// Evaluation the end
|
// Evaluation the end
|
||||||
// ****************
|
// ****************
|
||||||
|
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println("Normal attack");
|
System.out.println("Normal attack");
|
||||||
|
|
||||||
attackersLeft = this.notNeededAsBlockers(ai, attackersLeft);
|
attackersLeft = this.notNeededAsBlockers(ai, attackersLeft);
|
||||||
@@ -859,6 +867,7 @@ public class AiAttackController {
|
|||||||
boolean canBeBlocked = false;
|
boolean canBeBlocked = false;
|
||||||
int numberOfPossibleBlockers = 0;
|
int numberOfPossibleBlockers = 0;
|
||||||
|
|
||||||
|
|
||||||
if (!this.isEffectiveAttacker(ai, attacker, combat)) {
|
if (!this.isEffectiveAttacker(ai, attacker, combat)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -921,8 +930,8 @@ public class AiAttackController {
|
|||||||
// if the creature cannot block and can kill all opponents they might as
|
// if the creature cannot block and can kill all opponents they might as
|
||||||
// well attack, they do nothing staying back
|
// well attack, they do nothing staying back
|
||||||
if (canKillAll && isWorthLessThanAllKillers && !CombatUtil.canBlock(attacker)) {
|
if (canKillAll && isWorthLessThanAllKillers && !CombatUtil.canBlock(attacker)) {
|
||||||
System.out.println(attacker.getName()
|
if ( LOG_AI_ATTACKS )
|
||||||
+ " = attacking because they can't block, expecting to kill or damage player");
|
System.out.println(attacker.getName() + " = attacking because they can't block, expecting to kill or damage player");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,15 +947,18 @@ public class AiAttackController {
|
|||||||
switch (this.aiAggression) {
|
switch (this.aiAggression) {
|
||||||
case 6: // Exalted: expecting to at least kill a creature of equal value or not be blocked
|
case 6: // Exalted: expecting to at least kill a creature of equal value or not be blocked
|
||||||
if ((canKillAll && isWorthLessThanAllKillers) || !canBeBlocked) {
|
if ((canKillAll && isWorthLessThanAllKillers) || !canBeBlocked) {
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println(attacker.getName() + " = attacking expecting to kill creature, or is unblockable");
|
System.out.println(attacker.getName() + " = attacking expecting to kill creature, or is unblockable");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // all out attacking
|
case 5: // all out attacking
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println(attacker.getName() + " = all out attacking");
|
System.out.println(attacker.getName() + " = all out attacking");
|
||||||
return true;
|
return true;
|
||||||
case 4: // expecting to at least trade with something
|
case 4: // expecting to at least trade with something
|
||||||
if (canKillAll || (canKillAllDangerous && !canBeKilledByOne) || !canBeBlocked) {
|
if (canKillAll || (canKillAllDangerous && !canBeKilledByOne) || !canBeBlocked) {
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println(attacker.getName() + " = attacking expecting to at least trade with something");
|
System.out.println(attacker.getName() + " = attacking expecting to at least trade with something");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -956,20 +968,22 @@ public class AiAttackController {
|
|||||||
if ((canKillAll && isWorthLessThanAllKillers)
|
if ((canKillAll && isWorthLessThanAllKillers)
|
||||||
|| ((canKillAllDangerous || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne)
|
|| ((canKillAllDangerous || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne)
|
||||||
|| !canBeBlocked) {
|
|| !canBeBlocked) {
|
||||||
System.out.println(attacker.getName()
|
if ( LOG_AI_ATTACKS )
|
||||||
+ " = attacking expecting to kill creature or cause damage, or is unblockable");
|
System.out.println(attacker.getName() + " = attacking expecting to kill creature or cause damage, or is unblockable");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // attack expecting to attract a group block or destroying a
|
case 2: // attack expecting to attract a group block or destroying a
|
||||||
// single blocker and surviving
|
// single blocker and surviving
|
||||||
if (((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne) || !canBeBlocked) {
|
if (((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne) || !canBeBlocked) {
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println(attacker.getName() + " = attacking expecting to survive or attract group block");
|
System.out.println(attacker.getName() + " = attacking expecting to survive or attract group block");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1: // unblockable creatures only
|
case 1: // unblockable creatures only
|
||||||
if (!canBeBlocked || (numberOfPossibleBlockers == 1 && canKillAll && !canBeKilledByOne)) {
|
if (!canBeBlocked || (numberOfPossibleBlockers == 1 && canKillAll && !canBeKilledByOne)) {
|
||||||
|
if ( LOG_AI_ATTACKS )
|
||||||
System.out.println(attacker.getName() + " = attacking expecting not to be blocked");
|
System.out.println(attacker.getName() + " = attacking expecting not to be blocked");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import forge.game.GameType;
|
|||||||
import forge.game.MatchController;
|
import forge.game.MatchController;
|
||||||
import forge.game.MatchStartHelper;
|
import forge.game.MatchStartHelper;
|
||||||
import forge.game.PlayerStartConditions;
|
import forge.game.PlayerStartConditions;
|
||||||
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.gui.SOverlayUtils;
|
import forge.gui.SOverlayUtils;
|
||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
@@ -96,14 +97,14 @@ public enum CSubmenuConstructed implements ICDoc {
|
|||||||
* @param gameType
|
* @param gameType
|
||||||
*/
|
*/
|
||||||
private void startGame(final GameType gameType) {
|
private void startGame(final GameType gameType) {
|
||||||
PlayerStartConditions humanPsc = VSubmenuConstructed.SINGLETON_INSTANCE.getDcHuman().getDeck();
|
PlayerStartConditions humanPsc = view.getDcHuman().getDeck();
|
||||||
String humanDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(humanPsc.getOriginalDeck());
|
String humanDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(humanPsc.getOriginalDeck());
|
||||||
if (null != humanDeckErrorMessage) {
|
if (null != humanDeckErrorMessage) {
|
||||||
JOptionPane.showMessageDialog(null, "Your deck " + humanDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null, "Your deck " + humanDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerStartConditions aiDeck = VSubmenuConstructed.SINGLETON_INSTANCE.getDcAi().getDeck();
|
PlayerStartConditions aiDeck = view.getDcAi().getDeck();
|
||||||
String aiDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(aiDeck.getOriginalDeck());
|
String aiDeckErrorMessage = gameType.getDecksFormat().getDeckConformanceProblem(aiDeck.getOriginalDeck());
|
||||||
if (null != aiDeckErrorMessage) {
|
if (null != aiDeckErrorMessage) {
|
||||||
JOptionPane.showMessageDialog(null, "AI deck " + aiDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null, "AI deck " + aiDeckErrorMessage, "Invalid deck", JOptionPane.ERROR_MESSAGE);
|
||||||
@@ -115,7 +116,8 @@ public enum CSubmenuConstructed implements ICDoc {
|
|||||||
|
|
||||||
final MatchStartHelper starter = new MatchStartHelper();
|
final MatchStartHelper starter = new MatchStartHelper();
|
||||||
Lobby lobby = Singletons.getControl().getLobby();
|
Lobby lobby = Singletons.getControl().getLobby();
|
||||||
starter.addPlayer(lobby.getGuiPlayer(), humanPsc);
|
LobbyPlayer firstPlayer = view.getCbSpectate().isSelected() ? lobby.getAiPlayer() : lobby.getGuiPlayer();
|
||||||
|
starter.addPlayer(firstPlayer, humanPsc);
|
||||||
starter.addPlayer(lobby.getAiPlayer(), aiDeck);
|
starter.addPlayer(lobby.getAiPlayer(), aiDeck);
|
||||||
final MatchController mc = new MatchController(gameType, starter.getPlayerMap());
|
final MatchController mc = new MatchController(gameType, starter.getPlayerMap());
|
||||||
|
|
||||||
|
|||||||
@@ -35,13 +35,14 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
|||||||
/** */
|
/** */
|
||||||
private final LblHeader lblTitle = new LblHeader("Sanctioned Format: Constructed");
|
private final LblHeader lblTitle = new LblHeader("Sanctioned Format: Constructed");
|
||||||
|
|
||||||
private final JPanel pnlStart = new JPanel(new MigLayout("insets 0, gap 0, wrap 2"));
|
private final JPanel pnlStart = new JPanel(new MigLayout("insets 0, gap 0, wrap 3"));
|
||||||
|
|
||||||
private final StartButton btnStart = new StartButton();
|
private final StartButton btnStart = new StartButton();
|
||||||
|
|
||||||
private final JCheckBox cbSingletons = new FCheckBox("Singleton Mode");
|
private final JCheckBox cbSingletons = new FCheckBox("Singleton Mode");
|
||||||
private final JCheckBox cbArtifacts = new FCheckBox("Remove Artifacts");
|
private final JCheckBox cbArtifacts = new FCheckBox("Remove Artifacts");
|
||||||
private final JCheckBox cbRemoveSmall = new FCheckBox("Remove Small Creatures");
|
private final JCheckBox cbRemoveSmall = new FCheckBox("Remove Small Creatures");
|
||||||
|
private final JCheckBox cbAiVsAi = new FCheckBox("Spectate AI vs AI match");
|
||||||
|
|
||||||
private final FDeckChooser dcHuman = new FDeckChooser("Select your deck:", PlayerType.HUMAN);
|
private final FDeckChooser dcHuman = new FDeckChooser("Select your deck:", PlayerType.HUMAN);
|
||||||
private final FDeckChooser dcAi = new FDeckChooser("Select AI deck:", PlayerType.COMPUTER);
|
private final FDeckChooser dcAi = new FDeckChooser("Select AI deck:", PlayerType.COMPUTER);
|
||||||
@@ -51,12 +52,15 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
|||||||
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
|
lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
|
||||||
|
|
||||||
|
|
||||||
final String strCheckboxConstraints = "h 30px!, gap 0 20px 0 0";
|
final String strCheckboxConstraints = "pushy, gap 0 20px 0 0";
|
||||||
|
final String strCheckboxConstraintsTop = "pushy, gap 0 20px 20px 0";
|
||||||
pnlStart.setOpaque(false);
|
pnlStart.setOpaque(false);
|
||||||
pnlStart.add(cbSingletons, strCheckboxConstraints);
|
pnlStart.add(cbSingletons, strCheckboxConstraintsTop);
|
||||||
pnlStart.add(btnStart, "span 1 3, growx, pushx, align center");
|
pnlStart.add(cbAiVsAi, strCheckboxConstraintsTop);
|
||||||
|
pnlStart.add(btnStart, "span 1 2, growx, pushx, align center");
|
||||||
pnlStart.add(cbArtifacts, strCheckboxConstraints);
|
pnlStart.add(cbArtifacts, strCheckboxConstraints);
|
||||||
pnlStart.add(cbRemoveSmall, strCheckboxConstraints);
|
pnlStart.add(cbRemoveSmall, strCheckboxConstraints);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -106,7 +110,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
|||||||
dcHuman.populate();
|
dcHuman.populate();
|
||||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(dcAi, "w 44%!, gap 0 0 20px 20px, growy, pushy");
|
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(dcAi, "w 44%!, gap 0 0 20px 20px, growy, pushy");
|
||||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(dcHuman, "w 44%!, gap 4% 4% 20px 20px, growy, pushy");
|
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(dcHuman, "w 44%!, gap 4% 4% 20px 20px, growy, pushy");
|
||||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlStart, "span 2, gap 0 0 3.5%! 3.5%!, ax center");
|
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().add(pnlStart, "span 2, gap 0 0 2.5%! 3.5%!, ax center");
|
||||||
|
|
||||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate();
|
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().revalidate();
|
||||||
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf();
|
VHomeUI.SINGLETON_INSTANCE.getPnlDisplay().repaintSelf();
|
||||||
@@ -134,6 +138,11 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
|||||||
return cbRemoveSmall;
|
return cbRemoveSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return {@link javax.swing.JCheckBox} */
|
||||||
|
public JCheckBox getCbSpectate() {
|
||||||
|
return cbAiVsAi;
|
||||||
|
}
|
||||||
|
|
||||||
//========== Overridden from IVDoc
|
//========== Overridden from IVDoc
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -18,11 +18,15 @@
|
|||||||
package forge.gui.match;
|
package forge.gui.match;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
@@ -87,28 +91,34 @@ public enum CMatchUI {
|
|||||||
final List<VField> fields = new ArrayList<VField>();
|
final List<VField> fields = new ArrayList<VField>();
|
||||||
final List<VCommand> commands = new ArrayList<VCommand>();
|
final List<VCommand> commands = new ArrayList<VCommand>();
|
||||||
|
|
||||||
VField humanField = new VField(EDocID.valueOf("FIELD_0"), localPlayer, localPlayer);
|
List<Player> sortedPlayers = Lists.newArrayList(players);
|
||||||
VCommand humanCommand = new VCommand(EDocID.COMMAND_0, localPlayer);
|
|
||||||
fields.add(0, humanField);
|
|
||||||
commands.add(0, humanCommand);
|
|
||||||
setAvatar(humanField, new ImageIcon(FSkin.getAvatars().get(Integer.parseInt(indices[0]))));
|
|
||||||
humanField.getLayoutControl().initialize();
|
|
||||||
humanCommand.getLayoutControl().initialize();
|
|
||||||
|
|
||||||
int i = 1;
|
int ixLocal = -1;
|
||||||
for (Player p : players) {
|
for(int i = 0; i < players.size(); i++) {
|
||||||
if (p.equals(localPlayer)) {
|
if( sortedPlayers.get(i) == localPlayer ) {
|
||||||
continue;
|
ixLocal = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if( ixLocal > 0 ) {
|
||||||
|
Player p0 = sortedPlayers.remove(ixLocal);
|
||||||
|
sortedPlayers.add(0, p0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (Player p : sortedPlayers) {
|
||||||
// A field must be initialized after it's instantiated, to update player info.
|
// A field must be initialized after it's instantiated, to update player info.
|
||||||
// No player, no init.
|
// No player, no init.
|
||||||
VField f = new VField(EDocID.valueOf("FIELD_" + i), p, localPlayer);
|
VField f = new VField(EDocID.valueOf("FIELD_" + i), p, localPlayer);
|
||||||
setAvatar(f, getPlayerAvatar(p, Integer.parseInt(indices[1])));
|
|
||||||
f.getLayoutControl().initialize();
|
|
||||||
fields.add(f);
|
|
||||||
VCommand c = new VCommand(EDocID.valueOf("COMMAND_" + i), p);
|
VCommand c = new VCommand(EDocID.valueOf("COMMAND_" + i), p);
|
||||||
c.getLayoutControl().initialize();
|
fields.add(f);
|
||||||
commands.add(c);
|
commands.add(c);
|
||||||
|
|
||||||
|
//setAvatar(f, new ImageIcon(FSkin.getAvatars().get()));
|
||||||
|
setAvatar(f, getPlayerAvatar(p, Integer.parseInt(indices[i > 2 ? 1 : 0])));
|
||||||
|
f.getLayoutControl().initialize();
|
||||||
|
c.getLayoutControl().initialize();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ public class CHand implements ICDoc {
|
|||||||
if (initializedAlready) { return; }
|
if (initializedAlready) { return; }
|
||||||
initializedAlready = true;
|
initializedAlready = true;
|
||||||
|
|
||||||
|
if ( player != null)
|
||||||
player.getZone(ZoneType.Hand).addObserver(o1);
|
player.getZone(ZoneType.Hand).addObserver(o1);
|
||||||
|
|
||||||
view.getHandArea().addMouseListener(madCardClick);
|
view.getHandArea().addMouseListener(madCardClick);
|
||||||
|
|||||||
@@ -58,8 +58,7 @@ public class VHand implements IVDoc<CHand> {
|
|||||||
|
|
||||||
if (player0 == null) {
|
if (player0 == null) {
|
||||||
tab.setText("NO PLAYER Hand");
|
tab.setText("NO PLAYER Hand");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
tab.setText(player0.getName() + " Hand");
|
tab.setText(player0.getName() + " Hand");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user