diff --git a/src/main/java/inf112/fiasko/roborally/gamewrapper/screens/CardChoiceScreen.java b/src/main/java/inf112/fiasko/roborally/gamewrapper/screens/CardChoiceScreen.java index 4d11ce2..e7c9103 100644 --- a/src/main/java/inf112/fiasko/roborally/gamewrapper/screens/CardChoiceScreen.java +++ b/src/main/java/inf112/fiasko/roborally/gamewrapper/screens/CardChoiceScreen.java @@ -2,7 +2,6 @@ package inf112.fiasko.roborally.gamewrapper.screens; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; -import com.badlogic.gdx.Screen; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.GlyphLayout; import com.badlogic.gdx.graphics.g2d.TextureRegion; @@ -32,7 +31,7 @@ import static com.badlogic.gdx.graphics.Color.YELLOW; /** * This screen is used to let the user choose their program */ -public class CardChoiceScreen extends InteractiveScreen implements Screen { +public class CardChoiceScreen extends InteractiveScreen { private final RoboRallyWrapper roboRallyWrapper; private final List cardRectangles; @@ -169,13 +168,31 @@ public class CardChoiceScreen extends InteractiveScreen implements Screen { ProgrammingCard programmingCard = cardList.get(i); generateCardRectangle(i, cardWidth, cardHeight, programmingCard, true); } - List oldProgram = roboRallyWrapper.roboRallyGame.getProgram(); + //Adds locked cards to the card list + List oldProgram = getOldProgram(); for (int i = cardList.size(); i < cardList.size() + getNumberOfLockedCards(); i++) { ProgrammingCard programmingCard = oldProgram.get(4 - (i - cardList.size())); generateCardRectangle(i, cardWidth, cardHeight, programmingCard, false); } } + /** + * Gets the old program of the player with extra cards added + * + * @return The player's old program + */ + private List getOldProgram() { + List oldProgram = roboRallyWrapper.roboRallyGame.getProgram(); + if (oldProgram != null && oldProgram.size() == 0) { + oldProgram = roboRallyWrapper.roboRallyGame.getExtraCards().getCards(); + int nulls = 5 - oldProgram.size(); + for (int i = 0; i < nulls; i++) { + oldProgram.add(0, null); + } + } + return oldProgram; + } + /** * Adds a new card rectangle containing the appropriate data * @@ -316,7 +333,7 @@ public class CardChoiceScreen extends InteractiveScreen implements Screen { * @return A list of programming cards */ private List getChosenAndLockedCards() { - List oldProgram = roboRallyWrapper.roboRallyGame.getProgram(); + List oldProgram = getOldProgram(); int lockedCardsInt = getNumberOfLockedCards(); List newProgram = new ArrayList<>(getCards()); for (int i = 4; i > (4 - lockedCardsInt); i--) { @@ -325,31 +342,6 @@ public class CardChoiceScreen extends InteractiveScreen implements Screen { return newProgram; } - @Override - public void resize(int width, int height) { - viewport.update(width, height); - } - - @Override - public void pause() { - //Nothing to do - } - - @Override - public void resume() { - //Nothing to do - } - - @Override - public void hide() { - //Nothing to do - } - - @Override - public void dispose() { - stage.dispose(); - } - @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { Vector3 transformed = viewport.unproject(new Vector3(screenX, screenY, 0)); diff --git a/src/main/java/inf112/fiasko/roborally/networking/RoboRallyClientListener.java b/src/main/java/inf112/fiasko/roborally/networking/RoboRallyClientListener.java index 0ea0ea8..6b9ac68 100644 --- a/src/main/java/inf112/fiasko/roborally/networking/RoboRallyClientListener.java +++ b/src/main/java/inf112/fiasko/roborally/networking/RoboRallyClientListener.java @@ -6,11 +6,11 @@ import inf112.fiasko.roborally.elementproperties.GameState; import inf112.fiasko.roborally.gamewrapper.RoboRallyUI; import inf112.fiasko.roborally.networking.containers.ErrorResponse; import inf112.fiasko.roborally.networking.containers.GameStartInfoResponse; +import inf112.fiasko.roborally.networking.containers.HandResponse; import inf112.fiasko.roborally.networking.containers.HurryResponse; import inf112.fiasko.roborally.networking.containers.OkayResponse; import inf112.fiasko.roborally.networking.containers.PowerDownContainerResponse; import inf112.fiasko.roborally.networking.containers.ProgramsContainerResponse; -import inf112.fiasko.roborally.objects.ProgrammingCardDeck; import inf112.fiasko.roborally.objects.RoboRallyGame; import java.util.ArrayList; @@ -60,8 +60,8 @@ class RoboRallyClientListener extends Listener { handleError((ErrorResponse) object); } else if (object instanceof GameStartInfoResponse) { receiveGameStartInfo((GameStartInfoResponse) object); - } else if (object instanceof ProgrammingCardDeck) { - receiveHand((ProgrammingCardDeck) object); + } else if (object instanceof HandResponse) { + receiveHand((HandResponse) object); } else if (object instanceof ProgramsContainerResponse) { receivePrograms((ProgramsContainerResponse) object); } else if (object instanceof PowerDownContainerResponse) { @@ -102,7 +102,7 @@ class RoboRallyClientListener extends Listener { * * @param newHand The new hand this client can choose from */ - private void receiveHand(ProgrammingCardDeck newHand) { + private void receiveHand(HandResponse newHand) { new Thread(() -> { //Prevents a bug where the game while (wrapper.getGame().getGameState() != GameState.WAITING_FOR_CARDS_FROM_SERVER) { @@ -112,13 +112,14 @@ class RoboRallyClientListener extends Listener { e.printStackTrace(); } } - if (newHand.isEmpty() && wrapper.getGame().getRobotPowerDown()) { + if (newHand.getNewHand().isEmpty() && wrapper.getGame().getRobotPowerDown()) { wrapper.getGame().setProgram(new ArrayList<>()); wrapper.getGame().setGameState(GameState.SKIP_POWER_DOWN_SCREEN); } else { wrapper.getGame().setGameState(GameState.CHOOSING_CARDS); } - wrapper.getGame().setPlayerHand(newHand); + wrapper.getGame().setPlayerHand(newHand.getNewHand()); + wrapper.getGame().setExtraCards(newHand.getExtraCards()); }).start(); } diff --git a/src/main/java/inf112/fiasko/roborally/networking/containers/HandResponse.java b/src/main/java/inf112/fiasko/roborally/networking/containers/HandResponse.java new file mode 100644 index 0000000..ddda7c9 --- /dev/null +++ b/src/main/java/inf112/fiasko/roborally/networking/containers/HandResponse.java @@ -0,0 +1,46 @@ +package inf112.fiasko.roborally.networking.containers; + +import inf112.fiasko.roborally.objects.ProgrammingCardDeck; + +/** + * A response containing the client's new hand + */ +public class HandResponse { + private ProgrammingCardDeck newHand; + private ProgrammingCardDeck extraCards; + + /** + * Empty constructor required by KryoNet. DO NOT REMOVE THIS!!! + */ + public HandResponse() { + } + + /** + * Instantiates a new programming card deck response + * + * @param newHand The new hand of the client + * @param extraCards Extra cards necessary if the robot has no program to lock + */ + public HandResponse(ProgrammingCardDeck newHand, ProgrammingCardDeck extraCards) { + this.newHand = newHand; + this.extraCards = extraCards; + } + + /** + * Gets the hand contained within the response + * + * @return The client's new hand + */ + public ProgrammingCardDeck getNewHand() { + return this.newHand; + } + + /** + * Gets the extra cards contained within the response + * + * @return Extra cards necessary to lock registers + */ + public ProgrammingCardDeck getExtraCards() { + return this.extraCards; + } +} diff --git a/src/main/java/inf112/fiasko/roborally/objects/InteractableGame.java b/src/main/java/inf112/fiasko/roborally/objects/InteractableGame.java index dab9f22..d85f179 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/InteractableGame.java +++ b/src/main/java/inf112/fiasko/roborally/objects/InteractableGame.java @@ -67,6 +67,20 @@ public interface InteractableGame { */ void setPlayerHand(ProgrammingCardDeck playerHand); + /** + * Gets extra cards necessary when the player has no program to lock + * + * @return A deck of extra cards + */ + ProgrammingCardDeck getExtraCards(); + + /** + * Sets extra cards necessary when the player has no program to lock + * + * @param extraCards The extra cards to use + */ + void setExtraCards(ProgrammingCardDeck extraCards); + /** * Gets the amount of cards the player can choose for their program * diff --git a/src/main/java/inf112/fiasko/roborally/objects/RoboRallyGame.java b/src/main/java/inf112/fiasko/roborally/objects/RoboRallyGame.java index 1eb95d5..de96418 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/RoboRallyGame.java +++ b/src/main/java/inf112/fiasko/roborally/objects/RoboRallyGame.java @@ -6,6 +6,7 @@ import inf112.fiasko.roborally.elementproperties.Position; import inf112.fiasko.roborally.elementproperties.RobotID; import inf112.fiasko.roborally.elementproperties.TileType; import inf112.fiasko.roborally.networking.RoboRallyServer; +import inf112.fiasko.roborally.networking.containers.HandResponse; import inf112.fiasko.roborally.networking.containers.PowerDownContainerResponse; import inf112.fiasko.roborally.networking.containers.ProgramsContainerResponse; import inf112.fiasko.roborally.utility.BoardLoaderUtil; @@ -32,6 +33,7 @@ public class RoboRallyGame implements DrawableGame, InteractableGame { private String winningPlayerName; private List program; private ProgrammingCardDeck playerHand; + private ProgrammingCardDeck extraCards; /** * Instantiates a new Robo Rally game @@ -127,6 +129,16 @@ public class RoboRallyGame implements DrawableGame, InteractableGame { this.playerHand = playerHand; } + @Override + public ProgrammingCardDeck getExtraCards() { + return extraCards; + } + + @Override + public void setExtraCards(ProgrammingCardDeck extraCards) { + this.extraCards = extraCards; + } + @Override public List getProgram() { return program; @@ -277,7 +289,9 @@ public class RoboRallyGame implements DrawableGame, InteractableGame { String playerName = server.getPlayerNames().get(connection); Player player = getPlayerFromName(playerName); if (player != null && player.getProgrammingCardDeck() != null) { - server.sendToClient(connection, player.getProgrammingCardDeck()); + ProgrammingCardDeck extraCards = getExtraCardsDeck(player); + server.sendToClient(connection, new HandResponse(player.getProgrammingCardDeck(), extraCards)); + extraCards.emptyInto(player.getLockedProgrammingCardDeck()); } else { throw new IllegalArgumentException("Player " + playerName + " is not part of the game."); } @@ -285,6 +299,28 @@ public class RoboRallyGame implements DrawableGame, InteractableGame { } } + /** + * Gets a deck of extra cards to send to the player + * + *

These extra cards are cards which are locked, but not part of the player's program,

+ * + * @param player The player to get extra cards for + * @return The extra cards to send the player + */ + private ProgrammingCardDeck getExtraCardsDeck(Player player) { + //A player with an empty program and a robot not in power down may need extra cards + if (player.getProgram() == null || !player.getProgram().isEmpty() || gameBoard.getPowerDown(player.getRobotID())) { + return new ProgrammingCardDeck(new ArrayList<>()); + } + int programSize = Math.min(5, 5 - gameBoard.getRobotDamage(player.getRobotID()) + 4); + int lockedCards = 5 - programSize; + ProgrammingCardDeck extraDeck = new ProgrammingCardDeck(); + for (int i = 0; i < lockedCards; i++) { + extraDeck.draw(mainDeck); + } + return extraDeck; + } + /** * Sends information about players no longer part of the game to the server */ diff --git a/src/main/java/inf112/fiasko/roborally/utility/NetworkUtil.java b/src/main/java/inf112/fiasko/roborally/utility/NetworkUtil.java index ceb09d9..3941507 100644 --- a/src/main/java/inf112/fiasko/roborally/utility/NetworkUtil.java +++ b/src/main/java/inf112/fiasko/roborally/utility/NetworkUtil.java @@ -5,6 +5,7 @@ import inf112.fiasko.roborally.elementproperties.Action; import inf112.fiasko.roborally.elementproperties.RobotID; import inf112.fiasko.roborally.networking.containers.ErrorResponse; import inf112.fiasko.roborally.networking.containers.GameStartInfoResponse; +import inf112.fiasko.roborally.networking.containers.HandResponse; import inf112.fiasko.roborally.networking.containers.HurryResponse; import inf112.fiasko.roborally.networking.containers.OkayResponse; import inf112.fiasko.roborally.networking.containers.PowerDownContainerResponse; @@ -46,5 +47,6 @@ public final class NetworkUtil { kryo.register(UsernameRequest.class); kryo.register(OkayResponse.class); kryo.register(HurryResponse.class); + kryo.register(HandResponse.class); } } diff --git a/src/test/java/inf112/fiasko/roborally/objects/FakeGame.java b/src/test/java/inf112/fiasko/roborally/objects/FakeGame.java index fcf6f7b..86af7bc 100644 --- a/src/test/java/inf112/fiasko/roborally/objects/FakeGame.java +++ b/src/test/java/inf112/fiasko/roborally/objects/FakeGame.java @@ -52,6 +52,16 @@ public class FakeGame implements InteractableGame { //Not needed for testing } + @Override + public ProgrammingCardDeck getExtraCards() { + return null; + } + + @Override + public void setExtraCards(ProgrammingCardDeck extraCards) { + //Not needed for testing + } + @Override public int getProgramSize() { return 0;