Gir en spiller ekstra kort når den har et tomt program, ikke er i power down og har låste kort. Closes #85

This commit is contained in:
Kristian Knarvik 2020-05-01 19:44:01 +02:00
parent 60da3f679c
commit 1060fb70b6
7 changed files with 137 additions and 36 deletions

View File

@ -2,7 +2,6 @@ package inf112.fiasko.roborally.gamewrapper.screens;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input; import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.GlyphLayout; import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.TextureRegion; 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 * 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 RoboRallyWrapper roboRallyWrapper;
private final List<CardRectangle> cardRectangles; private final List<CardRectangle> cardRectangles;
@ -169,13 +168,31 @@ public class CardChoiceScreen extends InteractiveScreen implements Screen {
ProgrammingCard programmingCard = cardList.get(i); ProgrammingCard programmingCard = cardList.get(i);
generateCardRectangle(i, cardWidth, cardHeight, programmingCard, true); generateCardRectangle(i, cardWidth, cardHeight, programmingCard, true);
} }
List<ProgrammingCard> oldProgram = roboRallyWrapper.roboRallyGame.getProgram(); //Adds locked cards to the card list
List<ProgrammingCard> oldProgram = getOldProgram();
for (int i = cardList.size(); i < cardList.size() + getNumberOfLockedCards(); i++) { for (int i = cardList.size(); i < cardList.size() + getNumberOfLockedCards(); i++) {
ProgrammingCard programmingCard = oldProgram.get(4 - (i - cardList.size())); ProgrammingCard programmingCard = oldProgram.get(4 - (i - cardList.size()));
generateCardRectangle(i, cardWidth, cardHeight, programmingCard, false); 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<ProgrammingCard> getOldProgram() {
List<ProgrammingCard> 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 * 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 * @return A list of programming cards
*/ */
private List<ProgrammingCard> getChosenAndLockedCards() { private List<ProgrammingCard> getChosenAndLockedCards() {
List<ProgrammingCard> oldProgram = roboRallyWrapper.roboRallyGame.getProgram(); List<ProgrammingCard> oldProgram = getOldProgram();
int lockedCardsInt = getNumberOfLockedCards(); int lockedCardsInt = getNumberOfLockedCards();
List<ProgrammingCard> newProgram = new ArrayList<>(getCards()); List<ProgrammingCard> newProgram = new ArrayList<>(getCards());
for (int i = 4; i > (4 - lockedCardsInt); i--) { for (int i = 4; i > (4 - lockedCardsInt); i--) {
@ -325,31 +342,6 @@ public class CardChoiceScreen extends InteractiveScreen implements Screen {
return newProgram; 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 @Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) { public boolean touchUp(int screenX, int screenY, int pointer, int button) {
Vector3 transformed = viewport.unproject(new Vector3(screenX, screenY, 0)); Vector3 transformed = viewport.unproject(new Vector3(screenX, screenY, 0));

View File

@ -6,11 +6,11 @@ import inf112.fiasko.roborally.elementproperties.GameState;
import inf112.fiasko.roborally.gamewrapper.RoboRallyUI; import inf112.fiasko.roborally.gamewrapper.RoboRallyUI;
import inf112.fiasko.roborally.networking.containers.ErrorResponse; import inf112.fiasko.roborally.networking.containers.ErrorResponse;
import inf112.fiasko.roborally.networking.containers.GameStartInfoResponse; 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.HurryResponse;
import inf112.fiasko.roborally.networking.containers.OkayResponse; import inf112.fiasko.roborally.networking.containers.OkayResponse;
import inf112.fiasko.roborally.networking.containers.PowerDownContainerResponse; import inf112.fiasko.roborally.networking.containers.PowerDownContainerResponse;
import inf112.fiasko.roborally.networking.containers.ProgramsContainerResponse; import inf112.fiasko.roborally.networking.containers.ProgramsContainerResponse;
import inf112.fiasko.roborally.objects.ProgrammingCardDeck;
import inf112.fiasko.roborally.objects.RoboRallyGame; import inf112.fiasko.roborally.objects.RoboRallyGame;
import java.util.ArrayList; import java.util.ArrayList;
@ -60,8 +60,8 @@ class RoboRallyClientListener extends Listener {
handleError((ErrorResponse) object); handleError((ErrorResponse) object);
} else if (object instanceof GameStartInfoResponse) { } else if (object instanceof GameStartInfoResponse) {
receiveGameStartInfo((GameStartInfoResponse) object); receiveGameStartInfo((GameStartInfoResponse) object);
} else if (object instanceof ProgrammingCardDeck) { } else if (object instanceof HandResponse) {
receiveHand((ProgrammingCardDeck) object); receiveHand((HandResponse) object);
} else if (object instanceof ProgramsContainerResponse) { } else if (object instanceof ProgramsContainerResponse) {
receivePrograms((ProgramsContainerResponse) object); receivePrograms((ProgramsContainerResponse) object);
} else if (object instanceof PowerDownContainerResponse) { } else if (object instanceof PowerDownContainerResponse) {
@ -102,7 +102,7 @@ class RoboRallyClientListener extends Listener {
* *
* @param newHand The new hand this client can choose from * @param newHand The new hand this client can choose from
*/ */
private void receiveHand(ProgrammingCardDeck newHand) { private void receiveHand(HandResponse newHand) {
new Thread(() -> { new Thread(() -> {
//Prevents a bug where the game //Prevents a bug where the game
while (wrapper.getGame().getGameState() != GameState.WAITING_FOR_CARDS_FROM_SERVER) { while (wrapper.getGame().getGameState() != GameState.WAITING_FOR_CARDS_FROM_SERVER) {
@ -112,13 +112,14 @@ class RoboRallyClientListener extends Listener {
e.printStackTrace(); e.printStackTrace();
} }
} }
if (newHand.isEmpty() && wrapper.getGame().getRobotPowerDown()) { if (newHand.getNewHand().isEmpty() && wrapper.getGame().getRobotPowerDown()) {
wrapper.getGame().setProgram(new ArrayList<>()); wrapper.getGame().setProgram(new ArrayList<>());
wrapper.getGame().setGameState(GameState.SKIP_POWER_DOWN_SCREEN); wrapper.getGame().setGameState(GameState.SKIP_POWER_DOWN_SCREEN);
} else { } else {
wrapper.getGame().setGameState(GameState.CHOOSING_CARDS); wrapper.getGame().setGameState(GameState.CHOOSING_CARDS);
} }
wrapper.getGame().setPlayerHand(newHand); wrapper.getGame().setPlayerHand(newHand.getNewHand());
wrapper.getGame().setExtraCards(newHand.getExtraCards());
}).start(); }).start();
} }

View File

@ -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;
}
}

View File

@ -67,6 +67,20 @@ public interface InteractableGame {
*/ */
void setPlayerHand(ProgrammingCardDeck playerHand); 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 * Gets the amount of cards the player can choose for their program
* *

View File

@ -6,6 +6,7 @@ import inf112.fiasko.roborally.elementproperties.Position;
import inf112.fiasko.roborally.elementproperties.RobotID; import inf112.fiasko.roborally.elementproperties.RobotID;
import inf112.fiasko.roborally.elementproperties.TileType; import inf112.fiasko.roborally.elementproperties.TileType;
import inf112.fiasko.roborally.networking.RoboRallyServer; 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.PowerDownContainerResponse;
import inf112.fiasko.roborally.networking.containers.ProgramsContainerResponse; import inf112.fiasko.roborally.networking.containers.ProgramsContainerResponse;
import inf112.fiasko.roborally.utility.BoardLoaderUtil; import inf112.fiasko.roborally.utility.BoardLoaderUtil;
@ -32,6 +33,7 @@ public class RoboRallyGame implements DrawableGame, InteractableGame {
private String winningPlayerName; private String winningPlayerName;
private List<ProgrammingCard> program; private List<ProgrammingCard> program;
private ProgrammingCardDeck playerHand; private ProgrammingCardDeck playerHand;
private ProgrammingCardDeck extraCards;
/** /**
* Instantiates a new Robo Rally game * Instantiates a new Robo Rally game
@ -127,6 +129,16 @@ public class RoboRallyGame implements DrawableGame, InteractableGame {
this.playerHand = playerHand; this.playerHand = playerHand;
} }
@Override
public ProgrammingCardDeck getExtraCards() {
return extraCards;
}
@Override
public void setExtraCards(ProgrammingCardDeck extraCards) {
this.extraCards = extraCards;
}
@Override @Override
public List<ProgrammingCard> getProgram() { public List<ProgrammingCard> getProgram() {
return program; return program;
@ -277,7 +289,9 @@ public class RoboRallyGame implements DrawableGame, InteractableGame {
String playerName = server.getPlayerNames().get(connection); String playerName = server.getPlayerNames().get(connection);
Player player = getPlayerFromName(playerName); Player player = getPlayerFromName(playerName);
if (player != null && player.getProgrammingCardDeck() != null) { 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 { } else {
throw new IllegalArgumentException("Player " + playerName + " is not part of the game."); 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
*
* <p>These extra cards are cards which are locked, but not part of the player's program,</p>
*
* @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 * Sends information about players no longer part of the game to the server
*/ */

View File

@ -5,6 +5,7 @@ import inf112.fiasko.roborally.elementproperties.Action;
import inf112.fiasko.roborally.elementproperties.RobotID; import inf112.fiasko.roborally.elementproperties.RobotID;
import inf112.fiasko.roborally.networking.containers.ErrorResponse; import inf112.fiasko.roborally.networking.containers.ErrorResponse;
import inf112.fiasko.roborally.networking.containers.GameStartInfoResponse; 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.HurryResponse;
import inf112.fiasko.roborally.networking.containers.OkayResponse; import inf112.fiasko.roborally.networking.containers.OkayResponse;
import inf112.fiasko.roborally.networking.containers.PowerDownContainerResponse; import inf112.fiasko.roborally.networking.containers.PowerDownContainerResponse;
@ -46,5 +47,6 @@ public final class NetworkUtil {
kryo.register(UsernameRequest.class); kryo.register(UsernameRequest.class);
kryo.register(OkayResponse.class); kryo.register(OkayResponse.class);
kryo.register(HurryResponse.class); kryo.register(HurryResponse.class);
kryo.register(HandResponse.class);
} }
} }

View File

@ -52,6 +52,16 @@ public class FakeGame implements InteractableGame {
//Not needed for testing //Not needed for testing
} }
@Override
public ProgrammingCardDeck getExtraCards() {
return null;
}
@Override
public void setExtraCards(ProgrammingCardDeck extraCards) {
//Not needed for testing
}
@Override @Override
public int getProgramSize() { public int getProgramSize() {
return 0; return 0;