diff --git a/src/java/soc/common/actions/gameAction/GameAction.java b/src/java/soc/common/actions/gameAction/GameAction.java new file mode 100644 index 000000000..fcd4c1f8c --- /dev/null +++ b/src/java/soc/common/actions/gameAction/GameAction.java @@ -0,0 +1,134 @@ +package soc.common.actions.gameAction; + +import java.util.Date; + +import soc.common.game.Game; +import soc.common.game.IGame; +import soc.common.game.Player; +import soc.common.game.User; +import soc.common.game.gamePhase.GamePhase; +import soc.common.game.gamePhase.turnPhase.TurnPhase; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +/* + * A GameAction performed in a game + */ +public class GameAction +{ + private Player player; + private int sender; + protected String invalidMessage; + protected String toDoMessage; + protected String message; + + /* + * Should be omitted at hashCode calculation, since values differ at server + * and at client + */ + protected Date dateTimeExecuted; + + /** + * @return the toDoMessage + */ + public String getToDoMessage() + { + return toDoMessage; + } + + /** + * @return the dateTimeExecuted + */ + public Date getDateTimeExecuted() + { + return dateTimeExecuted; + } + + /** + * @return the sender + */ + public int getSender() + { + return sender; + } + + /** + * @param sender the sender to set + */ + public GameAction setSender(int sender) + { + this.sender = sender; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + + /** + * @return the invalidMessage + */ + public String getInvalidMessage() + { + return invalidMessage; + } + + + /** + * @return the message + */ + public String getMessage() + { + return message; + } + + /** + * @return the player + */ + public Player getPlayer() + { + if (sender == 0 && player == null) + { + User p = new Player() + .setId(0) + .setName("Server"); + + player = (Player)p; + } + return player; + } + + + /** + * @param player the player to set + */ + public GameAction setPlayer(Player player) + { + this.player = player; + this.sender = player.getId(); + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + + public void perform(Game game) + { + dateTimeExecuted = new Date(); + } + + /* + * Returns true if player is allowed to play this action in given TurnPhase + */ + public boolean isAllowed(TurnPhase turnPhase) + { + throw new NotImplementedException(); + } + + /* + * Returns true if player is allowed to play this action in given GamePhase + */ + public boolean isAllowed(GamePhase gamePhase) + { + throw new NotImplementedException(); + } + +} diff --git a/src/java/soc/common/actions/gameAction/GamePhaseHasEnded.java b/src/java/soc/common/actions/gameAction/GamePhaseHasEnded.java new file mode 100644 index 000000000..dd3c8c4e7 --- /dev/null +++ b/src/java/soc/common/actions/gameAction/GamePhaseHasEnded.java @@ -0,0 +1,31 @@ +package soc.common.actions.gameAction; + +import soc.common.game.gamePhase.GamePhase; + +/* + * Announces a gamephase which has been ended + */ +public class GamePhaseHasEnded extends GameAction +{ + private GamePhase endedGamePhase; + + /** + * @return the endedGamePhase + */ + public GamePhase getEndedGamePhase() + { + return endedGamePhase; + } + + /** + * @param endedGamePhase the endedGamePhase to set + */ + public GamePhaseHasEnded setEndedGamePhase(GamePhase endedGamePhase) + { + this.endedGamePhase = endedGamePhase; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } +} diff --git a/src/java/soc/common/actions/gameAction/InGameChatAction.java b/src/java/soc/common/actions/gameAction/InGameChatAction.java new file mode 100644 index 000000000..c8ccbcd8b --- /dev/null +++ b/src/java/soc/common/actions/gameAction/InGameChatAction.java @@ -0,0 +1,6 @@ +package soc.common.actions.gameAction; + +public class InGameChatAction extends GameAction +{ + +} diff --git a/src/java/soc/common/actions/gameAction/PlacePort.java b/src/java/soc/common/actions/gameAction/PlacePort.java new file mode 100644 index 000000000..ca4b4c909 --- /dev/null +++ b/src/java/soc/common/actions/gameAction/PlacePort.java @@ -0,0 +1,26 @@ +package soc.common.actions.gameAction; + +public class PlacePort extends GameAction +{ + private int territoryID; + + /** + * @return the territoryID + */ + public int getTerritoryID() + { + return territoryID; + } + + /** + * @param territoryID the territoryID to set + */ + public PlacePort setTerritoryID(int territoryID) + { + this.territoryID = territoryID; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } +} diff --git a/src/java/soc/common/actions/gameAction/RolledSame.java b/src/java/soc/common/actions/gameAction/RolledSame.java new file mode 100644 index 000000000..4987fb524 --- /dev/null +++ b/src/java/soc/common/actions/gameAction/RolledSame.java @@ -0,0 +1,27 @@ +package soc.common.actions.gameAction; + + +public class RolledSame extends GameAction +{ + private int highRoll; + + /** + * @return the highRoll + */ + public int getHighRoll() + { + return highRoll; + } + + /** + * @param highRoll the highRoll to set + */ + public RolledSame setHighRoll(int highRoll) + { + this.highRoll = highRoll; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } +} diff --git a/src/java/soc/common/actions/gameAction/StartingPlayerDetermined.java b/src/java/soc/common/actions/gameAction/StartingPlayerDetermined.java new file mode 100644 index 000000000..52cefe23f --- /dev/null +++ b/src/java/soc/common/actions/gameAction/StartingPlayerDetermined.java @@ -0,0 +1,28 @@ +package soc.common.actions.gameAction; + +public class StartingPlayerDetermined extends GameAction +{ + private int diceRoll; + + /** + * @return the diceRoll + */ + public int getDiceRoll() + { + return diceRoll; + } + + /** + * @param diceRoll the diceRoll to set + */ + public StartingPlayerDetermined setDiceRoll(int diceRoll) + { + this.diceRoll = diceRoll; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + + +} diff --git a/src/java/soc/common/actions/gameAction/turnActions/BuildCity.java b/src/java/soc/common/actions/gameAction/turnActions/BuildCity.java new file mode 100644 index 000000000..51ad6f7b0 --- /dev/null +++ b/src/java/soc/common/actions/gameAction/turnActions/BuildCity.java @@ -0,0 +1,6 @@ +package soc.common.actions.gameAction.turnActions; + +public class BuildCity extends TurnAction +{ + +} diff --git a/src/java/soc/common/actions/gameAction/turnActions/BuildRoad.java b/src/java/soc/common/actions/gameAction/turnActions/BuildRoad.java new file mode 100644 index 000000000..b75477f65 --- /dev/null +++ b/src/java/soc/common/actions/gameAction/turnActions/BuildRoad.java @@ -0,0 +1,10 @@ +package soc.common.actions.gameAction.turnActions; + +import soc.common.game.Player; + +public class BuildRoad extends TurnAction +{ + + + +} diff --git a/src/java/soc/common/actions/gameAction/turnActions/BuildShip.java b/src/java/soc/common/actions/gameAction/turnActions/BuildShip.java new file mode 100644 index 000000000..60088929e --- /dev/null +++ b/src/java/soc/common/actions/gameAction/turnActions/BuildShip.java @@ -0,0 +1,6 @@ +package soc.common.actions.gameAction.turnActions; + +public class BuildShip extends TurnAction +{ + +} diff --git a/src/java/soc/common/actions/gameAction/turnActions/BuildTown.java b/src/java/soc/common/actions/gameAction/turnActions/BuildTown.java new file mode 100644 index 000000000..3c3ae64f6 --- /dev/null +++ b/src/java/soc/common/actions/gameAction/turnActions/BuildTown.java @@ -0,0 +1,6 @@ +package soc.common.actions.gameAction.turnActions; + +public class BuildTown extends TurnAction +{ + +} diff --git a/src/java/soc/common/actions/gameAction/turnActions/RollDice.java b/src/java/soc/common/actions/gameAction/turnActions/RollDice.java new file mode 100644 index 000000000..0ad69683c --- /dev/null +++ b/src/java/soc/common/actions/gameAction/turnActions/RollDice.java @@ -0,0 +1,54 @@ +package soc.common.actions.gameAction.turnActions; + + + +public class RollDice extends TurnAction +{ + private int dice1; + private int dice2; + private int dice; + /** + * @return the dice1 + */ + public int getDice1() + { + return dice1; + } + /** + * @param dice1 the dice1 to set + */ + public RollDice setDice1(int dice1) + { + this.dice1 = dice1; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + /** + * @return the dice2 + */ + public int getDice2() + { + return dice2; + } + /** + * @param dice2 the dice2 to set + */ + public RollDice setDice2(int dice2) + { + this.dice2 = dice2; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + /** + * @return the dice + */ + public int getDice() + { + return dice; + } + +} diff --git a/src/java/soc/common/actions/gameAction/turnActions/TurnAction.java b/src/java/soc/common/actions/gameAction/turnActions/TurnAction.java new file mode 100644 index 000000000..e8a4d1810 --- /dev/null +++ b/src/java/soc/common/actions/gameAction/turnActions/TurnAction.java @@ -0,0 +1,9 @@ +package soc.common.actions.gameAction.turnActions; + +import soc.common.actions.gameAction.GameAction; +import soc.common.game.Player; + +public class TurnAction extends GameAction +{ + +} diff --git a/src/java/soc/common/actions/lobby/LobbyAction.java b/src/java/soc/common/actions/lobby/LobbyAction.java new file mode 100644 index 000000000..089239699 --- /dev/null +++ b/src/java/soc/common/actions/lobby/LobbyAction.java @@ -0,0 +1,7 @@ +package soc.common.actions.lobby; + + +public class LobbyAction +{ + +} diff --git a/src/java/soc/common/actions/lobby/LobbyChatAction.java b/src/java/soc/common/actions/lobby/LobbyChatAction.java new file mode 100644 index 000000000..6446bd064 --- /dev/null +++ b/src/java/soc/common/actions/lobby/LobbyChatAction.java @@ -0,0 +1,6 @@ +package soc.common.actions.lobby; + +public class LobbyChatAction extends LobbyAction +{ + +} diff --git a/src/java/soc/common/annotations/CitiesKnights.java b/src/java/soc/common/annotations/CitiesKnights.java new file mode 100644 index 000000000..48781a623 --- /dev/null +++ b/src/java/soc/common/annotations/CitiesKnights.java @@ -0,0 +1,32 @@ +/** + * + */ +package soc.common.annotations; + +import java.lang.annotation.*; + +/** + * Stub annotation to tag code for CitiesKnights ruleset + * @see Annotations in Tiger, Part 2: Custom annotations + */ + +// it may be put onto any element. Parent elements tag all child elements +// cumulatively +@Target({ElementType.TYPE, // Class, interface, or enum (but not annotation) + ElementType.FIELD, // Field (including enumerated values) + ElementType.METHOD, // Method (does not include constructors) + ElementType.PARAMETER, // Method parameter + ElementType.CONSTRUCTOR, // Constructor + ElementType.LOCAL_VARIABLE, // Local variable or catch clause + ElementType.ANNOTATION_TYPE, // Annotation Types (meta-annotations) + ElementType.PACKAGE}) // Java package + +// No need to keep this annotation at runtime +@Retention(RetentionPolicy.SOURCE) + +// Mirror kitteh looks in mirror +@CitiesKnights +public @interface CitiesKnights +{ + +} diff --git a/src/java/soc/common/annotations/Pioneers.java b/src/java/soc/common/annotations/Pioneers.java new file mode 100644 index 000000000..8837e6dc2 --- /dev/null +++ b/src/java/soc/common/annotations/Pioneers.java @@ -0,0 +1,33 @@ +/** + * + */ +package soc.common.annotations; + +import java.lang.annotation.*; + +/** + * Stub annotation to tag code for specific ruleset + * {@link } + * @see Annotations in Tiger, Part 2: Custom annotations + */ + +// it may be put onto any element. Parent elements tag all child elements +// cumulatively +@Target({ElementType.TYPE, // Class, interface, or enum (but not annotation) + ElementType.FIELD, // Field (including enumerated values) + ElementType.METHOD, // Method (does not include constructors) + ElementType.PARAMETER, // Method parameter + ElementType.CONSTRUCTOR, // Constructor + ElementType.LOCAL_VARIABLE, // Local variable or catch clause + ElementType.ANNOTATION_TYPE, // Annotation Types (meta-annotations) + ElementType.PACKAGE}) // Java package + +// No need to keep this annotation at runtime +@Retention(RetentionPolicy.SOURCE) + +// Mirror kitteh looks in mirror +@Pioneers +public @interface Pioneers +{ + +} diff --git a/src/java/soc/common/annotations/Sea3D.java b/src/java/soc/common/annotations/Sea3D.java new file mode 100644 index 000000000..c40e46783 --- /dev/null +++ b/src/java/soc/common/annotations/Sea3D.java @@ -0,0 +1,32 @@ +/** + * + */ +package soc.common.annotations; + +import java.lang.annotation.*; + +/** + * Stub annotation to tag code for specific ruleset + * {@link } + * @see Annotations in Tiger, Part 2: Custom annotations + */ + +// it may be put onto any element. Parent elements tag all child elements +// cumulatively +@Target({ElementType.TYPE, // Class, interface, or enum (but not annotation) + ElementType.FIELD, // Field (including enumerated values) + ElementType.METHOD, // Method (does not include constructors) + ElementType.PARAMETER, // Method parameter + ElementType.CONSTRUCTOR, // Constructor + ElementType.LOCAL_VARIABLE, // Local variable or catch clause + ElementType.ANNOTATION_TYPE, // Annotation Types (meta-annotations) + ElementType.PACKAGE}) // Java package + +// No need to keep this annotation at runtime +@Retention(RetentionPolicy.SOURCE) + + +public @interface Sea3D +{ + +} diff --git a/src/java/soc/common/annotations/SeaFarers.java b/src/java/soc/common/annotations/SeaFarers.java new file mode 100644 index 000000000..fbce9132e --- /dev/null +++ b/src/java/soc/common/annotations/SeaFarers.java @@ -0,0 +1,32 @@ +/** + * + */ +package soc.common.annotations; + +import java.lang.annotation.*; + +/** + * Stub annotation to tag code for specific ruleset + * @see Annotations in Tiger, Part 2: Custom annotations + */ + +// it may be put onto any element. Parent elements tag all child elements +// cumulatively +@Target({ElementType.TYPE, // Class, interface, or enum (but not annotation) + ElementType.FIELD, // Field (including enumerated values) + ElementType.METHOD, // Method (does not include constructors) + ElementType.PARAMETER, // Method parameter + ElementType.CONSTRUCTOR, // Constructor + ElementType.LOCAL_VARIABLE, // Local variable or catch clause + ElementType.ANNOTATION_TYPE, // Annotation Types (meta-annotations) + ElementType.PACKAGE}) // Java package + +// No need to keep this annotation at runtime +@Retention(RetentionPolicy.SOURCE) + +// Mirror kitteh looks in mirror +@SeaFarers +public @interface SeaFarers +{ + +} diff --git a/src/java/soc/common/annotations/TeamSettlers.java b/src/java/soc/common/annotations/TeamSettlers.java new file mode 100644 index 000000000..84bc0622a --- /dev/null +++ b/src/java/soc/common/annotations/TeamSettlers.java @@ -0,0 +1,32 @@ +/** + * + */ +package soc.common.annotations; + +import java.lang.annotation.*; + +/** + * Stub annotation to tag code for usage in Team Settlers ruleset + * @see Annotations in Tiger, Part 2: Custom annotations + */ + +// it may be put onto any element. Parent elements tag all child elements +// cumulatively +@Target({ElementType.TYPE, // Class, interface, or enum (but not annotation) + ElementType.FIELD, // Field (including enumerated values) + ElementType.METHOD, // Method (does not include constructors) + ElementType.PARAMETER, // Method parameter + ElementType.CONSTRUCTOR, // Constructor + ElementType.LOCAL_VARIABLE, // Local variable or catch clause + ElementType.ANNOTATION_TYPE, // Annotation Types (meta-annotations) + ElementType.PACKAGE}) // Java package + +// No need to keep this annotation at runtime +@Retention(RetentionPolicy.SOURCE) + +// Mirror kitteh looks in mirror +@TeamSettlers +public @interface TeamSettlers +{ + +} diff --git a/src/java/soc/common/board/Board.java b/src/java/soc/common/board/Board.java new file mode 100644 index 000000000..e8fc36b0a --- /dev/null +++ b/src/java/soc/common/board/Board.java @@ -0,0 +1,346 @@ +package soc.common.board; + +import java.util.List; +import java.util.Random; + +import soc.common.board.hexes.Hex; +import soc.common.board.hexes.ITerritoryHex; +import soc.common.board.hexes.RandomHex; +import soc.common.board.hexes.SeaHex; +import soc.common.game.GameSettings; + + +/// +/// Represents the board data structure. +/// +/// A board is made up of hexes in a 2D matrix. The even rows of the matrix +/// have an indentation length on the left side half the width of a hex. +/// For example, a 5x5 sized board will have the layout of: +/// +/// +/// |H| |H| |H| |H| |H| 0 +/// |H| |H| |H| |H| |H| 1 +/// |H| |H| |H| |H| |H| 2 +/// |H| |H| |H| |H| |H| 3 +/// |H| |H| |H| |H| |H| 4 +/// +/// +/// Sea3D has the same layout, only has the last hexes of the even rows +/// omitted. Thus, a Sea3D 'compatible' board would have the following +/// layout: +/// +/// +/// |H| |H| |H| |H| |H| 0 +/// |H| |H| |H| |H| 1 +/// |H| |H| |H| |H| |H| 2 +/// |H| |H| |H| |H| 3 +/// |H| |H| |H| |H| |H| 4 +/// +/// +/// The last hexes of each even row in a 'Sea3D compatible' configuration +/// should be made invisible, and/or locked. +/// + +public class Board +{ + // list of hexes this board is made of + public HexList hexes; + + // Name of the designer of the board + private String _Creator = "Unknown player"; + + // data fields + private String name = "New Board"; + private boolean useTradeRoutes = false; + private boolean assignPortsBeforePlacement = false; + private boolean requiresInitialShips = false; + private int allowedCards = 7; + private int bankResources = 19; + private int stockRoads = 15; + private int stockShips = 15; + private int stockTowns = 5; + private int stockCities = 4; + private int bonusNewIsland; + private int maxPlayers = 4; + private int minPlayers = 3; + private int vpToWin = 10; + private int width = 0; + private int height = 0; + private TerritoryList territories; + + private int maximumCardsInHandWhenSeven = 7; + + //private StandardDevCardStack _DevCards = new StandardDevCardStack(5, 2, 14, 2, 2); + + + /// + /// Resizes the board to a new size. + /// + /// New width of the board + /// New height of the board + public void Resize(int newWidth, int newHeight, Hex defaultHex) + { + // default on seahexes if we have no default + if (defaultHex == null) defaultHex = new SeaHex(); + + //return if there is nothing to resize + if (width == newWidth && height == newHeight) + { + return; + } + + //Instantiate a new board + HexList newboard = new HexList(newWidth, newHeight); + + //loop through new sized matrix. + for (int h = 0; h < newHeight; h++) + { + for (int w = 0; w < newWidth; w++) + { + //when width or height is bigger then original, add hexes + if (w >= width || h >= height) + { + Hex newHex = null; + + //if outer bounds, put a SeaHex in place, otherwise a defaulthex + if (w == newWidth - 1 || w == 0 || h == newHeight - 1 || h == 0) + newHex = new SeaHex(); + else + newHex = defaultHex.Copy(); + + newHex.setLocation(new HexLocation(w,h)); + newboard.set(w, h, newHex); + } + else + { + //if outer bounds, put a seahex in place, + // otherwise the defaulthex + if (w == newWidth - 1 || w == 0 || h == newHeight - 1 || h == 0) + { + newboard.set(w, h, new SeaHex()); + } + else + { + newboard.set(w, h, defaultHex.Copy()); + } + + newboard.set(w, h, hexes.get(w, h).Copy()); + } + + } + } + hexes = newboard; + } + + /// + /// Prepares a saved board definition into a playable board. + /// 1. Puts hexes from InitialRandomHexes list on RandomHexes + /// 2. Replaces random ports from those out of RandomPorts bag + /// 3. Replaces deserts by volcano/jungles if necessary + /// + public void PrepareForPlay(GameSettings settings) + { + // TODO: add code from JSettlers + + } + + public HexList getHexes() + { + return hexes; + } + + public void setHexes(HexList hexes) + { + this.hexes = hexes; + } + + public String get_Creator() + { + return _Creator; + } + + public void set_Creator(String creator) + { + _Creator = creator; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public boolean isUseTradeRoutes() + { + return useTradeRoutes; + } + + public void setUseTradeRoutes(boolean useTradeRoutes) + { + this.useTradeRoutes = useTradeRoutes; + } + + public boolean isAssignPortsBeforePlacement() + { + return assignPortsBeforePlacement; + } + + public void setAssignPortsBeforePlacement(boolean assignPortsBeforePlacement) + { + this.assignPortsBeforePlacement = assignPortsBeforePlacement; + } + + public boolean isRequiresInitialShips() + { + return requiresInitialShips; + } + + public void setRequiresInitialShips(boolean requiresInitialShips) + { + this.requiresInitialShips = requiresInitialShips; + } + + public int getAllowedCards() + { + return allowedCards; + } + + public void setAllowedCards(int allowedCards) + { + this.allowedCards = allowedCards; + } + + public int getBankResources() + { + return bankResources; + } + + public void setBankResources(int bankResources) + { + this.bankResources = bankResources; + } + + public int getStockRoads() + { + return stockRoads; + } + + public void setStockRoads(int stockRoads) + { + this.stockRoads = stockRoads; + } + + public int getStockShips() + { + return stockShips; + } + + public void setStockShips(int stockShips) + { + this.stockShips = stockShips; + } + + public int getStockTowns() + { + return stockTowns; + } + + public void setStockTowns(int stockTowns) + { + this.stockTowns = stockTowns; + } + + public int getStockCities() + { + return stockCities; + } + + public void setStockCities(int stockCities) + { + this.stockCities = stockCities; + } + + public int getBonusNewIsland() + { + return bonusNewIsland; + } + + public void setBonusNewIsland(int bonusNewIsland) + { + this.bonusNewIsland = bonusNewIsland; + } + + public int getMaxPlayers() + { + return maxPlayers; + } + + public void setMaxPlayers(int maxPlayers) + { + this.maxPlayers = maxPlayers; + } + + public int getMinPlayers() + { + return minPlayers; + } + + public void setMinPlayers(int minPlayers) + { + this.minPlayers = minPlayers; + } + + public int getVpToWin() + { + return vpToWin; + } + + public void setVpToWin(int vpToWin) + { + this.vpToWin = vpToWin; + } + + public int getWidth() + { + return width; + } + + public void setWidth(int width) + { + this.width = width; + } + + public int getHeight() + { + return height; + } + + public void setHeight(int height) + { + this.height = height; + } + + public TerritoryList getTerritories() + { + return territories; + } + + public void setTerritories(TerritoryList territories) + { + this.territories = territories; + } + + public int getMaximumCardsInHandWhenSeven() + { + return maximumCardsInHandWhenSeven; + } + + public void setMaximumCardsInHandWhenSeven(int maximumCardsInHandWhenSeven) + { + this.maximumCardsInHandWhenSeven = maximumCardsInHandWhenSeven; + } +} diff --git a/src/java/soc/common/board/BoardSettings.java b/src/java/soc/common/board/BoardSettings.java new file mode 100644 index 000000000..049e695da --- /dev/null +++ b/src/java/soc/common/board/BoardSettings.java @@ -0,0 +1,103 @@ +package soc.common.board; + +public class BoardSettings +{ + // Minimum amount of players expected + private int minPlayers = 3; + + // Maximum amount of players for this board + private int maxPlayers = 4; + + // max allowed cards in hand when a 7 rolls + private int maximumCardsInHandWhenSeven = 7; + + // Amount of vp to win on this board + private int vpToWin = 10; + + + public static BoardSettings standard() + { + BoardSettings settings = new BoardSettings(); + + // default settings are good (for now?) + + return settings; + } + + /** + * @return the minPlayers + */ + public int getMinPlayers() + { + return minPlayers; + } + + /** + * @param minPlayers the minPlayers to set + */ + public void setMinPlayers(int minPlayers) + { + this.minPlayers = minPlayers; + } + + + + /** + * @return the maxPlayers + */ + public int getMaxPlayers() + { + return maxPlayers; + } + + + + /** + * @param maxPlayers the maxPlayers to set + */ + public void setMaxPlayers(int maxPlayers) + { + this.maxPlayers = maxPlayers; + } + + + + /** + * @return the maximumCardsInHandWhenSeven + */ + public int getMaximumCardsInHandWhenSeven() + { + return maximumCardsInHandWhenSeven; + } + + + + /** + * @param maximumCardsInHandWhenSeven the maximumCardsInHandWhenSeven to set + */ + public void setMaximumCardsInHandWhenSeven(int maximumCardsInHandWhenSeven) + { + this.maximumCardsInHandWhenSeven = maximumCardsInHandWhenSeven; + } + + + + /** + * @return the vpToWin + */ + public int getVpToWin() + { + return vpToWin; + } + + + + /** + * @param vpToWin the vpToWin to set + */ + public void setVpToWin(int vpToWin) + { + this.vpToWin = vpToWin; + } + +} diff --git a/src/java/soc/common/board/Chit.java b/src/java/soc/common/board/Chit.java new file mode 100644 index 000000000..49c72eda5 --- /dev/null +++ b/src/java/soc/common/board/Chit.java @@ -0,0 +1,54 @@ +package soc.common.board; + +import java.util.Random; + +public class Chit +{ + private int number = 2; + + public Chit(int number) + { + this.number = number; + } + + public Chit() + { + // TODO Auto-generated constructor stub + } + + /** + * @return the number + */ + public int getNumber() + { + return number; + } + + /** + * @param number the number to set + */ + public void setNumber(int number) + { + this.number = number; + } + + public static Chit pickRandomChit(Random random) + { + Chit result = new Chit(); + int chitno = (int)(random.nextDouble() * 10); + switch (chitno) + { + case 0: result.setNumber(2); + case 1: result.setNumber(3); + case 2: result.setNumber(4); + case 3: result.setNumber(5); + case 4: result.setNumber(6); + case 5: result.setNumber(8); + case 6: result.setNumber(9); + case 7: result.setNumber(10); + case 8: result.setNumber(11); + case 9: result.setNumber(12); + } + return result; + } +} diff --git a/src/java/soc/common/board/ChitList.java b/src/java/soc/common/board/ChitList.java new file mode 100644 index 000000000..214b224b1 --- /dev/null +++ b/src/java/soc/common/board/ChitList.java @@ -0,0 +1,93 @@ +package soc.common.board; + + +import java.util.ArrayList; +import java.util.Random; + +import soc.common.annotations.SeaFarers; + + +public class ChitList extends ArrayList +{ + /* + * Returns a chitlist from standard settlers ruleset + */ + public static ChitList getStandardList() + { + ChitList result = new ChitList(); + + result.add(new Chit(2)); + result.add(new Chit(12)); + + result.add(new Chit(3)); + result.add(new Chit(3)); + result.add(new Chit(11)); + result.add(new Chit(11)); + + result.add(new Chit(4)); + result.add(new Chit(4)); + result.add(new Chit(10)); + result.add(new Chit(10)); + + result.add(new Chit(5)); + result.add(new Chit(5)); + result.add(new Chit(9)); + result.add(new Chit(9)); + + result.add(new Chit(6)); + result.add(new Chit(6)); + result.add(new Chit(8)); + result.add(new Chit(8)); + + + return result; + } + + /* + * Returns a Seafarers swapbag for Greater Catan maps + * A swapbag has 2,3,4,5, 9,10,11 + */ + @SeaFarers + public static ChitList getSwapBag() + { + ChitList result = new ChitList(); + + result.add(new Chit(2)); + + result.add(new Chit(3)); + result.add(new Chit(11)); + + result.add(new Chit(4)); + result.add(new Chit(10)); + + result.add(new Chit(5)); + result.add(new Chit(9)); + + return result; + } + /* + * Returns a random instance from this list + */ + public Chit pickRandomChit(Random random) + { + int randomIndex = (int)random.nextDouble() * size(); + + return this.get(randomIndex); + } + + /* + * Counts amount of chits with given chitnumber + */ + public int count(int number) + { + int result = 0; + + for (Chit chit : this) + { + if (chit.getNumber() == number) + result++; + } + + return result; + } +} diff --git a/src/java/soc/common/board/HexList.java b/src/java/soc/common/board/HexList.java new file mode 100644 index 000000000..73694b772 --- /dev/null +++ b/src/java/soc/common/board/HexList.java @@ -0,0 +1,93 @@ +package soc.common.board; + +import java.util.ArrayList; + +import soc.common.board.hexes.Hex; + + +public class HexList extends ArrayList +{ + private final int width; + private final int height; + + public int getHeight() + { + return width; + } + + public int getWidth() + { + return height; + } + + HexList(int w, int h) + { + // Set the capacity of the list only once to increase performance + this.ensureCapacity(w *h); + + // Initialize empty + for (int i = w * h; i < w * h; i++) + { + super.set(i, null); + } + + // Set the height & width fields + width = w; + height = h; + } + + public Hex get(int w, int h) + { + if (!checkInput(w, h)) return null; + + return get((width * h) + w); + } + + public void set(int w, int h, Hex value) + { + checkInput(w, h); + + if (size() - 1 < (width * h) + w) + { + super.set((width * h) + w, value); + } + else + { + // Oldhex needed for obsrvable listeners + Hex oldHex = get((width * h) + w); + set((width * h) + w, value); + get((width * h) + w).setLocation(new HexLocation(w, h)); + // TODO: make observable + //OnHexChanged(temp, value); + } + } + + public boolean checkInput(int w, int h) + { + return true; + /* + if (w < 0) return false; + if (h < 0) return false; + if (w >= Width) return false; + if (h >= Height) return false; + */ + } + + private boolean checkInput(HexLocation location) + { + return checkInput(location.getW(), location.getH()); + } + + public Hex get(HexLocation location) + { + if (!checkInput(location)) return null; + return get(location.getW(), location.getH()); + } + + public void set(HexLocation location, Hex value) + { + checkInput(location.getW(), location.getH()); + set(location.getW(), location.getH(), value); + } + +} diff --git a/src/java/soc/common/board/HexLocation.java b/src/java/soc/common/board/HexLocation.java new file mode 100644 index 000000000..5fd3f105f --- /dev/null +++ b/src/java/soc/common/board/HexLocation.java @@ -0,0 +1,142 @@ +package soc.common.board; + +import java.util.ArrayList; +import java.util.Formatter; +import java.util.List; + +/* + * Represents a location of an Hex. This location is represented by + * an w + h coordinate (width, height). + */ +public class HexLocation +{ + private int w; + private int h; + + public int getW() + { + return w; + } + + public int getH() + { + return h; + } + + public HexLocation(int w, int h) + { + this.w = w; + this.h = h; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + h; + result = prime * result + w; + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + HexLocation other = (HexLocation) obj; + if (h != other.h) + return false; + if (w != other.w) + return false; + return true; + } + + public List getNeighbours() + { + List result = new ArrayList(); + + // add an offset for uneven rows + int offset = h % 2 == 0 ? 0 : -1; + + //2 hexes on the same row + result.add(new HexLocation(w - 1, h)); + result.add(new HexLocation(w + 1, h)); + + //2 hexes on the row above + result.add(new HexLocation(w + 1 + offset, h - 1)); + result.add(new HexLocation(w + offset, h - 1)); + + //2 hexes on the row below + result.add(new HexLocation(w + 1 + offset, h + 1)); + result.add(new HexLocation(w + offset, h + 1)); + + return result; + } + + public List getNeighbourHexPoints() throws Exception + { + List result = new ArrayList(); + + // add an offset for uneven rows + int offset = h % 2 == 0 ? 0 : -1; + + result.add(new HexPoint( + this, + new HexLocation(w + offset, h - 1), + new HexLocation(w + offset + 1, h - 1))); + + result.add(new HexPoint( + this, + new HexLocation(w + offset + 1, h - 1), + new HexLocation(w + 1, h))); + + result.add(new HexPoint( + this, + new HexLocation(w + 1, h), + new HexLocation(w + offset + 1, h + 1))); + + result.add(new HexPoint( + this, + new HexLocation(w + offset + 1, h + 1), + new HexLocation(w + offset, h + 1))); + + result.add(new HexPoint( + this, + new HexLocation(w + offset, h + 1), + new HexLocation(w - 1, h))); + + result.add(new HexPoint( + this, + new HexLocation(w - 1, h), + new HexLocation(w + offset, h - 1))); + + return result; + } + + public HexSide GetSideLocation(RotationPosition position) throws Exception + { + List neighbours = getNeighbourHexPoints(); + + switch (position) + { + case DEG0: return new HexSide(neighbours.get(3), neighbours.get(4)); + case DEG60: return new HexSide(neighbours.get(2), neighbours.get(3)); + case DEG120: return new HexSide(neighbours.get(1), neighbours.get(2)); + case DEG180: return new HexSide(neighbours.get(0), neighbours.get(1)); + case DEG240: return new HexSide(neighbours.get(5), neighbours.get(0)); + case DEG300: return new HexSide(neighbours.get(4), neighbours.get(5)); + } + + return null; + } + + public String toString() + { + return String.format("w: %s, h: %s", w, h); + } +} diff --git a/src/java/soc/common/board/HexPoint.java b/src/java/soc/common/board/HexPoint.java new file mode 100644 index 000000000..a53b17845 --- /dev/null +++ b/src/java/soc/common/board/HexPoint.java @@ -0,0 +1,316 @@ +package soc.common.board; + +import java.util.ArrayList; +import java.util.List; + +public class HexPoint +{ + private HexLocation hex1; + private HexLocation hex2; + private HexLocation hex3; + + public HexLocation getHex1() + { + return hex1; + } + public HexLocation getHex2() + { + return hex2; + } + public HexLocation getHex3() + { + return hex3; + } + + public HexPointType getPointType() + { + List points = new ArrayList(); + points.add(hex3); + points.add(hex2); + points.add(hex1); + + int h = 220; + + for (HexLocation point : points) + { + if (point.getH() < h) h = point.getH(); + } + + int count=0; + + for (HexLocation p : points) + { + if (p.getH() == h) + { + count++; + } + } + + if (count==1) + { + // There is one Hex at the upper height coordinate + return HexPointType.UPPERROW1; + } + else + { + // There are two Hexes at the upper height coordinate + return HexPointType.UPPERROW2; + } + } + + public PointPositionOnHex getHexPositionOnTopLeftMost() + { + return getPointType() == HexPointType.UPPERROW1 ? + PointPositionOnHex.BOTTOMMIDDLE : PointPositionOnHex.BOTTOMRIGHT; + } + + public List getOtherSides(HexSide side) throws Exception + { + List result = new ArrayList(); + + for (HexSide s : getNeighbourSides()) + if (!side.equals(s)) + result.add(s); + + return result; + } + + + /* + * Returns a list of three HexSides adjacent to this point + */ + public List getNeighbourSides() throws Exception + { + List result = new ArrayList(); + + // add all three hex sides around point + result.add(new HexSide(hex1, hex2)); + result.add(new HexSide(hex1, hex3)); + result.add(new HexSide(hex2, hex3)); + + return result; + } + + /* + * Returns the topmost hex of the three hexes + */ + public HexLocation getTopMost() + { + List points = new ArrayList(); + points.add(hex3); + points.add(hex2); + points.add(hex1); + int w = 220; + int h = 220; + for (HexLocation point : points) + { + if (point.getW() < w) w = point.getW(); + if (point.getH() < h) h = point.getH(); + } + List res = new ArrayList(); + if (hex1.getH() == h) res.add(hex1); + if (hex2.getH() == h) res.add(hex2); + if (hex3.getH() == h) res.add(hex3); + if (res.size() == 1) + { + return res.get(0); + } + else + { + if (res.size() == 2) + { + HexLocation l = res.get(0); + if (l.getW() < res.get(1).getW()) return l; + else return res.get(1); + } + } + return null; + } + + public List getNeighbours() throws Exception + { + List result = new ArrayList(); + HexLocation topmost = getTopMost(); + + if (topmost.getH() % 2 == 0) + { + //even rows + if (getPointType() == HexPointType.UPPERROW1) + { + HexPoint p1 = new HexPoint( + topmost, + new HexLocation(topmost.getW() - 1, topmost.getH()), + new HexLocation(topmost.getW(), topmost.getH() + 1)); + result.add(p1); + + HexPoint p2 = new HexPoint( + new HexLocation(topmost.getW() + 1, topmost.getH() + 1), + new HexLocation(topmost.getW(), topmost.getH() + 1), + new HexLocation(topmost.getW(), topmost.getH() + 2)); + result.add(p2); + + HexPoint p3 = new HexPoint( + topmost, + new HexLocation(topmost.getW() + 1, topmost.getH() + 1), + new HexLocation(topmost.getW() + 1, topmost.getH())); + result.add(p3); + } + else + { + HexPoint p1 = new HexPoint( + topmost, + new HexLocation(topmost.getW() + 1, topmost.getH()), + new HexLocation(topmost.getW() + 1, topmost.getH() - 1)); + result.add(p1); + + HexPoint p2 = new HexPoint( + new HexLocation(topmost.getW() + 2, topmost.getH() + 1), + new HexLocation(topmost.getW() + 1, topmost.getH() + 1), + new HexLocation(topmost.getW() + 1, topmost.getH())); + result.add(p2); + + HexPoint p3 = new HexPoint( + topmost, + new HexLocation(topmost.getW() + 1, topmost.getH() + 1), + new HexLocation(topmost.getW(), topmost.getH() + 1)); + result.add(p3); + } + } + else + { + //uneven rows + if (getPointType() == HexPointType.UPPERROW1) + { + HexPoint p1 = new HexPoint( + topmost, + new HexLocation(topmost.getW() - 1, topmost.getH() + 1), + new HexLocation(topmost.getW() - 1, topmost.getH())); + result.add(p1); + + HexPoint p2 = new HexPoint( + new HexLocation(topmost.getW(), topmost.getH() + 1), + new HexLocation(topmost.getW() - 1, topmost.getH() + 1), + new HexLocation(topmost.getW(), topmost.getH() + 2)); + result.add(p2); + + HexPoint p3 = new HexPoint( + topmost, + new HexLocation(topmost.getW(), topmost.getH() + 1), + new HexLocation(topmost.getW() + 1, topmost.getH())); + result.add(p3); + } + else + { + // OK + HexPoint p1 = new HexPoint( + topmost, + new HexLocation(topmost.getW(), topmost.getH() - 1), + new HexLocation(topmost.getW() + 1, topmost.getH())); + result.add(p1); + + HexPoint p2 = new HexPoint( + new HexLocation(topmost.getW() + 1, topmost.getH()), + new HexLocation(topmost.getW() + 1, topmost.getH() + 1), + new HexLocation(topmost.getW(), topmost.getH() + 1)); + result.add(p2); + + HexPoint p3 = new HexPoint( + topmost, + new HexLocation(topmost.getW(), topmost.getH() + 1), + new HexLocation(topmost.getW() - 1, topmost.getH() + 1)); + result.add(p3); + } + } + return result; + } + + public List getOtherNeighbours(HexPoint center, HexPoint ignore) throws Exception + { + List result = getNeighbours(); + + result.remove(ignore); + + return result; + } + + public HexPoint(HexLocation hex1, HexLocation hex2, HexLocation hex3) throws Exception + { + this.hex1 = hex1; + this.hex2 = hex2; + this.hex3 = hex3; + if (hex1.equals(hex2) || + hex1.equals(hex3) || + hex2.equals(hex3)) + throw new IllegalArgumentException("WHOA"); + } + + public boolean getHasLocation(HexLocation location) + { + return hex1.equals(location) || + hex2.equals(location) || + hex3.equals(location); + } + + public HexPoint(HexLocation hex, PointPositionOnHex relativePosition) throws Exception + { + // we must assume hex comes from a uneven row, and + // relative position on the hex is never the two left positions + if (hex.getH() % 2 == 0) throw new Exception("WHooa!"); + hex1 = hex; + + switch (relativePosition) + { + case TOPMIDDLE: + hex2 = new HexLocation(hex.getW() - 1, hex.getH() - 1); + hex3 = new HexLocation(hex.getW(), hex.getH() - 1); + break; + case TOPRIGHT: + hex2 = new HexLocation(hex.getW(), hex.getH() - 1); + hex3 = new HexLocation(hex.getW() + 1, hex.getH()); + break; + case BOTTOMRIGHT: + hex2 = new HexLocation(hex.getW() + 1, hex.getH()); + hex3 = new HexLocation(hex.getW(), hex.getH() + 1); + break; + case BOTTOMMIDDLE: + hex2 = new HexLocation(hex.getW(), hex.getH() + 1); + hex3 = new HexLocation(hex.getW() - 1, hex.getH() + 1); + break; + default: throw new Exception("Whoa!"); + } + } + + public HexPoint() { } + + // create a point out of two neighbouring sides + public HexPoint(HexSide side1, HexSide side2) + { + List allLocations = new ArrayList(); + allLocations.add(side1.getHex1()); + allLocations.add(side1.getHex2()); + allLocations.add(side2.getHex1()); + allLocations.add(side2.getHex2()); + + HexLocation equalHex = null; + if (side1.getHex1().equals(side2.getHex1())) equalHex = side1.getHex1(); + if (side1.getHex1().equals(side2.getHex2())) equalHex = side1.getHex1(); + + allLocations.remove(equalHex); + + this.hex1 = allLocations.get(0); + this.hex2 = allLocations.get(1); + this.hex3 = allLocations.get(2); + } + + public String toString() + { + return String.format("hex1: %s, hex2: %s, hex3: %s", + hex1.toString(), hex2.toString(), hex3.toString()); + } + + public int hashCode() + { + return hex1.hashCode() ^ hex2.hashCode() ^ hex3.hashCode(); + } + +} diff --git a/src/java/soc/common/board/HexPointType.java b/src/java/soc/common/board/HexPointType.java new file mode 100644 index 000000000..b715c487b --- /dev/null +++ b/src/java/soc/common/board/HexPointType.java @@ -0,0 +1,9 @@ +package soc.common.board; + +public enum HexPointType +{ + // the point has 2 hexes on the highest row (1 on lowest) + UPPERROW2, + // the point has 1 hex on the highest row (2 on lowest) + UPPERROW1; +} diff --git a/src/java/soc/common/board/HexSide.java b/src/java/soc/common/board/HexSide.java new file mode 100644 index 000000000..020b8c80d --- /dev/null +++ b/src/java/soc/common/board/HexSide.java @@ -0,0 +1,239 @@ +package soc.common.board; + +import java.util.ArrayList; +import java.util.List; + +/* + * Represents a side, determined by two HexLocations. + */ +public class HexSide +{ + // A HexSide may be constructed using a set of two HexLocations or + // a set of two HexPoints + + // The two HexLocations the HexSide is represented by + private HexLocation hex1; + private HexLocation hex2; + + // The two HexPoints a hexside is represented by + private HexPoint hexPoint1; + private HexPoint hexPoint2; + + // Direction the side points to + private SideDirection sideDirection; + + public HexLocation getHex1() + { + return hex1; + } + public HexLocation getHex2() + { + return hex2; + } + + public HexPoint getHexPoint1() + { + return hexPoint1; + } + + public HexPoint getHexPoint2() + { + return hexPoint2; + } + + HexSide(HexLocation hex1, HexLocation hex2) throws Exception + { + this.hex1=hex1; + this.hex2=hex2; + calculatePoints(); + } + + HexSide(HexPoint point1, HexPoint point2) + { + this.hexPoint1=point1; + this.hexPoint2=point2; + calculateHexes(); + } + + public HexLocation getHighestOrLeftestHex() + { + if (hex1.getH() == hex2.getH()) + //both on same row, return leftest + return hex1.getW() < hex2.getW() ? hex1 : hex2; + else + //different rows, return highest + return hex1.getH() > hex2.getH() ? hex2 : hex1; + } + + /* + * Returns a list of (maximum) three points neighbouring + * this + */ + public List getNeighbourPoints() throws Exception + { + List result = new ArrayList(); + + HexLocation top = getHighestOrLeftestHex(); + + // TODO: headache code + // either visualize using pics or rewrite + switch (getDirection()) + { + case UPDOWN: + int offset = top.getH() % 2 == 0 ? 1 : 0; + result.add(new HexPoint(hex1, hex2, + new HexLocation(top.getW() + offset, top.getH() - 1))); + result.add(new HexPoint(hex1, hex2, + new HexLocation(top.getW() + offset, top.getH() + 1))); + break; + case SLOPEDOWN: + int offset2 = top.getH() % 2 == 0 ? 1 : 0; + result.add(new HexPoint(hex1, hex2, + new HexLocation(top.getW() - 1, top.getH()))); + // generates bad hex + result.add(new HexPoint(hex1, hex2, + new HexLocation(top.getW() + offset2, top.getH() + 1))); + break; + case SLOPEUP: + int offset3 = top.getH() % 2 == 0 ? 0 : 1; + result.add(new HexPoint(hex1, hex2, + new HexLocation(top.getW() - offset3, top.getH() + 1))); + result.add(new HexPoint(hex1, hex2, + new HexLocation(top.getW() + 1, top.getH()))); + break; + } + return result; + } + + /* + * Creates the two HexLocations this HexSide is primarily represented by + */ + private void calculateHexes() + { + List locations = new ArrayList(); + + locations.add(hexPoint1.getHex1()); + locations.add(hexPoint1.getHex2()); + locations.add(hexPoint1.getHex3()); + locations.add(hexPoint2.getHex1()); + locations.add(hexPoint2.getHex2()); + locations.add(hexPoint2.getHex3()); + + /* + * TODO: port to java + + + var x = from l in locations + group l by l into lunique + where lunique.Count() == 2 + select lunique.Key; + */ + + // first of resultset + hex1 = locations.get(0); + + // last of resultset + hex2 = locations.get(5); + } + + /* + * Returns the direction this side is pointing to + */ + public SideDirection getDirection() + { + // lazy init of direction variable + if (sideDirection == null) + { + // | + // both hexes are on the same row, so the side is updown + if (hex1.getH() == hex2.getH()) return SideDirection.UPDOWN; + + if (getHighestOrLeftestHex().getH() % 2 == 0) + //even rows + { + if (hex1.getW() == hex2.getW()) + sideDirection = SideDirection.SLOPEDOWN; + else + sideDirection = SideDirection.SLOPEUP; + } + else + //uneven rows + { + if (hex1.getW() == hex2.getW()) + sideDirection = SideDirection.SLOPEUP; + else + sideDirection = SideDirection.SLOPEDOWN; + } + } + return sideDirection; + } + + /* + * Creates two HexPoints, each consisting of three HexLocations + * TODO: copy+paste image reference from paper + */ + private void calculatePoints() throws Exception + { + HexLocation loc1 = null; + HexLocation loc2 = null; + + HexLocation lefttop = getHighestOrLeftestHex(); + int offset = lefttop.getH() % 2 == 0 ? 1 : 0; + switch (getDirection()) + { + case UPDOWN: + loc1 = new HexLocation(offset + lefttop.getW(), lefttop.getH() - 1); + loc2 = new HexLocation(offset + lefttop.getW(), lefttop.getH() + 1); + break; + case SLOPEDOWN: + loc1 = new HexLocation(offset + lefttop.getW(), lefttop.getH() + 1); + loc2 = new HexLocation(lefttop.getW() - 1, lefttop.getH()); + break; + case SLOPEUP: + loc1 = new HexLocation(lefttop.getW() + 1, lefttop.getH()); + loc2 = new HexLocation(lefttop.getW() -1 + offset, lefttop.getH() + 1); + break; + } + hexPoint1 = new HexPoint(hex1, hex2, loc1); + hexPoint2 = new HexPoint(hex1, hex2, loc2); + } + + public int getHashCode() + { + return hex1.hashCode() ^ hex2.hashCode(); + } + + private boolean isEqual(HexSide other) + { + return (hex1.equals(other.getHex1()) && hex2.equals(other.getHex2())) || + (hex1.equals(other.getHex2()) && hex2.equals(other.getHex1())); + } + + public HexPoint getOtherPoint(HexPoint first) + { + if (first.equals(hexPoint1)) + return hexPoint2; + else + return hexPoint1; + } + + /* + * Returns true when given location is contained by this HexSide + */ + public boolean HasLocation(HexLocation check) + { + return hex1.equals(check) || hex2.equals(check); + } + + public boolean equals(Object other) + { + if (other instanceof HexSide) + { + return isEqual((HexSide)other); + } + else + { + return false; + } + } +} diff --git a/src/java/soc/common/board/PointPositionOnHex.java b/src/java/soc/common/board/PointPositionOnHex.java new file mode 100644 index 000000000..27052409a --- /dev/null +++ b/src/java/soc/common/board/PointPositionOnHex.java @@ -0,0 +1,19 @@ +package soc.common.board; + +public enum PointPositionOnHex +{ + // TopMiddle, + // ^ + // TopLeft / \ TopRight + // | | + // | | + // BottomLeft \ / BottomRight + // + + // BottomMiddle + TOPMIDDLE, + TOPRIGHT, + BOTTOMRIGHT, + BOTTOMMIDDLE, + BOTTOMLEFT, + TOPLEFT; +} diff --git a/src/java/soc/common/board/RotationPosition.java b/src/java/soc/common/board/RotationPosition.java new file mode 100644 index 000000000..6dc8e9d4d --- /dev/null +++ b/src/java/soc/common/board/RotationPosition.java @@ -0,0 +1,23 @@ +package soc.common.board; + +public enum RotationPosition +{ + DEG60 (60), + DEG120 (120), + DEG180 (180), + DEG240 (240), + DEG300 (300), + DEG0 (0); + + private final int index; + + RotationPosition(int index) + { + this.index=index; + } + + public int index() + { + return index; + } +} diff --git a/src/java/soc/common/board/SideDirection.java b/src/java/soc/common/board/SideDirection.java new file mode 100644 index 000000000..ca926775c --- /dev/null +++ b/src/java/soc/common/board/SideDirection.java @@ -0,0 +1,14 @@ +package soc.common.board; + +/* + * Direction of a side + */ +public enum SideDirection +{ + // "/" + SLOPEUP, + // "\" + SLOPEDOWN, + // "|" + UPDOWN; +} diff --git a/src/java/soc/common/board/Territory.java b/src/java/soc/common/board/Territory.java new file mode 100644 index 000000000..e135a2760 --- /dev/null +++ b/src/java/soc/common/board/Territory.java @@ -0,0 +1,72 @@ +package soc.common.board; + +import soc.common.annotations.SeaFarers; +import soc.common.board.ports.PortList; + +/* + * Represents a group of LandHexes. A territory is useful for: + * - Trade routes + * - Chit swapping + * - Bonus island VPs + * + */ +@SeaFarers +public class Territory +{ + private String name; + private int ID; + private boolean isMainland; + private boolean isIsland; + private PortList ports; + + public String getName() + { + return name; + } + /** + * @return the ports + */ + public PortList getPorts() + { + return ports; + } + /** + * @param ports the ports to set + */ + public Territory setPorts(PortList ports) + { + this.ports = ports; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + public void setName(String name) + { + this.name = name; + } + public int getID() + { + return ID; + } + public void setID(int iD) + { + ID = iD; + } + public boolean isMainland() + { + return isMainland; + } + public void setMainland(boolean isMainland) + { + this.isMainland = isMainland; + } + public boolean isIsland() + { + return isIsland; + } + public void setIsland(boolean isIsland) + { + this.isIsland = isIsland; + } +} diff --git a/src/java/soc/common/board/TerritoryList.java b/src/java/soc/common/board/TerritoryList.java new file mode 100644 index 000000000..c78bc44d2 --- /dev/null +++ b/src/java/soc/common/board/TerritoryList.java @@ -0,0 +1,22 @@ +package soc.common.board; + +import java.awt.List; +import java.util.ArrayList; + +import soc.common.annotations.SeaFarers; + +@SeaFarers +public class TerritoryList extends ArrayList +{ + + public Territory findByID(int id) + { + for (Territory t : this) + { + if (t.getID() == id) + return t; + } + + throw new RuntimeException(); + } +} diff --git a/src/java/soc/common/board/hexes/DiscoveryHex.java b/src/java/soc/common/board/hexes/DiscoveryHex.java new file mode 100644 index 000000000..7ba07e668 --- /dev/null +++ b/src/java/soc/common/board/hexes/DiscoveryHex.java @@ -0,0 +1,9 @@ +package soc.common.board.hexes; + +import soc.common.annotations.SeaFarers; + +@SeaFarers +public class DiscoveryHex extends Hex +{ + +} diff --git a/src/java/soc/common/board/hexes/Hex.java b/src/java/soc/common/board/hexes/Hex.java new file mode 100644 index 000000000..442d14e02 --- /dev/null +++ b/src/java/soc/common/board/hexes/Hex.java @@ -0,0 +1,124 @@ +package soc.common.board.hexes; + +import soc.common.board.HexLocation; + +/// Represents the base type for each hex. +/// @seealso cref="http://www.codeproject.com/KB/cs/hexagonal_part1.aspx"/> +/// @seealso cref="http://gmc.yoyogames.com/index.php?showtopic=336183"/> +public class Hex +{ + private HexLocation hexLocation; + private static double s = 10; + private static double h; + private static double r; + private static double b; + private static double a; + + /// + /// The width of the hex measured from outer left to the middle + /// + public static double getHalfWidth() + { + return r; + } + + /// + /// Total width of the hex + /// + public static double getWidth() + { + return a; + } + + /// + /// Total height of the hex + /// + public static double getHeight() + { + return b; + } + /// + /// Height measured from top to the first line + /// __ _ + /// / \ _ } PartialHeight + /// | | + /// \ / + /// -- + /// + public static double getPartialHeight() + { + return s + h; + } + + /// + /// Height measured from the top to the second line + /// __ _ + /// / \ } BottomHeight + /// | | _ + /// \ / + /// -- + /// + public static double getBottomHeight() + { + return h; + } + + /// + /// Size of the hex, measured one line + /// | | --> size + /// __ + /// / \ _ + /// | | _ } --> size + /// \ / + /// -- + /// + public static int getSize() + { + return (int)s; + } + + static + { + h = Math.sin(DegreesToRadians(30)) * s; + r = Math.cos(DegreesToRadians(30)) * s; + b = s + 2 * h; + a = 2 * r; + } + + /// + /// Helper function for size calculation + /// + /// @param degrees + static private double DegreesToRadians(double degrees) + { + return degrees * Math.PI / 180; + } + + public void setLocation(HexLocation hexLocation) + { + this.hexLocation = hexLocation; + } + + public HexLocation getLocation() + { + return hexLocation; + } + + public Hex Copy() + { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return this.getClass().toString()+ " [hexLocation=" + hexLocation + "]"; + } + + + +} diff --git a/src/java/soc/common/board/hexes/ITerritoryHex.java b/src/java/soc/common/board/hexes/ITerritoryHex.java new file mode 100644 index 000000000..a5bbbb81e --- /dev/null +++ b/src/java/soc/common/board/hexes/ITerritoryHex.java @@ -0,0 +1,11 @@ +package soc.common.board.hexes; + +import soc.common.annotations.SeaFarers; + +@SeaFarers +public interface ITerritoryHex +{ + public int getTerritoryID(); + public void setTerritoryID(int id); + +} diff --git a/src/java/soc/common/board/hexes/LandHex.java b/src/java/soc/common/board/hexes/LandHex.java new file mode 100644 index 000000000..d1e820820 --- /dev/null +++ b/src/java/soc/common/board/hexes/LandHex.java @@ -0,0 +1,21 @@ +package soc.common.board.hexes; + +public class LandHex extends Hex implements ITerritoryHex +{ + //ID of territory hex belongs to. Default on mainland (ID=0). + private int territoryID = 0; + + @Override + public int getTerritoryID() + { + // TODO Auto-generated method stub + return territoryID; + } + + @Override + public void setTerritoryID(int id) + { + // TODO Auto-generated method stub + territoryID = id; + } +} diff --git a/src/java/soc/common/board/hexes/NoneHex.java b/src/java/soc/common/board/hexes/NoneHex.java new file mode 100644 index 000000000..00c1338d0 --- /dev/null +++ b/src/java/soc/common/board/hexes/NoneHex.java @@ -0,0 +1,9 @@ +package soc.common.board.hexes; + +/* + * Represents a hex removed at gamestart, acting as design-time placeholder + */ +public class NoneHex extends Hex +{ + +} diff --git a/src/java/soc/common/board/hexes/RandomHex.java b/src/java/soc/common/board/hexes/RandomHex.java new file mode 100644 index 000000000..80637195e --- /dev/null +++ b/src/java/soc/common/board/hexes/RandomHex.java @@ -0,0 +1,20 @@ +package soc.common.board.hexes; + +public class RandomHex extends Hex implements ITerritoryHex +{ + private int territoryID; + + @Override + public int getTerritoryID() + { + // TODO Auto-generated method stub + return territoryID; + } + + @Override + public void setTerritoryID(int id) + { + // TODO Auto-generated method stub + territoryID = id; + } +} diff --git a/src/java/soc/common/board/hexes/ResourceHex.java b/src/java/soc/common/board/hexes/ResourceHex.java new file mode 100644 index 000000000..e85bd4b3a --- /dev/null +++ b/src/java/soc/common/board/hexes/ResourceHex.java @@ -0,0 +1,49 @@ +package soc.common.board.hexes; + +import soc.common.board.Chit; +import soc.common.board.resources.Resource; + +public class ResourceHex extends LandHex +{ + private Resource resource; + private Chit chit; + + /** + * @return the chit + */ + public Chit getChit() + { + return chit; + } + + /** + * @param chit the chit to set + */ + public void setChit(Chit chit) + { + this.chit = chit; + } + + /** + * @return the production + */ + public Resource getResource() + { + return null; + } + + /* + * At init time, we want a resource + */ + public ResourceHex(Resource resource) + { + super(); + this.resource = resource; + } + + public ResourceHex() + { + + } + +} diff --git a/src/java/soc/common/board/hexes/SeaHex.java b/src/java/soc/common/board/hexes/SeaHex.java new file mode 100644 index 000000000..0d6bc598a --- /dev/null +++ b/src/java/soc/common/board/hexes/SeaHex.java @@ -0,0 +1,27 @@ +package soc.common.board.hexes; + +import soc.common.board.ports.Port; + +public class SeaHex extends Hex +{ + private Port port = null; + + /** + * @return the port + */ + public Port getPort() + { + return port; + } + + /** + * @param port the port to set + */ + public void setPort(Port port) + { + this.port = port; + } + + + +} diff --git a/src/java/soc/common/board/hexes/VolcanoHex.java b/src/java/soc/common/board/hexes/VolcanoHex.java new file mode 100644 index 000000000..3cb072d74 --- /dev/null +++ b/src/java/soc/common/board/hexes/VolcanoHex.java @@ -0,0 +1,22 @@ +package soc.common.board.hexes; + +import soc.common.annotations.Sea3D; +import soc.common.board.resources.Gold; +import soc.common.board.resources.Resource; + +@Sea3D +public class VolcanoHex extends ResourceHex +{ + private Resource resource = new Gold(); + + /* (non-Javadoc) + * @see soc.common.board.hexes.ResourceHex#getResource() + */ + @Override + public Resource getResource() + { + // TODO Auto-generated method stub + return resource; + } + +} diff --git a/src/java/soc/common/board/pieces/City.java b/src/java/soc/common/board/pieces/City.java new file mode 100644 index 000000000..965720b80 --- /dev/null +++ b/src/java/soc/common/board/pieces/City.java @@ -0,0 +1,26 @@ +package soc.common.board.pieces; + +import soc.common.board.resources.*; + +public class City extends PlayerPiece +{ + @Override + public ResourceList getCost() + { + ResourceList result = new ResourceList(); + + result.add(new Wheat()); + result.add(new Wheat()); + result.add(new Ore()); + result.add(new Ore()); + result.add(new Ore()); + + return result; + } + + @Override + public String toString() + { + return "City"; + } +} diff --git a/src/java/soc/common/board/pieces/Piece.java b/src/java/soc/common/board/pieces/Piece.java new file mode 100644 index 000000000..04c97a079 --- /dev/null +++ b/src/java/soc/common/board/pieces/Piece.java @@ -0,0 +1,6 @@ +package soc.common.board.pieces; + +public class Piece +{ + +} diff --git a/src/java/soc/common/board/pieces/PlayerPiece.java b/src/java/soc/common/board/pieces/PlayerPiece.java new file mode 100644 index 000000000..8691f9ff1 --- /dev/null +++ b/src/java/soc/common/board/pieces/PlayerPiece.java @@ -0,0 +1,12 @@ +package soc.common.board.pieces; + +import soc.common.board.resources.ResourceList; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +public class PlayerPiece extends Piece +{ + public ResourceList getCost() + { + throw new NotImplementedException(); + } +} diff --git a/src/java/soc/common/board/pieces/Road.java b/src/java/soc/common/board/pieces/Road.java new file mode 100644 index 000000000..e4b5c12d1 --- /dev/null +++ b/src/java/soc/common/board/pieces/Road.java @@ -0,0 +1,23 @@ +package soc.common.board.pieces; + +import soc.common.board.resources.*; + +public class Road extends PlayerPiece +{ + @Override + public String toString() + { + return "Road"; + } + + @Override + public ResourceList getCost() + { + ResourceList result = new ResourceList(); + + result.add(new Timber()); + result.add(new Clay()); + + return result; + } +} diff --git a/src/java/soc/common/board/pieces/Town.java b/src/java/soc/common/board/pieces/Town.java new file mode 100644 index 000000000..d3ae549c9 --- /dev/null +++ b/src/java/soc/common/board/pieces/Town.java @@ -0,0 +1,25 @@ +package soc.common.board.pieces; + +import soc.common.board.resources.*; + +public class Town extends PlayerPiece +{ + @Override + public String toString() + { + return "Town"; + } + + @Override + public ResourceList getCost() + { + ResourceList result = new ResourceList(); + + result.add(new Timber()); + result.add(new Wheat()); + result.add(new Clay()); + result.add(new Sheep()); + + return result; + } +} diff --git a/src/java/soc/common/board/ports/FivetoTwoJunglePort.java b/src/java/soc/common/board/ports/FivetoTwoJunglePort.java new file mode 100644 index 000000000..e090d7c45 --- /dev/null +++ b/src/java/soc/common/board/ports/FivetoTwoJunglePort.java @@ -0,0 +1,10 @@ +package soc.common.board.ports; + +/* + * Imaginary 2:5 port for diamonds. + * To have fun with those (whn devstack is empty) useless diamonds + */ +public class FivetoTwoJunglePort extends Port +{ + +} diff --git a/src/java/soc/common/board/ports/Port.java b/src/java/soc/common/board/ports/Port.java new file mode 100644 index 000000000..870fdb62d --- /dev/null +++ b/src/java/soc/common/board/ports/Port.java @@ -0,0 +1,76 @@ +package soc.common.board.ports; + +import soc.common.board.HexLocation; +import soc.common.board.HexSide; +import soc.common.board.RotationPosition; +import soc.common.board.resources.ResourceList; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +public abstract class Port +{ + protected HexLocation hexLocation; + protected HexSide hexSide; + protected RotationPosition rotationPosition; + + /** + * @return the hexLocation + */ + public HexLocation getHexLocation() + { + return hexLocation; + } + + + /** + * @return the hexSide + */ + public HexSide getHexSide() + { + return hexSide; + } + + + /** + * @param hexSide the hexSide to set + */ + public void setHexSide(HexSide hexSide) + { + this.hexSide = hexSide; + } + + + /** + * @return the rotationPosition + */ + public RotationPosition getRotationPosition() + { + return rotationPosition; + } + + /** + * @param hexLocation the hexLocation to set + * @throws Exception + */ + public void setHexLocation(HexLocation hexLocation) throws Exception + { + hexSide = hexLocation.GetSideLocation(rotationPosition); + } + + + public Port() + { + super(); + } + + public Port(HexLocation hexLocation) + { + super(); + this.hexLocation = hexLocation; + } + + + public int possibleTradesCount(ResourceList resources) + { + throw new NotImplementedException(); + } +} diff --git a/src/java/soc/common/board/ports/PortList.java b/src/java/soc/common/board/ports/PortList.java new file mode 100644 index 000000000..4b1a939a7 --- /dev/null +++ b/src/java/soc/common/board/ports/PortList.java @@ -0,0 +1,9 @@ +package soc.common.board.ports; + +import java.util.ArrayList; + + +public class PortList extends ArrayList +{ + +} diff --git a/src/java/soc/common/board/ports/RandomPort.java b/src/java/soc/common/board/ports/RandomPort.java new file mode 100644 index 000000000..149f004b6 --- /dev/null +++ b/src/java/soc/common/board/ports/RandomPort.java @@ -0,0 +1,9 @@ +package soc.common.board.ports; + +/* + * Placeholder for replacement of random ports at board preperation + */ +public class RandomPort extends Port +{ + +} diff --git a/src/java/soc/common/board/ports/ThreeToOnePort.java b/src/java/soc/common/board/ports/ThreeToOnePort.java new file mode 100644 index 000000000..e16a58449 --- /dev/null +++ b/src/java/soc/common/board/ports/ThreeToOnePort.java @@ -0,0 +1,35 @@ +package soc.common.board.ports; + +import java.util.ArrayList; +import java.util.List; + +import soc.common.board.resources.*; +import soc.common.board.resources.ResourceList; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +public class ThreeToOnePort extends Port +{ + private List tradeTypes = new ArrayList(); + + public ThreeToOnePort() + { + super(); + tradeTypes.add(new Timber()); + tradeTypes.add(new Wheat()); + tradeTypes.add(new Ore()); + tradeTypes.add(new Clay()); + tradeTypes.add(new Sheep()); + } + + @Override + public int possibleTradesCount(ResourceList resources) + { + int possibleTrades=0; + for (Resource resource : tradeTypes) + { + List resourcesOfType = resources.ofType(resource); + possibleTrades += resourcesOfType.size() / 3; + } + return possibleTrades; + } +} diff --git a/src/java/soc/common/board/ports/TwoToOneResourcePort.java b/src/java/soc/common/board/ports/TwoToOneResourcePort.java new file mode 100644 index 000000000..46fcc4d3c --- /dev/null +++ b/src/java/soc/common/board/ports/TwoToOneResourcePort.java @@ -0,0 +1,6 @@ +package soc.common.board.ports; + +public class TwoToOneResourcePort +{ + +} diff --git a/src/java/soc/common/board/resources/Clay.java b/src/java/soc/common/board/resources/Clay.java new file mode 100644 index 000000000..ca97341e8 --- /dev/null +++ b/src/java/soc/common/board/resources/Clay.java @@ -0,0 +1,8 @@ +package soc.common.board.resources; + +public class Clay extends Resource +{ + + + +} diff --git a/src/java/soc/common/board/resources/Diamond.java b/src/java/soc/common/board/resources/Diamond.java new file mode 100644 index 000000000..b8fe9ee14 --- /dev/null +++ b/src/java/soc/common/board/resources/Diamond.java @@ -0,0 +1,9 @@ +package soc.common.board.resources; + +import soc.common.annotations.Sea3D; + +@Sea3D +public class Diamond extends Resource +{ + +} diff --git a/src/java/soc/common/board/resources/Gold.java b/src/java/soc/common/board/resources/Gold.java new file mode 100644 index 000000000..e703bcd82 --- /dev/null +++ b/src/java/soc/common/board/resources/Gold.java @@ -0,0 +1,9 @@ +package soc.common.board.resources; + +import soc.common.annotations.SeaFarers; + +@SeaFarers +public class Gold extends Resource +{ + +} diff --git a/src/java/soc/common/board/resources/Ore.java b/src/java/soc/common/board/resources/Ore.java new file mode 100644 index 000000000..8de69db7d --- /dev/null +++ b/src/java/soc/common/board/resources/Ore.java @@ -0,0 +1,6 @@ +package soc.common.board.resources; + +public class Ore extends Resource +{ + +} diff --git a/src/java/soc/common/board/resources/Resource.java b/src/java/soc/common/board/resources/Resource.java new file mode 100644 index 000000000..4f5e4874f --- /dev/null +++ b/src/java/soc/common/board/resources/Resource.java @@ -0,0 +1,23 @@ +package soc.common.board.resources; + +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +/* + * Enum design pattern for the resource types. + * Each enum member is actually implmented as a class definition + */ +public class Resource +{ + public String name; + + @Override + public String toString() + { + return "Resource [name=" + name + "]"; + } + + public Resource copy() throws CloneNotSupportedException + { + return (Resource)super.clone(); + } +} diff --git a/src/java/soc/common/board/resources/ResourceList.java b/src/java/soc/common/board/resources/ResourceList.java new file mode 100644 index 000000000..0c02fc958 --- /dev/null +++ b/src/java/soc/common/board/resources/ResourceList.java @@ -0,0 +1,103 @@ +package soc.common.board.resources; + +import java.util.ArrayList; +import java.util.List; + +import soc.common.board.hexes.Hex; +import soc.common.board.pieces.*; + +public class ResourceList extends ArrayList +{ + public static ResourceList createList(Piece piece) + { + ResourceList result = new ResourceList(); + + if (piece instanceof Town) + { + result.add(new Timber()); + result.add(new Wheat()); + result.add(new Clay()); + result.add(new Sheep()); + + return result; + } + if (piece instanceof City) + { + result.add(new Wheat()); + result.add(new Wheat()); + result.add(new Ore()); + result.add(new Ore()); + result.add(new Ore()); + + return result; + } + if (piece instanceof Road) + { + result.add(new Timber()); + result.add(new Clay()); + } + + return null; + } + + private int countOfType(Resource type) + { + int result = 0; + for (Resource res : this) + { + if (res.getClass() == type.getClass()) + { + result++; + } + } + return result; + } + + public List ofType(Resource type) + { + List result = new ArrayList(); + + for (Resource res : this) + { + if (res.getClass() == type.getClass()) + { + result.add(res); + } + } + + return result; + } + + /* + * Returns true if given resources are available in this ResourceList + */ + public boolean hasAtLeast(ResourceList toHave) + { + return + ofType(new Timber()).size() >= toHave.ofType(new Timber()).size() && + ofType(new Wheat()).size() >= toHave.ofType(new Wheat()).size() && + ofType(new Ore()).size() >= toHave.ofType(new Ore()).size() && + ofType(new Clay()).size() >= toHave.ofType(new Clay()).size() && + ofType(new Sheep()).size() >= toHave.ofType(new Sheep()).size(); + } + + public void swapResourcesFrom(ResourceList resourcesToAdd, ResourceList from) + { + // add the resources to this list... + this.addAll(resourcesToAdd); + + // ...and remove them at the "from source" + from.removeAll(resourcesToAdd); + } + + /* + * Returns amount of items halfed and rounded down + */ + public int halfCount() + { + int count = size(); + // Make number even + if (count % 2 == 1) count--; + return count / 2; + } +} diff --git a/src/java/soc/common/board/resources/Sheep.java b/src/java/soc/common/board/resources/Sheep.java new file mode 100644 index 000000000..6d7fdc435 --- /dev/null +++ b/src/java/soc/common/board/resources/Sheep.java @@ -0,0 +1,6 @@ +package soc.common.board.resources; + +public class Sheep extends Resource +{ + +} diff --git a/src/java/soc/common/board/resources/Timber.java b/src/java/soc/common/board/resources/Timber.java new file mode 100644 index 000000000..0f6905353 --- /dev/null +++ b/src/java/soc/common/board/resources/Timber.java @@ -0,0 +1,6 @@ +package soc.common.board.resources; + +public class Timber extends Resource +{ + +} diff --git a/src/java/soc/common/board/resources/Wheat.java b/src/java/soc/common/board/resources/Wheat.java new file mode 100644 index 000000000..86c9d2ff5 --- /dev/null +++ b/src/java/soc/common/board/resources/Wheat.java @@ -0,0 +1,6 @@ +package soc.common.board.resources; + +public class Wheat extends Resource +{ + +} diff --git a/src/java/soc/common/game/ActionsQueue.java b/src/java/soc/common/game/ActionsQueue.java new file mode 100644 index 000000000..03a4ba396 --- /dev/null +++ b/src/java/soc/common/game/ActionsQueue.java @@ -0,0 +1,27 @@ +package soc.common.game; + +import java.util.ArrayList; + +import soc.common.actions.gameAction.GameAction; + +/* + * A list of queued actions. This aids the user in what to expect from them, they + * can actually see a list of things they must do. + */ +public class ActionsQueue extends ArrayList implements IActionsQueue +{ + @Override + public void enqueue(GameAction inGameAction) + { + // TODO Auto-generated method stub + } + + @Override + public GameAction peek() + { + // TODO Auto-generated method stub + return null; + } + + +} diff --git a/src/java/soc/common/game/Game.java b/src/java/soc/common/game/Game.java new file mode 100644 index 000000000..a9bbe9e73 --- /dev/null +++ b/src/java/soc/common/game/Game.java @@ -0,0 +1,217 @@ +package soc.common.game; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import soc.common.board.Board; +import soc.common.board.HexLocation; +import soc.common.board.resources.ResourceList; +import soc.common.game.gamePhase.GamePhase; +import soc.common.game.gamePhase.LobbyGamePhase; +import soc.common.game.rules.Pioneers; +import soc.common.game.rules.RuleSet; +import soc.common.game.rules.Sea3D; + +public class Game +{ + private RuleSet ruleSet; + private LinkedList gamePhases = new LinkedList(); + private IActionsQueue actionsQueue = new ActionsQueue(); + private ResourceList bank = new ResourceList(); + private List players = new ArrayList(); + private GameLog gameLog = new GameLog(); + private HexLocation pirate = new HexLocation(0,0); + private GamePhase currentPhase = new LobbyGamePhase(); + private GameSettings gameSettings = new GameSettings(); + private Player playerOnTurn; + private Board board; + private Player gameStarter; + + /** + * @return the gameStarter + */ + public Player getGameStarter() + { + return gameStarter; + } + /** + * @param gameStarter the gameStarter to set + */ + public Game setGameStarter(Player gameStarter) + { + this.gameStarter = gameStarter; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + /** + * @return the board + */ + public Board getBoard() + { + return board; + } + /** + * @param board the board to set + */ + public Game setBoard(Board board) + { + this.board = board; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + public Player getPlayerByID(int id) + { + for (Player p : players) + { + if (p.getId() == id) + return p; + } + throw new RuntimeException( + "Trying to get non-existing player. ID " + id + " is unknown"); + } + /** + * @return the playerOnTurn + */ + public Player getPlayerOnTurn() + { + if (playerOnTurn == null) + { + playerOnTurn = players.get(0); + } + return playerOnTurn; + } + + /** + * @param playerOnTurn the playerOnTurn to set + */ + public Game setPlayerOnTurn(Player playerOnTurn) + { + playerOnTurn.setOnTurn(false); + this.playerOnTurn = playerOnTurn; + playerOnTurn.setOnTurn(true); + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + + /** + * @return the gameSettings + */ + public GameSettings getGameSettings() + { + return gameSettings; + } + + /** + * @param gameSettings the gameSettings to set + */ + public void setGameSettings(GameSettings gameSettings) + { + this.gameSettings = gameSettings; + } + + Game() + { + ruleSet = new RuleSet(this); + ruleSet.setNextRuleSet(new Pioneers(this)); + + ruleSet.createBank(19); + + ruleSet.initialize(); + } + + public ResourceList getBank() + { + return bank; + } + + public void setBank(ResourceList bank) + { + this.bank = bank; + } + + public LinkedList getGamePhases() + { + return gamePhases; + } + + public void setGamePhases(LinkedList gamePhases) + { + this.gamePhases = gamePhases; + } + + public RuleSet getRuleSet() + { + return ruleSet; + } + + public void setRuleSet(RuleSet ruleSet) + { + this.ruleSet = ruleSet; + } + + public IActionsQueue getActionsQueue() + { + return actionsQueue; + } + + public void setActionsQueue(IActionsQueue actionsQueue) + { + this.actionsQueue = actionsQueue; + } + + public List getPlayers() + { + return players; + } + + public void setPlayers(List players) + { + this.players = players; + } + + public GameLog getGameLog() + { + return gameLog; + } + + public void setGameLog(GameLog gameLog) + { + this.gameLog = gameLog; + } + + public HexLocation getPirate() + { + return pirate; + } + + public void setPirate(HexLocation pirate) + { + this.pirate = pirate; + } + + public GamePhase getCurrentPhase() + { + return currentPhase; + } + + public void setCurrentPhase(GamePhase currentPhase) + { + this.currentPhase = currentPhase; + } + public Player getNextPlayer() + { + int index = players.indexOf(playerOnTurn) + 1; + if (index == players.size()) + { + index = 0; + } + return players.get(index); + } +} diff --git a/src/java/soc/common/game/GameLog.java b/src/java/soc/common/game/GameLog.java new file mode 100644 index 000000000..f9e589c14 --- /dev/null +++ b/src/java/soc/common/game/GameLog.java @@ -0,0 +1,67 @@ +package soc.common.game; + +import java.util.ArrayList; +import java.util.List; + +import soc.common.actions.gameAction.GameAction; +import soc.common.actions.gameAction.RolledSame; +import soc.common.actions.gameAction.turnActions.RollDice; + +public class GameLog extends ArrayList implements IGameLog +{ + @Override + public void addAction(GameAction inGameAction) + { + // TODO Auto-generated method stub + + } + + public List getCurrentRoundRolls(Game game) + { + List result = new ArrayList(); + + //We run the like a stack, first to examine is Last in the list + for (int i = size() -1; i > 0; i--) + { + GameAction action = this.get(i); + // we break the loop when we encountered a rolledsame action + if (action instanceof RolledSame) + break; + + // When we encounter a RollDiceAction, add it to the list + if (action instanceof RollDice) + result.add((RollDice)action); + + //We always have maximum of PlayerCount RollDiceAction + if (result.size() == game.getPlayers().size()) + break; + } + + return result; + } + + public Player firstPlayerIsDetermined(Game game, int highRoll) + { + List rolledDices = getCurrentRoundRolls(game); + + // Get a list of all highrolls + List highRolls = new ArrayList(); + for (RollDice rollDice : rolledDices) + { + if (rollDice.getDice() == highRoll) + highRolls.add(rollDice); + } + + // the player with highest dice is determined when we + // have only one result + if (highRolls.size()== 1) + { + return highRolls.get(0).getPlayer(); + } + else + { + // return false + return null; + } + } +} diff --git a/src/java/soc/common/game/GameSettings.java b/src/java/soc/common/game/GameSettings.java new file mode 100644 index 000000000..435878945 --- /dev/null +++ b/src/java/soc/common/game/GameSettings.java @@ -0,0 +1,170 @@ +package soc.common.game; + +import java.util.UUID; + +import soc.common.board.Board; +import soc.common.board.BoardSettings; + +public class GameSettings +{ + // Game boardsettings may be overridden by the user + // This implies not having a ladder game (where settings should equal + // original boardsettings) + private BoardSettings boardSettings = BoardSettings.standard(); + + /** + * @return the boardSettings + */ + public BoardSettings getBoardSettings() + { + return boardSettings; + } + /** + * @param boardSettings the boardSettings to set + */ + public void setBoardSettings(BoardSettings boardSettings) + { + this.boardSettings = boardSettings; + } + // Whether or not deserts will be replaced by jungles + private boolean replaceDesertWithJungles = false; + + // Whether or not deserts will b replaces by volcanos + private boolean replaceDesertWithVolcanos = false; + + // If selected, the build phase's second town will be a city, + // and a third road is added + private boolean tournamentStart = false; + + // Whether or not first round has sevens + private int noSevensFirstRound = 0; + + // Whether or not robbing from players with 2vp is allowed + private boolean no2VPPlayersRobbing = false; + + // Whether or not players can trade after they entered the build phase + private boolean tradingAfterBuilding = false; + + // Players do not see the chitnumbers before initial placement + // TODO:implement + private boolean showChitsAfterPlacing = false; + + private int maximumTradesPerTurn = 2; + private String mame = null; + private int host; + + private UUID boardGuid; + private boolean isLadder = true; + private Board board; + + + public boolean isReplaceDesertWithJungles() + { + return replaceDesertWithJungles; + } + public void setReplaceDesertWithJungles(boolean replaceDesertWithJungles) + { + this.replaceDesertWithJungles = replaceDesertWithJungles; + } + public boolean isReplaceDesertWithVolcanos() + { + return replaceDesertWithVolcanos; + } + public void setReplaceDesertWithVolcanos(boolean replaceDesertWithVolcanos) + { + this.replaceDesertWithVolcanos = replaceDesertWithVolcanos; + } + + public boolean isTournamentStart() + { + return tournamentStart; + } + public void setTournamentStart(boolean tournamentStart) + { + this.tournamentStart = tournamentStart; + } + public int getNoSevensFirstRound() + { + return noSevensFirstRound; + } + public void setNoSevensFirstRound(int noSevensFirstRound) + { + this.noSevensFirstRound = noSevensFirstRound; + } + public boolean isNo2VPPlayersRobbing() + { + return no2VPPlayersRobbing; + } + public void setNo2VPPlayersRobbing(boolean no2vpPlayersRobbing) + { + no2VPPlayersRobbing = no2vpPlayersRobbing; + } + public boolean isTradingAfterBuilding() + { + return tradingAfterBuilding; + } + public void setTradingAfterBuilding(boolean tradingAfterBuilding) + { + this.tradingAfterBuilding = tradingAfterBuilding; + } + public boolean isShowChitsAfterPlacing() + { + return showChitsAfterPlacing; + } + public void setShowChitsAfterPlacing(boolean showChitsAfterPlacing) + { + this.showChitsAfterPlacing = showChitsAfterPlacing; + } + + public int getMaximumTradesPerTurn() + { + return maximumTradesPerTurn; + } + public void setMaximumTradesPerTurn(int maximumTradesPerTurn) + { + this.maximumTradesPerTurn = maximumTradesPerTurn; + } + public String getMame() + { + return mame; + } + public void setMame(String mame) + { + this.mame = mame; + } + public int getHost() + { + return host; + } + + public void setHost(int host) + { + this.host = host; + } + + public UUID getBoardGuid() + { + return boardGuid; + } + public void setBoardGuid(UUID boardGuid) + { + this.boardGuid = boardGuid; + } + public boolean isLadder() + { + return isLadder; + } + public void setLadder(boolean isLadder) + { + this.isLadder = isLadder; + } + public Board getBoard() + { + return board; + } + public void setBoard(Board board) + { + this.board = board; + } + +} diff --git a/src/java/soc/common/game/IActionsQueue.java b/src/java/soc/common/game/IActionsQueue.java new file mode 100644 index 000000000..defda76e5 --- /dev/null +++ b/src/java/soc/common/game/IActionsQueue.java @@ -0,0 +1,10 @@ +package soc.common.game; + +import soc.common.actions.gameAction.GameAction; + +public interface IActionsQueue +{ + public void enqueue(GameAction inGameAction); + public GameAction peek(); + public int size(); +} diff --git a/src/java/soc/common/game/IGame.java b/src/java/soc/common/game/IGame.java new file mode 100644 index 000000000..02c5c79e9 --- /dev/null +++ b/src/java/soc/common/game/IGame.java @@ -0,0 +1,44 @@ +package soc.common.game; + +import java.util.List; + +import soc.common.board.Board; +import soc.common.board.HexLocation; +import soc.common.board.resources.ResourceList; +import soc.common.game.gamePhase.GamePhase; + +public interface IGame +{ + // List of actions during the game + public IGameLog getGameLog(); + + // List of actions expected to be performed + public IActionsQueue getActionsQueue(); + + // List of players in the game + public List getPlayers(); + + // The pirate is no more then a location on a hex + public HexLocation getPirate(); + + // Bank, list of available resources + public ResourceList getBank(); + + // List of users watching the game + public List getSpectators(); + + // Current player on turn + public Player getPlayerOnTurn(); + + // Player which turn it is next turn + public Player getNextPlayerOnTurn(); + + // Get the player object instance from an id + public Player getPlayer(int playerID); + + // Phase where the game is in + public GamePhase getGamePhase(); + + // Board with hextiles on it + public Board getBoard(); +} diff --git a/src/java/soc/common/game/IGameLog.java b/src/java/soc/common/game/IGameLog.java new file mode 100644 index 000000000..cce2c9d53 --- /dev/null +++ b/src/java/soc/common/game/IGameLog.java @@ -0,0 +1,9 @@ +package soc.common.game; + +import soc.common.actions.gameAction.GameAction; + +public interface IGameLog +{ + public void addAction(GameAction inGameAction); + +} diff --git a/src/java/soc/common/game/IResourceList.java b/src/java/soc/common/game/IResourceList.java new file mode 100644 index 000000000..2ed63d06d --- /dev/null +++ b/src/java/soc/common/game/IResourceList.java @@ -0,0 +1,6 @@ +package soc.common.game; + +public interface IResourceList +{ + +} diff --git a/src/java/soc/common/game/Player.java b/src/java/soc/common/game/Player.java new file mode 100644 index 000000000..1f9701957 --- /dev/null +++ b/src/java/soc/common/game/Player.java @@ -0,0 +1,95 @@ +package soc.common.game; + +import soc.common.board.resources.ResourceList; + +public class Player extends User +{ + private ResourceList resources; + private int maximumCardsInHandWhenSeven; + private int stockRoads = 15; + private int stockShips = 15; + private int stockTowns = 5; + private int stockCities = 4; + private boolean isOnTurn=false; + + /** + * @return the isOnTurn + */ + public boolean isOnTurn() + { + return isOnTurn; + } + + /** + * @param isOnTurn the isOnTurn to set + */ + public Player setOnTurn(boolean isOnTurn) + { + this.isOnTurn = isOnTurn; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + + public int getStockRoads() + { + return stockRoads; + } + + public void setStockRoads(int stockRoads) + { + this.stockRoads = stockRoads; + } + + public int getStockShips() + { + return stockShips; + } + + public void setStockShips(int stockShips) + { + this.stockShips = stockShips; + } + + public int getStockTowns() + { + return stockTowns; + } + + public void setStockTowns(int stockTowns) + { + this.stockTowns = stockTowns; + } + + public int getStockCities() + { + return stockCities; + } + + public void setStockCities(int stockCities) + { + this.stockCities = stockCities; + } + + public int getMaximumCardsInHandWhenSeven() + { + return maximumCardsInHandWhenSeven; + } + + public void setMaximumCardsInHandWhenSeven(int maximumCardsInHandWhenSeven) + { + this.maximumCardsInHandWhenSeven = maximumCardsInHandWhenSeven; + } + + public ResourceList getResources() + { + return resources; + } + + public void setResources(ResourceList resources) + { + this.resources = resources; + } + +} diff --git a/src/java/soc/common/game/User.java b/src/java/soc/common/game/User.java new file mode 100644 index 000000000..f1cfaa3fa --- /dev/null +++ b/src/java/soc/common/game/User.java @@ -0,0 +1,43 @@ +package soc.common.game; + +public class User +{ + private int id; + private String name; + /** + * @return the id + */ + public int getId() + { + return id; + } + /** + * @param id the id to set + */ + public User setId(int id) + { + this.id = id; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } + /** + * @return the name + */ + public String getName() + { + return name; + } + /** + * @param name the name to set + */ + public User setName(String name) + { + this.name = name; + + // Enables fluent interface usage + // http://en.wikipedia.org/wiki/Fluent_interface + return this; + } +} diff --git a/src/java/soc/common/game/developmentCards/DevelopmentCard.java b/src/java/soc/common/game/developmentCards/DevelopmentCard.java new file mode 100644 index 000000000..354225871 --- /dev/null +++ b/src/java/soc/common/game/developmentCards/DevelopmentCard.java @@ -0,0 +1,83 @@ +package soc.common.game.developmentCards; + +import soc.common.game.Game; +import soc.common.game.Player; +import soc.common.game.gamePhase.GamePhase; +import soc.common.game.gamePhase.turnPhase.TurnPhase; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +public class DevelopmentCard +{ + protected String invalidMessage; + protected String message; + protected int _turnBought = 0; + private int id = 0; + private boolean isPlayable = false; + + public void play(Game game, Player player) + { + isPlayable = false; + } + + public boolean isValid(Game game) + { + return true; + } + + /* + * Returns true if player is allowed to play this card in given TurnPhase + */ + public boolean isAllowed(TurnPhase turnPhase) + { + throw new NotImplementedException(); + } + + /* + * Returns true if player is allowed to play this card in given GamePhase + */ + public boolean isAllowed(GamePhase turnPhase) + { + throw new NotImplementedException(); + } + + public String getInvalidMessage() + { + return invalidMessage; + } + public void setInvalidMessage(String invalidMessage) + { + this.invalidMessage = invalidMessage; + } + public String getMessage() + { + return message; + } + public void setMessage(String message) + { + this.message = message; + } + public int get_turnBought() + { + return _turnBought; + } + public void set_turnBought(int turnBought) + { + _turnBought = turnBought; + } + public int getId() + { + return id; + } + public void setId(int id) + { + this.id = id; + } + public boolean isPlayable() + { + return isPlayable; + } + public void setPlayable(boolean isPlayable) + { + this.isPlayable = isPlayable; + } +} diff --git a/src/java/soc/common/game/developmentCards/DevelopmentCardList.java b/src/java/soc/common/game/developmentCards/DevelopmentCardList.java new file mode 100644 index 000000000..29ba49888 --- /dev/null +++ b/src/java/soc/common/game/developmentCards/DevelopmentCardList.java @@ -0,0 +1,52 @@ +package soc.common.game.developmentCards; + +import java.util.ArrayList; + + + +public class DevelopmentCardList extends ArrayList +{ + public static DevelopmentCardList standard() + { + DevelopmentCardList result = new DevelopmentCardList(); + + for (int i=0; i<14; i++) + result.add(new Soldier()); + + for (int i=0; i<5; i++) + result.add(new VictoryPoint()); + + for (int i=0; i<2; i++) + result.add(new RoadBuilding()); + + for (int i=0; i<2; i++) + result.add(new Monopoly()); + + for (int i=0; i<2; i++) + result.add(new YearOfPlenty()); + + return result; + } + + public static DevelopmentCardList extended() + { + DevelopmentCardList result = new DevelopmentCardList(); + + for (int i=0; i<19; i++) + result.add(new Soldier()); + + for (int i=0; i<5; i++) + result.add(new VictoryPoint()); + + for (int i=0; i<3; i++) + result.add(new RoadBuilding()); + + for (int i=0; i<3; i++) + result.add(new Monopoly()); + + for (int i=0; i<3; i++) + result.add(new YearOfPlenty()); + + return result; + } +} diff --git a/src/java/soc/common/game/developmentCards/Monopoly.java b/src/java/soc/common/game/developmentCards/Monopoly.java new file mode 100644 index 000000000..cca824242 --- /dev/null +++ b/src/java/soc/common/game/developmentCards/Monopoly.java @@ -0,0 +1,6 @@ +package soc.common.game.developmentCards; + +public class Monopoly extends DevelopmentCard +{ + +} diff --git a/src/java/soc/common/game/developmentCards/RoadBuilding.java b/src/java/soc/common/game/developmentCards/RoadBuilding.java new file mode 100644 index 000000000..2d8456bfe --- /dev/null +++ b/src/java/soc/common/game/developmentCards/RoadBuilding.java @@ -0,0 +1,6 @@ +package soc.common.game.developmentCards; + +public class RoadBuilding extends DevelopmentCard +{ + +} diff --git a/src/java/soc/common/game/developmentCards/Soldier.java b/src/java/soc/common/game/developmentCards/Soldier.java new file mode 100644 index 000000000..91f044d28 --- /dev/null +++ b/src/java/soc/common/game/developmentCards/Soldier.java @@ -0,0 +1,8 @@ +package soc.common.game.developmentCards; + +import java.util.Random; + +public class Soldier extends DevelopmentCard +{ + +} diff --git a/src/java/soc/common/game/developmentCards/VictoryPoint.java b/src/java/soc/common/game/developmentCards/VictoryPoint.java new file mode 100644 index 000000000..8584642f0 --- /dev/null +++ b/src/java/soc/common/game/developmentCards/VictoryPoint.java @@ -0,0 +1,6 @@ +package soc.common.game.developmentCards; + +public class VictoryPoint extends DevelopmentCard +{ + +} diff --git a/src/java/soc/common/game/developmentCards/YearOfPlenty.java b/src/java/soc/common/game/developmentCards/YearOfPlenty.java new file mode 100644 index 000000000..9b707215a --- /dev/null +++ b/src/java/soc/common/game/developmentCards/YearOfPlenty.java @@ -0,0 +1,38 @@ +package soc.common.game.developmentCards; + +import soc.common.board.resources.ResourceList; +import soc.common.game.Game; +import soc.common.game.Player; + +public class YearOfPlenty extends DevelopmentCard +{ + //actual picked resources by player + private ResourceList goldPick = new ResourceList(); + + @Override + public void play(Game game, Player player) + { + message = String.format("%s gained %s by playing a Year of Plenty card", + player.getName(), goldPick.toString()); + + // give player the resources + player.getResources().swapResourcesFrom(goldPick, game.getBank()); + + super.play(game, player); + } + + @Override + public boolean isValid(Game game) + { + if (!super.isValid(game)) + return false; + + if (goldPick == null) + return false; + + if (goldPick.size() != 2) + return false; + + return true; + } +} diff --git a/src/java/soc/common/game/gamePhase/DetermineFirstPlayerGamePhase.java b/src/java/soc/common/game/gamePhase/DetermineFirstPlayerGamePhase.java new file mode 100644 index 000000000..1a7b6d3b5 --- /dev/null +++ b/src/java/soc/common/game/gamePhase/DetermineFirstPlayerGamePhase.java @@ -0,0 +1,150 @@ +package soc.common.game.gamePhase; + +import java.util.ArrayList; +import java.util.List; + +import soc.common.actions.gameAction.GameAction; +import soc.common.actions.gameAction.RolledSame; +import soc.common.actions.gameAction.StartingPlayerDetermined; +import soc.common.actions.gameAction.turnActions.RollDice; +import soc.common.board.Territory; +import soc.common.board.ports.Port; +import soc.common.game.Game; +import soc.common.game.Player; + +public class DetermineFirstPlayerGamePhase extends GamePhase +{ + @Override + public void start(Game game) + { + // expect each player to roll at least once (first phase: everyone rolls once) + for (Player p : game.getPlayers()) + { + game.getActionsQueue().enqueue + ( + new RollDice() + .setPlayer(p) + ); + } + } + + private int getHighRoll(List rolledDices) + { + int result = 2; + + for (RollDice rollDice : rolledDices) + { + if (rollDice.getDice() > result) + result = rollDice.getDice(); + } + + return result; + } + + @Override + public void performAction(GameAction action, Game game) + { + action.perform(game); + + if (action instanceof RollDice) + { + RollDice rollDice = (RollDice)action; + // Check if a phase has ended. If the queue is empty, every player has rolled the dice. + if (game.getActionsQueue().size() == 0) + { + // Make a list of rolls in this round + List rolledDices = game.getGameLog().getCurrentRoundRolls(game); + + // highroll dice number + int highRoll = getHighRoll(rolledDices); + + // When starting player is not determined yet, repeat dice roll between winners until + // winner is determined + Player gameStarter = game.getGameLog().firstPlayerIsDetermined(game, highRoll); + if (gameStarter !=null) + { + // We have a starting player + game.getActionsQueue().enqueue + ( + new StartingPlayerDetermined() + // winning dice + .setDiceRoll(highRoll) + // The starter of the placement/portplacement/turnactionsgamephase + .setPlayer(gameStarter) + // Server will send this message + .setSender(0) + ); + return; + } + else + { + // Starting player is not determined. Notify players and update Game object + game.getActionsQueue().enqueue + ( + new RolledSame() + // Pass on the highest diceroll + .setHighRoll(highRoll) + // Server says dice rolled the same + .setSender(0) + ); + + // Enqueue each highroller + for (RollDice sameRoll : rolledDices) + { + if (sameRoll.getDice() == highRoll) + { + game.getActionsQueue().enqueue + ( + new RollDice() + .setPlayer(sameRoll.getPlayer()) + ); + } + } + + // First player is on turn + game.setPlayerOnTurn(game.getActionsQueue().peek().getPlayer()); + return; + } + } + + // Next player should be the player next on the queue + /* TODO: port to java + game.setPlayerOnTurn = game.GetPlayer(game.ActionsQueue + .OfType() + .First() + .Sender); + */ + + } + } + + /* (non-Javadoc) + * @see soc.common.game.gamePhase.GamePhase#next(soc.common.game.Game) + */ + @Override + public GamePhase next(Game game) + { + // Determine if we should skip placing ports + // randomports are assigned at start using the port lists on each territory. + // The remaining ports are placed in the placement phase + List allPorts = new ArrayList(); + for (Territory t : game.getBoard().getTerritories()) + { + for (Port p : t.getPorts()) + { + allPorts.add(p); + } + } + if (allPorts.size() == 0) + { + // We do not have any ports to set, skip to placement phase + return new InitialPlacementGamePhase(); + } + else + { + // players should place ports + return new InitialPlacementGamePhase(); + } + } + +} diff --git a/src/java/soc/common/game/gamePhase/EndedGamePhase.java b/src/java/soc/common/game/gamePhase/EndedGamePhase.java new file mode 100644 index 000000000..0838ee65a --- /dev/null +++ b/src/java/soc/common/game/gamePhase/EndedGamePhase.java @@ -0,0 +1,7 @@ +package soc.common.game.gamePhase; + + +public class EndedGamePhase extends GamePhase +{ + +} diff --git a/src/java/soc/common/game/gamePhase/GamePhase.java b/src/java/soc/common/game/gamePhase/GamePhase.java new file mode 100644 index 000000000..aeb19ac1a --- /dev/null +++ b/src/java/soc/common/game/gamePhase/GamePhase.java @@ -0,0 +1,16 @@ +package soc.common.game.gamePhase; + +import soc.common.actions.gameAction.GameAction; +import soc.common.game.Game; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +/* + * Represent a phase in the overall game phases + * A GamePhase ends itself by adding an EndedGamePhase action onto the actionsQueue. + */ +public abstract class GamePhase +{ + public void performAction(GameAction action, Game game) {}; + public void start(Game game) {}; + public GamePhase next(Game game) { throw new NotImplementedException(); } +} diff --git a/src/java/soc/common/game/gamePhase/InitialPlacementGamePhase.java b/src/java/soc/common/game/gamePhase/InitialPlacementGamePhase.java new file mode 100644 index 000000000..625971169 --- /dev/null +++ b/src/java/soc/common/game/gamePhase/InitialPlacementGamePhase.java @@ -0,0 +1,127 @@ +package soc.common.game.gamePhase; + +import soc.common.actions.gameAction.GameAction; +import soc.common.actions.gameAction.GamePhaseHasEnded; +import soc.common.actions.gameAction.turnActions.BuildCity; +import soc.common.actions.gameAction.turnActions.BuildRoad; +import soc.common.actions.gameAction.turnActions.BuildShip; +import soc.common.actions.gameAction.turnActions.BuildTown; +import soc.common.game.Game; + +public class InitialPlacementGamePhase extends GamePhase +{ + + @Override + public void start(Game game) + { + // Expect each player to place town/road - town/road + int i = 0; + boolean back = false; + + // A loop going backward. Each index should be hit twice. + // Example with 4 players: p1 - p2 - p3 - p4 - p4 - p3 - p2 - p1 + while (i > -1) + { + // If tournament starting rules are set, second building should be a city + if (back && game.getGameSettings().isTournamentStart()) + { + // Tournament starting rules, add a city + game.getActionsQueue().enqueue + ( + new BuildCity() + .setPlayer(game.getPlayers().get(i)) + ); + + } + else + { + // Normal starting rules, add two towns + game.getActionsQueue().enqueue + ( + new BuildTown() + .setPlayer(game.getPlayers().get(i)) + ); + } + + // This action actually might be a BuildShipAction too. + // TODO: implement this somewhere + game.getActionsQueue().enqueue + ( + new BuildRoad() + .setPlayer(game.getPlayers().get(i)) + ); + + // if the "back" flag is set, we should decrease the counter + if (back) + { + i--; + } + else + { + i++; + } + + // flip the flag when counter reaches maximum value + // (maximum value equals amount of players) + if (i == game.getPlayers().size()) + { + // next loop is walked with same maximum value + i--; + + // switch flag + back = true; + } + } + + + // When in tournament phase, every player may build a third road + if (game.getGameSettings().isTournamentStart()) + { + for (int j = 0; j < game.getPlayers().size(); j++) + { + game.getActionsQueue().enqueue + ( + new BuildRoad() + .setPlayer(game.getPlayers().get(i)) + ); + } + } + } + + @Override + public void performAction(GameAction gameAction, Game game) + { + gameAction.perform(game); + + // If the last road or ship has been built, add new gamephase action on the queue + if (gameAction.getClass() == new BuildRoad().getClass() || + gameAction.getClass() == new BuildShip().getClass()) + { + if (game.getActionsQueue().size() == 0) + { + game.getActionsQueue().enqueue + ( + new GamePhaseHasEnded() + .setEndedGamePhase(this) + .setSender(0) + ); + } + else + { + // Next player is the player of the first action on the queue + game.setPlayerOnTurn + ( + game.getActionsQueue().peek().getPlayer() + ); + } + } + + } + + @Override + public GamePhase next(Game game) + { + return new PlayTurnsGamePhase(); + } + +} diff --git a/src/java/soc/common/game/gamePhase/LobbyGamePhase.java b/src/java/soc/common/game/gamePhase/LobbyGamePhase.java new file mode 100644 index 000000000..4ee375993 --- /dev/null +++ b/src/java/soc/common/game/gamePhase/LobbyGamePhase.java @@ -0,0 +1,21 @@ +package soc.common.game.gamePhase; + +import soc.common.actions.gameAction.*; +import soc.common.game.Game; + +public class LobbyGamePhase extends GamePhase +{ + + public void PerformAction(GameAction action, Game game) + { + // TODO Auto-generated method stub + + } + + @Override + public void start(Game game) + { + // TODO Auto-generated method stub + + } +} diff --git a/src/java/soc/common/game/gamePhase/PlacePortsGamePhase.java b/src/java/soc/common/game/gamePhase/PlacePortsGamePhase.java new file mode 100644 index 000000000..011ae4f6e --- /dev/null +++ b/src/java/soc/common/game/gamePhase/PlacePortsGamePhase.java @@ -0,0 +1,77 @@ +package soc.common.game.gamePhase; + +import soc.common.actions.gameAction.GameAction; +import soc.common.actions.gameAction.GamePhaseHasEnded; +import soc.common.actions.gameAction.PlacePort; +import soc.common.annotations.SeaFarers; +import soc.common.board.Territory; +import soc.common.board.ports.Port; +import soc.common.game.Game; + +@SeaFarers +public class PlacePortsGamePhase extends GamePhase +{ + /* + * @see soc.common.game.gamePhase.GamePhase#performAction(soc.common.actions.gameAction.GameAction, soc.common.game.Game) + */ + @Override + public void performAction(GameAction action, Game game) + { + action.perform(game); + + if (game.getActionsQueue().size() == 0) + { + // Notify we want to start the placement phase + game.getActionsQueue().enqueue + ( + new GamePhaseHasEnded() + .setSender(0) + ); + } + else + { + // Move to the next player + game.setPlayerOnTurn(game.getNextPlayer()); + } + } + + @Override + public void start(Game game) + { + int portCount = 0; + + for (Territory t : game.getBoard().getTerritories()) + { + for (@SuppressWarnings("unused") + Port port : t.getPorts()) + { + game.getActionsQueue().enqueue + ( + new PlacePort() + // Placing ports goes chronologically starting with the winner. + // The first player always has the advantage: + // - For example with 5 ports and 4 players, first player may place twice + // while the rest only once. + // - First player may place first, conveniently placing port alongside + // - Since port stack is open, first player placing last port is 100% certain + // known port + .setTerritoryID(t.getID()) + .setPlayer(game.getPlayers().get(portCount % game.getPlayers().size())) + // pass territoryID such that player knows to expect possible port locations + ); + + portCount++; + } + } + } + + /* + * @see soc.common.game.gamePhase.GamePhase#next(soc.common.game.Game) + */ + @Override + public GamePhase next(Game game) + { + // TODO Auto-generated method stub + return new InitialPlacementGamePhase(); + } +} diff --git a/src/java/soc/common/game/gamePhase/PlayTurnsGamePhase.java b/src/java/soc/common/game/gamePhase/PlayTurnsGamePhase.java new file mode 100644 index 000000000..3666c89bb --- /dev/null +++ b/src/java/soc/common/game/gamePhase/PlayTurnsGamePhase.java @@ -0,0 +1,6 @@ +package soc.common.game.gamePhase; + +public class PlayTurnsGamePhase extends GamePhase +{ + +} diff --git a/src/java/soc/common/game/gamePhase/turnPhase/BeforeDiceRollTurnPhase.java b/src/java/soc/common/game/gamePhase/turnPhase/BeforeDiceRollTurnPhase.java new file mode 100644 index 000000000..e5a2a5ae5 --- /dev/null +++ b/src/java/soc/common/game/gamePhase/turnPhase/BeforeDiceRollTurnPhase.java @@ -0,0 +1,6 @@ +package soc.common.game.gamePhase.turnPhase; + +public class BeforeDiceRollTurnPhase extends TurnPhase +{ + +} diff --git a/src/java/soc/common/game/gamePhase/turnPhase/BuildingTurnPhase.java b/src/java/soc/common/game/gamePhase/turnPhase/BuildingTurnPhase.java new file mode 100644 index 000000000..cb2ce719b --- /dev/null +++ b/src/java/soc/common/game/gamePhase/turnPhase/BuildingTurnPhase.java @@ -0,0 +1,6 @@ +package soc.common.game.gamePhase.turnPhase; + +public class BuildingTurnPhase extends TurnPhase +{ + +} diff --git a/src/java/soc/common/game/gamePhase/turnPhase/RollDiceTurnPhase.java b/src/java/soc/common/game/gamePhase/turnPhase/RollDiceTurnPhase.java new file mode 100644 index 000000000..1da4887fc --- /dev/null +++ b/src/java/soc/common/game/gamePhase/turnPhase/RollDiceTurnPhase.java @@ -0,0 +1,6 @@ +package soc.common.game.gamePhase.turnPhase; + +public class RollDiceTurnPhase extends TurnPhase +{ + +} diff --git a/src/java/soc/common/game/gamePhase/turnPhase/TradingTurnPhase.java b/src/java/soc/common/game/gamePhase/turnPhase/TradingTurnPhase.java new file mode 100644 index 000000000..9fc29183f --- /dev/null +++ b/src/java/soc/common/game/gamePhase/turnPhase/TradingTurnPhase.java @@ -0,0 +1,6 @@ +package soc.common.game.gamePhase.turnPhase; + +public class TradingTurnPhase extends TurnPhase +{ + +} diff --git a/src/java/soc/common/game/gamePhase/turnPhase/TurnPhase.java b/src/java/soc/common/game/gamePhase/turnPhase/TurnPhase.java new file mode 100644 index 000000000..bba35ef25 --- /dev/null +++ b/src/java/soc/common/game/gamePhase/turnPhase/TurnPhase.java @@ -0,0 +1,33 @@ +package soc.common.game.gamePhase.turnPhase; + +import java.util.ArrayList; +import java.util.List; + +import soc.common.actions.gameAction.GameAction; +import soc.common.game.Game; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +public abstract class TurnPhase +{ + protected List _AllowedActions = new ArrayList(); + + protected void addActions() + { + + } + + public TurnPhase next() + { + throw new NotImplementedException(); + } + + public TurnPhase processAction(GameAction action, Game game) + { + throw new NotImplementedException(); + } + + public boolean isAllowed(GameAction action, Game game) + { + throw new NotImplementedException(); + } +} diff --git a/src/java/soc/common/game/routing/Route.java b/src/java/soc/common/game/routing/Route.java new file mode 100644 index 000000000..91c120144 --- /dev/null +++ b/src/java/soc/common/game/routing/Route.java @@ -0,0 +1,6 @@ +package soc.common.game.routing; + +public class Route +{ + +} diff --git a/src/java/soc/common/game/routing/TradeRoute.java b/src/java/soc/common/game/routing/TradeRoute.java new file mode 100644 index 000000000..897da4a43 --- /dev/null +++ b/src/java/soc/common/game/routing/TradeRoute.java @@ -0,0 +1,6 @@ +package soc.common.game.routing; + +public class TradeRoute +{ + +} diff --git a/src/java/soc/common/game/rules/CitiesKnights.java b/src/java/soc/common/game/rules/CitiesKnights.java new file mode 100644 index 000000000..4fd382f13 --- /dev/null +++ b/src/java/soc/common/game/rules/CitiesKnights.java @@ -0,0 +1,20 @@ +package soc.common.game.rules; + +import soc.common.board.resources.Clay; +import soc.common.board.resources.Ore; +import soc.common.board.resources.ResourceList; +import soc.common.board.resources.Sheep; +import soc.common.board.resources.Timber; +import soc.common.board.resources.Wheat; +import soc.common.game.Game; + +public class CitiesKnights extends RuleSet +{ + + public CitiesKnights(Game game) + { + super(game); + // TODO Auto-generated constructor stub + } + +} diff --git a/src/java/soc/common/game/rules/Extended.java b/src/java/soc/common/game/rules/Extended.java new file mode 100644 index 000000000..cf5161427 --- /dev/null +++ b/src/java/soc/common/game/rules/Extended.java @@ -0,0 +1,19 @@ +package soc.common.game.rules; + +import soc.common.game.Game; + +public class Extended extends RuleSet +{ + + public Extended(Game game) + { + super(game); + // TODO Auto-generated constructor stub + } + + public void createBank(int amount) + { + // add 6 cards to each found type + } + +} diff --git a/src/java/soc/common/game/rules/Pioneers.java b/src/java/soc/common/game/rules/Pioneers.java new file mode 100644 index 000000000..79065802e --- /dev/null +++ b/src/java/soc/common/game/rules/Pioneers.java @@ -0,0 +1,33 @@ +package soc.common.game.rules; + +import soc.common.game.Game; + +/* + * A Pioneers ruleset adds two pieces: a wall and a bridge. + * - A wall can be purchased for 2 clay to increase the maximum amount of cards + * for a player by two + * - A bridge behaves exactly like a road, except that it can be built on water. + * + * Those two pieces can be built in the usual BuildingTurnPhase + */ +public class Pioneers extends RuleSet +{ + public Pioneers(Game game) + { + super(game); + // TODO Auto-generated constructor stub + } + + public void CreateBank(int amount) + { + if (nextRuleSet !=null) + { + nextRuleSet.createBank(amount); + } + } + + public void Initialize(Game game) + { + // get the BuildingTurnPhase, and add BuildWall and BuildBridge as allowed actions + } +} diff --git a/src/java/soc/common/game/rules/RuleSet.java b/src/java/soc/common/game/rules/RuleSet.java new file mode 100644 index 000000000..b8bc9c121 --- /dev/null +++ b/src/java/soc/common/game/rules/RuleSet.java @@ -0,0 +1,76 @@ +package soc.common.game.rules; + +import soc.common.board.resources.Clay; +import soc.common.board.resources.Ore; +import soc.common.board.resources.ResourceList; +import soc.common.board.resources.Sheep; +import soc.common.board.resources.Timber; +import soc.common.board.resources.Wheat; +import soc.common.game.Game; + +/* + * Basic standard settlers ruleset + */ +public class RuleSet +{ + protected RuleSet nextRuleSet; + private int bankAmount = 19; + protected Game game; + + public RuleSet(Game game) + { + this.game=game; + } + + public void createBank(int amount) + { + ResourceList result = game.getBank(); + + // Standard Settlers has 19 cards in the bank for each of 5 resources + for (int i=0; i< amount; i++) + result.add(new Timber()); + for (int i=0; i< amount; i++) + result.add(new Wheat()); + for (int i=0; i< amount; i++) + result.add(new Ore()); + for (int i=0; i< amount; i++) + result.add(new Clay()); + for (int i=0; i< amount; i++) + result.add(new Sheep()); + + // Call next ruleset to add additional stock resources to the bank + if (nextRuleSet != null) + nextRuleSet.createBank(amount); + } + + public int getBankAmount() + { + return bankAmount; + } + + public void setBankAmount(int bankAmount) + { + this.bankAmount = bankAmount; + } + + public Game getGame() + { + return game; + } + + public void setGame(Game game) + { + this.game = game; + } + + public void setNextRuleSet(RuleSet nextRuleSet) + { + this.nextRuleSet = nextRuleSet; + } + + public void initialize() + { + // TODO Auto-generated method stub + + } +} diff --git a/src/java/soc/common/game/rules/Sea3D.java b/src/java/soc/common/game/rules/Sea3D.java new file mode 100644 index 000000000..6674a6bf5 --- /dev/null +++ b/src/java/soc/common/game/rules/Sea3D.java @@ -0,0 +1,36 @@ +package soc.common.game.rules; + +import soc.common.board.resources.Diamond; +import soc.common.board.resources.ResourceList; +import soc.common.game.Game; + +public class Sea3D extends RuleSet +{ + public Sea3D(Game game) + { + super(game); + // TODO Auto-generated constructor stub + } + + @Override + public void createBank(int amount) + { + ResourceList result = game.getBank(); + + // Sea3D supports Jungle's which produce diamonds + for (int i = 0; i < amount * 2; i++) + result.add(new Diamond()); + + if (nextRuleSet != null) + nextRuleSet.createBank(amount); + } + + @Override + public void initialize() + { + if (true) // TODO: add logic to determine if a placeport phase is necessary + { + // find DetermineFirstPlayerPhase, and add PlacePortPhase after + } + } +} diff --git a/src/java/soc/common/game/rules/SeaFarers.java b/src/java/soc/common/game/rules/SeaFarers.java new file mode 100644 index 000000000..381a2c308 --- /dev/null +++ b/src/java/soc/common/game/rules/SeaFarers.java @@ -0,0 +1,16 @@ +package soc.common.game.rules; + +import soc.common.board.resources.Diamond; +import soc.common.board.resources.ResourceList; +import soc.common.game.Game; + +public class SeaFarers extends RuleSet +{ + + public SeaFarers(Game game) + { + super(game); + // TODO Auto-generated constructor stub + } + +}