diff --git a/My Part 2/README.md b/My Part 2/README.md new file mode 100644 index 0000000..9b29637 --- /dev/null +++ b/My Part 2/README.md @@ -0,0 +1,7 @@ +# Advanced Programming Project - Spring 2021 +## Team 22 + +### Team Members: +- Amir Mohammad Fakhimi 99170531 +- Parsa Sharify 99101762 +- Iman Mohammadi 99102207 diff --git a/My Part 2/src/main/java/controller/AIClass.java b/My Part 2/src/main/java/controller/AIClass.java new file mode 100644 index 0000000..5e41136 --- /dev/null +++ b/My Part 2/src/main/java/controller/AIClass.java @@ -0,0 +1,60 @@ +package controller; + +import model.Board; +import model.cards.monstercard.MonsterCard; +import model.Player; + +public class AIClass { + +// public static String getOrder(Board machineBoard, Board playerBoard, Player AIPlayer, Player humanPlayer, Enum phaseOfGame) { +// if () {//TODO PUT A CONDITION THAT PHASE IS BATTLE PHASE +// int numberOfMonsterToAttack = -1; +// selectMachineMonsterCardToAttack(machineBoard, AIPlayer); +// if (canAttackToFaceUpMonster(machineBoard, playerBoard) != -1) { +// return "attack" + canAttackToFaceUpMonster(machineBoard, playerBoard); +// } else if (canAttackToFaceDownCard(playerBoard) != -1) { +// return "attack" + canAttackToFaceDownCard(playerBoard); +// } +// } +// } +// +// private static int canAttackToFaceDownCard(Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DH")) +// return i; +// } +// return -1; +// } +// +// private static void selectMachineMonsterCardToAttack(Board board, Player player) { +// MonsterCard[] monsterArray = board.getMonstersZone(); +// MonsterCard monsterCard = monsterArray[1]; +// for (int i = 2; i <= 5; i++) { +// if (monsterCard.getAttackLevel() < monsterArray[i].getAttackLevel()) +// monsterCard = monsterArray[i]; +// board.setMyCardSelected(true); +// board.setSelectedCard(monsterCard); +// } +// } +// +// private static int canAttackToFaceUpMonster(Board machineBoard, Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// MonsterCard monsterToAttack = (MonsterCard) machineBoard.getSelectedCard(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("OO") && monsterArray[i].getAttackLevel() < monsterToAttack.getAttackLevel()) +// return i; +// } +// +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DO") && monsterArray[i].getDefenseLevel() < monsterToAttack.getAttackLevel()) { +// } +// return i; +// } +// return -1; +// } +// +// public static String getRandomMove() { +// +// } +} diff --git a/My Part 2/src/main/java/controller/Database.java b/My Part 2/src/main/java/controller/Database.java new file mode 100644 index 0000000..e5d87af --- /dev/null +++ b/My Part 2/src/main/java/controller/Database.java @@ -0,0 +1,120 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.magiccard.MagicCardStatuses; +import model.cards.monstercard.MonsterCard; +import model.cards.monstercard.MonsterCardAttributes; + +import java.io.*; +import java.util.ArrayList; + +public class Database { + public static void prepareGame() { + new File("src/main/resources/players").mkdirs(); + addCardsToGame(); + readPlayersDataFromDatabase(); + } + + private static void addCardsToGame() { + try { + FileReader monsterCardFileReader = new FileReader("src/main/resources/cards/Monster Upgraded.csv"); + CSVReader monsterCardCSVReader = new CSVReaderBuilder(monsterCardFileReader).withSkipLines(1).build(); + + String[] monsterCardData; + while ((monsterCardData = monsterCardCSVReader.readNext()) != null) { + createNewMonsterCard(monsterCardData); + } + + + FileReader magicCardFileReader = new FileReader("src/main/resources/cards/SpellTrap.csv"); + CSVReader magicCardCSVReader = new CSVReaderBuilder(magicCardFileReader).withSkipLines(1).build(); + + String[] magicCardData; + while ((magicCardData = magicCardCSVReader.readNext()) != null) { + createNewMagicCard(magicCardData); + } + + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + } + + private static void createNewMonsterCard(String[] data) { + String name = data[0]; + short level = Short.parseShort(data[1]); + MonsterCardAttributes monsterCardAttributes = MonsterCardAttributes.valueOf(data[2]); + String monsterType = data[3]; + CardTypes cardType = CardTypes.valueOf(data[4].toUpperCase()); + int attackPoints = Integer.parseInt(data[5]); + int defensePoints = Integer.parseInt(data[6]); + String description = data[7]; + int price = Integer.parseInt(data[8]); + + new MonsterCard(name, level, monsterCardAttributes, monsterType, cardType, attackPoints, defensePoints, description, price); + } + + private static void createNewMagicCard(String[] data) { + String name = data[0]; + CardTypes cardType = CardTypes.valueOf(data[1].toUpperCase()); + String icon = data[2]; + String description = data[3]; + MagicCardStatuses status = MagicCardStatuses.valueOf(data[4].toUpperCase()); + int price = Integer.parseInt(data[5]); + + new MagicCard(name, cardType, icon, description, status,price); + } + + public static void readPlayersDataFromDatabase() { +// TODO: complete it by Iman's code + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + File file = new File("src/main/resources/players"); + FilenameFilter filenameFilter = (direction, name) -> name.endsWith(".json"); + String[] filesName = file.list(filenameFilter); + + if (filesName == null) return; + for (String fileName : filesName) { + try { + FileReader fileReader = new FileReader("src/main/resources/players/" + fileName); + Player player = gson.fromJson(fileReader, Player.class); + fileReader.close(); + Player.addPlayerToAllPlayers(player); + addCardsToPlayer(player); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + private static void addCardsToPlayer(Player player) { + ArrayList boughtCards = player.getBoughtCards(); + for (int i = 0; i < boughtCards.size(); i++) { + Card fakeCard = boughtCards.get(0); + Card originalCard = Card.getCardByName(fakeCard.getName()); + boughtCards.remove(fakeCard); + player.addCardToBoughtCards(originalCard); + } + } + + public static void updatePlayerInformationInDatabase(Player player) { + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + try { + FileWriter fileWriter = new FileWriter("src/main/resources/players/" + player.getUsername() + ".json"); + fileWriter.write(gson.toJson(player)); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/My Part 2/src/main/java/controller/Main.java b/My Part 2/src/main/java/controller/Main.java new file mode 100644 index 0000000..274e490 --- /dev/null +++ b/My Part 2/src/main/java/controller/Main.java @@ -0,0 +1,10 @@ +package controller; + +import view.LoginMenuView; + +public class Main { + public static void main(String[] args) { + Database.prepareGame(); + LoginMenuView.loginMenuView(); + } +} \ No newline at end of file diff --git a/My Part 2/src/main/java/controller/SpellCardController.java b/My Part 2/src/main/java/controller/SpellCardController.java new file mode 100644 index 0000000..6080ef6 --- /dev/null +++ b/My Part 2/src/main/java/controller/SpellCardController.java @@ -0,0 +1,537 @@ +package controller; + +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.SpellCardView; + +import java.util.ArrayList; +import java.util.Collections; + +public class SpellCardController { +// this method doesn't handle field spell cards + public static boolean doSpellCardEffect(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { +// handle every kind of spell cards except field and equip + String cardName = spellCard.getName(); + switch (cardName) { + case "Monster Reborn": + return doMonsterRebornEffect(turnPlayer, notTurnPlayer); + case "Terraforming": + return doTerraformingEffect(turnPlayer); + case "Pot of Greed": + return doPotOfGreedEffect(turnPlayer); + case "Raigeki": + return doRaigekiEffect(notTurnPlayer); + case "Change of Heart": + return doChangeOfHeartEffect(); + case "Harpie's Feather Duster": + return doHarpieFeatherDusterEffect(notTurnPlayer); + case "Swords of Revealing Light": + return doSwordsOfRevealingLight(); + case "Dark Hole": + return doDarkHoleEffect(turnPlayer, notTurnPlayer); + case "Supply Squad": +// TODO: i should know how turn changes, then handle it --> it shouldn't handle here + break; + case "Spell Absorption": + return true; + case "Messenger of peace": +// TODO: handle it base on Parsa code + break; + case "Twin Twisters": + return doTwinTwistersEffect(turnPlayer, notTurnPlayer); + case "Mystical space typhoon": + return doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + case "Ring of defense": +// TODO: handle it base trap and monster code + break; +// it's the only ritual spell card + case "Advanced Ritual Art": + return doAdvancedRitualArtEffect(); + } + +// handle equip spell cards + return chooseMonsterToEquip(turnPlayer, notTurnPlayer, spellCard); +// any other kind of card doesn't enter to this method + } + + +// handle every kind of spell cards except field and equip + private static boolean doMonsterRebornEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showGraveyardsMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(turnPlayer.getBoard().getGraveyard()); + int notTurnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()); + if (turnPlayerGraveyardMonsterCardsSize + notTurnPlayerGraveyardMonsterCardsSize == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findMonsterRebornChosenCard(turnPlayer, notTurnPlayer, cardNumber); + if (chosenCard != null) break; + SpellCardView.invalidNumber(); + } + +// TODO: how to handle special summon + return true; + } + + private static int getCardNumber() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findCardNumber()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static MonsterCard findMonsterRebornChosenCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + ArrayList turnPlayerGraveyard = turnPlayer.getBoard().getGraveyard(); + ArrayList notTurnPlayerGraveyard = notTurnPlayer.getBoard().getGraveyard(); + + for (Card card : turnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + for (Card card : notTurnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + + return null; + } + + private static boolean doTerraformingEffect(Player player) { +// TODO: do Iman handle with main cards? + ArrayList cards = player.getBoard().getDeck().getMainCards(); + ArrayList fieldSpellCards = findFieldSpellCards(cards); + + SpellCardView.showFieldSpellCards(fieldSpellCards); + if (fieldSpellCards.size() == 0) return false; + + MagicCard chosenFieldSpellCard; + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= fieldSpellCards.size()) { + chosenFieldSpellCard = fieldSpellCards.get(cardNumber - 1); + player.getBoard().getCardsInHand().add(chosenFieldSpellCard); + cards.remove(chosenFieldSpellCard); + break; + } + SpellCardView.invalidNumber(); + } + + Collections.shuffle(cards); + return true; + } + + private static ArrayList findFieldSpellCards(ArrayList cards) { +// create array list of field spell cards + ArrayList fieldSpellCards = new ArrayList<>(); + for (Card card : cards) { + if (!Card.isMonsterCard(card)) { + MagicCard magicCard = (MagicCard) card; + if (magicCard.getIcon().equals("Field")) fieldSpellCards.add(magicCard); + } + } + return fieldSpellCards; + } + + private static boolean doPotOfGreedEffect(Player player) { + Board board = player.getBoard(); + ArrayList deckCards = board.getDeck().getMainCards(); + if (deckCards.size() < 2) return false; + + Card firstCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + Card secondCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + board.getCardsInHand().add(firstCard); + board.getCardsInHand().add(secondCard); + + return true; + } + + private static boolean doRaigekiEffect(Player player) { + MonsterCard[] monstersZone = player.getBoard().getMonstersZone(); + if (isCardArrayNull(monstersZone)) return false; + emptyAZone(player, monstersZone); + return true; + } + + private static boolean isCardArrayNull(Card[] cards) { + for (Card card : cards) { + if (card != null) return false; + } + return true; + } + + private static void emptyAZone(Player player, Card[] cards) { + for (int i = 0; i < cards.length; ++i) { + if (cards[i] != null) { + player.getBoard().getGraveyard().add(cards[i]); + cards[i] = null; + } + } + } + + private static boolean doChangeOfHeartEffect() { +// TODO: handle it! + return true; + } + + private static boolean doHarpieFeatherDusterEffect(Player player) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (isCardArrayNull(magicsZone)) return false; + emptyAZone(player, magicsZone); + return true; + } + + private static boolean doSwordsOfRevealingLight() { +// TODO: handle it! + return true; + } + + private static boolean doDarkHoleEffect(Player turnPlayer, Player notTurnPlayer) { + return doRaigekiEffect(turnPlayer) || doRaigekiEffect(notTurnPlayer); + } + + public static void doSpellAbsorptionEffect(Player player) { + if (player.getBoard().isCardFaceUp("Spell Absorption")) player.increaseLifePoint(500); + } + + private static boolean doTwinTwistersEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showCardsInHand(turnPlayer); + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= cardsInHand.size()) { + turnPlayer.getBoard().getGraveyard().add(cardsInHand.get(cardNumber - 1)); + cardsInHand.remove(cardNumber - 1); + break; + } + SpellCardView.invalidNumber(); + } + + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return true; + + int numberOfChosenCards; + while (true) { + numberOfChosenCards = getNumberOfCardsToChoose(); + if (0 <= numberOfChosenCards && numberOfChosenCards <= 2 && + numberOfChosenCards <= turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards) { + break; + } + SpellCardView.invalidNumber(); + } + + for (int i = 0; i < numberOfChosenCards; i++) { + doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + } + + return true; + } + + private static int getNumberOfCardsToChoose() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findNumberOfCardsToChoose()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static boolean destroyAMagicCardFromMagicZone(Player player, int cardNumber, int startNumber) { + MagicCard[] playerMagicsZone = player.getBoard().getMagicsZone(); + for (int i = 1; i < playerMagicsZone.length; i++) { + if (playerMagicsZone[i] != null) { + if (startNumber == cardNumber) { + player.getBoard().getGraveyard().add(playerMagicsZone[i]); + playerMagicsZone[i] = null; + return true; + } + ++startNumber; + } + } + + return false; + } + + private static boolean doMysticalSpaceTyphoonEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (destroyAMagicCardFromMagicZone(turnPlayer, cardNumber, 1) || + destroyAMagicCardFromMagicZone(notTurnPlayer, cardNumber, turnPlayerNumberOfMagicCards + 1)) + break; + SpellCardView.invalidNumber(); + } + + return true; + } + +// it's the only ritual spell card + private static boolean doAdvancedRitualArtEffect() { +// TODO: handle it based on Iman's code + return false; + } + + +// handle field spell cards + public static void handleFieldSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + MagicCard firstPlayerFieldZoneCard = firstPlayer.getBoard().getFieldZone(); + MagicCard secondPlayerFieldZoneCard = secondPlayer.getBoard().getFieldZone(); + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, firstPlayerFieldZoneCard, doEffect); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, secondPlayerFieldZoneCard, doEffect); + } + + private static Player findMonsterCardOwner(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard) { + if (firstPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return firstPlayer; + if (secondPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return secondPlayer; + +// this will never happen, just for assurance + return null; + } + + private static void handleEachFieldSpellCardEffect(Player monsterCardOwner, MonsterCard monsterCard, MagicCard fieldZoneCard, + boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + if (fieldZoneCard == null || !fieldZoneCard.getCardFaceUp()) return; + + switch (fieldZoneCard.getName()) { + case "Yami": + handleYamiEffect(monsterCard, doEffect); + break; + case "Forest": + handleForestEffect(monsterCard, doEffect); + break; + case "Closed Forest": + handleClosedForestEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Umiiruka": + handleUmiirukaEffect(monsterCard, doEffect); + break; + } + } + + private static void handleYamiEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } else if (monsterCard.getMonsterType().equals("Fairy")) { + if (doEffect) { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } + } + } + + private static void handleForestEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Insect") || monsterCardType.equals("Beast") || + monsterCardType.equals("Beast-Warrior")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } + } + + private static void handleClosedForestEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int graveyardMonsterCardsSize = Card.findNumberOfMonsterCards(monsterCardOwner.getBoard().getGraveyard()); + MonsterCard[] monstersZone = monsterCardOwner.getBoard().getMonstersZone(); + + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null && monstersZone[i].getMonsterType().equals("Beast-Type")) { + if (doEffect) monsterCard.increaseAttackPoints(100 * graveyardMonsterCardsSize); + else monsterCard.decreaseAttackPoints(100 * graveyardMonsterCardsSize); + } + } + + } + + private static void handleUmiirukaEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (monsterCard.getMonsterType().equals("Aqua")) { + if (doEffect) { + monsterCard.increaseAttackPoints(500); + monsterCard.decreaseDefencePoints(400); + } else { + monsterCard.decreaseAttackPoints(500); + monsterCard.increaseDefencePoints(400); + } + } + } + + +// handle equip spell cards + private static boolean chooseMonsterToEquip(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { + SpellCardView.showFaceUpMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerFaceUpMonsterCardsNumber = turnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + int notTurnPlayerFaceUpMonsterCardsNumber = notTurnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + Board turnPlayerBoard = turnPlayer.getBoard(); + if (turnPlayerFaceUpMonsterCardsNumber + notTurnPlayerFaceUpMonsterCardsNumber == 0 || + !turnPlayerBoard.isMagicsZoneFull()) return false; + if (spellCard.getName().equals("Magnum Shield") && turnPlayerBoard.getNumberOfWarriorMonsterCards() == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findFaceUpMonsterCard(turnPlayer, notTurnPlayer, cardNumber); +// second and third condition assure me that Magnum Shield just equipped Warrior Monster Cards + if (chosenCard != null && + (!spellCard.getName().equals("Magnum Shield") || chosenCard.getMonsterType().equals("Warrior"))) break; + SpellCardView.invalidNumber(); + } + + chosenCard.addToEquippedBy(spellCard); + turnPlayerBoard.addMagicCardToMagicsZone(spellCard); + return true; + } + + private static MonsterCard findFaceUpMonsterCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + MonsterCard[] turnPlayerFaceUpMonsterCards = turnPlayer.getBoard().getMonstersZone(); + MonsterCard[] notTurnPlayerFaceUpMonsterCards = notTurnPlayer.getBoard().getMonstersZone(); + + for (int i = 1; i < turnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = turnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + for (int i = 1; i < notTurnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = notTurnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + + return null; + } + + public static void handleEquipSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + for (MagicCard spellCard : monsterCard.getEquippedBy()) { + switch (spellCard.getName()) { + case "Sword of dark destruction": + handleSwordOfDarkDestructionEffect(monsterCard, doEffect); + break; + case "Black Pendant": + handleBlackPendantEffect(monsterCard, doEffect); + break; + case "United We Stand": + handleUnitedWeStandEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Magnum Shield": + handleMagnumShieldEffect(monsterCard, doEffect); + break; + } + } + } + + private static void handleSwordOfDarkDestructionEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(400); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(400); + monsterCard.increaseDefencePoints(200); + } + } + + } + + private static void handleBlackPendantEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (doEffect) monsterCard.increaseAttackPoints(500); + else monsterCard.decreaseAttackPoints(500); + } + + private static void handleUnitedWeStandEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int numberOfFaceUpMonsterCards = monsterCardOwner.getBoard().getNumberOfFaceUpMonsterCards(); + if (doEffect) { + monsterCard.increaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.increaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } else { + monsterCard.decreaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.decreaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } + } + + private static void handleMagnumShieldEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + +// I know that Magnum Shield just equipped Warrior monster cards + if (monsterCard.isDefensePosition()) { + if (doEffect) monsterCard.increaseDefencePoints(monsterCard.getAttackPoints()); + else monsterCard.decreaseDefencePoints(monsterCard.getAttackPoints()); + } else { + if (doEffect) monsterCard.increaseAttackPoints(monsterCard.getDefensePoints()); + else monsterCard.decreaseAttackPoints(monsterCard.getDefensePoints()); + } + } +} diff --git a/My Part 2/src/main/java/controller/Utils.java b/My Part 2/src/main/java/controller/Utils.java new file mode 100644 index 0000000..05df0d8 --- /dev/null +++ b/My Part 2/src/main/java/controller/Utils.java @@ -0,0 +1,34 @@ +package controller; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Utils { + private static Scanner scanner; + + static { + scanner = new Scanner(System.in); + } + + public static Scanner getScanner() { + return scanner; + } + + public static void resetScanner(String input) { + scanner = new Scanner(new ByteArrayInputStream(input.getBytes())); + } + + public static ByteArrayOutputStream setByteArrayOutputStream() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + return outContent; + } + + public static Matcher getMatcher(String regex, String command) { + return Pattern.compile(regex).matcher(command); + } +} diff --git a/My Part 2/src/main/java/controller/deckmenu/DeckMenuController.java b/My Part 2/src/main/java/controller/deckmenu/DeckMenuController.java new file mode 100644 index 0000000..d5c3912 --- /dev/null +++ b/My Part 2/src/main/java/controller/deckmenu/DeckMenuController.java @@ -0,0 +1,98 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +import java.util.Objects; + +public class DeckMenuController { + + private static DeckMenuController instance = null; + + private DeckMenuController() { + } + + public static DeckMenuController getInstance() { + return Objects.requireNonNullElseGet(instance, () -> (instance = new DeckMenuController())); + } + + public void createDeck(String name, Player owner) { + if (!DeckMenuTools.isDeckNameUnique(name)) + return; + + new Deck(name, owner , true , true); + DeckMenuOutput.getInstance().showMessage("deck created successfully!"); + } + + public void deleteDeck(String name) { + if (DeckMenuTools.isDeckNameUnique(name)) + return; + + DeckMenuDatabase.removeDeck(name); + DeckMenuOutput.getInstance().showMessage("deck deleted successfully!"); + + } + + + public void setActiveDeck(String name, Player player) { + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesDeckExist(name) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(name), player); + if (isPermitted) { + player.activateADeck(deck); + + DeckMenuOutput.getInstance().showMessage("deck activated successfully!"); + } + + } + + public void addCardToDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card = null; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player) + && ((isMain) ? DeckMenuTools.doesDeckHaveSpace(deck) : DeckMenuTools.doesSideDeckHaveSpace(deck)) + && DeckMenuTools.isNumberOfCardsInDeckLessThanFour(deck, card = DeckMenuDatabase.getInstance().getCardByName(cardName)) + && DeckMenuTools.doesPlayerHaveEnoughCards(card , player); + if (isPermitted) { + player.getAllPlayerCard().moveCardTo(deck , card , true , isMain); + DeckMenuOutput.getInstance().showMessage("card added to deck successfully!"); + } + } + + public void removeCardFromDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player); + if (isPermitted) { + card = DeckMenuDatabase.getInstance().getCardByName(cardName); + deck.moveCardTo(player.getAllPlayerCard(),card, isMain , true); + DeckMenuOutput.getInstance().showMessage("card removed from deck successfully!"); + } + } + + public void showAllDecks(Player player) { + for (Deck deck : player.getAllDeck()) + DeckMenuOutput.getInstance().showMessage(deck.toString()); + + } + + public void showDeck(String name, Player player, boolean isMain) { + if (!DeckMenuTools.doesDeckExist(name)) + return; + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (!DeckMenuTools.doesDeckBelongToPlayer(deck, player)) + return; + String message; + if (isMain) + message = "true"; + else + message = "false"; + DeckMenuOutput.getInstance().showMessage(message); + + + } +} diff --git a/My Part 2/src/main/java/controller/deckmenu/DeckMenuDatabase.java b/My Part 2/src/main/java/controller/deckmenu/DeckMenuDatabase.java new file mode 100644 index 0000000..d16b03f --- /dev/null +++ b/My Part 2/src/main/java/controller/deckmenu/DeckMenuDatabase.java @@ -0,0 +1,50 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; +import java.util.ArrayList; + +public class DeckMenuDatabase { + + public static ArrayList allPlayers = new ArrayList<>(); + public static ArrayList allCards = new ArrayList<>(); + public static ArrayList allDecks = new ArrayList<>(); + + private DeckMenuDatabase() { + } + + private static DeckMenuDatabase instance; + + public static DeckMenuDatabase getInstance() { + if (instance == null) + instance = new DeckMenuDatabase(); + return instance; + } + + public static void removeDeck(String name) { + allDecks.removeIf(deck -> deck.getName().equals(name)); + } + + public Card getCardByName(String name) { + for (Card card : allCards) { + if (card.getName().equals(name)) + return card; + } + return null; + + } + + public Deck getDeckByName(String name) { + for (Deck deck : allDecks) { + if (deck.getName().equals(name)) + return deck; + } + return null; + + } + // setPlayers() {file v Jason} + // setDecks() {file v Jason} + // loadingDatabase() + // updatingDatabase() + +} diff --git a/My Part 2/src/main/java/controller/deckmenu/DeckMenuOutput.java b/My Part 2/src/main/java/controller/deckmenu/DeckMenuOutput.java new file mode 100644 index 0000000..92896b1 --- /dev/null +++ b/My Part 2/src/main/java/controller/deckmenu/DeckMenuOutput.java @@ -0,0 +1,23 @@ +package controller.deckmenu; + +public class DeckMenuOutput { + + private DeckMenuOutput() { + } + + private static DeckMenuOutput instance; + + public static DeckMenuOutput getInstance() { + if (instance == null) + instance = new DeckMenuOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My Part 2/src/main/java/controller/deckmenu/DeckMenuTools.java b/My Part 2/src/main/java/controller/deckmenu/DeckMenuTools.java new file mode 100644 index 0000000..1350533 --- /dev/null +++ b/My Part 2/src/main/java/controller/deckmenu/DeckMenuTools.java @@ -0,0 +1,70 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +public class DeckMenuTools { + public static boolean isDeckNameUnique(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck == null) + return true; + + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " already exists"); + return false; + + } + public static boolean doesDeckExist(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck != null) + return true; + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " does not exist"); + return false; + + } + public static boolean doesDeckBelongToPlayer(Deck deck, Player player) { + if (deck.getOwner().getUsername().equals(player.getUsername())) + return true; + DeckMenuOutput.getInstance().showMessage("this deck doesn't belong to you!"); + return false; + } + public static boolean doesDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getMainCards().size() < 60) + return true; + DeckMenuOutput.getInstance().showMessage("main deck is full!"); + return false; + } + public static boolean doesSideDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getSideCards().size() < 15) + return true; + DeckMenuOutput.getInstance().showMessage("side deck is full!"); + return false; + } + public static boolean isNumberOfCardsInDeckLessThanFour(Deck deck, Card card) { + if (deck.getNumberOfCardsInDeck(card) < 3) + return true; + DeckMenuOutput.getInstance().showMessage("there are already three cards with name " + card.getName() + + " in deck " + deck.getName() + " !"); + return false; + } + public static boolean isDeckAllowed(Deck deck) { + int numberOfCardsInSideDeck = deck.getNumberOfCardsInSideDeck(); + int numberOfCardsInMainDeck = deck.getNumberOfCardsInMainDeck(); + return numberOfCardsInMainDeck <= 60 && numberOfCardsInMainDeck >= 40 && numberOfCardsInSideDeck <= 15; + } + public static boolean doesPlayerHaveEnoughCards(Card card, Player player) { + if (player.hasCard(card)) + return true; + DeckMenuOutput.getInstance().showMessage("you dont have this type of card anymore!"); + return false; + } + public static boolean doesCardExist(String cardName) { + Card card = DeckMenuDatabase.getInstance().getCardByName(cardName); + if (card != null) + return true; + DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist"); + return false; + } + +} diff --git a/My Part 2/src/main/java/controller/duelmenu/DuelMenuController.java b/My Part 2/src/main/java/controller/duelmenu/DuelMenuController.java new file mode 100644 index 0000000..f73d262 --- /dev/null +++ b/My Part 2/src/main/java/controller/duelmenu/DuelMenuController.java @@ -0,0 +1,494 @@ +package controller.duelmenu; + +import controller.SpellCardController; +import controller.Utils; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.DuelMenuView; + +import java.util.Collections; +import java.util.regex.Matcher; + +public class DuelMenuController { + private Player turnPlayer; + private Player notTurnPlayer; + private Phases phase; + private boolean isAITurn; + + public static String specifyTurnPlayer(Player firstPlayer, Player secondPlayer) { + String firstPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(firstPlayer); + if (!isMiniGameChoiceValid(firstPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices firstPlayerChoice = MiniGameChoices.valueOf(firstPlayerChoiceInString.toUpperCase()); + + String secondPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(secondPlayer); + if (!isMiniGameChoiceValid(secondPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices secondPlayerChoice = MiniGameChoices.valueOf(secondPlayerChoiceInString.toUpperCase()); + + if (firstPlayerChoice.equals(secondPlayerChoice)) return "draw"; + + return findMiniGameWinner(firstPlayer, secondPlayer, firstPlayerChoice, secondPlayerChoice); + } + + private static boolean isMiniGameChoiceValid(String choice) { + try { + MiniGameChoices.valueOf(choice.toUpperCase()); + return true; + } catch (Exception exception) { + return false; + } + } + + private static String findMiniGameWinner(Player firstPlayer, Player secondPlayer, + MiniGameChoices firstPlayerChoice, MiniGameChoices secondPlayerChoice) { + switch (firstPlayerChoice) { + case STONE: + if (secondPlayerChoice.equals(MiniGameChoices.PAPER)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case PAPER: + if (secondPlayerChoice.equals(MiniGameChoices.SCISSOR)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case SCISSOR: + if (secondPlayerChoice.equals(MiniGameChoices.STONE)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + } + +// this is never happen + return null; + } + + public DuelMenuMessages initialGame(Player firstPlayer, Player secondPlayer) { +// TODO: handle it for ai + String result = specifyTurnPlayer(firstPlayer, secondPlayer); + if (result.equals("invalid choice")) return DuelMenuMessages.MINI_GAME_INVALID_CHOICE; + else if (result.equals("draw")) return DuelMenuMessages.DRAW; + else turnPlayer = Player.getPlayerByUsername(result); + + if (turnPlayer.equals(firstPlayer)) notTurnPlayer = secondPlayer; + else notTurnPlayer = firstPlayer; + + turnPlayer.createBoard(); + notTurnPlayer.createBoard(); + + turnPlayer.getBoard().setDeck(turnPlayer.getActivatedDeck()); + notTurnPlayer.getBoard().setDeck(notTurnPlayer.getActivatedDeck()); + + Collections.shuffle(turnPlayer.getActivatedDeck().getMainCards()); + Collections.shuffle(notTurnPlayer.getActivatedDeck().getMainCards()); + + return DuelMenuMessages.SHOW_TURN_PLAYER; + } + + public DuelMenuMessages findCommand(String command) { +// TODO: handle menu commands --> menu exit and ... + if (command.startsWith("decrease ")) return cheatCodeDecreaseOpponentLifePont(command); + else if (command.startsWith("increase ")) return cheatCodeIncreaseLifePoint(command); + else if (command.startsWith("duel set-winner ")) return cheatCodeSetWinner(command); + else if (command.startsWith("increase --money ")) return cheatCodeIncreaseMoney(command); + else if (command.startsWith("select ")) return checkSelectCard(command); + else if (command.equals("select -d")) return deselectCard(); + else if (command.equals("summon")) ;//return checkSummonMonster(); + else if (command.equals("set")) return checkSetACard(); + else if (command.startsWith("set --position"));// return checkChangePosition(command); + else if (command.equals("flip-summon")) ;//return checkFlipSummon(); + else if (command.equals("attack direct")) return directAttack(); + else if (command.startsWith("attack")) return attack(command); + else if (command.equals("activate effect")) return checkActiveASpellCard(); + else if (command.equals("show graveyard")) { + DuelMenuView.showGraveyard(turnPlayer.getBoard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("back")) ;//checkBack(); + else if (command.equals("card show --selected")) { + DuelMenuView.printCard(1, turnPlayer.getBoard().getSelectedCard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("cancel")) ;//cancelCommand(); + else if (command.equals("surrender")) /*TODO*/; + +// TODO: handle cheat/debug commands + + return DuelMenuMessages.INVALID_COMMAND; + } + + private DuelMenuMessages cheatCodeDecreaseOpponentLifePont(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_DECREASE_OPPONENT_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + notTurnPlayer.decreaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + } + + private DuelMenuMessages cheatCodeIncreaseLifePoint(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_INCREASE_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + turnPlayer.increaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + } + + private DuelMenuMessages cheatCodeSetWinner(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_SET_WINNER.getRegex(), command); + if (matcher.find()) { + String nickname = matcher.group(1); + if (turnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/; + else if (notTurnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/; + else DuelMenuMessages.WRONG_NICKNAME_CHEAT_CODE; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + } + + private DuelMenuMessages cheatCodeIncreaseMoney(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_INCREASE_MONEY.getRegex(), command); + if (matcher.find()) { + turnPlayer.increaseMoney(Integer.parseInt(matcher.group(1))); + return null; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + } + + private DuelMenuMessages checkSelectCard(String command) { +// TODO: handle --> if there isn't any card in main deck, he/she loses +// TODO: maybe clean it more + Matcher matcher; + if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MONSTER_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MAGIC_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_FIELD_ZONE.getRegex(), command).find()) { + if (turnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(true); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_CARDS_IN_HAND.getRegex(), command)).find() ) { + int number = Integer.parseInt(matcher.group(1)); + if (number > turnPlayer.getBoard().getCardsInHand().size()) { + return DuelMenuMessages.INVALID_SELECTION; + } + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getCardsInHand().get(number - 1)); + turnPlayer.getBoard().setMyCardSelected(true); + turnPlayer.getBoard().setACardInHandSelected(true); + + } else { + turnPlayer.getBoard().setSelectedCard(null); + turnPlayer.getBoard().setMyCardSelected(false); + return DuelMenuMessages.INVALID_SELECTION; + } + + return DuelMenuMessages.CARD_SELECTED; + } + + private boolean isSelectionValid(Matcher matcher) { + int number = Integer.parseInt(matcher.group(1)); + return number <= 5 && number >= 1; + } + + private boolean isCardAvailableInMonstersZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMonstersZone()[number] != null; + } + + private boolean isCardAvailableInMagicsZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMagicsZone()[number] != null; + } + + private void selectCardFromMonstersZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMonstersZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMonstersZone()[number]); + } + } + + private void selectCardFromMagicsZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMagicsZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMagicsZone()[number]); + } + } + + private void selectCardFromFieldZone(boolean isMyCardSelected) { + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getFieldZone()); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getSelectedCard()); + } + } + + private DuelMenuMessages deselectCard() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages result = checkDeselectCard(); + if (result == null) { + board.setSelectedCard(null); + return DuelMenuMessages.DESELECTED; + } else return result; + } + + private DuelMenuMessages checkDeselectCard() { + Board board = turnPlayer.getBoard(); + if (board.getSelectedCard() == null) + return DuelMenuMessages.NOT_SELECTED_CARD; + return null; + } +// +// private DuelMenuMessages checkSummonMonster() { +//// TODO: maybe change the name to --> checkSummonCard +// } +// +// private DuelMenuMessages summonMonster() { +//// TODO: maybe change the name to --> summonCard +// } +// +// private void victimize() { +//// TODO: handle it! +// } +// + private DuelMenuMessages checkSetACard() { + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (board.getSelectedCard() == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!board.isACardInHandSelected()) return DuelMenuMessages.CANT_SET; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.NOT_TRUE_PHASE; + else if (Card.isMonsterCard(selectedCard)) return checkSetAMonsterCard(selectedCard); + + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + } + + private DuelMenuMessages checkSetAMonsterCard(Card card) { + return DuelMenuMessages.EMPTY; + } + +// private DuelMenuMessages setAMonster() { +// +// } +// +// private DuelMenuMessages checkChangePosition(String command) { +// +// } +// +// private DuelMenuMessages changePosition(String command) { +// +// } +// +// private void updateGraveyard() { +//// TODO: handle it! +// } +// +// private DuelMenuMessages checkFlipSummon() { +// +// } +// +// private DuelMenuMessages flipSummon() { +// +// } + + private DuelMenuMessages attack(String command) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.ATTACK.getRegex(), command); + if (matcher.find()) { + int numberOfChosenCard = Integer.parseInt(matcher.group(1)); + + DuelMenuMessages result = checkAttack(numberOfChosenCard); + if (result == null) { + MonsterCard attackingMonster = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentMonster = opponentPlayerBoard.getMonstersZone()[numberOfChosenCard]; + + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + DuelMenuMessages tempResult = attackingMonster.attack(turnPlayer, notTurnPlayer, numberOfChosenCard); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + + return tempResult; + } + return result; + + } else return DuelMenuMessages.INVALID_CARD_SELECT; + } + + private DuelMenuMessages checkAttack(int numberOfChosenCard) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + if (attackingPlayerBoard.getSelectedCard() == null || !attackingPlayerBoard.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (attackingPlayerBoard.getSelectedCard() instanceof MonsterCard) + return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + //TODO check battle phase + MonsterCard card = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + if (card.isAttacked()) + return DuelMenuMessages.ATTACKED_BEFORE; + if (opponentPlayerBoard.getMonstersZone()[numberOfChosenCard] == null) + return DuelMenuMessages.NO_CARD_FOUND_IN_THE_POSITION; + return null; + } + + private DuelMenuMessages directAttack() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages messages = checkDirectAttack(); + if (messages != null) + return messages; + else { + MonsterCard card = (MonsterCard) board.getSelectedCard(); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + notTurnPlayer.decreaseLifePoint(card.getAttackPoints()); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + + DuelMenuMessages.setDamageAmount(card.getAttackPoints()); + return DuelMenuMessages.DIRECT_ATTACK_DONE; + } + } + + private DuelMenuMessages checkDirectAttack() { + Board board = turnPlayer.getBoard(); + + if (board.getSelectedCard() == null || !board.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (phase.equals(phase.)) + return DuelMenuMessages.NOT_SUITABLE_PHASE; + if (board.getSelectedCard() instanceof MonsterCard) { + MonsterCard card = (MonsterCard) board.getSelectedCard();//TODO: handle cast exception!! + if (card.isAttacked()) return DuelMenuMessages.ATTACKED_BEFORE; + } else return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + + return null; + } + + private DuelMenuMessages checkActiveASpellCard() { +// TODO: clean it! + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (selectedCard == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!selectedCard.getCardType().equals(CardTypes.SPELL)) return DuelMenuMessages.NOT_SPELL_CARD; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.CANT_ACTIVATE_SPELL_EFFECT; + else if (selectedCard.isPowerUsed()) return DuelMenuMessages.CARD_ACTIVATED_BEFORE; + else if (!turnPlayer.getBoard().isMyCardSelected()) return DuelMenuMessages.NOT_OWNER; + + MagicCard spellCard = (MagicCard) selectedCard; + if (spellCard.getIcon().equals("Field")) { + turnPlayer.getBoard().addSpellCardToFieldZone(spellCard); + spellCard.setPowerUsed(true); + spellCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } else if (board.isMagicsZoneFull() && board.isACardInHandSelected()) return DuelMenuMessages.FULL_MAGICS_ZONE; + + if (!SpellCardController.doSpellCardEffect(turnPlayer, notTurnPlayer, spellCard)) return DuelMenuMessages.UNDONE_PREPARATIONS; + if (board.isACardInHandSelected()) board.addMagicCardToMagicsZone(spellCard); + selectedCard.setPowerUsed(true); + selectedCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } + + private DuelMenuMessages setAMagicCard(MagicCard magicCard) { + Board board = turnPlayer.getBoard(); + if (magicCard.getIcon().equals("Field")) board.addSpellCardToFieldZone(magicCard); + else if (board.isMagicsZoneFull()) return DuelMenuMessages.FULL_MAGICS_ZONE; + else board.addMagicCardToMagicsZone(magicCard); + magicCard.setPowerUsed(false); + magicCard.setCardFaceUp(false); + + return DuelMenuMessages.SET_SUCCESSFULLY; + } + +// private DuelMenuMessages checkBack() { +// +// } +// +// private void cancelCommand() { +// +// } +// +// TODO: handle activeASpellInOpponentTurn +// TODO: ----------------------------------------------- +// TODO: we are not sure about under functions +// +// private DuelMenuMessages ritualSummon(String command) { +// +// } +// +// private DuelMenuMessages specialSummon(String command) { +// +// } +// +// private Player/*or Enum*/ checkWinner() { +// +// } +// +// TODO: ----------------------------------------------- + +} diff --git a/My Part 2/src/main/java/controller/duelmenu/DuelMenuMessages.java b/My Part 2/src/main/java/controller/duelmenu/DuelMenuMessages.java new file mode 100644 index 0000000..8593e35 --- /dev/null +++ b/My Part 2/src/main/java/controller/duelmenu/DuelMenuMessages.java @@ -0,0 +1,75 @@ +package controller.duelmenu; + +import model.Player; + +public enum DuelMenuMessages { + MINI_GAME_INVALID_CHOICE("please enter a valid option\n"), + DRAW("draw\nplease try again:\n"), + SHOW_TURN_PLAYER(" should start first\n"), + INVALID_SELECTION("invalid selection\n"), + CARD_SELECTED("card selected\n"), + CARD_NOT_FOUND("no card found in the given position\n"), + UNAVAILABLE_SELECTED_CARD("no card is selected yet\n"), + NOT_SPELL_CARD("activate effect is only for spell cards.\n"), + CANT_ACTIVATE_SPELL_EFFECT("you can’t activate an effect on this turn\n"), + CARD_ACTIVATED_BEFORE("you have already activated this card\n"), + FULL_MAGICS_ZONE("spell card zone is full\n"), + UNDONE_PREPARATIONS("preparations of this spell are not done yet\n"), + SPELL_ACTIVATED("spell activated\n"), + NOT_OWNER("you aren't owner of selected card\n"), + CANT_SET("you can’t set this card\n"), + NOT_TRUE_PHASE("you can’t do this action in this phase\n"), + SET_SUCCESSFULLY("set successfully\n"), + NOT_SELECTED_CARD("no card is selected yet\n"), + ATTACKED_BEFORE("this card already attacked\n"), + NOT_SUITABLE_PHASE("you can’t do this action in this phase\n"), + INVALID_CARD_SELECT("invalid selection\n"), + NO_CARD_FOUND_IN_THE_POSITION("no card found in the given position\n"), + CANT_ATTACK_WITH_CARD("you can’t attack with this card\n"), + YOU_CANT_ATTACK_TO_THIS_CARD("you cant attack to this card\n"), + ATTACK_CANCELED("attack to this card was canceled\n"), + DIRECT_ATTACK_DONE("you opponent receives battle damage\n"), + DESELECTED("card deselected\n"), + INVALID_COMMAND_CHEAT_CODE("invalid command\n"), + OPPONENT_GOT_DAMAGE_IN_ATTACK("your opponent’s monster is destroyed and your opponent receives battle damage\n"), + ATTACKING_PLAYER_CARD_DESTROYED("Your monster card is destroyed and you received battle damage\n"), + DEFENSE_POSITION_MONSTER_DESTROYED("the defense position monster is destroyed\n"), + NO_CARD_DESTROYED("no card is destroyed\n"), + RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD("no card is destroyed and you received battle damage\n"), + BOTH_CARDS_GET_DESTROYED("both you and your opponent monster cards are destroyed and no one receives damage\n"), + EMPTY(""), + INVALID_COMMAND("invalid command\n"); + + private String message; + + DuelMenuMessages(String message) { + this.message = message; + } + + public static void setShowTurnPlayer(Player player) { + SHOW_TURN_PLAYER.message = player.getUsername() + " should start first\n"; + } + + public static void setDamageAmount(int damageAmount) { + DuelMenuMessages.DIRECT_ATTACK_DONE.message = "you opponent receives " + damageAmount + " battle damage\n"; + } + + public static void setOpponentGotDamageInAttack(int damage) { + DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK.message = + "your opponent’s monster is destroyed and your opponent receives" + damage + " battle damage\n"; + } + + public static void setAttackingPlayerCardDestroyed(int damage) { + DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED.message = + "Your monster card is destroyed and you received " + damage + " battle damage\n"; + } + + public static void setReceiveDamageByAttackingToDefenseCard(int damage) { + DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD.message = + "no card is destroyed and you received " + damage + " battle damage\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 2/src/main/java/controller/duelmenu/DuelMenuRegexes.java b/My Part 2/src/main/java/controller/duelmenu/DuelMenuRegexes.java new file mode 100644 index 0000000..9c6c26f --- /dev/null +++ b/My Part 2/src/main/java/controller/duelmenu/DuelMenuRegexes.java @@ -0,0 +1,29 @@ +package controller.duelmenu; + +public enum DuelMenuRegexes { + SELECT_MONSTER_ZONE("^select --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_MAGIC_ZONE("^select --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN("^select --(?:monster|M) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN("^select --(?:spell|S) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_FIELD_ZONE("^select --(?:field|F)$"), + SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN("^select --(?:field|F) --(?:opponent|O)$"), + SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:field|F)$"), + SELECT_CARDS_IN_HAND("^select --(?:hand|H) ((?:-|)\\d+)$"), + CHEAT_DECREASE_OPPONENT_LIFE_POINT("^decrease --opponentLP ([0-9]+)$"), + CHEAT_INCREASE_LIFE_POINT("^increase --LP ([0-9]+)$"), + CHEAT_SET_WINNER("^duel set-winner (\\S+)$"), + CHEAT_INCREASE_MONEY("^increase --money ([0-9]+)$"), + ATTACK("^attack ([0-9]+)$"); + + private final String regex; + + DuelMenuRegexes(String message) { + this.regex = message; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 2/src/main/java/controller/duelmenu/MiniGameChoices.java b/My Part 2/src/main/java/controller/duelmenu/MiniGameChoices.java new file mode 100644 index 0000000..57881a4 --- /dev/null +++ b/My Part 2/src/main/java/controller/duelmenu/MiniGameChoices.java @@ -0,0 +1,17 @@ +package controller.duelmenu; + +public enum MiniGameChoices { + STONE("stone"), + PAPER("paper"), + SCISSOR("scissor"); + + private final String choice; + + MiniGameChoices(String choice) { + this.choice = choice; + } + + public String getChoice() { + return choice; + } +} diff --git a/My Part 2/src/main/java/controller/duelmenu/Phases.java b/My Part 2/src/main/java/controller/duelmenu/Phases.java new file mode 100644 index 0000000..a6047ab --- /dev/null +++ b/My Part 2/src/main/java/controller/duelmenu/Phases.java @@ -0,0 +1,9 @@ +package controller.duelmenu; + +public enum Phases { + DRAW_PHASE, + STANDBY_PHASE, + MAIN_PHASE_1, + BATTLE_PHASE, + MAIN_PHASE_2; +} diff --git a/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuController.java b/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuController.java new file mode 100644 index 0000000..cde2f83 --- /dev/null +++ b/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuController.java @@ -0,0 +1,100 @@ +package controller.importexportmenu; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Utils; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.regex.Matcher; + +public class ImportExportMenuController { + public static ImportExportMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU; + else if (command.equals("menu show-current")) return ImportExportMenuMessages.SHOW_MENU; + else if (command.startsWith("import card")) return importCard(command); + else if (command.startsWith("export card")) return exportCard(command); + + return ImportExportMenuMessages.INVALID_COMMAND; + } + + private static ImportExportMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + return ImportExportMenuMessages.INVALID_NAVIGATION; + } + + private static ImportExportMenuMessages importCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.IMPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + try { + FileReader fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + MonsterCard monsterCard = gson.fromJson(fileReader, MonsterCard.class); + + if (Card.getCardByName(cardName) != null) return ImportExportMenuMessages.AVAILABLE_CARD; + if (monsterCard.getAttribute() == null) { +// so we understand that the card is a magic card + fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + MagicCard magicCard = gson.fromJson(fileReader, MagicCard.class); + Card.addCardToAllCards(magicCard); + if (isCardIncomplete(magicCard) || isMagicCardIncomplete(magicCard)) + return ImportExportMenuMessages.INVALID_FILE; + } else { +// so we understand that the card is a monster card + monsterCard.createEquippedByArrayList(); + Card.addCardToAllCards(monsterCard); + if (isCardIncomplete(monsterCard) || isMonsterCardIncomplete(monsterCard)) + return ImportExportMenuMessages.INVALID_FILE; + } + fileReader.close(); + } catch (IOException ignore) { + return ImportExportMenuMessages.UNAVAILABLE_FILE; + } + + + return ImportExportMenuMessages.EMPTY; + } + + private static boolean isCardIncomplete(Card card) { + return card.getName() == null || card.getDescription() == null || card.getCardType() == null; + } + + private static boolean isMonsterCardIncomplete(MonsterCard monsterCard) { + return monsterCard.getAttribute() == null || monsterCard.getMonsterType() == null; + } + + private static boolean isMagicCardIncomplete(MagicCard magicCard) { + return magicCard.getIcon() == null || magicCard.getStatus() == null; + } + + private static ImportExportMenuMessages exportCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.EXPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card card = Card.getCardByName(cardName); + if (card == null) return ImportExportMenuMessages.UNAVAILABLE_CARD; + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(card)); + fileWriter.close(); + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + + + return ImportExportMenuMessages.EMPTY; + } +} diff --git a/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java b/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java new file mode 100644 index 0000000..8f83021 --- /dev/null +++ b/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java @@ -0,0 +1,23 @@ +package controller.importexportmenu; + +public enum ImportExportMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_IMPORT_EXPORT_MENU(""), + SHOW_MENU("Import/Export Menu\n"), + INVALID_COMMAND("invalid command\n"), + UNAVAILABLE_FILE("there isn't any file with your entered card name\n"), + INVALID_FILE("your card file is not valid to import\n"), + AVAILABLE_CARD("your entered card name is available\n"), + UNAVAILABLE_CARD("your entered card name is not available\n"), + EMPTY(""); + + private final String message; + + ImportExportMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java b/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java new file mode 100644 index 0000000..65c74dc --- /dev/null +++ b/My Part 2/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.importexportmenu; + +public enum ImportExportMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + IMPORT_CARD("^import card ([^\n]+)$"), + EXPORT_CARD("^export card ([^\n]+)$"); + + private final String regex; + + ImportExportMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 2/src/main/java/controller/loginmenu/LoginMenuController.java b/My Part 2/src/main/java/controller/loginmenu/LoginMenuController.java new file mode 100644 index 0000000..178d000 --- /dev/null +++ b/My Part 2/src/main/java/controller/loginmenu/LoginMenuController.java @@ -0,0 +1,120 @@ +package controller.loginmenu; + +import controller.Utils; +import model.Player; +import view.MainMenuView; + +import java.util.regex.Matcher; + +public class LoginMenuController { + public static LoginMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) System.exit(0); + else if (command.equals("menu show-current")) return LoginMenuMessages.SHOW_MENU; + else if (command.startsWith("user create")) { + return checkCreateUser(command); + } else if (command.startsWith("user login")) { + return checkLoginUser(command); + } + + return LoginMenuMessages.INVALID_COMMAND; + } + + private static LoginMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(LoginMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return LoginMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return LoginMenuMessages.INVALID_NAVIGATION; + } + + return LoginMenuMessages.FIRST_LOGIN; + } + + private static LoginMenuMessages checkCreateUser(String command) { + Matcher matcher; + String username, nickname, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIRST_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(2); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SECOND_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(3); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_THIRD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(1); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FOURTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIFTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(3); + password = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SIXTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (Player.getPlayerByUsername(username) != null) { + LoginMenuMessages.setUsername(username); + return LoginMenuMessages.USERNAME_EXISTS; + } + if (Player.isNicknameExist(nickname)) { + LoginMenuMessages.setNickname(nickname); + return LoginMenuMessages.NICKNAME_EXISTS; + } + +// TODO: handle to have "strong password" error + createUser(username, password, nickname); + return LoginMenuMessages.USER_CREATED; + } + + private static void createUser(String username, String password, String nickname) { + new Player(username, password, nickname); + } + + private static LoginMenuMessages checkLoginUser(String command) { + Matcher matcher; + String username, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (!Player.isPasswordCorrect(username, password)) { + return LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD; + } + + return LoginMenuMessages.USER_LOGGED_IN; + } + + public static void loginUser(String command) { + Matcher matcher; + String username = null; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + } + + + MainMenuView mainMenuView = new MainMenuView(Player.getPlayerByUsername(username)); + mainMenuView.mainMenuView(); + } +} diff --git a/My Part 2/src/main/java/controller/loginmenu/LoginMenuMessages.java b/My Part 2/src/main/java/controller/loginmenu/LoginMenuMessages.java new file mode 100644 index 0000000..167c111 --- /dev/null +++ b/My Part 2/src/main/java/controller/loginmenu/LoginMenuMessages.java @@ -0,0 +1,31 @@ +package controller.loginmenu; + +public enum LoginMenuMessages { + FIRST_LOGIN("please login first"), + INVALID_NAVIGATION("menu navigation is not possible"), + SHOW_MENU("Login Menu"), + USER_CREATED("user created successfully!"), + USERNAME_EXISTS("user with username already exists"), + NICKNAME_EXISTS("user with nickname already exists"), + USER_LOGGED_IN("user logged in successfully!"), + UNMATCHED_USERNAME_AND_PASSWORD("Username and password didn’t match!"), + INVALID_COMMAND("invalid command"); + + private String message; + + LoginMenuMessages(String message) { + this.message = message; + } + + public static void setUsername(String username) { + USERNAME_EXISTS.message = "user with username " + username + " already exists"; + } + + public static void setNickname(String nickname) { + NICKNAME_EXISTS.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 2/src/main/java/controller/loginmenu/LoginMenuRegexes.java b/My Part 2/src/main/java/controller/loginmenu/LoginMenuRegexes.java new file mode 100644 index 0000000..f518551 --- /dev/null +++ b/My Part 2/src/main/java/controller/loginmenu/LoginMenuRegexes.java @@ -0,0 +1,23 @@ +package controller.loginmenu; + +public enum LoginMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + CREATE_USER_FIRST_PATTERN("^user create --(?:username|U) (\\S+) --(?:nickname|N) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_SECOND_PATTERN("^user create --(?:username|U) (\\S+) --(?:password|P) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_THIRD_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_FOURTH_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"), + CREATE_USER_FIFTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:username|U) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_SIXTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:nickname|N) (\\S+) --(?:username|U) (\\S+)$"), + LOGIN_USER_USERNAME_PATTERN("^user login --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + LOGIN_USER_PASSWORD_PATTERN("^user login --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"); + + private final String regex; + + LoginMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 2/src/main/java/controller/mainmenu/MainMenuController.java b/My Part 2/src/main/java/controller/mainmenu/MainMenuController.java new file mode 100644 index 0000000..6f68f7b --- /dev/null +++ b/My Part 2/src/main/java/controller/mainmenu/MainMenuController.java @@ -0,0 +1,117 @@ +package controller.mainmenu; + +import controller.Utils; +import model.Player; +import view.DuelMenuView; +import view.ImportExportMenuView; +import view.ProfileMenuView; +import view.ShopMenuView; + +import java.util.regex.Matcher; + +public class MainMenuController { + private final Player loggedInPlayer; + + public MainMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public MainMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return MainMenuMessages.EXIT_MAIN_MENU; + else if (command.equals("menu show-current")) return MainMenuMessages.SHOW_MENU; + else if (command.equals("user logout")) return MainMenuMessages.USER_LOGGED_OUT; + else if (command.startsWith("duel")) return enterDuelMenu(command); + + return MainMenuMessages.INVALID_COMMAND; + } + + private MainMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(MainMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return MainMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Main")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Duel")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Deck")) { + DeckMenuView deckMenuView = new DeckMenuView(loggedInPlayer); + deckMenuView.deckMenuView(); + } else if (menu.equalsIgnoreCase("Scoreboard")) { + ScoreboardMenuView scoreboardMenuView = new ScoreboardMenuView(); + scoreboardMenuView.runScoreboard(); + } else if (menu.equalsIgnoreCase("Profile")) { + ProfileMenuView profileMenuView = new ProfileMenuView(loggedInPlayer); + profileMenuView.profileMenuView(); + } else if (menu.equalsIgnoreCase("Shop")) { + ShopMenuView shopMenuView = new ShopMenuView(loggedInPlayer); + shopMenuView.shopMenuView(); + } else if (menu.equalsIgnoreCase("ImportExport")) { + ImportExportMenuView importExportMenuView = new ImportExportMenuView(); + importExportMenuView.ImportExportMenuView(); + } + + return MainMenuMessages.EMPTY; + } + + private MainMenuMessages enterDuelMenu(String command) { +// TODO: clean and optimise this code according to AI + Matcher matcher; + String opponentPlayerCommand, rounds; + if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIRST_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_THIRD_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FOURTH_PATTERN.getRegex(), command) ).find()) { + opponentPlayerCommand = matcher.group(1); + rounds = matcher.group(2); + } else if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SECOND_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIFTH_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SIXTH_PATTERN.getRegex(), command) ).find()) { + rounds = matcher.group(1); + opponentPlayerCommand = matcher.group(2); + } else { + return MainMenuMessages.INVALID_COMMAND; + } + + if (opponentPlayerCommand.startsWith("second-player")) { + String opponentPlayerUsername = opponentPlayerCommand.substring(14); + Player opponentPlayer = Player.getPlayerByUsername(opponentPlayerUsername); + if (opponentPlayer == null) { + return MainMenuMessages.UNAVAILABLE_USERNAME; + } + + if (opponentPlayer.equals(loggedInPlayer)) return MainMenuMessages.SAME_USERNAME; + + if (loggedInPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(loggedInPlayer.getUsername()); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } else if (opponentPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(opponentPlayerUsername); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } + +// TODO: handle MainMenuMessages.INVALID_DECK message +// TODO: MainMenuMessages.setInvalidDeck(opponentPlayerUsername or loggedInPlayer.getUsername()); +// TODO: return MainMenuMessages.INVALID_DECK; + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + +// TODO: handle 1 or 3 turn game + DuelMenuView duelMenuView = new DuelMenuView(loggedInPlayer, opponentPlayer); + duelMenuView.duelMenuView(); + } else { +// TODO: handle entering to enter duel menu by AI + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + } + + return MainMenuMessages.EMPTY; + } +} diff --git a/My Part 2/src/main/java/controller/mainmenu/MainMenuMessages.java b/My Part 2/src/main/java/controller/mainmenu/MainMenuMessages.java new file mode 100644 index 0000000..85fa672 --- /dev/null +++ b/My Part 2/src/main/java/controller/mainmenu/MainMenuMessages.java @@ -0,0 +1,33 @@ +package controller.mainmenu; + +public enum MainMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_MAIN_MENU(""), + SHOW_MENU("Main Menu\n"), + USER_LOGGED_OUT("user logged out successfully!\n"), + UNAVAILABLE_USERNAME("there is no player with this username\n"), + SAME_USERNAME("please enter another username\n"), + UNAVAILABLE_ACTIVE_DECK(" has no active deck\n"), + INVALID_DECK("’s deck is invalid\n"), + INVALID_ROUNDS_NUMBER("number of rounds is not supported\n"), + INVALID_COMMAND("invalid command\n"), + EMPTY(""); + + private String message; + + MainMenuMessages(String message) { + this.message = message; + } + + public static void setUnavailableActiveDeck(String username) { + UNAVAILABLE_ACTIVE_DECK.message = username + " has no active deck\n"; + } + + public static void setInvalidDeck(String username) { + INVALID_DECK.message = username + "’s deck is invalid\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 2/src/main/java/controller/mainmenu/MainMenuRegexes.java b/My Part 2/src/main/java/controller/mainmenu/MainMenuRegexes.java new file mode 100644 index 0000000..210780f --- /dev/null +++ b/My Part 2/src/main/java/controller/mainmenu/MainMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.mainmenu; + +public enum MainMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + ENTER_DUEL_MENU_FIRST_PATTERN("^duel --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_SECOND_PATTERN("^duel --(?:new|N) --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_THIRD_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_FOURTH_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+) --(?:new|N)$"), + ENTER_DUEL_MENU_FIFTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_SIXTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N)$"); + + private final String regex; + + MainMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 2/src/main/java/controller/profilemenu/ProfileMenuController.java b/My Part 2/src/main/java/controller/profilemenu/ProfileMenuController.java new file mode 100644 index 0000000..5384e86 --- /dev/null +++ b/My Part 2/src/main/java/controller/profilemenu/ProfileMenuController.java @@ -0,0 +1,99 @@ +package controller.profilemenu; + +import controller.Database; +import controller.Utils; +import model.Player; + +import java.util.regex.Matcher; + +public class ProfileMenuController { + private final Player loggedInPlayer; + + public ProfileMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ProfileMenuMessages findCommand(String command) { + String[] split = command.split("\\s+"); + if (split.length < 2) { + return ProfileMenuMessages.INVALID_COMMAND; + } else if (split[1].equals("enter")) { + return ProfileMenuMessages.CANT_NAVIGATE_MENU; + } else if (split[1].equals("exit")) { + return ProfileMenuMessages.EXIT_MENU; + } else if (split[1].equals("show")) { + return ProfileMenuMessages.PROFILE_MENU; + } else if (split[2].equals("--nickname")) { + return changeNickname(command); + } else if (command.startsWith("profile change")) { + return changePassword(command); + } + + return ProfileMenuMessages.INVALID_COMMAND; + } + + public ProfileMenuMessages changeNickname(String command) { + Matcher matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_NICKNAME.getRegex(), command); + + ProfileMenuMessages holdEnum = checkChangeNickName(matcher); + + if (holdEnum == null) { + loggedInPlayer.setNickname(matcher.group(1)); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_NICKNAME_DONE; + } + return holdEnum; + } + + public ProfileMenuMessages checkChangeNickName(Matcher matcher) { + if (matcher.find()) { + String nickname = matcher.group(1); + if (Player.isNicknameExist(nickname)) { + ProfileMenuMessages.setNickname(nickname); + return ProfileMenuMessages.NOT_UNIQUE_NICKNAME; + } + return null; + } else return ProfileMenuMessages.INVALID_COMMAND; + + } + + public ProfileMenuMessages changePassword(String command) { + String currentPassword, newPassword; + Matcher matcher; + if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIRST_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SECOND_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_THIRD_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FOURTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIFTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SIXTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else return ProfileMenuMessages.INVALID_COMMAND; + + ProfileMenuMessages holdEnum = checkChangePassword(currentPassword, newPassword); + + if (holdEnum == null) { + loggedInPlayer.setPassword(newPassword); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_PASSWORD_DONE; + } + + return holdEnum; + } + + public ProfileMenuMessages checkChangePassword(String currentPassword, String newPassword) { + if (!loggedInPlayer.getPassword().equals(currentPassword)) return ProfileMenuMessages.WRONG_CURRENT_PASSWORD; + if (currentPassword.equals(newPassword)) return ProfileMenuMessages.SAME_PASSWORD; + return null; + } +} diff --git a/My Part 2/src/main/java/controller/profilemenu/ProfileMenuMessages.java b/My Part 2/src/main/java/controller/profilemenu/ProfileMenuMessages.java new file mode 100644 index 0000000..4c0895f --- /dev/null +++ b/My Part 2/src/main/java/controller/profilemenu/ProfileMenuMessages.java @@ -0,0 +1,27 @@ +package controller.profilemenu; + +public enum ProfileMenuMessages { + NOT_UNIQUE_NICKNAME("user with nickname already exists"), + CHANGE_NICKNAME_DONE("nickname changed successfully!"), + CHANGE_PASSWORD_DONE("password changed successfully!"), + WRONG_CURRENT_PASSWORD("current password is invalid"), + INVALID_COMMAND("invalid command"), + PROFILE_MENU("profile menu"), + EXIT_MENU("exit"), + CANT_NAVIGATE_MENU("menu navigation is not possible"), + SAME_PASSWORD("please enter a new password"); + + private String message; + + ProfileMenuMessages(String message) { + this.message = message; + } + + public static void setNickname(String nickname) { + ProfileMenuMessages.NOT_UNIQUE_NICKNAME.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 2/src/main/java/controller/profilemenu/ProfileMenuRegexes.java b/My Part 2/src/main/java/controller/profilemenu/ProfileMenuRegexes.java new file mode 100644 index 0000000..ba8630d --- /dev/null +++ b/My Part 2/src/main/java/controller/profilemenu/ProfileMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.profilemenu; + +public enum ProfileMenuRegexes { + CHANGE_NICKNAME("^profile change --nickname (\\S+)$"), + CHANGE_PASSWORD_FIRST_PATTERN("^profile change --(?:password|P) --(?:current|C) (\\S+) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_SECOND_PATTERN("^profile change --(?:password|P) --(?:new|N) (\\S+) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_THIRD_PATTERN("^profile change --(?:current|C) (\\S+) --(?:password|P) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_FOURTH_PATTERN("^profile change --(?:current|C) (\\S+) --(?:new|N) (\\S+) --(?:password$|P)"), + CHANGE_PASSWORD_FIFTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:password|P) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_SIXTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:current|C) (\\S+) --(?:password$|P)"); + + private final String regex; + + ProfileMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 2/src/main/java/controller/scoreboardmenu/Scoreboard.java b/My Part 2/src/main/java/controller/scoreboardmenu/Scoreboard.java new file mode 100644 index 0000000..cb725a7 --- /dev/null +++ b/My Part 2/src/main/java/controller/scoreboardmenu/Scoreboard.java @@ -0,0 +1,40 @@ +package controller.scoreboardmenu; + +import java.util.ArrayList; +import model.*; + +public class Scoreboard { + + private Scoreboard() { + } + + private static Scoreboard instance; + + public static Scoreboard getInstance() { + if (instance == null) + instance = new Scoreboard(); + return instance; + } + + public void showScoreboard() { + int counter = 1; + int index = 0; + long previousScore = -1; + StringBuilder output = new StringBuilder(); + ArrayList allUsers = Player.getAllPlayers(); + allUsers.sort(Player::compareTo); + for (Player player : allUsers) { + + + if (player.getScore() != previousScore) { + index += counter; + counter = 1; + } else counter++; + output.append(index).append(". ").append(player.getNickname()).append(": ").append(player.getScore()).append("\n"); + previousScore = player.getScore(); + + } + ScoreboardOutput.getInstance().showMessage(output.toString()); + } + +} diff --git a/My Part 2/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java b/My Part 2/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java new file mode 100644 index 0000000..c77252d --- /dev/null +++ b/My Part 2/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java @@ -0,0 +1,23 @@ +package controller.scoreboardmenu; + +public class ScoreboardOutput { + + private ScoreboardOutput() { + } + + private static ScoreboardOutput instance; + + public static ScoreboardOutput getInstance() { + if (instance == null) + instance = new ScoreboardOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My Part 2/src/main/java/controller/shopmenu/ShopMenuController.java b/My Part 2/src/main/java/controller/shopmenu/ShopMenuController.java new file mode 100644 index 0000000..e8b9e95 --- /dev/null +++ b/My Part 2/src/main/java/controller/shopmenu/ShopMenuController.java @@ -0,0 +1,51 @@ +package controller.shopmenu; + +import controller.Database; +import controller.Utils; +import model.Player; +import model.cards.Card; + +import java.util.regex.Matcher; + +public class ShopMenuController { + private final Player loggedInPlayer; + + public ShopMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ShopMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ShopMenuMessages.EXIT_SHOP_MENU; + else if (command.equals("menu show-current")) return ShopMenuMessages.SHOW_MENU; + else if (command.startsWith("shop buy")) return buyACard(command); + else if (command.equals("shop show --all")) return ShopMenuMessages.SHOW_ALL_CARDS; + + return ShopMenuMessages.INVALID_COMMAND; + } + + private ShopMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + return ShopMenuMessages.INVALID_NAVIGATION; + } + + private ShopMenuMessages buyACard(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.BUY_CARD.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card boughtCard = Card.getCardByName(cardName); + if (boughtCard == null) return ShopMenuMessages.UNAVAILABLE_CARD; + + int boughtCardPrice = boughtCard.getPrice(); + if (boughtCardPrice > loggedInPlayer.getMoney()) return ShopMenuMessages.NOT_ENOUGH_MONEY; + + loggedInPlayer.decreaseMoney(boughtCardPrice); + loggedInPlayer.addCardToBoughtCards(boughtCard); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ShopMenuMessages.EMPTY; + } +} diff --git a/My Part 2/src/main/java/controller/shopmenu/ShopMenuMessages.java b/My Part 2/src/main/java/controller/shopmenu/ShopMenuMessages.java new file mode 100644 index 0000000..339bd0a --- /dev/null +++ b/My Part 2/src/main/java/controller/shopmenu/ShopMenuMessages.java @@ -0,0 +1,22 @@ +package controller.shopmenu; + +public enum ShopMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_SHOP_MENU(""), + SHOW_MENU("Shop Menu\n"), + UNAVAILABLE_CARD("there is no card with this name\n"), + NOT_ENOUGH_MONEY("not enough money\n"), + EMPTY(""), + SHOW_ALL_CARDS(""), + INVALID_COMMAND("invalid command\n"); + + private final String message; + + ShopMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 2/src/main/java/controller/shopmenu/ShopMenuRegexes.java b/My Part 2/src/main/java/controller/shopmenu/ShopMenuRegexes.java new file mode 100644 index 0000000..c2ca1ca --- /dev/null +++ b/My Part 2/src/main/java/controller/shopmenu/ShopMenuRegexes.java @@ -0,0 +1,16 @@ +package controller.shopmenu; + +public enum ShopMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + BUY_CARD("^shop buy ([^\n]+)$"); + + private final String regex; + + ShopMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 2/src/main/java/model/Board.java b/My Part 2/src/main/java/model/Board.java new file mode 100644 index 0000000..b0a5e2e --- /dev/null +++ b/My Part 2/src/main/java/model/Board.java @@ -0,0 +1,155 @@ +package model; + +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Board { + private MonsterCard[] monstersZone; + private MagicCard[] magicsZone; + private ArrayList graveyard; + private ArrayList cardsInHand; + private Deck deck; + private MagicCard fieldZone;//TODO: maybe it should be from these classes --> Spell / fieldSpell + private Card selectedCard; +// if this boolean equals "false" so we can conclude that opponent card selected or nothing selected + private boolean isMyCardSelected; + private boolean isACardInHandSelected; + + { + monstersZone = new MonsterCard[6]; + magicsZone = new MagicCard[6]; + graveyard = new ArrayList<>(); + cardsInHand = new ArrayList<>(); + fieldZone = null; + isMyCardSelected = false; + isACardInHandSelected = false; + } + + public void setDeck(Deck deck) { + this.deck = deck;//TODO: maybe we should have a copy of deck in duel menu --> if all changes don't apply in main deck + } + + public MonsterCard[] getMonstersZone() { + return monstersZone; + } + + public MagicCard[] getMagicsZone() { + return magicsZone; + } + + public ArrayList getGraveyard() { + return graveyard; + } + + public ArrayList getCardsInHand() { + return cardsInHand; + } + + public MagicCard getFieldZone() { + return fieldZone; + } + + public Card getSelectedCard() { + return selectedCard; + } + + public Deck getDeck() { + return deck; + } + + public void setSelectedCard(Card selectedCard) { + this.selectedCard = selectedCard; + } + + public void setFieldZone(MagicCard fieldZone) { + this.fieldZone = fieldZone; + } + + public boolean isMyCardSelected() { + return isMyCardSelected; + } + + public void setMyCardSelected(boolean myCardSelected) { + isMyCardSelected = myCardSelected; + } + + public boolean isACardInHandSelected() { + return isACardInHandSelected; + } + + public void setACardInHandSelected(boolean ACardInHandSelected) { + isACardInHandSelected = ACardInHandSelected; + } + + public boolean isMagicsZoneFull() { + return getNumberOfFullPartsOfMagicsZone() == 5; + } + + public boolean isMagicsZoneEmpty() { + return getNumberOfFullPartsOfMagicsZone() == 0; + } + + public int getNumberOfFullPartsOfMagicsZone() { + int numberOfFullPartsOfMagicsZone = 0; + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) ++numberOfFullPartsOfMagicsZone; + } + return numberOfFullPartsOfMagicsZone; + } + + public boolean isCardFaceUp(String cardName) { +// if cardName isn't available, then this method returns false + boolean isCardFaceUp = false; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = monstersZone[i].getCardFaceUp(); + } + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = magicsZone[i].getCardFaceUp(); + } + return isCardFaceUp; + } + + public void addSpellCardToFieldZone(MagicCard spellCard) { + MagicCard previousFieldZone = fieldZone; + if (previousFieldZone != null) graveyard.add(previousFieldZone); + setFieldZone(spellCard); + } + + public boolean addMagicCardToMagicsZone(MagicCard magicCard) { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] == null) { + magicsZone[i] = magicCard; + return true; + } + } + return false; + } + + public boolean isCardAvailableInMonstersZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monsterCard)) return true; + } + return false; + } + + public int getNumberOfFaceUpMonsterCards() { + int numberOfFaceUpMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getCardFaceUp()) ++numberOfFaceUpMonsterCards; + } + + return numberOfFaceUpMonsterCards; + } + + public int getNumberOfWarriorMonsterCards() { + int numberOfWarriorMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getMonsterType().equals("Warrior")) ++numberOfWarriorMonsterCards; + } + + return numberOfWarriorMonsterCards; + } +} diff --git a/My Part 2/src/main/java/model/Deck.java b/My Part 2/src/main/java/model/Deck.java new file mode 100644 index 0000000..217f43b --- /dev/null +++ b/My Part 2/src/main/java/model/Deck.java @@ -0,0 +1,195 @@ +package model; + +import controller.deckmenu.DeckMenuDatabase; +import model.*; +import controller.deckmenu.*; +import model.cards.Card; + +import java.util.ArrayList; + +public class Deck { + public ArrayList mainCards = new ArrayList<>(); + public ArrayList sideCards = new ArrayList<>(); + Player owner; + String name; + DeckType type; + Boolean isActive = false; + Boolean IsValid; + + public Deck(String name, Player owner, boolean hasSideDeck, boolean shouldBeSaved) { + this.name = name; + if (shouldBeSaved) + DeckMenuDatabase.allDecks.add(this); + if (!hasSideDeck) + sideCards = null; + this.owner = owner; + } + + public Deck(String name, Player owner) { + this.name = name; + sideCards = null; + this.owner = owner; + } + + public Deck(String name) { + this.name = name; + sideCards = null; + } + public Deck() { + sideCards = null; + } + + public void updateOwnerDecks() { + String deckType = (name.length() > 16) ? name.substring(name.length() - 16) : ""; + if (deckType.equals(".purchased-cards")) + owner.setAllPlayerCard(this); + else { + owner.getAllDeck().add(this); + if (this.isActive) + owner.setActiveDeck(this); + } + } + + public ArrayList getMainCards() { + if (mainCards == null) + return (mainCards = new ArrayList<>()); + return mainCards; + } + + public void setMainCards(ArrayList mainCards) { + this.mainCards = mainCards; + } + + public ArrayList getSideCards() { + return sideCards; + } + + public void setSideCards(ArrayList sideCards) { + this.sideCards = sideCards; + } + + public Player getOwner() { + return owner; + } + + public void setOwner(Player owner) { + this.owner = owner; + } + + public void setActive(Boolean active) { + isActive = active; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setActivation(Boolean active) { + isActive = active; + } + + public void setValid(Boolean valid) { + IsValid = valid; + } + + public void setType(DeckType type) { + this.type = type; + } + + public void addCard(Card card, boolean shouldBeAddedToMain) { + if (shouldBeAddedToMain) + mainCards.add(card); + else + sideCards.add(card); + if (card != null) + card.setCurrentDeck(this); + } + + public void addCard(Card card) { + mainCards.add(card); + if (card != null && !name.equals("selected collected deck")) + card.setCurrentDeck(this); + } + + public void moveCardTo(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCard(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public void moveCardToForGame(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCardForGame(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public boolean hasCard(Card card, boolean isMain) { + if (isMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) + return true; + + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + return true; + } + return false; + } + + public void removeCard(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) { + mainCards.remove(cardInMain); + return; + } + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + sideCards.remove(cardInSide); + return; + } + } + + public void removeCardForGame(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) + mainCards.remove(card); + else + sideCards.remove(card); + } + + public int getNumberOfCardsInDeck(Card card) { + int count = 0; + for (Card cardInDeck : mainCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + for (Card cardInDeck : sideCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + return count; + } + + public int getNumberOfCardsInMainDeck() { + return mainCards.size(); + } + + public int getNumberOfCardsInSideDeck() { + return sideCards.size(); + } + + public void updateCurrentDeck() { + if (mainCards != null) + for (Card card : mainCards) + if (card != null) + card.setCurrentDeck(this); + if (sideCards != null) + for (Card card : sideCards) + if (card != null) + card.setCurrentDeck(this); + } +} \ No newline at end of file diff --git a/My Part 2/src/main/java/model/DeckType.java b/My Part 2/src/main/java/model/DeckType.java new file mode 100644 index 0000000..2d1643c --- /dev/null +++ b/My Part 2/src/main/java/model/DeckType.java @@ -0,0 +1,8 @@ +package model; + +public enum DeckType { + regulardeck, + inactivedeck, + graveyarddeck, + selectedcarddeck +} diff --git a/My Part 2/src/main/java/model/Player.java b/My Part 2/src/main/java/model/Player.java new file mode 100644 index 0000000..b6c3bcd --- /dev/null +++ b/My Part 2/src/main/java/model/Player.java @@ -0,0 +1,280 @@ +package model; + +import com.google.gson.annotations.Expose; +import controller.Database; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Player { + private static ArrayList allPlayers; + + static { + allPlayers = new ArrayList<>(); + } + + @Expose + private ArrayList boughtCards; + @Expose + private ArrayList allMainDecks; + private Board board; + @Expose + private Deck sideDeck; + @Expose + private Deck activatedDeck; + @Expose + private String username; + @Expose + private String password; + @Expose + private String nickname; + @Expose + private long score; + @Expose + private long money; + private int lifePoint = 8000; + private transient Deck allPlayerCard; + private transient ArrayList allDeck = new ArrayList<>(); + private transient ArrayList gameDecks = new ArrayList<>(); + + { + boughtCards = new ArrayList<>(); + allMainDecks = new ArrayList<>(); + board = null; + sideDeck = new Deck(); + activatedDeck = null; + score = 0; + money = 100000; + } + + public Player(String username, String password, String nickname) { + setUsername(username); + setPassword(password); + setNickname(nickname); + addPlayerToAllPlayers(this); + allPlayers.add(this); + Database.updatePlayerInformationInDatabase(this); + } + + public static Boolean isNicknameExist(String nickname) { + for (Player player : allPlayers) { + if (player.nickname.equals(nickname)) return true; + } + return false; + } + + public static Boolean isPasswordCorrect(String username, String password) { + Player player = getPlayerByUsername(username); + if (player == null) return false; + + return player.password.equals(password); + } + + public static Player getPlayerByUsername(String username) { + for (Player player : allPlayers) { + if (player.username.equals(username)) return player; + } + return null; + } + + public void setBoughtCards(ArrayList boughtCards) { + this.boughtCards = boughtCards; + } + + public Deck getActiveDeck() { + return activatedDeck; + } + + public void setActiveDeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public ArrayList getAllDeck() { + if (allDeck == null) + return (allDeck = new ArrayList<>()); + return allDeck; + } + + public void setAllDeck(ArrayList allDeck) { + this.allDeck = allDeck; + } + + public Deck getAllPlayerCard() { + return allPlayerCard; + } + + public static ArrayList getAllPlayers() { + return allPlayers; + } + + public void addCardToAllPlayerCard(Card card) { + this.allPlayerCard.getMainCards().add(card); + } + + public void setAllPlayerCard(Deck allPlayerCard) { + this.allPlayerCard = allPlayerCard; + } + + public static void addPlayerToAllPlayers(Player player) { + allPlayers.add(player); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public long getScore() { + return score; + } + + public long getMoney() { + return money; + } + + public Deck getActivatedDeck() { + return activatedDeck; + } + + public ArrayList getBoughtCards() { + return boughtCards; + } + + public void increaseScore(long score) { + this.score += score; + } + + public void decreaseScore(long score) { + this.score -= score; + } + + public void increaseMoney(long money) { + this.money += money; + } + + public void decreaseMoney(long money) { + this.money -= money; + } + + public void addCardToBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.add(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.add(new MagicCard((MagicCard) card)); + } + } + + public void addMainDeck(String deckName) { + Deck mainDeck = new Deck(deckName); + this.allMainDecks.add(mainDeck); + } + + public Boolean isMainDeckExist(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return true; + } + return false; + } + + public void deleteMainDeck(String deckName) { + Deck mainDeck = getDeckByName(deckName); + if (mainDeck != null) { + boughtCards.addAll(mainDeck.getMainCards()); + allMainDecks.remove(mainDeck); + } + } + + public Deck getDeckByName(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return deck; + } + return null; + } + + public int compareTo(Player player) { + if (this.score > player.score) + return -1; + if (this.score < player.score) + return 1; + if (this.nickname.compareTo(player.getNickname()) > 0) + return -1; + if (this.nickname.compareTo(player.getNickname()) < 0) + return 1; + return 0; + } + + public void activateADeck(String deckName) { + Deck deck = getDeckByName(deckName); + if (deck != null) activatedDeck = deck; + } + public void activateADeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public void addCardToMainDeck() { +// TODO: ???? but remember to remove this card from boughtCards :) + } + + public void removeACard() { +// TODO: ???? but remember to add this card from boughtCards :) + } + + public void decreaseLifePoint(int amount) { + this.lifePoint -= amount; + } + + public void increaseLifePoint(int amount) { + this.lifePoint += amount; + } + + public void setLifePoint(int lifePoint) { + this.lifePoint = lifePoint; + } + + public int getLifePoint() { + return lifePoint; + } + + public void createBoard() { + board = new Board(); + } + + public Board getBoard() { + return board; + } + + public boolean hasCard(Card card){ + for (Card boughtCard : boughtCards) { + if (card.getName().equals(boughtCard.getName())) + return true; + } + return false; + } +} \ No newline at end of file diff --git a/My Part 2/src/main/java/model/cards/Card.java b/My Part 2/src/main/java/model/cards/Card.java new file mode 100644 index 0000000..9ebd536 --- /dev/null +++ b/My Part 2/src/main/java/model/cards/Card.java @@ -0,0 +1,115 @@ +package model.cards; + +import com.google.gson.annotations.Expose; +import model.Deck; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.TreeMap; + +public class Card { + protected static HashMap allCards; + + static { + allCards = new HashMap<>(); + } + + @Expose + protected final String name; + protected final String description; + protected final CardTypes cardType; + protected final int price; +// if this boolean equals "false" so we can conclude that card is "face down" + protected transient boolean isCardFaceUp; + protected transient boolean isPowerUsed; + protected transient Deck currentDeck; + + { + isCardFaceUp = false; + isPowerUsed = false; + } + + public Card(String name, String description, CardTypes cardType, int price) { + this.name = name; + this.description = description; + this.cardType = cardType; + this.price = price; + } + + public static Card getCardByName(String name) { + return allCards.get(name); + } + + public static TreeMap getListOfCards() { + TreeMap listOfCards = new TreeMap<>(); + for (String cardName : allCards.keySet()) { + Integer cardPrice = allCards.get(cardName).getPrice(); + listOfCards.put(cardName, cardPrice); + } + return listOfCards; + } + + public static boolean isMonsterCard(Card card) { + try { + MonsterCard monsterCard = (MonsterCard) card; + return true; + } catch (Exception exception) { + return false; + } + } + + public static int findNumberOfMonsterCards(ArrayList cards) { + int numberOfMonsterCards = 0; + for (Card card : cards) { + if (Card.isMonsterCard(card)) ++numberOfMonsterCards; + } + return numberOfMonsterCards; + } + + public static void addCardToAllCards(Card card) { + allCards.put(card.getName(), card); + } + + public static HashMap getAllCards() { + return allCards; + } + + public String getName() { + return name; + } + + public void setCurrentDeck(Deck currentDeck) { this.currentDeck = currentDeck; } + + public Deck getCurrentDeck() { + return currentDeck; + } + + public CardTypes getCardType() { + return cardType; + } + + public int getPrice() { + return price; + } + + public void setPowerUsed(boolean powerUsed) { + isPowerUsed = powerUsed; + } + + public boolean isPowerUsed() { + return isPowerUsed; + } + + public String getDescription() { + return description; + } + + public Boolean getCardFaceUp() { + return isCardFaceUp; + } + + public void setCardFaceUp(Boolean cardFaceUp) { + isCardFaceUp = cardFaceUp; + } +} diff --git a/My Part 2/src/main/java/model/cards/CardTypes.java b/My Part 2/src/main/java/model/cards/CardTypes.java new file mode 100644 index 0000000..520056f --- /dev/null +++ b/My Part 2/src/main/java/model/cards/CardTypes.java @@ -0,0 +1,26 @@ +package model.cards; + +import com.google.gson.annotations.SerializedName; + +public enum CardTypes { + @SerializedName("Normal") + NORMAL("Normal"), + @SerializedName("Effect") + EFFECT("Effect"), + @SerializedName("Ritual") + RITUAL("Ritual"), + @SerializedName("Spell") + SPELL("Spell"), + @SerializedName("Trap") + TRAP("Trap"); + + private final String regex; + + CardTypes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 2/src/main/java/model/cards/magiccard/MagicCard.java b/My Part 2/src/main/java/model/cards/magiccard/MagicCard.java new file mode 100644 index 0000000..396faf8 --- /dev/null +++ b/My Part 2/src/main/java/model/cards/magiccard/MagicCard.java @@ -0,0 +1,39 @@ +package model.cards.magiccard; + +import model.cards.Card; +import model.cards.CardTypes; + +public class MagicCard extends Card { + protected final String icon; + protected final MagicCardStatuses status; + + public MagicCard(String name, CardTypes cardType, String icon, String description, MagicCardStatuses status, int price) { + super(name, description, cardType, price); + this.icon = icon; + this.status = status; + allCards.put(name, this); + } + + public MagicCard(MagicCard magicCard) { + super(magicCard.name, magicCard.description, magicCard.cardType, magicCard.price); + this.icon = magicCard.icon; + this.status = magicCard.status; + } + + public String getIcon() { + return icon; + } + + public MagicCardStatuses getStatus() { + return status; + } + + public void print() { +// TODO: handle it --> «this.equals(null)» have error and «System.out.print» should be in the view +// if (this.equals(null)) +// System.out.print("E "); +// else if (isCardFaceUp) +// System.out.print("O "); +// else System.out.print("H "); + } +} diff --git a/My Part 2/src/main/java/model/cards/magiccard/MagicCardStatuses.java b/My Part 2/src/main/java/model/cards/magiccard/MagicCardStatuses.java new file mode 100644 index 0000000..a2540c9 --- /dev/null +++ b/My Part 2/src/main/java/model/cards/magiccard/MagicCardStatuses.java @@ -0,0 +1,20 @@ +package model.cards.magiccard; + +import com.google.gson.annotations.SerializedName; + +public enum MagicCardStatuses { + @SerializedName("Limited") + LIMITED("Limited"), + @SerializedName("Unlimited") + UNLIMITED("Unlimited"); + + private final String regex; + + MagicCardStatuses(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 2/src/main/java/model/cards/monstercard/MonsterCard.java b/My Part 2/src/main/java/model/cards/monstercard/MonsterCard.java new file mode 100644 index 0000000..f73d8b7 --- /dev/null +++ b/My Part 2/src/main/java/model/cards/monstercard/MonsterCard.java @@ -0,0 +1,124 @@ +package model.cards.monstercard; + +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; + +import java.util.ArrayList; + +public class MonsterCard extends Card implements SpecialMonstersFunction { + protected final short level; + protected final MonsterCardAttributes attribute; + protected final String monsterType; + protected int attackPoints; + protected int defensePoints; + protected transient ArrayList equippedBy; +// if this boolean equals "false" so we can conclude that card is in attack position + protected transient boolean isDefensePosition; + protected transient boolean isAttacked = false; + + { + equippedBy = new ArrayList<>(); + isDefensePosition = false; + } + + public MonsterCard(String name, short level, MonsterCardAttributes attribute, String monsterType, CardTypes cardType, + int attackPoints, int defensePoints, String description, int price) { + super(name, description, cardType, price); + this.level = level; + this.attribute = attribute; + this.monsterType = monsterType; + setAttackPoints(attackPoints); + setDefensePoints(defensePoints); + allCards.put(name, this); + } + + public MonsterCard(MonsterCard monsterCard) { + super(monsterCard.name, monsterCard.description, monsterCard.cardType, monsterCard.price); + this.level = monsterCard.level; + this.attribute = monsterCard.attribute; + this.monsterType = monsterCard.monsterType; + this.attackPoints = monsterCard.attackPoints; + this.defensePoints = monsterCard.defensePoints; + } + + public short getLevel() { + return level; + } + + public MonsterCardAttributes getAttribute() { + return attribute; + } + + public String getMonsterType() { + return monsterType; + } + + public int getAttackPoints() { + return attackPoints; + } + + public void setAttackPoints(int attackPoints) { + this.attackPoints = attackPoints; + } + + public int getDefensePoints() { + return defensePoints; + } + + public void setDefensePoints(int defensePoints) { + this.defensePoints = defensePoints; + } + + public boolean isAttacked() { + return isAttacked; + } + + public void setAttacked(boolean attacked) { + isAttacked = attacked; + } + + public boolean isDefensePosition() { + return isDefensePosition; + } + + public void setDefensePosition(boolean defensePosition) { + isDefensePosition = defensePosition; + } + + public ArrayList getEquippedBy() { + return equippedBy; + } + + public void addToEquippedBy(MagicCard equippedBy) { + this.equippedBy.add(equippedBy); + } + + public void increaseAttackPoints(int amount) { + attackPoints += amount; + } + + public void decreaseAttackPoints(int amount) { + attackPoints -= amount; + } + + public void increaseDefencePoints(int amount) { + defensePoints += amount; + } + + public void decreaseDefencePoints(int amount) { + defensePoints -= amount; + } + + public void createEquippedByArrayList() { + equippedBy = new ArrayList<>(); + } + + @Override + public String toString() { + if (!this.getCardFaceUp() && this.isDefensePosition) return "DH"; + else if (this.getCardFaceUp() && this.isDefensePosition) return "DO"; + else if (this.getCardFaceUp() && !this.isDefensePosition) return "OO"; + return "E "; + } +} diff --git a/My Part 2/src/main/java/model/cards/monstercard/MonsterCardAttributes.java b/My Part 2/src/main/java/model/cards/monstercard/MonsterCardAttributes.java new file mode 100644 index 0000000..4677550 --- /dev/null +++ b/My Part 2/src/main/java/model/cards/monstercard/MonsterCardAttributes.java @@ -0,0 +1,10 @@ +package model.cards.monstercard; + +public enum MonsterCardAttributes { + DARK, + EARTH, + FIRE, + LIGHT, + WATER, + WIND; +} diff --git a/My Part 2/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java b/My Part 2/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java new file mode 100644 index 0000000..0b73141 --- /dev/null +++ b/My Part 2/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java @@ -0,0 +1,157 @@ +package model.cards.monstercard; + +import controller.duelmenu.DuelMenuMessages; +import model.Board; +import model.Player; + +public interface SpecialMonstersFunction { + default DuelMenuMessages attack(Player attackingPlayer, Player opponentPlayer, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + MonsterCard attackingCard = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentCard = opponentPlayerBoard.getMonstersZone()[numberToAttack]; + + if (opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack) != null) { + + switch (opponentCard.toString()) { + case "OO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayer.decreaseLifePoint(attackingCard.attackPoints - opponentCard.attackPoints); + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + DuelMenuMessages.setOpponentGotDamageInAttack(attackingCard.attackPoints - opponentCard.attackPoints); + return DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setAttackingPlayerCardDestroyed(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED; + } + + case "DO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + return DuelMenuMessages.DEFENSE_POSITION_MONSTER_DESTROYED; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + return DuelMenuMessages.NO_CARD_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setReceiveDamageByAttackingToDefenseCard(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD; + } + case "DH": + break; + } + + return null; + + } else + return opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + + default DuelMenuMessages defense(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + switch (opponentCard.getName()) { + case "Command knight": + commandKnightFunction(opponentPlayerBoard); + break; + case "Yomi Ship": + return yomiShipFunction(attackingPlayerBoard, attackingCard, opponentCard); + case "Suijin": + return suijinFunction(attackingCard); + case "Marshmallon": + return marshmallonFunction(attackingPlayer); + case "Texchanger": + return texchangerFunction(opponentCard); + case "Exploder Dragon": + return exploderDragon(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + return null; + } + + default DuelMenuMessages texchangerFunction(MonsterCard opponentCard) { + if (!opponentCard.isPowerUsed()) { + opponentCard.setPowerUsed(true); + // choosing a card ehzar??????? + return DuelMenuMessages.ATTACK_CANCELED; + } + return null; + } + + default DuelMenuMessages commandKnightFunction(Board opponentPlayerBoard) { + for (int i = 1; i <= 5; i++) { + if (opponentPlayerBoard.getMonstersZone()[i] != null && !opponentPlayerBoard.getMonstersZone()[i].getName().equals("Command knight")) { + return DuelMenuMessages.YOU_CANT_ATTACK_TO_THIS_CARD; + } + } + return null; + } + + default DuelMenuMessages yomiShipFunction(Board attackingPlayerBoard, MonsterCard attackingCard, MonsterCard opponentCard) { + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + return null; + } + + default DuelMenuMessages suijinFunction(MonsterCard attackingCard) { +// attackingCard.setAttackLevel(0);//TODO: undo it!! + return null; + } + + default DuelMenuMessages marshmallonFunction(Player attackingPlayer) { + attackingPlayer.decreaseLifePoint(1000); + return null; + } + + default DuelMenuMessages exploderDragon(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int number) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + return null; + } + + default void deleteMonsterFromZone(MonsterCard monster, MonsterCard[] monstersZone) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monster)) { + monstersZone[i] = null; + break; + } + } + } +} diff --git a/My Part 2/src/main/java/view/DeckMenuView.java b/My Part 2/src/main/java/view/DeckMenuView.java new file mode 100644 index 0000000..fd374b8 --- /dev/null +++ b/My Part 2/src/main/java/view/DeckMenuView.java @@ -0,0 +1,136 @@ +package view; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import controller.deckmenu.DeckMenuController; +import controller.deckmenu.DeckMenuOutput; +import model.*; + +public class DeckMenuView { + public static Scanner scanner = new Scanner(System.in); + + private Player loggedInPlayer; + + public DeckMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + private final String[] deckMenuRegexes = { + "^deck create (?\\w+)$", + "^deck delete (?\\w+)$", + "^deck set-activate (?\\w+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck add-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck show (?:--all|-a)$", + "^deck show (?:--deck-name|-d) (?.+) (?:--side|-s)$", + "^deck show (?:--side|-s) (?:--deck-name|-d) (?.+)$", + "^deck show (?:--deck-name|-d) (?.+)$", + "^menu show-current$", + "^menu exit$" + }; + + public void runDeckMenu() { + Matcher commandMatcher; + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + int whichCommand; + for (whichCommand = 0; whichCommand < deckMenuRegexes.length; whichCommand++) { + commandMatcher = findMatcher(command, deckMenuRegexes[whichCommand]); + if (commandMatcher.find()) { + executeDeckMenuCommands(commandMatcher, whichCommand); + break; + } else if (whichCommand == deckMenuRegexes.length - 1) + DeckMenuOutput.getInstance().showMessage("invalid command"); + } + + } + } + + private void executeDeckMenuCommands(Matcher commandMatcher, int whichCommand) { + DeckMenuController controller = DeckMenuController.getInstance(); + switch (whichCommand) { + case 0: + controller.createDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 1: + controller.deleteDeck(commandMatcher.group("name")); + break; + case 2: + controller.setActiveDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + String cardName = commandMatcher.group("cardName"), + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, false); + break; + case 9: + case 10: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, true); + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, false); + break; + case 17: + case 18: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, true); + break; + case 19: + controller.showAllDecks(loggedInPlayer); + break; + case 20: + case 21: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, false); + break; + case 22: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, true); + break; + case 23: + DeckMenuOutput.getInstance().showMessage("Deck Menu"); + break; + case 24: + MainMenuView.mainMenuView; +// go to main menu; + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } + + +} diff --git a/My Part 2/src/main/java/view/DuelMenuView.java b/My Part 2/src/main/java/view/DuelMenuView.java new file mode 100644 index 0000000..24661b5 --- /dev/null +++ b/My Part 2/src/main/java/view/DuelMenuView.java @@ -0,0 +1,140 @@ +package view; + +import controller.Utils; +import controller.duelmenu.DuelMenuController; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.Phases; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +public class DuelMenuView { + private Player firstPlayer; + private Player secondPlayer; + private Phases phase; + + public DuelMenuView(Player firstPlayer, Player secondPlayer) { + this.firstPlayer = firstPlayer; + this.secondPlayer = secondPlayer; + } + + public static String findChooseOfPlayerInMiniGame(Player player) { + System.out.println(player.getUsername() + ", please choose between stone, paper and scissor:"); + return Utils.getScanner().nextLine().trim(); + } + + public static void showGraveyard(Board board) { + if (board.getGraveyard().size() != 0) { + for (int i = 1; i <= board.getGraveyard().size(); i++) { + printCard(i , board.getGraveyard().get(i)); + } + } else System.out.println("graveyard empty"); + while (true) { + String input = Utils.getScanner().nextLine(); + if (input.equals("back")) + break; + } + } + + public static void printCard(int number, Card card) { + System.out.println(number + ". " + card.getName() + ": " + card.getDescription()); + } + + private static void showBoard(Board playerBoard, Board opponentBoard) { + showCardsInHand(opponentBoard); +// showLeftCardDeck(opponentBoard);//?????????????????????? + showOpponentMagicsZone(opponentBoard); + showOpponentMonstersZone(opponentBoard); + showGraveyard(opponentBoard); + System.out.println("--------------------------"); + showCardsInHand(playerBoard); +// showLeftCardDeck(playerBoard);//???????? + showMagicsZone(playerBoard); + showMonstersZone(playerBoard); + showGraveyard(playerBoard); + } + + private static void showMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// monsters[5].print(); +// System.out.print(monsters[5].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[4].print() + " "); +// System.out.println(); + } + + private static void showMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[5].print(); + magicsZone[3].print(); + magicsZone[1].print(); + magicsZone[2].print(); + magicsZone[4].print(); + } + + private static void showOpponentMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// System.out.print(monsters[4].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[5].print() + " "); + } + + private static void showOpponentMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[4].print(); + magicsZone[2].print(); + magicsZone[1].print(); + magicsZone[3].print(); + magicsZone[5].print(); + } + + private static void showCardsInHand(Board board) { + for (int i = 0; i < board.getCardsInHand().size(); i++) { + System.out.print("C "); + } + System.out.println(); + } + + private static void showSelectedCard(Board board) { + if (showCardCheck(board)) { + System.out.println(board.getSelectedCard().getName() + " " + board.getSelectedCard().getDescription()); + + } + } + + private static boolean showCardCheck(Board board) { + if (board.getSelectedCard() == null) { + System.out.println("you have not selected card"); + return false; + } + if (!board.isMyCardSelected() && !board.getSelectedCard().getCardFaceUp()) { + System.out.println("you cant see this card!"); + return false; + } + return true; + } + + public void duelMenuView() { + DuelMenuController duelMenuController = new DuelMenuController(); + + DuelMenuMessages resultOfInitialGame = null; + while (resultOfInitialGame == null || !resultOfInitialGame.equals(DuelMenuMessages.SHOW_TURN_PLAYER)) { + resultOfInitialGame = duelMenuController.initialGame(firstPlayer, secondPlayer); + System.out.print(resultOfInitialGame.getMessage()); + } + + while (true) { + String command = Utils.getScanner().nextLine().trim(); + DuelMenuMessages result = duelMenuController.findCommand(command); + + System.out.print(result.getMessage()); + } + } + +} diff --git a/My Part 2/src/main/java/view/ImportExportMenuView.java b/My Part 2/src/main/java/view/ImportExportMenuView.java new file mode 100644 index 0000000..ee91f94 --- /dev/null +++ b/My Part 2/src/main/java/view/ImportExportMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; + +public class ImportExportMenuView { + public void ImportExportMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ImportExportMenuMessages result = ImportExportMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU)) break; + } + } +} diff --git a/My Part 2/src/main/java/view/LoginMenuView.java b/My Part 2/src/main/java/view/LoginMenuView.java new file mode 100644 index 0000000..f094c8b --- /dev/null +++ b/My Part 2/src/main/java/view/LoginMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; + +public class LoginMenuView { + public static void loginMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + LoginMenuMessages result = LoginMenuController.findCommand(command); + + System.out.println(result.getMessage()); + + if (result.equals(LoginMenuMessages.USER_LOGGED_IN)) LoginMenuController.loginUser(command); + } + } +} diff --git a/My Part 2/src/main/java/view/MainMenuView.java b/My Part 2/src/main/java/view/MainMenuView.java new file mode 100644 index 0000000..7dde978 --- /dev/null +++ b/My Part 2/src/main/java/view/MainMenuView.java @@ -0,0 +1,31 @@ +package view; + +import controller.Utils; +import controller.mainmenu.MainMenuController; +import controller.mainmenu.MainMenuMessages; +import model.Player; + +public class MainMenuView { + private Player loggedInPlayer; + + public MainMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void mainMenuView() { + MainMenuController mainMenuController = new MainMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + MainMenuMessages result = mainMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(MainMenuMessages.EXIT_MAIN_MENU) || + result.equals(MainMenuMessages.USER_LOGGED_OUT)) break; + } + } +} diff --git a/My Part 2/src/main/java/view/ProfileMenuView.java b/My Part 2/src/main/java/view/ProfileMenuView.java new file mode 100644 index 0000000..1e1b091 --- /dev/null +++ b/My Part 2/src/main/java/view/ProfileMenuView.java @@ -0,0 +1,25 @@ +package view; + +import controller.profilemenu.ProfileMenuController; +import controller.profilemenu.ProfileMenuMessages; +import controller.Utils; +import model.Player; + +public class ProfileMenuView { + private final Player loggedInPlayer; + + public ProfileMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void profileMenuView() { + ProfileMenuController profileMenuController = new ProfileMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ProfileMenuMessages result = profileMenuController.findCommand(command); + + if (result.equals(ProfileMenuMessages.EXIT_MENU)) break; + else System.out.print(result.getMessage()); + } + } +} diff --git a/My Part 2/src/main/java/view/ScoreboardView.java b/My Part 2/src/main/java/view/ScoreboardView.java new file mode 100644 index 0000000..2deeb33 --- /dev/null +++ b/My Part 2/src/main/java/view/ScoreboardView.java @@ -0,0 +1,37 @@ +package view; + +import controller.scoreboardmenu.Scoreboard; +import controller.scoreboardmenu.ScoreboardOutput; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ScoreboardView { + public static Scanner scanner = new Scanner(System.in); + + public void runScoreboard() { + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + switch (command) { + case "scoreboard show": + Scoreboard.getInstance().showScoreboard(); + break; + case "menu show-current": + ScoreboardOutput.getInstance().showMessage("Scoreboard Menu"); + break; + case "menu exit": + MainMenuView.mainMenuView; + default: + ScoreboardOutput.getInstance().showMessage("invalid command"); + } + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } +} diff --git a/My Part 2/src/main/java/view/ShopMenuView.java b/My Part 2/src/main/java/view/ShopMenuView.java new file mode 100644 index 0000000..0ed2331 --- /dev/null +++ b/My Part 2/src/main/java/view/ShopMenuView.java @@ -0,0 +1,41 @@ +package view; + +import controller.Utils; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import model.cards.Card; + +import java.util.TreeMap; + +public class ShopMenuView { + private Player loggedInPlayer; + + public ShopMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + private static void showListOfCards() { + TreeMap listOfCards = Card.getListOfCards(); + for (String cardName : listOfCards.keySet()) { + System.out.println(cardName + ": " + listOfCards.get(cardName)); + } + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void shopMenuView() { + ShopMenuController shopMenuController = new ShopMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ShopMenuMessages result = shopMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ShopMenuMessages.EXIT_SHOP_MENU)) break; + else if (result.equals(ShopMenuMessages.SHOW_ALL_CARDS)) showListOfCards(); + } + } +} diff --git a/My Part 2/src/main/java/view/SpellCardView.java b/My Part 2/src/main/java/view/SpellCardView.java new file mode 100644 index 0000000..69bf703 --- /dev/null +++ b/My Part 2/src/main/java/view/SpellCardView.java @@ -0,0 +1,118 @@ +package view; + +import controller.Utils; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class SpellCardView extends DuelMenuView { + private SpellCardView(Player firstPlayer, Player secondPlayer) { + super(firstPlayer, secondPlayer); + } + + public static void showGraveyardsMonsterCards(Player turnPlayer, Player notTurnPlayer) { +// it used for Monster Reborn spell card + System.out.println("your graveyard monster cards:"); + showGraveyardMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent graveyard monster cards:"); + showGraveyardMonsterCards(notTurnPlayer.getBoard(), Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()) + 1); + } + + private static void showGraveyardMonsterCards(Board board, int startNumber) { +// it used for Monster Reborn spell card + int count = startNumber; + for (int i = 0; i < board.getGraveyard().size(); i++) { + if (Card.isMonsterCard(board.getGraveyard().get(i))) { + printCard(count, board.getGraveyard().get(i)); + ++count; + } + } + if (count == startNumber) System.out.println("There isn't any monster card."); + } + + public static String findCardNumber() { + System.out.println("choose a number:"); + return Utils.getScanner().nextLine(); + } + + public static void invalidNumber() { + System.out.println("invalid number"); + } + + public static void showFieldSpellCards(ArrayList magicCards) { + System.out.println("your field spell cards:"); + if (magicCards.size() == 0) System.out.println("There isn't any field spell card."); + else { + for (int i = 1; i <= magicCards.size(); i++) { + printCard(i, magicCards.get(i - 1)); + } + } + } + + public static void showCardsInHand(Player player) { + System.out.println("you have these cards in hand:"); + ArrayList cardsInHand = player.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) System.out.println("There isn't any card in your hand."); + else { + for (int i = 1; i <= cardsInHand.size(); i++) { + printCard(i, cardsInHand.get(i - 1)); + } + } + } + + public static void showMagicsZonesCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your spell and trap zone cards:"); + int endNumber = showMagicsZoneCards(turnPlayer, 1); + System.out.println("opponent spell and trap zone cards:"); + showMagicsZoneCards(notTurnPlayer, endNumber); + } + + private static int showMagicsZoneCards(Player player, int startNumber) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (player.getBoard().isMagicsZoneEmpty()) System.out.println("There isn't any spell and trap card."); + else { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) { + printCard(startNumber, magicsZone[i]); + ++startNumber; + } + } + } + + return startNumber; + } + + public static String findNumberOfCardsToChoose() { + System.out.println("How many cards do you want to choose to destroy?"); + return Utils.getScanner().nextLine(); + } + + public static void showFaceUpMonsterCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your face up monster cards:"); + int endNumber = showEachPlayerFaceUpMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent face up monster cards:"); + showEachPlayerFaceUpMonsterCards(notTurnPlayer.getBoard(), endNumber); + } + + private static int showEachPlayerFaceUpMonsterCards(Board board, int startNumber) { + if (board.getNumberOfFaceUpMonsterCards() == 0) { + System.out.println("There isn't any face up monster card."); + return startNumber; + } + + MonsterCard[] monstersZone = board.getMonstersZone(); + for (int i = 1; i < monstersZone.length; i++) { + MonsterCard monsterCard = monstersZone[i]; + if (monsterCard.getCardFaceUp()) { + printCard(startNumber, monsterCard); + ++startNumber; + } + } + + return startNumber; + } +} diff --git a/My Part 2/src/main/main.iml b/My Part 2/src/main/main.iml new file mode 100644 index 0000000..2185ddd --- /dev/null +++ b/My Part 2/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/My Part 2/src/main/resources/cards/Monster Upgraded.csv b/My Part 2/src/main/resources/cards/Monster Upgraded.csv new file mode 100644 index 0000000..eae794e --- /dev/null +++ b/My Part 2/src/main/resources/cards/Monster Upgraded.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARTH,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARTH,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,FIRE,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My Part 2/src/main/resources/cards/Monster.csv b/My Part 2/src/main/resources/cards/Monster.csv new file mode 100644 index 0000000..8c45a5c --- /dev/null +++ b/My Part 2/src/main/resources/cards/Monster.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARHT,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARHT,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron ,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,Fire,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My Part 2/src/main/resources/cards/SpellTrap.csv b/My Part 2/src/main/resources/cards/SpellTrap.csv new file mode 100644 index 0000000..e536e99 --- /dev/null +++ b/My Part 2/src/main/resources/cards/SpellTrap.csv @@ -0,0 +1,38 @@ +Name,Type ,Icon (Property),Description,Status,Price +Trap Hole,Trap,Normal,When your opponent Normal or Flip Summons 1 monster with 1000 or more ATK: Target that monster; destroy that target.,Unlimited,2000 +Mirror Force,Trap,Normal,When an opponent's monster declares an attack: Destroy all your opponent's Attack Position monsters.,Unlimited,2000 +Magic Cylinder,Trap,Normal,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, and if you do, inflict damage to your opponent equal to its ATK.",Unlimited,2000 +Mind Crush,Trap,Normal,"Declare 1 card name; if that card is in your opponent's hand, they must discard all copies of it, otherwise you discard 1 random card.",Unlimited,2000 +Torrential Tribute,Trap,Normal,When a monster(s) is Summoned: Destroy all monsters on the field.,Unlimited,2000 +Time Seal,Trap,Normal,Skip the Draw Phase of your opponent's next turn.,Limited,2000 +Negate Attack,Trap,Counter,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, then end the Battle Phase.",Unlimited,3000 +Solemn Warning,Trap,Counter,"When a monster(s) would be Summoned, OR when a Spell/Trap Card, or monster effect, is activated that includes an effect that Special Summons a monster(s): Pay 2000 LP; negate the Summon or activation, and if you do, destroy it.",Unlimited,3000 +Magic Jamamer,Trap,Counter,"When a Spell Card is activated: Discard 1 card; negate the activation, and if you do, destroy it.",Unlimited,3000 +Call of The Haunted,Trap,Continuous,"Activate this card by targeting 1 monster in your GY; Special Summon that target in Attack Position. When this card leaves the field, destroy that monster. When that monster is destroyed, destroy this card.",Unlimited,3500 +Vanity's Emptiness,Trap,Continuous,Neither player can Special Summon monsters. If a card is sent from the Deck or the field to your Graveyard: Destroy this card.,Limited,3500 +Wall of Revealing Light,Trap,Continuous,Activate by paying any multiple of 1000 Life Points. Monsters your opponent controls cannot attack if their ATK is less than or equal to the amount you paid.,Limited,3500 +Monster Reborn,Spell,Normal,Target 1 monster in either GY; Special Summon it.,Limited,2500 +Terraforming,Spell,Normal,Add 1 Field Spell from your Deck to your hand.,Limited,2500 +Pot of Greed,Spell,Normal,Draw 2 cards.,Limited,2500 +Raigeki,Spell,Normal,Destroy all monsters your opponent controls.,Limited,2500 +Change of Heart,Spell,Normal,Target 1 monster your opponent controls; take control of it until the End Phase.,Limited,2500 +Swords of Revealing Light,Spell,Normal,"After this card's activation, it remains on the field, but destroy it during the End Phase of your opponent's 3rd turn. When this card is activated: If your opponent controls a face-down monster, flip all monsters they control face-up. While this card is face-up on the field, your opponent's monsters cannot declare an attack.",Unlimited,2500 +Harpie's Feather Duster,Spell,Normal,Destroy all Spells and Traps your opponent controls.,Limited,2500 +Dark Hole,Spell,Normal,Destroy all monsters on the field.,Unlimited,2500 +Supply Squad,Spell,Continuous,"Once per turn, if a monster(s) you control is destroyed by battle or card effect: Draw 1 card.",Unlimited,4000 +Spell Absorption,Spell,Continuous,"Each time a Spell Card is activated, gain 500 Life Points immediately after it resolves.",Unlimited,4000 +Messenger of peace,Spell,Continuous,"Monsters with 1500 or more ATK cannot declare an attack. Once per turn, during your Standby Phase, pay 100 LP or destroy this card.",Unlimited,4000 +Twin Twisters,Spell,Quick-play,"Discard 1 card, then target up to 2 Spells/Traps on the field; destroy them.",Unlimited,3500 +Mystical space typhoon,Spell,Quick-play,Target 1 Spell/Trap on the field; destroy that target.,Unlimited,3500 +Ring of defense,Spell,Quick-play,When a Trap effect that inflicts damage is activated: Make that effect damage 0.,Unlimited,3500 +Yami,Spell,Field,"All Fiend and Spellcaster monsters on the field gain 200 ATK/DEF, also all Fairy monsters on the field lose 200 ATK/DEF.",Unlimited,4300 +Forest,Spell,Field,"All Insect, Beast, Plant, and Beast-Warrior monsters on the field gain 200 ATK/DEF.",Unlimited,4300 +Closed Forest,Spell,Field,All Beast-Type monsters you control gain 100 ATK for each monster in your Graveyard. Field Spell Cards cannot be activated. Field Spell Cards cannot be activated during the turn this card is destroyed.,Unlimited,4300 +Umiiruka,Spell,Field,Increase the ATK of all WATER monsters by 500 points and decrease their DEF by 400 points.,Unlimited,4300 +Sword of dark destruction,Spell,Equip,A DARK monster equipped with this card increases its ATK by 400 points and decreases its DEF by 200 points.,Unlimited,4300 +Black Pendant,Spell,Equip,The equipped monster gains 500 ATK. When this card is sent from the field to the Graveyard: Inflict 500 damage to your opponent.,Unlimited,4300 +United We Stand,Spell,Equip,The equipped monster gains 800 ATK/DEF for each face-up monster you control.,Unlimited,4300 +Magnum Shield,Spell,Equip,"Equip only to a Warrior-Type monster. Apply this effect, depending on its battle position. +● Attack Position: It gains ATK equal to its original DEF. +● Defense Position: It gains DEF equal to its original ATK.",Unlimited,4300 +Advanced Ritual Art,Spell,Ritual,This card can be used to Ritual Summon any 1 Ritual Monster. You must also send Normal Monsters from your Deck to the Graveyard whose total Levels equal the Level of that Ritual Monster.,Unlimited,3000 \ No newline at end of file diff --git a/My Part 2/src/main/resources/players/parsa.json b/My Part 2/src/main/resources/players/parsa.json new file mode 100644 index 0000000..2825eb1 --- /dev/null +++ b/My Part 2/src/main/resources/players/parsa.json @@ -0,0 +1,10 @@ +{ + "boughtCards": [], + "allMainDecks": [], + "sideDeck": {}, + "username": "parsa", + "password": "newPass", + "nickname": "P", + "score": 0, + "money": 100000 +} \ No newline at end of file diff --git a/My Part 2/src/test/java/controller/ImportExportMenuControllerTest.java b/My Part 2/src/test/java/controller/ImportExportMenuControllerTest.java new file mode 100644 index 0000000..aea2298 --- /dev/null +++ b/My Part 2/src/test/java/controller/ImportExportMenuControllerTest.java @@ -0,0 +1,140 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Database; +import controller.MenuTest; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; +import model.cards.Card; +import org.apache.commons.io.FileUtils; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +class ImportExportMenuControllerTest extends MenuTest { + + @Test + void findCommandEnterAMenuMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu exit"); + Assertions.assertEquals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU, result); + + result = ImportExportMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ImportExportMenuMessages.SHOW_MENU, result); + + result = ImportExportMenuController.findCommand("menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandImportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("import cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_FILE, result); + + createCardJsonFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.AVAILABLE_CARD, result); + + Card.getAllCards().remove("Battle OX"); + removeNameValueFromJsonCardFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Battle OX"); + Card.getAllCards().remove("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Battle OX.json")); + + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + removeNameValueFromJsonCardFile("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Trap Hole.json")); + } + + void createCardJsonFile(String cardName) { + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(Card.getCardByName(cardName))); + fileWriter.close(); + } catch (IOException ignored) { + } + } + + void removeNameValueFromJsonCardFile(String cardName) { + JSONParser parser = new JSONParser(); + try { + Object object = parser.parse(new FileReader("src/database/cards/" + cardName + ".json")); + JSONObject jsonObject = (JSONObject) object; + jsonObject.remove("name"); + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(jsonObject)); + fileWriter.close(); + } catch (Exception ignored) { + } + } + + @Test + void findCommandExportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("export cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("export card A"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_CARD, result); + + result = ImportExportMenuController.findCommand("export card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My Part 2/src/test/java/controller/LoginMenuControllerTest.java b/My Part 2/src/test/java/controller/LoginMenuControllerTest.java new file mode 100644 index 0000000..b095e9e --- /dev/null +++ b/My Part 2/src/test/java/controller/LoginMenuControllerTest.java @@ -0,0 +1,87 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; + +class LoginMenuControllerTest extends MenuTest { + @Test + void findCommandEnterAMenuMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_NAVIGATION, result); + + result = LoginMenuController.findCommand("menu enter MaIn MenU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + + result = LoginMenuController.findCommand("menu enter DUEL MENU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + } + + @Test + void findCommandCheckCreateUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user create --username John 1 --nickname Johny --password 12345"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user create --U John1 --nickname Johny1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --username John2 --P 12345 --nickname Johny2"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny3 --username John3 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny4 --password 12345 --U John4"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --username John5 --nickname Johny5"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --nickname Johny6 --username John6"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John6 --N Johny6"); + Assertions.assertEquals(LoginMenuMessages.USERNAME_EXISTS, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John7 --nickname Johny6"); + Assertions.assertEquals(LoginMenuMessages.NICKNAME_EXISTS, result); + } + + @Test + void findCommandCheckLoginUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user login --username John 12 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user login --username John12 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + + result = LoginMenuController.findCommand("user login --username John2 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + result = LoginMenuController.findCommand("user login --username John1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + + result = LoginMenuController.findCommand("user login --password 12345 --username John1"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + } + + @Test + void loginUser() { + Utils.resetScanner("user logout\n"); + ByteArrayOutputStream outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --password 12345 --username John1"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + + Utils.resetScanner("user logout\n"); + outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --username John1 --password 12345"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + } +} \ No newline at end of file diff --git a/My Part 2/src/test/java/controller/MenuTest.java b/My Part 2/src/test/java/controller/MenuTest.java new file mode 100644 index 0000000..5df1b3c --- /dev/null +++ b/My Part 2/src/test/java/controller/MenuTest.java @@ -0,0 +1,20 @@ +package controller; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +import java.io.File; +import java.io.IOException; + +public class MenuTest { + @BeforeAll + static void prepareGame() { + Database.prepareGame(); + } + + @AfterAll + static void deletePlayersDirectory() throws IOException { + FileUtils.deleteDirectory(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/main/resources/players")); + } +} \ No newline at end of file diff --git a/My Part 2/src/test/java/controller/ProfileMenuTest.java b/My Part 2/src/test/java/controller/ProfileMenuTest.java new file mode 100644 index 0000000..ddad54d --- /dev/null +++ b/My Part 2/src/test/java/controller/ProfileMenuTest.java @@ -0,0 +1,57 @@ +package controller; + +import controller.profilemenu.ProfileMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import controller.profilemenu.ProfileMenuController; + +public class ProfileMenuTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + String userName = "parsa"; + String password = "123"; + String nickname = "P"; + new Player(userName, password, nickname); + } + + @Test + public void changeName() { + Player player = Player.getPlayerByUsername("parsa"); + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --nickname newname"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + Assertions.assertEquals("newname", player.getNickname()); + result = profileMenuController.findCommand("profile change --nickname P"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + } + + @Test + public void changePassword() { + Player player = Player.getPlayerByUsername("parsa"); + + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --password --current 12 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.WRONG_CURRENT_PASSWORD, result); + Assertions.assertEquals("123", player.getPassword()); + + result = profileMenuController.findCommand("profile change --password --current 123 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_PASSWORD_DONE, result); + Assertions.assertEquals("newPass", player.getPassword()); + } + + @Test + public void allError() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.INVALID_COMMAND, profileMenuController.findCommand("profile")); + Assertions.assertEquals(ProfileMenuMessages.CANT_NAVIGATE_MENU, profileMenuController.findCommand("loginmenu enter")); + } + + @Test + public void checkExit() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.EXIT_MENU , profileMenuController.findCommand("menu exit")); + } +} diff --git a/My Part 2/src/test/java/controller/ShopMenuControllerTest.java b/My Part 2/src/test/java/controller/ShopMenuControllerTest.java new file mode 100644 index 0000000..58d998d --- /dev/null +++ b/My Part 2/src/test/java/controller/ShopMenuControllerTest.java @@ -0,0 +1,77 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ShopMenuControllerTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + LoginMenuController.findCommand("user create --username John --P 12345 --nickname Johny"); + } + + @Test + void findCommandEnterAMenuMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu exit"); + Assertions.assertEquals(ShopMenuMessages.EXIT_SHOP_MENU, result); + + result = shopMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ShopMenuMessages.SHOW_MENU, result); + + result = shopMenuController.findCommand("menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandBuyACardMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("shop buy:)"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("shop buy A"); + Assertions.assertEquals(ShopMenuMessages.UNAVAILABLE_CARD, result); + + result = shopMenuController.findCommand("shop buy Battle OX"); + Assertions.assertEquals(ShopMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My Part 2/src/test/test.iml b/My Part 2/src/test/test.iml new file mode 100644 index 0000000..c2315e9 --- /dev/null +++ b/My Part 2/src/test/test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/My Part 3/README.md b/My Part 3/README.md new file mode 100644 index 0000000..9b29637 --- /dev/null +++ b/My Part 3/README.md @@ -0,0 +1,7 @@ +# Advanced Programming Project - Spring 2021 +## Team 22 + +### Team Members: +- Amir Mohammad Fakhimi 99170531 +- Parsa Sharify 99101762 +- Iman Mohammadi 99102207 diff --git a/My Part 3/src/main/java/controller/AIClass.java b/My Part 3/src/main/java/controller/AIClass.java new file mode 100644 index 0000000..5e41136 --- /dev/null +++ b/My Part 3/src/main/java/controller/AIClass.java @@ -0,0 +1,60 @@ +package controller; + +import model.Board; +import model.cards.monstercard.MonsterCard; +import model.Player; + +public class AIClass { + +// public static String getOrder(Board machineBoard, Board playerBoard, Player AIPlayer, Player humanPlayer, Enum phaseOfGame) { +// if () {//TODO PUT A CONDITION THAT PHASE IS BATTLE PHASE +// int numberOfMonsterToAttack = -1; +// selectMachineMonsterCardToAttack(machineBoard, AIPlayer); +// if (canAttackToFaceUpMonster(machineBoard, playerBoard) != -1) { +// return "attack" + canAttackToFaceUpMonster(machineBoard, playerBoard); +// } else if (canAttackToFaceDownCard(playerBoard) != -1) { +// return "attack" + canAttackToFaceDownCard(playerBoard); +// } +// } +// } +// +// private static int canAttackToFaceDownCard(Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DH")) +// return i; +// } +// return -1; +// } +// +// private static void selectMachineMonsterCardToAttack(Board board, Player player) { +// MonsterCard[] monsterArray = board.getMonstersZone(); +// MonsterCard monsterCard = monsterArray[1]; +// for (int i = 2; i <= 5; i++) { +// if (monsterCard.getAttackLevel() < monsterArray[i].getAttackLevel()) +// monsterCard = monsterArray[i]; +// board.setMyCardSelected(true); +// board.setSelectedCard(monsterCard); +// } +// } +// +// private static int canAttackToFaceUpMonster(Board machineBoard, Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// MonsterCard monsterToAttack = (MonsterCard) machineBoard.getSelectedCard(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("OO") && monsterArray[i].getAttackLevel() < monsterToAttack.getAttackLevel()) +// return i; +// } +// +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DO") && monsterArray[i].getDefenseLevel() < monsterToAttack.getAttackLevel()) { +// } +// return i; +// } +// return -1; +// } +// +// public static String getRandomMove() { +// +// } +} diff --git a/My Part 3/src/main/java/controller/Database.java b/My Part 3/src/main/java/controller/Database.java new file mode 100644 index 0000000..e5d87af --- /dev/null +++ b/My Part 3/src/main/java/controller/Database.java @@ -0,0 +1,120 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.magiccard.MagicCardStatuses; +import model.cards.monstercard.MonsterCard; +import model.cards.monstercard.MonsterCardAttributes; + +import java.io.*; +import java.util.ArrayList; + +public class Database { + public static void prepareGame() { + new File("src/main/resources/players").mkdirs(); + addCardsToGame(); + readPlayersDataFromDatabase(); + } + + private static void addCardsToGame() { + try { + FileReader monsterCardFileReader = new FileReader("src/main/resources/cards/Monster Upgraded.csv"); + CSVReader monsterCardCSVReader = new CSVReaderBuilder(monsterCardFileReader).withSkipLines(1).build(); + + String[] monsterCardData; + while ((monsterCardData = monsterCardCSVReader.readNext()) != null) { + createNewMonsterCard(monsterCardData); + } + + + FileReader magicCardFileReader = new FileReader("src/main/resources/cards/SpellTrap.csv"); + CSVReader magicCardCSVReader = new CSVReaderBuilder(magicCardFileReader).withSkipLines(1).build(); + + String[] magicCardData; + while ((magicCardData = magicCardCSVReader.readNext()) != null) { + createNewMagicCard(magicCardData); + } + + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + } + + private static void createNewMonsterCard(String[] data) { + String name = data[0]; + short level = Short.parseShort(data[1]); + MonsterCardAttributes monsterCardAttributes = MonsterCardAttributes.valueOf(data[2]); + String monsterType = data[3]; + CardTypes cardType = CardTypes.valueOf(data[4].toUpperCase()); + int attackPoints = Integer.parseInt(data[5]); + int defensePoints = Integer.parseInt(data[6]); + String description = data[7]; + int price = Integer.parseInt(data[8]); + + new MonsterCard(name, level, monsterCardAttributes, monsterType, cardType, attackPoints, defensePoints, description, price); + } + + private static void createNewMagicCard(String[] data) { + String name = data[0]; + CardTypes cardType = CardTypes.valueOf(data[1].toUpperCase()); + String icon = data[2]; + String description = data[3]; + MagicCardStatuses status = MagicCardStatuses.valueOf(data[4].toUpperCase()); + int price = Integer.parseInt(data[5]); + + new MagicCard(name, cardType, icon, description, status,price); + } + + public static void readPlayersDataFromDatabase() { +// TODO: complete it by Iman's code + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + File file = new File("src/main/resources/players"); + FilenameFilter filenameFilter = (direction, name) -> name.endsWith(".json"); + String[] filesName = file.list(filenameFilter); + + if (filesName == null) return; + for (String fileName : filesName) { + try { + FileReader fileReader = new FileReader("src/main/resources/players/" + fileName); + Player player = gson.fromJson(fileReader, Player.class); + fileReader.close(); + Player.addPlayerToAllPlayers(player); + addCardsToPlayer(player); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + private static void addCardsToPlayer(Player player) { + ArrayList boughtCards = player.getBoughtCards(); + for (int i = 0; i < boughtCards.size(); i++) { + Card fakeCard = boughtCards.get(0); + Card originalCard = Card.getCardByName(fakeCard.getName()); + boughtCards.remove(fakeCard); + player.addCardToBoughtCards(originalCard); + } + } + + public static void updatePlayerInformationInDatabase(Player player) { + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + try { + FileWriter fileWriter = new FileWriter("src/main/resources/players/" + player.getUsername() + ".json"); + fileWriter.write(gson.toJson(player)); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/My Part 3/src/main/java/controller/Main.java b/My Part 3/src/main/java/controller/Main.java new file mode 100644 index 0000000..274e490 --- /dev/null +++ b/My Part 3/src/main/java/controller/Main.java @@ -0,0 +1,10 @@ +package controller; + +import view.LoginMenuView; + +public class Main { + public static void main(String[] args) { + Database.prepareGame(); + LoginMenuView.loginMenuView(); + } +} \ No newline at end of file diff --git a/My Part 3/src/main/java/controller/SpellCardController.java b/My Part 3/src/main/java/controller/SpellCardController.java new file mode 100644 index 0000000..6080ef6 --- /dev/null +++ b/My Part 3/src/main/java/controller/SpellCardController.java @@ -0,0 +1,537 @@ +package controller; + +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.SpellCardView; + +import java.util.ArrayList; +import java.util.Collections; + +public class SpellCardController { +// this method doesn't handle field spell cards + public static boolean doSpellCardEffect(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { +// handle every kind of spell cards except field and equip + String cardName = spellCard.getName(); + switch (cardName) { + case "Monster Reborn": + return doMonsterRebornEffect(turnPlayer, notTurnPlayer); + case "Terraforming": + return doTerraformingEffect(turnPlayer); + case "Pot of Greed": + return doPotOfGreedEffect(turnPlayer); + case "Raigeki": + return doRaigekiEffect(notTurnPlayer); + case "Change of Heart": + return doChangeOfHeartEffect(); + case "Harpie's Feather Duster": + return doHarpieFeatherDusterEffect(notTurnPlayer); + case "Swords of Revealing Light": + return doSwordsOfRevealingLight(); + case "Dark Hole": + return doDarkHoleEffect(turnPlayer, notTurnPlayer); + case "Supply Squad": +// TODO: i should know how turn changes, then handle it --> it shouldn't handle here + break; + case "Spell Absorption": + return true; + case "Messenger of peace": +// TODO: handle it base on Parsa code + break; + case "Twin Twisters": + return doTwinTwistersEffect(turnPlayer, notTurnPlayer); + case "Mystical space typhoon": + return doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + case "Ring of defense": +// TODO: handle it base trap and monster code + break; +// it's the only ritual spell card + case "Advanced Ritual Art": + return doAdvancedRitualArtEffect(); + } + +// handle equip spell cards + return chooseMonsterToEquip(turnPlayer, notTurnPlayer, spellCard); +// any other kind of card doesn't enter to this method + } + + +// handle every kind of spell cards except field and equip + private static boolean doMonsterRebornEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showGraveyardsMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(turnPlayer.getBoard().getGraveyard()); + int notTurnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()); + if (turnPlayerGraveyardMonsterCardsSize + notTurnPlayerGraveyardMonsterCardsSize == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findMonsterRebornChosenCard(turnPlayer, notTurnPlayer, cardNumber); + if (chosenCard != null) break; + SpellCardView.invalidNumber(); + } + +// TODO: how to handle special summon + return true; + } + + private static int getCardNumber() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findCardNumber()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static MonsterCard findMonsterRebornChosenCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + ArrayList turnPlayerGraveyard = turnPlayer.getBoard().getGraveyard(); + ArrayList notTurnPlayerGraveyard = notTurnPlayer.getBoard().getGraveyard(); + + for (Card card : turnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + for (Card card : notTurnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + + return null; + } + + private static boolean doTerraformingEffect(Player player) { +// TODO: do Iman handle with main cards? + ArrayList cards = player.getBoard().getDeck().getMainCards(); + ArrayList fieldSpellCards = findFieldSpellCards(cards); + + SpellCardView.showFieldSpellCards(fieldSpellCards); + if (fieldSpellCards.size() == 0) return false; + + MagicCard chosenFieldSpellCard; + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= fieldSpellCards.size()) { + chosenFieldSpellCard = fieldSpellCards.get(cardNumber - 1); + player.getBoard().getCardsInHand().add(chosenFieldSpellCard); + cards.remove(chosenFieldSpellCard); + break; + } + SpellCardView.invalidNumber(); + } + + Collections.shuffle(cards); + return true; + } + + private static ArrayList findFieldSpellCards(ArrayList cards) { +// create array list of field spell cards + ArrayList fieldSpellCards = new ArrayList<>(); + for (Card card : cards) { + if (!Card.isMonsterCard(card)) { + MagicCard magicCard = (MagicCard) card; + if (magicCard.getIcon().equals("Field")) fieldSpellCards.add(magicCard); + } + } + return fieldSpellCards; + } + + private static boolean doPotOfGreedEffect(Player player) { + Board board = player.getBoard(); + ArrayList deckCards = board.getDeck().getMainCards(); + if (deckCards.size() < 2) return false; + + Card firstCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + Card secondCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + board.getCardsInHand().add(firstCard); + board.getCardsInHand().add(secondCard); + + return true; + } + + private static boolean doRaigekiEffect(Player player) { + MonsterCard[] monstersZone = player.getBoard().getMonstersZone(); + if (isCardArrayNull(monstersZone)) return false; + emptyAZone(player, monstersZone); + return true; + } + + private static boolean isCardArrayNull(Card[] cards) { + for (Card card : cards) { + if (card != null) return false; + } + return true; + } + + private static void emptyAZone(Player player, Card[] cards) { + for (int i = 0; i < cards.length; ++i) { + if (cards[i] != null) { + player.getBoard().getGraveyard().add(cards[i]); + cards[i] = null; + } + } + } + + private static boolean doChangeOfHeartEffect() { +// TODO: handle it! + return true; + } + + private static boolean doHarpieFeatherDusterEffect(Player player) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (isCardArrayNull(magicsZone)) return false; + emptyAZone(player, magicsZone); + return true; + } + + private static boolean doSwordsOfRevealingLight() { +// TODO: handle it! + return true; + } + + private static boolean doDarkHoleEffect(Player turnPlayer, Player notTurnPlayer) { + return doRaigekiEffect(turnPlayer) || doRaigekiEffect(notTurnPlayer); + } + + public static void doSpellAbsorptionEffect(Player player) { + if (player.getBoard().isCardFaceUp("Spell Absorption")) player.increaseLifePoint(500); + } + + private static boolean doTwinTwistersEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showCardsInHand(turnPlayer); + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= cardsInHand.size()) { + turnPlayer.getBoard().getGraveyard().add(cardsInHand.get(cardNumber - 1)); + cardsInHand.remove(cardNumber - 1); + break; + } + SpellCardView.invalidNumber(); + } + + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return true; + + int numberOfChosenCards; + while (true) { + numberOfChosenCards = getNumberOfCardsToChoose(); + if (0 <= numberOfChosenCards && numberOfChosenCards <= 2 && + numberOfChosenCards <= turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards) { + break; + } + SpellCardView.invalidNumber(); + } + + for (int i = 0; i < numberOfChosenCards; i++) { + doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + } + + return true; + } + + private static int getNumberOfCardsToChoose() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findNumberOfCardsToChoose()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static boolean destroyAMagicCardFromMagicZone(Player player, int cardNumber, int startNumber) { + MagicCard[] playerMagicsZone = player.getBoard().getMagicsZone(); + for (int i = 1; i < playerMagicsZone.length; i++) { + if (playerMagicsZone[i] != null) { + if (startNumber == cardNumber) { + player.getBoard().getGraveyard().add(playerMagicsZone[i]); + playerMagicsZone[i] = null; + return true; + } + ++startNumber; + } + } + + return false; + } + + private static boolean doMysticalSpaceTyphoonEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (destroyAMagicCardFromMagicZone(turnPlayer, cardNumber, 1) || + destroyAMagicCardFromMagicZone(notTurnPlayer, cardNumber, turnPlayerNumberOfMagicCards + 1)) + break; + SpellCardView.invalidNumber(); + } + + return true; + } + +// it's the only ritual spell card + private static boolean doAdvancedRitualArtEffect() { +// TODO: handle it based on Iman's code + return false; + } + + +// handle field spell cards + public static void handleFieldSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + MagicCard firstPlayerFieldZoneCard = firstPlayer.getBoard().getFieldZone(); + MagicCard secondPlayerFieldZoneCard = secondPlayer.getBoard().getFieldZone(); + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, firstPlayerFieldZoneCard, doEffect); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, secondPlayerFieldZoneCard, doEffect); + } + + private static Player findMonsterCardOwner(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard) { + if (firstPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return firstPlayer; + if (secondPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return secondPlayer; + +// this will never happen, just for assurance + return null; + } + + private static void handleEachFieldSpellCardEffect(Player monsterCardOwner, MonsterCard monsterCard, MagicCard fieldZoneCard, + boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + if (fieldZoneCard == null || !fieldZoneCard.getCardFaceUp()) return; + + switch (fieldZoneCard.getName()) { + case "Yami": + handleYamiEffect(monsterCard, doEffect); + break; + case "Forest": + handleForestEffect(monsterCard, doEffect); + break; + case "Closed Forest": + handleClosedForestEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Umiiruka": + handleUmiirukaEffect(monsterCard, doEffect); + break; + } + } + + private static void handleYamiEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } else if (monsterCard.getMonsterType().equals("Fairy")) { + if (doEffect) { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } + } + } + + private static void handleForestEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Insect") || monsterCardType.equals("Beast") || + monsterCardType.equals("Beast-Warrior")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } + } + + private static void handleClosedForestEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int graveyardMonsterCardsSize = Card.findNumberOfMonsterCards(monsterCardOwner.getBoard().getGraveyard()); + MonsterCard[] monstersZone = monsterCardOwner.getBoard().getMonstersZone(); + + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null && monstersZone[i].getMonsterType().equals("Beast-Type")) { + if (doEffect) monsterCard.increaseAttackPoints(100 * graveyardMonsterCardsSize); + else monsterCard.decreaseAttackPoints(100 * graveyardMonsterCardsSize); + } + } + + } + + private static void handleUmiirukaEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (monsterCard.getMonsterType().equals("Aqua")) { + if (doEffect) { + monsterCard.increaseAttackPoints(500); + monsterCard.decreaseDefencePoints(400); + } else { + monsterCard.decreaseAttackPoints(500); + monsterCard.increaseDefencePoints(400); + } + } + } + + +// handle equip spell cards + private static boolean chooseMonsterToEquip(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { + SpellCardView.showFaceUpMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerFaceUpMonsterCardsNumber = turnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + int notTurnPlayerFaceUpMonsterCardsNumber = notTurnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + Board turnPlayerBoard = turnPlayer.getBoard(); + if (turnPlayerFaceUpMonsterCardsNumber + notTurnPlayerFaceUpMonsterCardsNumber == 0 || + !turnPlayerBoard.isMagicsZoneFull()) return false; + if (spellCard.getName().equals("Magnum Shield") && turnPlayerBoard.getNumberOfWarriorMonsterCards() == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findFaceUpMonsterCard(turnPlayer, notTurnPlayer, cardNumber); +// second and third condition assure me that Magnum Shield just equipped Warrior Monster Cards + if (chosenCard != null && + (!spellCard.getName().equals("Magnum Shield") || chosenCard.getMonsterType().equals("Warrior"))) break; + SpellCardView.invalidNumber(); + } + + chosenCard.addToEquippedBy(spellCard); + turnPlayerBoard.addMagicCardToMagicsZone(spellCard); + return true; + } + + private static MonsterCard findFaceUpMonsterCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + MonsterCard[] turnPlayerFaceUpMonsterCards = turnPlayer.getBoard().getMonstersZone(); + MonsterCard[] notTurnPlayerFaceUpMonsterCards = notTurnPlayer.getBoard().getMonstersZone(); + + for (int i = 1; i < turnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = turnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + for (int i = 1; i < notTurnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = notTurnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + + return null; + } + + public static void handleEquipSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + for (MagicCard spellCard : monsterCard.getEquippedBy()) { + switch (spellCard.getName()) { + case "Sword of dark destruction": + handleSwordOfDarkDestructionEffect(monsterCard, doEffect); + break; + case "Black Pendant": + handleBlackPendantEffect(monsterCard, doEffect); + break; + case "United We Stand": + handleUnitedWeStandEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Magnum Shield": + handleMagnumShieldEffect(monsterCard, doEffect); + break; + } + } + } + + private static void handleSwordOfDarkDestructionEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(400); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(400); + monsterCard.increaseDefencePoints(200); + } + } + + } + + private static void handleBlackPendantEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (doEffect) monsterCard.increaseAttackPoints(500); + else monsterCard.decreaseAttackPoints(500); + } + + private static void handleUnitedWeStandEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int numberOfFaceUpMonsterCards = monsterCardOwner.getBoard().getNumberOfFaceUpMonsterCards(); + if (doEffect) { + monsterCard.increaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.increaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } else { + monsterCard.decreaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.decreaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } + } + + private static void handleMagnumShieldEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + +// I know that Magnum Shield just equipped Warrior monster cards + if (monsterCard.isDefensePosition()) { + if (doEffect) monsterCard.increaseDefencePoints(monsterCard.getAttackPoints()); + else monsterCard.decreaseDefencePoints(monsterCard.getAttackPoints()); + } else { + if (doEffect) monsterCard.increaseAttackPoints(monsterCard.getDefensePoints()); + else monsterCard.decreaseAttackPoints(monsterCard.getDefensePoints()); + } + } +} diff --git a/My Part 3/src/main/java/controller/Utils.java b/My Part 3/src/main/java/controller/Utils.java new file mode 100644 index 0000000..05df0d8 --- /dev/null +++ b/My Part 3/src/main/java/controller/Utils.java @@ -0,0 +1,34 @@ +package controller; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Utils { + private static Scanner scanner; + + static { + scanner = new Scanner(System.in); + } + + public static Scanner getScanner() { + return scanner; + } + + public static void resetScanner(String input) { + scanner = new Scanner(new ByteArrayInputStream(input.getBytes())); + } + + public static ByteArrayOutputStream setByteArrayOutputStream() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + return outContent; + } + + public static Matcher getMatcher(String regex, String command) { + return Pattern.compile(regex).matcher(command); + } +} diff --git a/My Part 3/src/main/java/controller/deckmenu/DeckMenuController.java b/My Part 3/src/main/java/controller/deckmenu/DeckMenuController.java new file mode 100644 index 0000000..7a497dd --- /dev/null +++ b/My Part 3/src/main/java/controller/deckmenu/DeckMenuController.java @@ -0,0 +1,100 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +import java.util.Objects; + +public class DeckMenuController { + + private static DeckMenuController instance = null; + + private DeckMenuController() { + } + + public static DeckMenuController getInstance() { + return Objects.requireNonNullElseGet(instance, () -> (instance = new DeckMenuController())); + } + + public void createDeck(String name, Player owner) { + if (!DeckMenuTools.isDeckNameUnique(name)) + return; + + new Deck(name, owner , true , true); + DeckMenuOutput.getInstance().showMessage("deck created successfully!"); + } + + public void deleteDeck(String name) { + if (DeckMenuTools.isDeckNameUnique(name)) + return; + + DeckMenuDatabase.removeDeck(name); + DeckMenuOutput.getInstance().showMessage("deck deleted successfully!"); + + } + + + public void setActiveDeck(String name, Player player) { + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesDeckExist(name) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(name), player); + if (isPermitted) { + player.activateADeck(deck); + + DeckMenuOutput.getInstance().showMessage("deck activated successfully!"); + } + + } + + public void addCardToDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card = null; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player) + && ((isMain) ? DeckMenuTools.doesDeckHaveSpace(deck) : DeckMenuTools.doesSideDeckHaveSpace(deck)) + && DeckMenuTools.isNumberOfCardsInDeckLessThanFour(deck, card = DeckMenuDatabase.getInstance().getCardByName(cardName)) + && DeckMenuTools.doesPlayerHaveEnoughCards(card , player); + if (isPermitted) { + player.removeCardFromBoughtCards(card); + player.getAllPlayerCard().moveCardTo(deck , card , true , isMain); + DeckMenuOutput.getInstance().showMessage("card added to deck successfully!"); + } + } + + public void removeCardFromDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player); + if (isPermitted) { + card = DeckMenuDatabase.getInstance().getCardByName(cardName); + player.addCardToBoughtCards(card); + deck.moveCardTo(player.getAllPlayerCard(),card, isMain , true); + DeckMenuOutput.getInstance().showMessage("card removed from deck successfully!"); + } + } + + public void showAllDecks(Player player) { + for (Deck deck : player.getAllDeck()) + DeckMenuOutput.getInstance().showMessage(deck.toString()); + + } + + public void showDeck(String name, Player player, boolean isMain) { + if (!DeckMenuTools.doesDeckExist(name)) + return; + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (!DeckMenuTools.doesDeckBelongToPlayer(deck, player)) + return; + String message; + if (isMain) + message = "true"; + else + message = "false"; + DeckMenuOutput.getInstance().showMessage(message); + + + } +} diff --git a/My Part 3/src/main/java/controller/deckmenu/DeckMenuDatabase.java b/My Part 3/src/main/java/controller/deckmenu/DeckMenuDatabase.java new file mode 100644 index 0000000..d16b03f --- /dev/null +++ b/My Part 3/src/main/java/controller/deckmenu/DeckMenuDatabase.java @@ -0,0 +1,50 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; +import java.util.ArrayList; + +public class DeckMenuDatabase { + + public static ArrayList allPlayers = new ArrayList<>(); + public static ArrayList allCards = new ArrayList<>(); + public static ArrayList allDecks = new ArrayList<>(); + + private DeckMenuDatabase() { + } + + private static DeckMenuDatabase instance; + + public static DeckMenuDatabase getInstance() { + if (instance == null) + instance = new DeckMenuDatabase(); + return instance; + } + + public static void removeDeck(String name) { + allDecks.removeIf(deck -> deck.getName().equals(name)); + } + + public Card getCardByName(String name) { + for (Card card : allCards) { + if (card.getName().equals(name)) + return card; + } + return null; + + } + + public Deck getDeckByName(String name) { + for (Deck deck : allDecks) { + if (deck.getName().equals(name)) + return deck; + } + return null; + + } + // setPlayers() {file v Jason} + // setDecks() {file v Jason} + // loadingDatabase() + // updatingDatabase() + +} diff --git a/My Part 3/src/main/java/controller/deckmenu/DeckMenuOutput.java b/My Part 3/src/main/java/controller/deckmenu/DeckMenuOutput.java new file mode 100644 index 0000000..92896b1 --- /dev/null +++ b/My Part 3/src/main/java/controller/deckmenu/DeckMenuOutput.java @@ -0,0 +1,23 @@ +package controller.deckmenu; + +public class DeckMenuOutput { + + private DeckMenuOutput() { + } + + private static DeckMenuOutput instance; + + public static DeckMenuOutput getInstance() { + if (instance == null) + instance = new DeckMenuOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My Part 3/src/main/java/controller/deckmenu/DeckMenuTools.java b/My Part 3/src/main/java/controller/deckmenu/DeckMenuTools.java new file mode 100644 index 0000000..1350533 --- /dev/null +++ b/My Part 3/src/main/java/controller/deckmenu/DeckMenuTools.java @@ -0,0 +1,70 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +public class DeckMenuTools { + public static boolean isDeckNameUnique(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck == null) + return true; + + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " already exists"); + return false; + + } + public static boolean doesDeckExist(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck != null) + return true; + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " does not exist"); + return false; + + } + public static boolean doesDeckBelongToPlayer(Deck deck, Player player) { + if (deck.getOwner().getUsername().equals(player.getUsername())) + return true; + DeckMenuOutput.getInstance().showMessage("this deck doesn't belong to you!"); + return false; + } + public static boolean doesDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getMainCards().size() < 60) + return true; + DeckMenuOutput.getInstance().showMessage("main deck is full!"); + return false; + } + public static boolean doesSideDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getSideCards().size() < 15) + return true; + DeckMenuOutput.getInstance().showMessage("side deck is full!"); + return false; + } + public static boolean isNumberOfCardsInDeckLessThanFour(Deck deck, Card card) { + if (deck.getNumberOfCardsInDeck(card) < 3) + return true; + DeckMenuOutput.getInstance().showMessage("there are already three cards with name " + card.getName() + + " in deck " + deck.getName() + " !"); + return false; + } + public static boolean isDeckAllowed(Deck deck) { + int numberOfCardsInSideDeck = deck.getNumberOfCardsInSideDeck(); + int numberOfCardsInMainDeck = deck.getNumberOfCardsInMainDeck(); + return numberOfCardsInMainDeck <= 60 && numberOfCardsInMainDeck >= 40 && numberOfCardsInSideDeck <= 15; + } + public static boolean doesPlayerHaveEnoughCards(Card card, Player player) { + if (player.hasCard(card)) + return true; + DeckMenuOutput.getInstance().showMessage("you dont have this type of card anymore!"); + return false; + } + public static boolean doesCardExist(String cardName) { + Card card = DeckMenuDatabase.getInstance().getCardByName(cardName); + if (card != null) + return true; + DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist"); + return false; + } + +} diff --git a/My Part 3/src/main/java/controller/duelmenu/DuelMenuController.java b/My Part 3/src/main/java/controller/duelmenu/DuelMenuController.java new file mode 100644 index 0000000..6b06f49 --- /dev/null +++ b/My Part 3/src/main/java/controller/duelmenu/DuelMenuController.java @@ -0,0 +1,681 @@ +package controller.duelmenu; + +import controller.SpellCardController; +import controller.Utils; +import model.Board; +import model.Deck; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.DuelMenuView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.regex.Matcher; + +public class DuelMenuController { + private Player turnPlayer; + private Player notTurnPlayer; + private Player helpTurnPlayer; + private Phases phase; + private boolean isAITurn; + private int isSummoned = 0; //0 : is not summoned before, 1 : is summoned before + + public static String specifyTurnPlayer(Player firstPlayer, Player secondPlayer) { + String firstPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(firstPlayer); + if (!isMiniGameChoiceValid(firstPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices firstPlayerChoice = MiniGameChoices.valueOf(firstPlayerChoiceInString.toUpperCase()); + + String secondPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(secondPlayer); + if (!isMiniGameChoiceValid(secondPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices secondPlayerChoice = MiniGameChoices.valueOf(secondPlayerChoiceInString.toUpperCase()); + + if (firstPlayerChoice.equals(secondPlayerChoice)) return "draw"; + + return findMiniGameWinner(firstPlayer, secondPlayer, firstPlayerChoice, secondPlayerChoice); + } + + private static boolean isMiniGameChoiceValid(String choice) { + try { + MiniGameChoices.valueOf(choice.toUpperCase()); + return true; + } catch (Exception exception) { + return false; + } + } + + private static String findMiniGameWinner(Player firstPlayer, Player secondPlayer, + MiniGameChoices firstPlayerChoice, MiniGameChoices secondPlayerChoice) { + switch (firstPlayerChoice) { + case STONE: + if (secondPlayerChoice.equals(MiniGameChoices.PAPER)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case PAPER: + if (secondPlayerChoice.equals(MiniGameChoices.SCISSOR)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case SCISSOR: + if (secondPlayerChoice.equals(MiniGameChoices.STONE)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + } + +// this is never happen + return null; + } + + public DuelMenuMessages initialGame(Player firstPlayer, Player secondPlayer) { +// TODO: handle it for ai + String result = specifyTurnPlayer(firstPlayer, secondPlayer); + if (result.equals("invalid choice")) return DuelMenuMessages.MINI_GAME_INVALID_CHOICE; + else if (result.equals("draw")) return DuelMenuMessages.DRAW; + else turnPlayer = Player.getPlayerByUsername(result); + + if (turnPlayer.equals(firstPlayer)) notTurnPlayer = secondPlayer; + else notTurnPlayer = firstPlayer; + + turnPlayer.createBoard(); + notTurnPlayer.createBoard(); + + turnPlayer.getBoard().setDeck(turnPlayer.getActivatedDeck()); + notTurnPlayer.getBoard().setDeck(notTurnPlayer.getActivatedDeck()); + + Collections.shuffle(turnPlayer.getActivatedDeck().getMainCards()); + Collections.shuffle(notTurnPlayer.getActivatedDeck().getMainCards()); + + return DuelMenuMessages.SHOW_TURN_PLAYER; + } + + public DuelMenuMessages findCommand(String command) { +// TODO: handle menu commands --> menu exit and ... + if (command.startsWith("decrease ")) return cheatCodeDecreaseOpponentLifePont(command); + else if (command.startsWith("increase ")) return cheatCodeIncreaseLifePoint(command); + else if (command.startsWith("duel set-winner ")) return cheatCodeSetWinner(command); + else if (command.startsWith("increase --money ")) return cheatCodeIncreaseMoney(command); + else if (command.startsWith("select ")) return checkSelectCard(command); + else if (command.equals("select -d")) return deselectCard(); + else if (command.equals("summon")) ;//return checkSummonMonster(); + else if (command.equals("set")) return checkSetACard(); + else if (command.startsWith("set --position"));// return checkChangePosition(command); + else if (command.equals("flip-summon")) ;//return checkFlipSummon(); + else if (command.equals("attack direct")) return directAttack(); + else if (command.startsWith("attack")) return attack(command); + else if (command.equals("activate effect")) return checkActiveASpellCard(); + else if (command.equals("show graveyard")) { + DuelMenuView.showGraveyard(turnPlayer.getBoard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("back")) ;//checkBack(); + else if (command.equals("card show --selected")) { + DuelMenuView.printCard(1, turnPlayer.getBoard().getSelectedCard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("cancel")) ;//cancelCommand(); + else if (command.equals("surrender")) /*TODO*/; + +// TODO: handle cheat/debug commands + + return DuelMenuMessages.INVALID_COMMAND; + } + + private DuelMenuMessages cheatCodeDecreaseOpponentLifePont(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_DECREASE_OPPONENT_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + notTurnPlayer.decreaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + } + + private DuelMenuMessages cheatCodeIncreaseLifePoint(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_INCREASE_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + turnPlayer.increaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + } + + private DuelMenuMessages cheatCodeSetWinner(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_SET_WINNER.getRegex(), command); + if (matcher.find()) { + String nickname = matcher.group(1); + if (turnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/; + else if (notTurnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/; + else DuelMenuMessages.WRONG_NICKNAME_CHEAT_CODE; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + } + + private DuelMenuMessages cheatCodeIncreaseMoney(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_INCREASE_MONEY.getRegex(), command); + if (matcher.find()) { + turnPlayer.increaseMoney(Integer.parseInt(matcher.group(1))); + return null; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + } + + //Iman's Code + private void changePhase() { + phase = phase.next(); + DuelMenuMessages.changephase(phase); + + } + + private void changeGameTurn(Player firstPlayer, Player secondPlayer) { + if (turnPlayer == firstPlayer) { + turnPlayer = secondPlayer; + notTurnPlayer = firstPlayer; + } + if (turnPlayer == secondPlayer) { + turnPlayer = firstPlayer; + notTurnPlayer = secondPlayer; + } + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void changeGameTurn() { + helpTurnPlayer = turnPlayer; + turnPlayer = notTurnPlayer; + notTurnPlayer = helpTurnPlayer; + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void drawPhase() { + changeGameTurn(); + DuelMenuMessages.playerTurn(turnPlayer); + cardDraw(); + } + + public void cardDraw() { + Deck deck = turnPlayer.getBoard().getDeck(); + if (deck.getNumberOfCardsInMainDeck() == 0) { + turnPlayer.setLifePoint(0); + return; + } + turnPlayer.getBoard().drawCard(); + } + + private DuelMenuMessages summonMonster() { + int position = 0; // TODO fix this + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (selectedMonster.getLevel() <= 4) { + selectedCard.getCardFaceUp(); + selectedMonster.settoOO(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + } + else if (selectedMonster.getLevel() == 5 || selectedMonster.getLevel() == 6) { + summonWithOneTribute(position); + } + else if (selectedMonster.getLevel() == 7 || selectedMonster.getLevel() == 8) { + summonWithTwoTribute(position); + } + } + + private DuelMenuMessages checkSummonMonster() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard) || selectedCard.getCardType() == CardTypes.RITUAL) { + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + else if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + else if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + else if (isSummoned == 1){ + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + + } + + private DuelMenuMessages summonWithOneTribute(int position) { + if (!turnPlayer.getBoard().isThereOneMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + return DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE; + } + String addressString = Utils.getScanner().nextLine().trim(); + if (addressString.equals("")) return null; // TODO fix this + int address = setCardAddressInMyBoard(Integer.parseInt(addressString)); + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address)) { + return DuelMenuMessages.NO_MONSTER_ON_THIS_ADDRESS; + } + //turnPlayer.getBoard().removeFromMonsterZone(monsterZone.get(address1)); + //turnPlayer.getBoard().removeFromHand(selectedCard); + + } + + private void summonWithTwoTribute(int position) { + if (!turnPlayer.getBoard().isThereTwoMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + DuelMenuMessages.NotEnoughCardForTribute(); + } + String addressString1 = Utils.getScanner().nextLine().trim(); + if (addressString1.equals("surrender")) return; + String addressString2 = Utils.getScanner().nextLine().trim(); + if (addressString2.equals("surrender")) return; + int address1 = setCardAddressInMyBoard(Integer.parseInt(addressString1)); + int address2 = setCardAddressInMyBoard(Integer.parseInt(addressString2)); + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address1)) return; + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address2)) return; + // turnPlayer.getBoard().deleteMonsterFromZone(monsterZone.get(address1), monsterZone); + // turnPlayer.getBoard().deleteMonsterFromZone(monsterZone.get(address2)); + + } + + private int setCardAddressInMyBoard(int address) { + if (address == 5) return 0; + if (address == 3) return 1; + if (address == 1) return 2; + if (address == 2) return 3; + if (address == 4) return 4; + return -1; + } + + private DuelMenuMessages set() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + // int position = selectedCardIndex; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected()) { + return DuelMenuMessages.SET_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + if (isSummoned == 1){ + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + return DuelMenuMessages.SET_SUCCESSFULLY; + if (model.cards.Card.isMonsterCard(selectedCard)) { + setMonster(); + } + if (model.cards.Card.isMonsterCard(selectedCard)) { + setSpell(); + } + + + } + + private DuelMenuMessages setMonster() { + + } + + private DuelMenuMessages setSpell() { + + } + + private DuelMenuMessages checkFlipSummon() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard)) { // check type of monsters + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (selectedMonster.toString().equals("DH") || isSummoned != 0) { + return DuelMenuMessages.FLIP_SUMMON_NOT_POSSIBLE; + } + selectedMonster.settoDO(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + + } + + private DuelMenuMessages ritualSummon() { + + + } + + private DuelMenuMessages specialSummon() { + + + } + + private DuelMenuMessages checkSelectCard(String command) { +// TODO: handle --> if there isn't any card in main deck, he/she loses +// TODO: maybe clean it more + Matcher matcher; + if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MONSTER_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MAGIC_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_FIELD_ZONE.getRegex(), command).find()) { + if (turnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(true); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_CARDS_IN_HAND.getRegex(), command)).find() ) { + int number = Integer.parseInt(matcher.group(1)); + if (number > turnPlayer.getBoard().getCardsInHand().size()) { + return DuelMenuMessages.INVALID_SELECTION; + } + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getCardsInHand().get(number - 1)); + turnPlayer.getBoard().setMyCardSelected(true); + turnPlayer.getBoard().setACardInHandSelected(true); + + } else { + turnPlayer.getBoard().setSelectedCard(null); + turnPlayer.getBoard().setMyCardSelected(false); + return DuelMenuMessages.INVALID_SELECTION; + } + + return DuelMenuMessages.CARD_SELECTED; + } + + private boolean isSelectionValid(Matcher matcher) { + int number = Integer.parseInt(matcher.group(1)); + return number <= 5 && number >= 1; + } + + private boolean isCardAvailableInMonstersZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMonstersZone()[number] != null; + } + + private boolean isCardAvailableInMagicsZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMagicsZone()[number] != null; + } + + private void selectCardFromMonstersZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMonstersZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMonstersZone()[number]); + } + } + + private void selectCardFromMagicsZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMagicsZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMagicsZone()[number]); + } + } + + private void selectCardFromFieldZone(boolean isMyCardSelected) { + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getFieldZone()); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getSelectedCard()); + } + } + + private DuelMenuMessages deselectCard() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages result = checkDeselectCard(); + if (result == null) { + board.setSelectedCard(null); + return DuelMenuMessages.DESELECTED; + } else return result; + } + + private DuelMenuMessages checkDeselectCard() { + Board board = turnPlayer.getBoard(); + if (board.getSelectedCard() == null) + return DuelMenuMessages.NOT_SELECTED_CARD; + return null; + } +// +// +// private void victimize() { +//// TODO: handle it! +// } +// + private DuelMenuMessages checkSetACard() { + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (board.getSelectedCard() == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!board.isACardInHandSelected()) return DuelMenuMessages.CANT_SET; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.NOT_TRUE_PHASE; + else if (Card.isMonsterCard(selectedCard)) return checkSetAMonsterCard(selectedCard); + + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + } + + private DuelMenuMessages checkSetAMonsterCard(Card card) { + return DuelMenuMessages.EMPTY; + } + +// private DuelMenuMessages setAMonster() { +// +// } +// +// private DuelMenuMessages checkChangePosition(String command) { +// +// } +// +// private DuelMenuMessages changePosition(String command) { +// +// } +// +// private void updateGraveyard() { +//// TODO: handle it! +// } +// + + private DuelMenuMessages attack(String command) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.ATTACK.getRegex(), command); + if (matcher.find()) { + int numberOfChosenCard = Integer.parseInt(matcher.group(1)); + + DuelMenuMessages result = checkAttack(numberOfChosenCard); + if (result == null) { + MonsterCard attackingMonster = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentMonster = opponentPlayerBoard.getMonstersZone()[numberOfChosenCard]; + + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + DuelMenuMessages tempResult = attackingMonster.attack(turnPlayer, notTurnPlayer, numberOfChosenCard); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + + return tempResult; + } + return result; + + } else return DuelMenuMessages.INVALID_CARD_SELECT; + } + + private DuelMenuMessages checkAttack(int numberOfChosenCard) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + if (attackingPlayerBoard.getSelectedCard() == null || !attackingPlayerBoard.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (attackingPlayerBoard.getSelectedCard() instanceof MonsterCard) + return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + //TODO check battle phase + MonsterCard card = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + if (card.isAttacked()) + return DuelMenuMessages.ATTACKED_BEFORE; + if (opponentPlayerBoard.getMonstersZone()[numberOfChosenCard] == null) + return DuelMenuMessages.NO_CARD_FOUND_IN_THE_POSITION; + return null; + } + + private DuelMenuMessages directAttack() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages messages = checkDirectAttack(); + if (messages != null) + return messages; + else { + MonsterCard card = (MonsterCard) board.getSelectedCard(); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + notTurnPlayer.decreaseLifePoint(card.getAttackPoints()); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + + DuelMenuMessages.setDamageAmount(card.getAttackPoints()); + return DuelMenuMessages.DIRECT_ATTACK_DONE; + } + } + + private DuelMenuMessages checkDirectAttack() { + Board board = turnPlayer.getBoard(); + + if (board.getSelectedCard() == null || !board.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (phase.equals(phase.)) + return DuelMenuMessages.NOT_SUITABLE_PHASE; + if (board.getSelectedCard() instanceof MonsterCard) { + MonsterCard card = (MonsterCard) board.getSelectedCard();//TODO: handle cast exception!! + if (card.isAttacked()) return DuelMenuMessages.ATTACKED_BEFORE; + } else return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + + return null; + } + + private DuelMenuMessages checkActiveASpellCard() { +// TODO: clean it! + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (selectedCard == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!selectedCard.getCardType().equals(CardTypes.SPELL)) return DuelMenuMessages.NOT_SPELL_CARD; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.CANT_ACTIVATE_SPELL_EFFECT; + else if (selectedCard.isPowerUsed()) return DuelMenuMessages.CARD_ACTIVATED_BEFORE; + else if (!turnPlayer.getBoard().isMyCardSelected()) return DuelMenuMessages.NOT_OWNER; + + MagicCard spellCard = (MagicCard) selectedCard; + if (spellCard.getIcon().equals("Field")) { + turnPlayer.getBoard().addSpellCardToFieldZone(spellCard); + spellCard.setPowerUsed(true); + spellCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } else if (board.isMagicsZoneFull() && board.isACardInHandSelected()) return DuelMenuMessages.FULL_MAGICS_ZONE; + + if (!SpellCardController.doSpellCardEffect(turnPlayer, notTurnPlayer, spellCard)) return DuelMenuMessages.UNDONE_PREPARATIONS; + if (board.isACardInHandSelected()) board.addMagicCardToMagicsZone(spellCard); + selectedCard.setPowerUsed(true); + selectedCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } + + private DuelMenuMessages setAMagicCard(MagicCard magicCard) { + Board board = turnPlayer.getBoard(); + if (magicCard.getIcon().equals("Field")) board.addSpellCardToFieldZone(magicCard); + else if (board.isMagicsZoneFull()) return DuelMenuMessages.FULL_MAGICS_ZONE; + else board.addMagicCardToMagicsZone(magicCard); + magicCard.setPowerUsed(false); + magicCard.setCardFaceUp(false); + + return DuelMenuMessages.SET_SUCCESSFULLY; + } + +// private DuelMenuMessages checkBack() { +// +// } +// +// private void cancelCommand() { +// +// } +// +// TODO: handle activeASpellInOpponentTurn +// TODO: ----------------------------------------------- +// TODO: we are not sure about under functions +// +// private DuelMenuMessages ritualSummon(String command) { +// +// } +// +// private DuelMenuMessages specialSummon(String command) { +// +// } +// +// private Player/*or Enum*/ checkWinner() { +// +// } +// +// TODO: ----------------------------------------------- + +} diff --git a/My Part 3/src/main/java/controller/duelmenu/DuelMenuMessages.java b/My Part 3/src/main/java/controller/duelmenu/DuelMenuMessages.java new file mode 100644 index 0000000..966b148 --- /dev/null +++ b/My Part 3/src/main/java/controller/duelmenu/DuelMenuMessages.java @@ -0,0 +1,103 @@ +package controller.duelmenu; + +import model.Player; + +public enum DuelMenuMessages { + MINI_GAME_INVALID_CHOICE("please enter a valid option\n"), + DRAW("draw\nplease try again:\n"), + SHOW_TURN_PLAYER(" should start first\n"), + INVALID_SELECTION("invalid selection\n"), + CARD_SELECTED("card selected\n"), + CARD_NOT_FOUND("no card found in the given position\n"), + UNAVAILABLE_SELECTED_CARD("no card is selected yet\n"), + NOT_SPELL_CARD("activate effect is only for spell cards.\n"), + CANT_ACTIVATE_SPELL_EFFECT("you can’t activate an effect on this turn\n"), + CARD_ACTIVATED_BEFORE("you have already activated this card\n"), + FULL_MAGICS_ZONE("spell card zone is full\n"), + UNDONE_PREPARATIONS("preparations of this spell are not done yet\n"), + SPELL_ACTIVATED("spell activated\n"), + NOT_OWNER("you aren't owner of selected card\n"), + CANT_SET("you can’t set this card\n"), + NOT_TRUE_PHASE("you can’t do this action in this phase\n"), + SET_SUCCESSFULLY("set successfully\n"), + NOT_SELECTED_CARD("no card is selected yet\n"), + ATTACKED_BEFORE("this card already attacked\n"), + NOT_SUITABLE_PHASE("you can’t do this action in this phase\n"), + INVALID_CARD_SELECT("invalid selection\n"), + NO_CARD_FOUND_IN_THE_POSITION("no card found in the given position\n"), + CANT_ATTACK_WITH_CARD("you can’t attack with this card\n"), + YOU_CANT_ATTACK_TO_THIS_CARD("you cant attack to this card\n"), + ATTACK_CANCELED("attack to this card was canceled\n"), + DIRECT_ATTACK_DONE("you opponent receives battle damage\n"), + DESELECTED("card deselected\n"), + INVALID_COMMAND_CHEAT_CODE("invalid command\n"), + OPPONENT_GOT_DAMAGE_IN_ATTACK("your opponent’s monster is destroyed and your opponent receives battle damage\n"), + ATTACKING_PLAYER_CARD_DESTROYED("Your monster card is destroyed and you received battle damage\n"), + DEFENSE_POSITION_MONSTER_DESTROYED("the defense position monster is destroyed\n"), + NO_CARD_DESTROYED("no card is destroyed\n"), + RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD("no card is destroyed and you received battle damage\n"), + BOTH_CARDS_GET_DESTROYED("both you and your opponent monster cards are destroyed and no one receives damage\n"), + EMPTY(""), + NO_CARD_SELECTED("no card is selected yet\n"), + SUMMON_NOT_POSSIBLE("you can’t summon this card\n"), + FLIP_SUMMON_NOT_POSSIBLE("you can’t flip summon this card\n"), + SET_NOT_POSSIBLE("you can’t set this card\n"), + PLAYER_TURN("it's 's turn"), + PHASE_IS_CHANGED("phase: \n"), + ALREADY_SUMMONED_OR_SET("you already summoned/set on this turn\n"), + NOT_ENOUGH_CARD_FOR_TRIBUTE("there are not enough card for tribute\n"), + NO_MONSTER_ON_THIS_ADDRESS("there are no monster one this address\n"), + MONSTER_ZONE_IS_FULL("monster card zone is full\n"), + SUMMONED_SUCCESSFULLY("summoned successfully\n"), + CHANG_POSITION_NOT_POSSIBLE("you can’t change this card position\n"), + INVALID_COMMAND("invalid command\n"); + private String message; + + DuelMenuMessages(String message) { + this.message = message; + } + + public static void setShowTurnPlayer(Player player) { + DuelMenuMessages.SHOW_TURN_PLAYER.message = player.getUsername() + " should start first\n"; + } + + public static void NotEnoughCardForTribute(){ + DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE.message = "there are not enough card for tribute\n"; + System.out.print("there are not enough card for tribute\n"); + } + + public static void noCardSelected() { + DuelMenuMessages.NO_CARD_SELECTED.message = "no card is selected yet"; + } + + public static void playerTurn(Player player) { + DuelMenuMessages.PLAYER_TURN.message = "it's + player.getUsername() + 's turn"; + } + + public static void changephase(Phases phase) { + DuelMenuMessages.PHASE_IS_CHANGED.message = "phase: " + phase; + } + + public static void setDamageAmount(int damageAmount) { + DuelMenuMessages.DIRECT_ATTACK_DONE.message = "you opponent receives " + damageAmount + " battle damage\n"; + } + + public static void setOpponentGotDamageInAttack(int damage) { + DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK.message = + "your opponent’s monster is destroyed and your opponent receives" + damage + " battle damage\n"; + } + + public static void setAttackingPlayerCardDestroyed(int damage) { + DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED.message = + "Your monster card is destroyed and you received " + damage + " battle damage\n"; + } + + public static void setReceiveDamageByAttackingToDefenseCard(int damage) { + DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD.message = + "no card is destroyed and you received " + damage + " battle damage\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 3/src/main/java/controller/duelmenu/DuelMenuRegexes.java b/My Part 3/src/main/java/controller/duelmenu/DuelMenuRegexes.java new file mode 100644 index 0000000..9c6c26f --- /dev/null +++ b/My Part 3/src/main/java/controller/duelmenu/DuelMenuRegexes.java @@ -0,0 +1,29 @@ +package controller.duelmenu; + +public enum DuelMenuRegexes { + SELECT_MONSTER_ZONE("^select --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_MAGIC_ZONE("^select --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN("^select --(?:monster|M) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN("^select --(?:spell|S) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_FIELD_ZONE("^select --(?:field|F)$"), + SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN("^select --(?:field|F) --(?:opponent|O)$"), + SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:field|F)$"), + SELECT_CARDS_IN_HAND("^select --(?:hand|H) ((?:-|)\\d+)$"), + CHEAT_DECREASE_OPPONENT_LIFE_POINT("^decrease --opponentLP ([0-9]+)$"), + CHEAT_INCREASE_LIFE_POINT("^increase --LP ([0-9]+)$"), + CHEAT_SET_WINNER("^duel set-winner (\\S+)$"), + CHEAT_INCREASE_MONEY("^increase --money ([0-9]+)$"), + ATTACK("^attack ([0-9]+)$"); + + private final String regex; + + DuelMenuRegexes(String message) { + this.regex = message; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 3/src/main/java/controller/duelmenu/MiniGameChoices.java b/My Part 3/src/main/java/controller/duelmenu/MiniGameChoices.java new file mode 100644 index 0000000..57881a4 --- /dev/null +++ b/My Part 3/src/main/java/controller/duelmenu/MiniGameChoices.java @@ -0,0 +1,17 @@ +package controller.duelmenu; + +public enum MiniGameChoices { + STONE("stone"), + PAPER("paper"), + SCISSOR("scissor"); + + private final String choice; + + MiniGameChoices(String choice) { + this.choice = choice; + } + + public String getChoice() { + return choice; + } +} diff --git a/My Part 3/src/main/java/controller/duelmenu/Phases.java b/My Part 3/src/main/java/controller/duelmenu/Phases.java new file mode 100644 index 0000000..14000bb --- /dev/null +++ b/My Part 3/src/main/java/controller/duelmenu/Phases.java @@ -0,0 +1,15 @@ +package controller.duelmenu; + +public enum Phases { + DRAW_PHASE, + STANDBY_PHASE, + MAIN_PHASE_1, + BATTLE_PHASE, + MAIN_PHASE_2, + END_PHASE; + private static Phases[] values = values(); + + public Phases next() { + return values[(this.ordinal() + 1) % values.length]; + } +} diff --git a/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuController.java b/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuController.java new file mode 100644 index 0000000..cde2f83 --- /dev/null +++ b/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuController.java @@ -0,0 +1,100 @@ +package controller.importexportmenu; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Utils; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.regex.Matcher; + +public class ImportExportMenuController { + public static ImportExportMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU; + else if (command.equals("menu show-current")) return ImportExportMenuMessages.SHOW_MENU; + else if (command.startsWith("import card")) return importCard(command); + else if (command.startsWith("export card")) return exportCard(command); + + return ImportExportMenuMessages.INVALID_COMMAND; + } + + private static ImportExportMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + return ImportExportMenuMessages.INVALID_NAVIGATION; + } + + private static ImportExportMenuMessages importCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.IMPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + try { + FileReader fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + MonsterCard monsterCard = gson.fromJson(fileReader, MonsterCard.class); + + if (Card.getCardByName(cardName) != null) return ImportExportMenuMessages.AVAILABLE_CARD; + if (monsterCard.getAttribute() == null) { +// so we understand that the card is a magic card + fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + MagicCard magicCard = gson.fromJson(fileReader, MagicCard.class); + Card.addCardToAllCards(magicCard); + if (isCardIncomplete(magicCard) || isMagicCardIncomplete(magicCard)) + return ImportExportMenuMessages.INVALID_FILE; + } else { +// so we understand that the card is a monster card + monsterCard.createEquippedByArrayList(); + Card.addCardToAllCards(monsterCard); + if (isCardIncomplete(monsterCard) || isMonsterCardIncomplete(monsterCard)) + return ImportExportMenuMessages.INVALID_FILE; + } + fileReader.close(); + } catch (IOException ignore) { + return ImportExportMenuMessages.UNAVAILABLE_FILE; + } + + + return ImportExportMenuMessages.EMPTY; + } + + private static boolean isCardIncomplete(Card card) { + return card.getName() == null || card.getDescription() == null || card.getCardType() == null; + } + + private static boolean isMonsterCardIncomplete(MonsterCard monsterCard) { + return monsterCard.getAttribute() == null || monsterCard.getMonsterType() == null; + } + + private static boolean isMagicCardIncomplete(MagicCard magicCard) { + return magicCard.getIcon() == null || magicCard.getStatus() == null; + } + + private static ImportExportMenuMessages exportCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.EXPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card card = Card.getCardByName(cardName); + if (card == null) return ImportExportMenuMessages.UNAVAILABLE_CARD; + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(card)); + fileWriter.close(); + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + + + return ImportExportMenuMessages.EMPTY; + } +} diff --git a/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java b/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java new file mode 100644 index 0000000..8f83021 --- /dev/null +++ b/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java @@ -0,0 +1,23 @@ +package controller.importexportmenu; + +public enum ImportExportMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_IMPORT_EXPORT_MENU(""), + SHOW_MENU("Import/Export Menu\n"), + INVALID_COMMAND("invalid command\n"), + UNAVAILABLE_FILE("there isn't any file with your entered card name\n"), + INVALID_FILE("your card file is not valid to import\n"), + AVAILABLE_CARD("your entered card name is available\n"), + UNAVAILABLE_CARD("your entered card name is not available\n"), + EMPTY(""); + + private final String message; + + ImportExportMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java b/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java new file mode 100644 index 0000000..65c74dc --- /dev/null +++ b/My Part 3/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.importexportmenu; + +public enum ImportExportMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + IMPORT_CARD("^import card ([^\n]+)$"), + EXPORT_CARD("^export card ([^\n]+)$"); + + private final String regex; + + ImportExportMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 3/src/main/java/controller/loginmenu/LoginMenuController.java b/My Part 3/src/main/java/controller/loginmenu/LoginMenuController.java new file mode 100644 index 0000000..178d000 --- /dev/null +++ b/My Part 3/src/main/java/controller/loginmenu/LoginMenuController.java @@ -0,0 +1,120 @@ +package controller.loginmenu; + +import controller.Utils; +import model.Player; +import view.MainMenuView; + +import java.util.regex.Matcher; + +public class LoginMenuController { + public static LoginMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) System.exit(0); + else if (command.equals("menu show-current")) return LoginMenuMessages.SHOW_MENU; + else if (command.startsWith("user create")) { + return checkCreateUser(command); + } else if (command.startsWith("user login")) { + return checkLoginUser(command); + } + + return LoginMenuMessages.INVALID_COMMAND; + } + + private static LoginMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(LoginMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return LoginMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return LoginMenuMessages.INVALID_NAVIGATION; + } + + return LoginMenuMessages.FIRST_LOGIN; + } + + private static LoginMenuMessages checkCreateUser(String command) { + Matcher matcher; + String username, nickname, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIRST_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(2); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SECOND_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(3); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_THIRD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(1); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FOURTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIFTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(3); + password = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SIXTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (Player.getPlayerByUsername(username) != null) { + LoginMenuMessages.setUsername(username); + return LoginMenuMessages.USERNAME_EXISTS; + } + if (Player.isNicknameExist(nickname)) { + LoginMenuMessages.setNickname(nickname); + return LoginMenuMessages.NICKNAME_EXISTS; + } + +// TODO: handle to have "strong password" error + createUser(username, password, nickname); + return LoginMenuMessages.USER_CREATED; + } + + private static void createUser(String username, String password, String nickname) { + new Player(username, password, nickname); + } + + private static LoginMenuMessages checkLoginUser(String command) { + Matcher matcher; + String username, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (!Player.isPasswordCorrect(username, password)) { + return LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD; + } + + return LoginMenuMessages.USER_LOGGED_IN; + } + + public static void loginUser(String command) { + Matcher matcher; + String username = null; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + } + + + MainMenuView mainMenuView = new MainMenuView(Player.getPlayerByUsername(username)); + mainMenuView.mainMenuView(); + } +} diff --git a/My Part 3/src/main/java/controller/loginmenu/LoginMenuMessages.java b/My Part 3/src/main/java/controller/loginmenu/LoginMenuMessages.java new file mode 100644 index 0000000..167c111 --- /dev/null +++ b/My Part 3/src/main/java/controller/loginmenu/LoginMenuMessages.java @@ -0,0 +1,31 @@ +package controller.loginmenu; + +public enum LoginMenuMessages { + FIRST_LOGIN("please login first"), + INVALID_NAVIGATION("menu navigation is not possible"), + SHOW_MENU("Login Menu"), + USER_CREATED("user created successfully!"), + USERNAME_EXISTS("user with username already exists"), + NICKNAME_EXISTS("user with nickname already exists"), + USER_LOGGED_IN("user logged in successfully!"), + UNMATCHED_USERNAME_AND_PASSWORD("Username and password didn’t match!"), + INVALID_COMMAND("invalid command"); + + private String message; + + LoginMenuMessages(String message) { + this.message = message; + } + + public static void setUsername(String username) { + USERNAME_EXISTS.message = "user with username " + username + " already exists"; + } + + public static void setNickname(String nickname) { + NICKNAME_EXISTS.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 3/src/main/java/controller/loginmenu/LoginMenuRegexes.java b/My Part 3/src/main/java/controller/loginmenu/LoginMenuRegexes.java new file mode 100644 index 0000000..f518551 --- /dev/null +++ b/My Part 3/src/main/java/controller/loginmenu/LoginMenuRegexes.java @@ -0,0 +1,23 @@ +package controller.loginmenu; + +public enum LoginMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + CREATE_USER_FIRST_PATTERN("^user create --(?:username|U) (\\S+) --(?:nickname|N) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_SECOND_PATTERN("^user create --(?:username|U) (\\S+) --(?:password|P) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_THIRD_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_FOURTH_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"), + CREATE_USER_FIFTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:username|U) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_SIXTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:nickname|N) (\\S+) --(?:username|U) (\\S+)$"), + LOGIN_USER_USERNAME_PATTERN("^user login --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + LOGIN_USER_PASSWORD_PATTERN("^user login --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"); + + private final String regex; + + LoginMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 3/src/main/java/controller/mainmenu/MainMenuController.java b/My Part 3/src/main/java/controller/mainmenu/MainMenuController.java new file mode 100644 index 0000000..6f68f7b --- /dev/null +++ b/My Part 3/src/main/java/controller/mainmenu/MainMenuController.java @@ -0,0 +1,117 @@ +package controller.mainmenu; + +import controller.Utils; +import model.Player; +import view.DuelMenuView; +import view.ImportExportMenuView; +import view.ProfileMenuView; +import view.ShopMenuView; + +import java.util.regex.Matcher; + +public class MainMenuController { + private final Player loggedInPlayer; + + public MainMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public MainMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return MainMenuMessages.EXIT_MAIN_MENU; + else if (command.equals("menu show-current")) return MainMenuMessages.SHOW_MENU; + else if (command.equals("user logout")) return MainMenuMessages.USER_LOGGED_OUT; + else if (command.startsWith("duel")) return enterDuelMenu(command); + + return MainMenuMessages.INVALID_COMMAND; + } + + private MainMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(MainMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return MainMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Main")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Duel")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Deck")) { + DeckMenuView deckMenuView = new DeckMenuView(loggedInPlayer); + deckMenuView.deckMenuView(); + } else if (menu.equalsIgnoreCase("Scoreboard")) { + ScoreboardMenuView scoreboardMenuView = new ScoreboardMenuView(); + scoreboardMenuView.runScoreboard(); + } else if (menu.equalsIgnoreCase("Profile")) { + ProfileMenuView profileMenuView = new ProfileMenuView(loggedInPlayer); + profileMenuView.profileMenuView(); + } else if (menu.equalsIgnoreCase("Shop")) { + ShopMenuView shopMenuView = new ShopMenuView(loggedInPlayer); + shopMenuView.shopMenuView(); + } else if (menu.equalsIgnoreCase("ImportExport")) { + ImportExportMenuView importExportMenuView = new ImportExportMenuView(); + importExportMenuView.ImportExportMenuView(); + } + + return MainMenuMessages.EMPTY; + } + + private MainMenuMessages enterDuelMenu(String command) { +// TODO: clean and optimise this code according to AI + Matcher matcher; + String opponentPlayerCommand, rounds; + if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIRST_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_THIRD_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FOURTH_PATTERN.getRegex(), command) ).find()) { + opponentPlayerCommand = matcher.group(1); + rounds = matcher.group(2); + } else if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SECOND_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIFTH_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SIXTH_PATTERN.getRegex(), command) ).find()) { + rounds = matcher.group(1); + opponentPlayerCommand = matcher.group(2); + } else { + return MainMenuMessages.INVALID_COMMAND; + } + + if (opponentPlayerCommand.startsWith("second-player")) { + String opponentPlayerUsername = opponentPlayerCommand.substring(14); + Player opponentPlayer = Player.getPlayerByUsername(opponentPlayerUsername); + if (opponentPlayer == null) { + return MainMenuMessages.UNAVAILABLE_USERNAME; + } + + if (opponentPlayer.equals(loggedInPlayer)) return MainMenuMessages.SAME_USERNAME; + + if (loggedInPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(loggedInPlayer.getUsername()); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } else if (opponentPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(opponentPlayerUsername); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } + +// TODO: handle MainMenuMessages.INVALID_DECK message +// TODO: MainMenuMessages.setInvalidDeck(opponentPlayerUsername or loggedInPlayer.getUsername()); +// TODO: return MainMenuMessages.INVALID_DECK; + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + +// TODO: handle 1 or 3 turn game + DuelMenuView duelMenuView = new DuelMenuView(loggedInPlayer, opponentPlayer); + duelMenuView.duelMenuView(); + } else { +// TODO: handle entering to enter duel menu by AI + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + } + + return MainMenuMessages.EMPTY; + } +} diff --git a/My Part 3/src/main/java/controller/mainmenu/MainMenuMessages.java b/My Part 3/src/main/java/controller/mainmenu/MainMenuMessages.java new file mode 100644 index 0000000..85fa672 --- /dev/null +++ b/My Part 3/src/main/java/controller/mainmenu/MainMenuMessages.java @@ -0,0 +1,33 @@ +package controller.mainmenu; + +public enum MainMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_MAIN_MENU(""), + SHOW_MENU("Main Menu\n"), + USER_LOGGED_OUT("user logged out successfully!\n"), + UNAVAILABLE_USERNAME("there is no player with this username\n"), + SAME_USERNAME("please enter another username\n"), + UNAVAILABLE_ACTIVE_DECK(" has no active deck\n"), + INVALID_DECK("’s deck is invalid\n"), + INVALID_ROUNDS_NUMBER("number of rounds is not supported\n"), + INVALID_COMMAND("invalid command\n"), + EMPTY(""); + + private String message; + + MainMenuMessages(String message) { + this.message = message; + } + + public static void setUnavailableActiveDeck(String username) { + UNAVAILABLE_ACTIVE_DECK.message = username + " has no active deck\n"; + } + + public static void setInvalidDeck(String username) { + INVALID_DECK.message = username + "’s deck is invalid\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 3/src/main/java/controller/mainmenu/MainMenuRegexes.java b/My Part 3/src/main/java/controller/mainmenu/MainMenuRegexes.java new file mode 100644 index 0000000..210780f --- /dev/null +++ b/My Part 3/src/main/java/controller/mainmenu/MainMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.mainmenu; + +public enum MainMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + ENTER_DUEL_MENU_FIRST_PATTERN("^duel --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_SECOND_PATTERN("^duel --(?:new|N) --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_THIRD_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_FOURTH_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+) --(?:new|N)$"), + ENTER_DUEL_MENU_FIFTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_SIXTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N)$"); + + private final String regex; + + MainMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 3/src/main/java/controller/profilemenu/ProfileMenuController.java b/My Part 3/src/main/java/controller/profilemenu/ProfileMenuController.java new file mode 100644 index 0000000..5384e86 --- /dev/null +++ b/My Part 3/src/main/java/controller/profilemenu/ProfileMenuController.java @@ -0,0 +1,99 @@ +package controller.profilemenu; + +import controller.Database; +import controller.Utils; +import model.Player; + +import java.util.regex.Matcher; + +public class ProfileMenuController { + private final Player loggedInPlayer; + + public ProfileMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ProfileMenuMessages findCommand(String command) { + String[] split = command.split("\\s+"); + if (split.length < 2) { + return ProfileMenuMessages.INVALID_COMMAND; + } else if (split[1].equals("enter")) { + return ProfileMenuMessages.CANT_NAVIGATE_MENU; + } else if (split[1].equals("exit")) { + return ProfileMenuMessages.EXIT_MENU; + } else if (split[1].equals("show")) { + return ProfileMenuMessages.PROFILE_MENU; + } else if (split[2].equals("--nickname")) { + return changeNickname(command); + } else if (command.startsWith("profile change")) { + return changePassword(command); + } + + return ProfileMenuMessages.INVALID_COMMAND; + } + + public ProfileMenuMessages changeNickname(String command) { + Matcher matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_NICKNAME.getRegex(), command); + + ProfileMenuMessages holdEnum = checkChangeNickName(matcher); + + if (holdEnum == null) { + loggedInPlayer.setNickname(matcher.group(1)); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_NICKNAME_DONE; + } + return holdEnum; + } + + public ProfileMenuMessages checkChangeNickName(Matcher matcher) { + if (matcher.find()) { + String nickname = matcher.group(1); + if (Player.isNicknameExist(nickname)) { + ProfileMenuMessages.setNickname(nickname); + return ProfileMenuMessages.NOT_UNIQUE_NICKNAME; + } + return null; + } else return ProfileMenuMessages.INVALID_COMMAND; + + } + + public ProfileMenuMessages changePassword(String command) { + String currentPassword, newPassword; + Matcher matcher; + if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIRST_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SECOND_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_THIRD_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FOURTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIFTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SIXTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else return ProfileMenuMessages.INVALID_COMMAND; + + ProfileMenuMessages holdEnum = checkChangePassword(currentPassword, newPassword); + + if (holdEnum == null) { + loggedInPlayer.setPassword(newPassword); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_PASSWORD_DONE; + } + + return holdEnum; + } + + public ProfileMenuMessages checkChangePassword(String currentPassword, String newPassword) { + if (!loggedInPlayer.getPassword().equals(currentPassword)) return ProfileMenuMessages.WRONG_CURRENT_PASSWORD; + if (currentPassword.equals(newPassword)) return ProfileMenuMessages.SAME_PASSWORD; + return null; + } +} diff --git a/My Part 3/src/main/java/controller/profilemenu/ProfileMenuMessages.java b/My Part 3/src/main/java/controller/profilemenu/ProfileMenuMessages.java new file mode 100644 index 0000000..4c0895f --- /dev/null +++ b/My Part 3/src/main/java/controller/profilemenu/ProfileMenuMessages.java @@ -0,0 +1,27 @@ +package controller.profilemenu; + +public enum ProfileMenuMessages { + NOT_UNIQUE_NICKNAME("user with nickname already exists"), + CHANGE_NICKNAME_DONE("nickname changed successfully!"), + CHANGE_PASSWORD_DONE("password changed successfully!"), + WRONG_CURRENT_PASSWORD("current password is invalid"), + INVALID_COMMAND("invalid command"), + PROFILE_MENU("profile menu"), + EXIT_MENU("exit"), + CANT_NAVIGATE_MENU("menu navigation is not possible"), + SAME_PASSWORD("please enter a new password"); + + private String message; + + ProfileMenuMessages(String message) { + this.message = message; + } + + public static void setNickname(String nickname) { + ProfileMenuMessages.NOT_UNIQUE_NICKNAME.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 3/src/main/java/controller/profilemenu/ProfileMenuRegexes.java b/My Part 3/src/main/java/controller/profilemenu/ProfileMenuRegexes.java new file mode 100644 index 0000000..ba8630d --- /dev/null +++ b/My Part 3/src/main/java/controller/profilemenu/ProfileMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.profilemenu; + +public enum ProfileMenuRegexes { + CHANGE_NICKNAME("^profile change --nickname (\\S+)$"), + CHANGE_PASSWORD_FIRST_PATTERN("^profile change --(?:password|P) --(?:current|C) (\\S+) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_SECOND_PATTERN("^profile change --(?:password|P) --(?:new|N) (\\S+) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_THIRD_PATTERN("^profile change --(?:current|C) (\\S+) --(?:password|P) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_FOURTH_PATTERN("^profile change --(?:current|C) (\\S+) --(?:new|N) (\\S+) --(?:password$|P)"), + CHANGE_PASSWORD_FIFTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:password|P) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_SIXTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:current|C) (\\S+) --(?:password$|P)"); + + private final String regex; + + ProfileMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 3/src/main/java/controller/scoreboardmenu/Scoreboard.java b/My Part 3/src/main/java/controller/scoreboardmenu/Scoreboard.java new file mode 100644 index 0000000..cb725a7 --- /dev/null +++ b/My Part 3/src/main/java/controller/scoreboardmenu/Scoreboard.java @@ -0,0 +1,40 @@ +package controller.scoreboardmenu; + +import java.util.ArrayList; +import model.*; + +public class Scoreboard { + + private Scoreboard() { + } + + private static Scoreboard instance; + + public static Scoreboard getInstance() { + if (instance == null) + instance = new Scoreboard(); + return instance; + } + + public void showScoreboard() { + int counter = 1; + int index = 0; + long previousScore = -1; + StringBuilder output = new StringBuilder(); + ArrayList allUsers = Player.getAllPlayers(); + allUsers.sort(Player::compareTo); + for (Player player : allUsers) { + + + if (player.getScore() != previousScore) { + index += counter; + counter = 1; + } else counter++; + output.append(index).append(". ").append(player.getNickname()).append(": ").append(player.getScore()).append("\n"); + previousScore = player.getScore(); + + } + ScoreboardOutput.getInstance().showMessage(output.toString()); + } + +} diff --git a/My Part 3/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java b/My Part 3/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java new file mode 100644 index 0000000..c77252d --- /dev/null +++ b/My Part 3/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java @@ -0,0 +1,23 @@ +package controller.scoreboardmenu; + +public class ScoreboardOutput { + + private ScoreboardOutput() { + } + + private static ScoreboardOutput instance; + + public static ScoreboardOutput getInstance() { + if (instance == null) + instance = new ScoreboardOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My Part 3/src/main/java/controller/shopmenu/ShopMenuController.java b/My Part 3/src/main/java/controller/shopmenu/ShopMenuController.java new file mode 100644 index 0000000..e8b9e95 --- /dev/null +++ b/My Part 3/src/main/java/controller/shopmenu/ShopMenuController.java @@ -0,0 +1,51 @@ +package controller.shopmenu; + +import controller.Database; +import controller.Utils; +import model.Player; +import model.cards.Card; + +import java.util.regex.Matcher; + +public class ShopMenuController { + private final Player loggedInPlayer; + + public ShopMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ShopMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ShopMenuMessages.EXIT_SHOP_MENU; + else if (command.equals("menu show-current")) return ShopMenuMessages.SHOW_MENU; + else if (command.startsWith("shop buy")) return buyACard(command); + else if (command.equals("shop show --all")) return ShopMenuMessages.SHOW_ALL_CARDS; + + return ShopMenuMessages.INVALID_COMMAND; + } + + private ShopMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + return ShopMenuMessages.INVALID_NAVIGATION; + } + + private ShopMenuMessages buyACard(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.BUY_CARD.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card boughtCard = Card.getCardByName(cardName); + if (boughtCard == null) return ShopMenuMessages.UNAVAILABLE_CARD; + + int boughtCardPrice = boughtCard.getPrice(); + if (boughtCardPrice > loggedInPlayer.getMoney()) return ShopMenuMessages.NOT_ENOUGH_MONEY; + + loggedInPlayer.decreaseMoney(boughtCardPrice); + loggedInPlayer.addCardToBoughtCards(boughtCard); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ShopMenuMessages.EMPTY; + } +} diff --git a/My Part 3/src/main/java/controller/shopmenu/ShopMenuMessages.java b/My Part 3/src/main/java/controller/shopmenu/ShopMenuMessages.java new file mode 100644 index 0000000..339bd0a --- /dev/null +++ b/My Part 3/src/main/java/controller/shopmenu/ShopMenuMessages.java @@ -0,0 +1,22 @@ +package controller.shopmenu; + +public enum ShopMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_SHOP_MENU(""), + SHOW_MENU("Shop Menu\n"), + UNAVAILABLE_CARD("there is no card with this name\n"), + NOT_ENOUGH_MONEY("not enough money\n"), + EMPTY(""), + SHOW_ALL_CARDS(""), + INVALID_COMMAND("invalid command\n"); + + private final String message; + + ShopMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 3/src/main/java/controller/shopmenu/ShopMenuRegexes.java b/My Part 3/src/main/java/controller/shopmenu/ShopMenuRegexes.java new file mode 100644 index 0000000..c2ca1ca --- /dev/null +++ b/My Part 3/src/main/java/controller/shopmenu/ShopMenuRegexes.java @@ -0,0 +1,16 @@ +package controller.shopmenu; + +public enum ShopMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + BUY_CARD("^shop buy ([^\n]+)$"); + + private final String regex; + + ShopMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 3/src/main/java/model/Board.java b/My Part 3/src/main/java/model/Board.java new file mode 100644 index 0000000..b7f7274 --- /dev/null +++ b/My Part 3/src/main/java/model/Board.java @@ -0,0 +1,193 @@ +package model; + +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Board { + private MonsterCard[] monstersZone; + private MagicCard[] magicsZone; + private ArrayList graveyard; + private ArrayList cardsInHand; + private Deck deck; + private MagicCard fieldZone;//TODO: maybe it should be from these classes --> Spell / fieldSpell + private Card selectedCard; +// if this boolean equals "false" so we can conclude that opponent card selected or nothing selected + private boolean isMyCardSelected; + private boolean isACardInHandSelected; + + { + monstersZone = new MonsterCard[6]; + magicsZone = new MagicCard[6]; + graveyard = new ArrayList<>(); + cardsInHand = new ArrayList<>(); + fieldZone = null; + isMyCardSelected = false; + isACardInHandSelected = false; + } + + public void setDeck(Deck deck) { + this.deck = deck;//TODO: maybe we should have a copy of deck in duel menu --> if all changes don't apply in main deck + } + + public MonsterCard[] getMonstersZone() { + return monstersZone; + } + + public MagicCard[] getMagicsZone() { + return magicsZone; + } + + public ArrayList getGraveyard() { + return graveyard; + } + + public ArrayList getCardsInHand() { + return cardsInHand; + } + + public MagicCard getFieldZone() { + return fieldZone; + } + + public Card getSelectedCard() { + return selectedCard; + } + + public Deck getDeck() { + return deck; + } + + public void setSelectedCard(Card selectedCard) { + this.selectedCard = selectedCard; + } + + public void setFieldZone(MagicCard fieldZone) { this.fieldZone = fieldZone; } + + public boolean isMyCardSelected() { + return isMyCardSelected; + } + + public void setMyCardSelected(boolean myCardSelected) { + isMyCardSelected = myCardSelected; + } + + public boolean isACardInHandSelected() { + return isACardInHandSelected; + } + + public void setACardInHandSelected(boolean ACardInHandSelected) { + isACardInHandSelected = ACardInHandSelected; + } + + public boolean isMagicsZoneFull() { + return getNumberOfFullPartsOfMagicsZone() == 5; + } + + public boolean isMonsterZoneFull() { + return getNumberOfFullPartsOfMonstersZone() == 5; + } + + public boolean isMagicsZoneEmpty() { + return getNumberOfFullPartsOfMagicsZone() == 0; + } + + public int getNumberOfFullPartsOfMagicsZone() { + int numberOfFullPartsOfMagicsZone = 0; + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) ++numberOfFullPartsOfMagicsZone; + } + return numberOfFullPartsOfMagicsZone; + } + + public int getNumberOfFullPartsOfMonstersZone() { + int getNumberOfFullPartsOfMonstersZone = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null) ++getNumberOfFullPartsOfMonstersZone; + } + return getNumberOfFullPartsOfMonstersZone; + } + + public boolean isCardFaceUp(String cardName) { +// if cardName isn't available, then this method returns false + boolean isCardFaceUp = false; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = monstersZone[i].getCardFaceUp(); + } + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = magicsZone[i].getCardFaceUp(); + } + return isCardFaceUp; + } + + public void addSpellCardToFieldZone(MagicCard spellCard) { + MagicCard previousFieldZone = fieldZone; + if (previousFieldZone != null) graveyard.add(previousFieldZone); + setFieldZone(spellCard); + } + + public boolean addMagicCardToMagicsZone(MagicCard magicCard) { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] == null) { + magicsZone[i] = magicCard; + return true; + } + } + return false; + } + + public boolean isCardAvailableInMonstersZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monsterCard)) return true; + } + return false; + } + + public int getNumberOfFaceUpMonsterCards() { + int numberOfFaceUpMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getCardFaceUp()) ++numberOfFaceUpMonsterCards; + } + + return numberOfFaceUpMonsterCards; + } + + public int getNumberOfWarriorMonsterCards() { + int numberOfWarriorMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getMonsterType().equals("Warrior")) ++numberOfWarriorMonsterCards; + } + + return numberOfWarriorMonsterCards; + } + + public boolean isThereCardInAddress(MonsterCard[] monsterZone, int address) { + if (monsterZone[address] != null) return true; + return false; + } + + public boolean isThereOneMonsterForTribute(MonsterCard[] monsterZone) { + for (Card card : monsterZone) { + if (card != null) return true; + } + return false; + } + + public boolean isThereTwoMonsterForTribute(MonsterCard[] monstersZone) { + int counter = 0; + for (Card card : monstersZone) { + if (card != null) counter++; + } + if (counter < 2) { + return false; + } + return true; + } + + public void drawCard() { + + } + +} diff --git a/My Part 3/src/main/java/model/Deck.java b/My Part 3/src/main/java/model/Deck.java new file mode 100644 index 0000000..217f43b --- /dev/null +++ b/My Part 3/src/main/java/model/Deck.java @@ -0,0 +1,195 @@ +package model; + +import controller.deckmenu.DeckMenuDatabase; +import model.*; +import controller.deckmenu.*; +import model.cards.Card; + +import java.util.ArrayList; + +public class Deck { + public ArrayList mainCards = new ArrayList<>(); + public ArrayList sideCards = new ArrayList<>(); + Player owner; + String name; + DeckType type; + Boolean isActive = false; + Boolean IsValid; + + public Deck(String name, Player owner, boolean hasSideDeck, boolean shouldBeSaved) { + this.name = name; + if (shouldBeSaved) + DeckMenuDatabase.allDecks.add(this); + if (!hasSideDeck) + sideCards = null; + this.owner = owner; + } + + public Deck(String name, Player owner) { + this.name = name; + sideCards = null; + this.owner = owner; + } + + public Deck(String name) { + this.name = name; + sideCards = null; + } + public Deck() { + sideCards = null; + } + + public void updateOwnerDecks() { + String deckType = (name.length() > 16) ? name.substring(name.length() - 16) : ""; + if (deckType.equals(".purchased-cards")) + owner.setAllPlayerCard(this); + else { + owner.getAllDeck().add(this); + if (this.isActive) + owner.setActiveDeck(this); + } + } + + public ArrayList getMainCards() { + if (mainCards == null) + return (mainCards = new ArrayList<>()); + return mainCards; + } + + public void setMainCards(ArrayList mainCards) { + this.mainCards = mainCards; + } + + public ArrayList getSideCards() { + return sideCards; + } + + public void setSideCards(ArrayList sideCards) { + this.sideCards = sideCards; + } + + public Player getOwner() { + return owner; + } + + public void setOwner(Player owner) { + this.owner = owner; + } + + public void setActive(Boolean active) { + isActive = active; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setActivation(Boolean active) { + isActive = active; + } + + public void setValid(Boolean valid) { + IsValid = valid; + } + + public void setType(DeckType type) { + this.type = type; + } + + public void addCard(Card card, boolean shouldBeAddedToMain) { + if (shouldBeAddedToMain) + mainCards.add(card); + else + sideCards.add(card); + if (card != null) + card.setCurrentDeck(this); + } + + public void addCard(Card card) { + mainCards.add(card); + if (card != null && !name.equals("selected collected deck")) + card.setCurrentDeck(this); + } + + public void moveCardTo(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCard(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public void moveCardToForGame(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCardForGame(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public boolean hasCard(Card card, boolean isMain) { + if (isMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) + return true; + + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + return true; + } + return false; + } + + public void removeCard(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) { + mainCards.remove(cardInMain); + return; + } + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + sideCards.remove(cardInSide); + return; + } + } + + public void removeCardForGame(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) + mainCards.remove(card); + else + sideCards.remove(card); + } + + public int getNumberOfCardsInDeck(Card card) { + int count = 0; + for (Card cardInDeck : mainCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + for (Card cardInDeck : sideCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + return count; + } + + public int getNumberOfCardsInMainDeck() { + return mainCards.size(); + } + + public int getNumberOfCardsInSideDeck() { + return sideCards.size(); + } + + public void updateCurrentDeck() { + if (mainCards != null) + for (Card card : mainCards) + if (card != null) + card.setCurrentDeck(this); + if (sideCards != null) + for (Card card : sideCards) + if (card != null) + card.setCurrentDeck(this); + } +} \ No newline at end of file diff --git a/My Part 3/src/main/java/model/DeckType.java b/My Part 3/src/main/java/model/DeckType.java new file mode 100644 index 0000000..2d1643c --- /dev/null +++ b/My Part 3/src/main/java/model/DeckType.java @@ -0,0 +1,8 @@ +package model; + +public enum DeckType { + regulardeck, + inactivedeck, + graveyarddeck, + selectedcarddeck +} diff --git a/My Part 3/src/main/java/model/Player.java b/My Part 3/src/main/java/model/Player.java new file mode 100644 index 0000000..22981f3 --- /dev/null +++ b/My Part 3/src/main/java/model/Player.java @@ -0,0 +1,288 @@ +package model; + +import com.google.gson.annotations.Expose; +import controller.Database; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Player { + private static ArrayList allPlayers; + + static { + allPlayers = new ArrayList<>(); + } + + @Expose + private ArrayList boughtCards; + @Expose + private ArrayList allMainDecks; + private Board board; + @Expose + private Deck sideDeck; + @Expose + private Deck activatedDeck; + @Expose + private String username; + @Expose + private String password; + @Expose + private String nickname; + @Expose + private long score; + @Expose + private long money; + private int lifePoint = 8000; + private transient Deck allPlayerCard; + private transient ArrayList allDeck = new ArrayList<>(); + private transient ArrayList gameDecks = new ArrayList<>(); + + { + boughtCards = new ArrayList<>(); + allMainDecks = new ArrayList<>(); + board = null; + sideDeck = new Deck(); + activatedDeck = null; + score = 0; + money = 100000; + } + + public Player(String username, String password, String nickname) { + setUsername(username); + setPassword(password); + setNickname(nickname); + addPlayerToAllPlayers(this); + allPlayers.add(this); + Database.updatePlayerInformationInDatabase(this); + } + + public static Boolean isNicknameExist(String nickname) { + for (Player player : allPlayers) { + if (player.nickname.equals(nickname)) return true; + } + return false; + } + + public static Boolean isPasswordCorrect(String username, String password) { + Player player = getPlayerByUsername(username); + if (player == null) return false; + + return player.password.equals(password); + } + + public static Player getPlayerByUsername(String username) { + for (Player player : allPlayers) { + if (player.username.equals(username)) return player; + } + return null; + } + + public void setBoughtCards(ArrayList boughtCards) { + this.boughtCards = boughtCards; + } + + public Deck getActiveDeck() { + return activatedDeck; + } + + public void setActiveDeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public ArrayList getAllDeck() { + if (allDeck == null) + return (allDeck = new ArrayList<>()); + return allDeck; + } + + public void setAllDeck(ArrayList allDeck) { + this.allDeck = allDeck; + } + + public Deck getAllPlayerCard() { + return allPlayerCard; + } + + public static ArrayList getAllPlayers() { + return allPlayers; + } + + public void addCardToAllPlayerCard(Card card) { + this.allPlayerCard.getMainCards().add(card); + } + + public void setAllPlayerCard(Deck allPlayerCard) { + this.allPlayerCard = allPlayerCard; + } + + public static void addPlayerToAllPlayers(Player player) { + allPlayers.add(player); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public long getScore() { + return score; + } + + public long getMoney() { + return money; + } + + public Deck getActivatedDeck() { + return activatedDeck; + } + + public ArrayList getBoughtCards() { + return boughtCards; + } + + public void increaseScore(long score) { + this.score += score; + } + + public void decreaseScore(long score) { + this.score -= score; + } + + public void increaseMoney(long money) { + this.money += money; + } + + public void decreaseMoney(long money) { + this.money -= money; + } + + public void addCardToBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.add(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.add(new MagicCard((MagicCard) card)); + } + } + + public void addMainDeck(String deckName) { + Deck mainDeck = new Deck(deckName); + this.allMainDecks.add(mainDeck); + } + + public Boolean isMainDeckExist(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return true; + } + return false; + } + + public void deleteMainDeck(String deckName) { + Deck mainDeck = getDeckByName(deckName); + if (mainDeck != null) { + boughtCards.addAll(mainDeck.getMainCards()); + allMainDecks.remove(mainDeck); + } + } + + public Deck getDeckByName(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return deck; + } + return null; + } + + public int compareTo(Player player) { + if (this.score > player.score) + return -1; + if (this.score < player.score) + return 1; + if (this.nickname.compareTo(player.getNickname()) > 0) + return -1; + if (this.nickname.compareTo(player.getNickname()) < 0) + return 1; + return 0; + } + + public void activateADeck(String deckName) { + Deck deck = getDeckByName(deckName); + if (deck != null) activatedDeck = deck; + } + public void activateADeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public void addCardToMainDeck() { +// TODO: ???? but remember to remove this card from boughtCards :) + } + + public void removeACard() { +// TODO: ???? but remember to add this card from boughtCards :) + } + + public void decreaseLifePoint(int amount) { + this.lifePoint -= amount; + } + + public void increaseLifePoint(int amount) { + this.lifePoint += amount; + } + + public void setLifePoint(int lifePoint) { + this.lifePoint = lifePoint; + } + + public int getLifePoint() { + return lifePoint; + } + + public void createBoard() { + board = new Board(); + } + + public Board getBoard() { + return board; + } + + public boolean hasCard(Card card){ + for (Card boughtCard : boughtCards) { + if (card.getName().equals(boughtCard.getName())) + return true; + } + return false; + } + + public void removeCardFromBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.remove(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.remove(new MagicCard((MagicCard) card)); + } + } +} \ No newline at end of file diff --git a/My Part 3/src/main/java/model/cards/Card.java b/My Part 3/src/main/java/model/cards/Card.java new file mode 100644 index 0000000..9ebd536 --- /dev/null +++ b/My Part 3/src/main/java/model/cards/Card.java @@ -0,0 +1,115 @@ +package model.cards; + +import com.google.gson.annotations.Expose; +import model.Deck; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.TreeMap; + +public class Card { + protected static HashMap allCards; + + static { + allCards = new HashMap<>(); + } + + @Expose + protected final String name; + protected final String description; + protected final CardTypes cardType; + protected final int price; +// if this boolean equals "false" so we can conclude that card is "face down" + protected transient boolean isCardFaceUp; + protected transient boolean isPowerUsed; + protected transient Deck currentDeck; + + { + isCardFaceUp = false; + isPowerUsed = false; + } + + public Card(String name, String description, CardTypes cardType, int price) { + this.name = name; + this.description = description; + this.cardType = cardType; + this.price = price; + } + + public static Card getCardByName(String name) { + return allCards.get(name); + } + + public static TreeMap getListOfCards() { + TreeMap listOfCards = new TreeMap<>(); + for (String cardName : allCards.keySet()) { + Integer cardPrice = allCards.get(cardName).getPrice(); + listOfCards.put(cardName, cardPrice); + } + return listOfCards; + } + + public static boolean isMonsterCard(Card card) { + try { + MonsterCard monsterCard = (MonsterCard) card; + return true; + } catch (Exception exception) { + return false; + } + } + + public static int findNumberOfMonsterCards(ArrayList cards) { + int numberOfMonsterCards = 0; + for (Card card : cards) { + if (Card.isMonsterCard(card)) ++numberOfMonsterCards; + } + return numberOfMonsterCards; + } + + public static void addCardToAllCards(Card card) { + allCards.put(card.getName(), card); + } + + public static HashMap getAllCards() { + return allCards; + } + + public String getName() { + return name; + } + + public void setCurrentDeck(Deck currentDeck) { this.currentDeck = currentDeck; } + + public Deck getCurrentDeck() { + return currentDeck; + } + + public CardTypes getCardType() { + return cardType; + } + + public int getPrice() { + return price; + } + + public void setPowerUsed(boolean powerUsed) { + isPowerUsed = powerUsed; + } + + public boolean isPowerUsed() { + return isPowerUsed; + } + + public String getDescription() { + return description; + } + + public Boolean getCardFaceUp() { + return isCardFaceUp; + } + + public void setCardFaceUp(Boolean cardFaceUp) { + isCardFaceUp = cardFaceUp; + } +} diff --git a/My Part 3/src/main/java/model/cards/CardTypes.java b/My Part 3/src/main/java/model/cards/CardTypes.java new file mode 100644 index 0000000..520056f --- /dev/null +++ b/My Part 3/src/main/java/model/cards/CardTypes.java @@ -0,0 +1,26 @@ +package model.cards; + +import com.google.gson.annotations.SerializedName; + +public enum CardTypes { + @SerializedName("Normal") + NORMAL("Normal"), + @SerializedName("Effect") + EFFECT("Effect"), + @SerializedName("Ritual") + RITUAL("Ritual"), + @SerializedName("Spell") + SPELL("Spell"), + @SerializedName("Trap") + TRAP("Trap"); + + private final String regex; + + CardTypes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 3/src/main/java/model/cards/magiccard/MagicCard.java b/My Part 3/src/main/java/model/cards/magiccard/MagicCard.java new file mode 100644 index 0000000..396faf8 --- /dev/null +++ b/My Part 3/src/main/java/model/cards/magiccard/MagicCard.java @@ -0,0 +1,39 @@ +package model.cards.magiccard; + +import model.cards.Card; +import model.cards.CardTypes; + +public class MagicCard extends Card { + protected final String icon; + protected final MagicCardStatuses status; + + public MagicCard(String name, CardTypes cardType, String icon, String description, MagicCardStatuses status, int price) { + super(name, description, cardType, price); + this.icon = icon; + this.status = status; + allCards.put(name, this); + } + + public MagicCard(MagicCard magicCard) { + super(magicCard.name, magicCard.description, magicCard.cardType, magicCard.price); + this.icon = magicCard.icon; + this.status = magicCard.status; + } + + public String getIcon() { + return icon; + } + + public MagicCardStatuses getStatus() { + return status; + } + + public void print() { +// TODO: handle it --> «this.equals(null)» have error and «System.out.print» should be in the view +// if (this.equals(null)) +// System.out.print("E "); +// else if (isCardFaceUp) +// System.out.print("O "); +// else System.out.print("H "); + } +} diff --git a/My Part 3/src/main/java/model/cards/magiccard/MagicCardStatuses.java b/My Part 3/src/main/java/model/cards/magiccard/MagicCardStatuses.java new file mode 100644 index 0000000..a2540c9 --- /dev/null +++ b/My Part 3/src/main/java/model/cards/magiccard/MagicCardStatuses.java @@ -0,0 +1,20 @@ +package model.cards.magiccard; + +import com.google.gson.annotations.SerializedName; + +public enum MagicCardStatuses { + @SerializedName("Limited") + LIMITED("Limited"), + @SerializedName("Unlimited") + UNLIMITED("Unlimited"); + + private final String regex; + + MagicCardStatuses(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 3/src/main/java/model/cards/monstercard/MonsterCard.java b/My Part 3/src/main/java/model/cards/monstercard/MonsterCard.java new file mode 100644 index 0000000..d72dedd --- /dev/null +++ b/My Part 3/src/main/java/model/cards/monstercard/MonsterCard.java @@ -0,0 +1,139 @@ +package model.cards.monstercard; + +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; + +import java.util.ArrayList; + +public class MonsterCard extends Card implements SpecialMonstersFunction { + protected final short level; + protected final MonsterCardAttributes attribute; + protected final String monsterType; + protected int attackPoints; + protected int defensePoints; + protected transient ArrayList equippedBy; +// if this boolean equals "false" so we can conclude that card is in attack position + protected transient boolean isDefensePosition; + protected transient boolean isAttacked = false; + + { + equippedBy = new ArrayList<>(); + isDefensePosition = false; + } + + public MonsterCard(String name, short level, MonsterCardAttributes attribute, String monsterType, CardTypes cardType, + int attackPoints, int defensePoints, String description, int price) { + super(name, description, cardType, price); + this.level = level; + this.attribute = attribute; + this.monsterType = monsterType; + setAttackPoints(attackPoints); + setDefensePoints(defensePoints); + allCards.put(name, this); + } + + public MonsterCard(MonsterCard monsterCard) { + super(monsterCard.name, monsterCard.description, monsterCard.cardType, monsterCard.price); + this.level = monsterCard.level; + this.attribute = monsterCard.attribute; + this.monsterType = monsterCard.monsterType; + this.attackPoints = monsterCard.attackPoints; + this.defensePoints = monsterCard.defensePoints; + } + + public short getLevel() { + return level; + } + + public MonsterCardAttributes getAttribute() { + return attribute; + } + + public String getMonsterType() { + return monsterType; + } + + public int getAttackPoints() { + return attackPoints; + } + + public void setAttackPoints(int attackPoints) { + this.attackPoints = attackPoints; + } + + public int getDefensePoints() { + return defensePoints; + } + + public void setDefensePoints(int defensePoints) { + this.defensePoints = defensePoints; + } + + public boolean isAttacked() { + return isAttacked; + } + + public void setAttacked(boolean attacked) { + isAttacked = attacked; + } + + public boolean isDefensePosition() { + return isDefensePosition; + } + + public void setDefensePosition(boolean defensePosition) { + isDefensePosition = defensePosition; + } + + public ArrayList getEquippedBy() { + return equippedBy; + } + + public void addToEquippedBy(MagicCard equippedBy) { + this.equippedBy.add(equippedBy); + } + + public void increaseAttackPoints(int amount) { + attackPoints += amount; + } + + public void decreaseAttackPoints(int amount) { + attackPoints -= amount; + } + + public void increaseDefencePoints(int amount) { + defensePoints += amount; + } + + public void decreaseDefencePoints(int amount) { + defensePoints -= amount; + } + + public void createEquippedByArrayList() { + equippedBy = new ArrayList<>(); + } + + public void settoDO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoDH(MonsterCard selectedMonster) { + this.setCardFaceUp(!isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoOO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = false; + } + + @Override + public String toString() { + if (!this.getCardFaceUp() && this.isDefensePosition) return "DH"; + else if (this.getCardFaceUp() && this.isDefensePosition) return "DO"; + else if (this.getCardFaceUp() && !this.isDefensePosition) return "OO"; + return "E "; + } +} diff --git a/My Part 3/src/main/java/model/cards/monstercard/MonsterCardAttributes.java b/My Part 3/src/main/java/model/cards/monstercard/MonsterCardAttributes.java new file mode 100644 index 0000000..4677550 --- /dev/null +++ b/My Part 3/src/main/java/model/cards/monstercard/MonsterCardAttributes.java @@ -0,0 +1,10 @@ +package model.cards.monstercard; + +public enum MonsterCardAttributes { + DARK, + EARTH, + FIRE, + LIGHT, + WATER, + WIND; +} diff --git a/My Part 3/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java b/My Part 3/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java new file mode 100644 index 0000000..0b73141 --- /dev/null +++ b/My Part 3/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java @@ -0,0 +1,157 @@ +package model.cards.monstercard; + +import controller.duelmenu.DuelMenuMessages; +import model.Board; +import model.Player; + +public interface SpecialMonstersFunction { + default DuelMenuMessages attack(Player attackingPlayer, Player opponentPlayer, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + MonsterCard attackingCard = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentCard = opponentPlayerBoard.getMonstersZone()[numberToAttack]; + + if (opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack) != null) { + + switch (opponentCard.toString()) { + case "OO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayer.decreaseLifePoint(attackingCard.attackPoints - opponentCard.attackPoints); + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + DuelMenuMessages.setOpponentGotDamageInAttack(attackingCard.attackPoints - opponentCard.attackPoints); + return DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setAttackingPlayerCardDestroyed(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED; + } + + case "DO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + return DuelMenuMessages.DEFENSE_POSITION_MONSTER_DESTROYED; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + return DuelMenuMessages.NO_CARD_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setReceiveDamageByAttackingToDefenseCard(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD; + } + case "DH": + break; + } + + return null; + + } else + return opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + + default DuelMenuMessages defense(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + switch (opponentCard.getName()) { + case "Command knight": + commandKnightFunction(opponentPlayerBoard); + break; + case "Yomi Ship": + return yomiShipFunction(attackingPlayerBoard, attackingCard, opponentCard); + case "Suijin": + return suijinFunction(attackingCard); + case "Marshmallon": + return marshmallonFunction(attackingPlayer); + case "Texchanger": + return texchangerFunction(opponentCard); + case "Exploder Dragon": + return exploderDragon(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + return null; + } + + default DuelMenuMessages texchangerFunction(MonsterCard opponentCard) { + if (!opponentCard.isPowerUsed()) { + opponentCard.setPowerUsed(true); + // choosing a card ehzar??????? + return DuelMenuMessages.ATTACK_CANCELED; + } + return null; + } + + default DuelMenuMessages commandKnightFunction(Board opponentPlayerBoard) { + for (int i = 1; i <= 5; i++) { + if (opponentPlayerBoard.getMonstersZone()[i] != null && !opponentPlayerBoard.getMonstersZone()[i].getName().equals("Command knight")) { + return DuelMenuMessages.YOU_CANT_ATTACK_TO_THIS_CARD; + } + } + return null; + } + + default DuelMenuMessages yomiShipFunction(Board attackingPlayerBoard, MonsterCard attackingCard, MonsterCard opponentCard) { + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + return null; + } + + default DuelMenuMessages suijinFunction(MonsterCard attackingCard) { +// attackingCard.setAttackLevel(0);//TODO: undo it!! + return null; + } + + default DuelMenuMessages marshmallonFunction(Player attackingPlayer) { + attackingPlayer.decreaseLifePoint(1000); + return null; + } + + default DuelMenuMessages exploderDragon(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int number) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + return null; + } + + default void deleteMonsterFromZone(MonsterCard monster, MonsterCard[] monstersZone) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monster)) { + monstersZone[i] = null; + break; + } + } + } +} diff --git a/My Part 3/src/main/java/view/DeckMenuView.java b/My Part 3/src/main/java/view/DeckMenuView.java new file mode 100644 index 0000000..c9ada5c --- /dev/null +++ b/My Part 3/src/main/java/view/DeckMenuView.java @@ -0,0 +1,136 @@ +package view; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import controller.deckmenu.DeckMenuController; +import controller.deckmenu.DeckMenuOutput; +import model.*; + +public class DeckMenuView { + public static Scanner scanner = new Scanner(System.in); + + private Player loggedInPlayer; + + public DeckMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + private final String[] deckMenuRegexes = { + "^deck create (?\\w+)$", + "^deck delete (?\\w+)$", + "^deck set-activate (?\\w+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck add-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck show (?:--all|-a)$", + "^deck show (?:--deck-name|-d) (?.+) (?:--side|-s)$", + "^deck show (?:--side|-s) (?:--deck-name|-d) (?.+)$", + "^deck show (?:--deck-name|-d) (?.+)$", + "^menu show-current$", + "^menu exit$" + }; + + public void runDeckMenu() { + Matcher commandMatcher; + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + int whichCommand; + for (whichCommand = 0; whichCommand < deckMenuRegexes.length; whichCommand++) { + commandMatcher = findMatcher(command, deckMenuRegexes[whichCommand]); + if (commandMatcher.find()) { + executeDeckMenuCommands(commandMatcher, whichCommand); + break; + } else if (whichCommand == deckMenuRegexes.length - 1) + DeckMenuOutput.getInstance().showMessage("invalid command"); + } + + } + } + + private void executeDeckMenuCommands(Matcher commandMatcher, int whichCommand) { + DeckMenuController controller = DeckMenuController.getInstance(); + switch (whichCommand) { + case 0: + controller.createDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 1: + controller.deleteDeck(commandMatcher.group("name")); + break; + case 2: + controller.setActiveDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + String cardName = commandMatcher.group("cardName"), + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, false); + break; + case 9: + case 10: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, true); + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, false); + break; + case 17: + case 18: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, true); + break; + case 19: + controller.showAllDecks(loggedInPlayer); + break; + case 20: + case 21: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, false); + break; + case 22: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, true); + break; + case 23: + DeckMenuOutput.getInstance().showMessage("Deck Menu"); + break; + case 24: + MainMenuView.mainMenuView(); +// go to main menu; + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } + + +} diff --git a/My Part 3/src/main/java/view/DuelMenuView.java b/My Part 3/src/main/java/view/DuelMenuView.java new file mode 100644 index 0000000..24661b5 --- /dev/null +++ b/My Part 3/src/main/java/view/DuelMenuView.java @@ -0,0 +1,140 @@ +package view; + +import controller.Utils; +import controller.duelmenu.DuelMenuController; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.Phases; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +public class DuelMenuView { + private Player firstPlayer; + private Player secondPlayer; + private Phases phase; + + public DuelMenuView(Player firstPlayer, Player secondPlayer) { + this.firstPlayer = firstPlayer; + this.secondPlayer = secondPlayer; + } + + public static String findChooseOfPlayerInMiniGame(Player player) { + System.out.println(player.getUsername() + ", please choose between stone, paper and scissor:"); + return Utils.getScanner().nextLine().trim(); + } + + public static void showGraveyard(Board board) { + if (board.getGraveyard().size() != 0) { + for (int i = 1; i <= board.getGraveyard().size(); i++) { + printCard(i , board.getGraveyard().get(i)); + } + } else System.out.println("graveyard empty"); + while (true) { + String input = Utils.getScanner().nextLine(); + if (input.equals("back")) + break; + } + } + + public static void printCard(int number, Card card) { + System.out.println(number + ". " + card.getName() + ": " + card.getDescription()); + } + + private static void showBoard(Board playerBoard, Board opponentBoard) { + showCardsInHand(opponentBoard); +// showLeftCardDeck(opponentBoard);//?????????????????????? + showOpponentMagicsZone(opponentBoard); + showOpponentMonstersZone(opponentBoard); + showGraveyard(opponentBoard); + System.out.println("--------------------------"); + showCardsInHand(playerBoard); +// showLeftCardDeck(playerBoard);//???????? + showMagicsZone(playerBoard); + showMonstersZone(playerBoard); + showGraveyard(playerBoard); + } + + private static void showMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// monsters[5].print(); +// System.out.print(monsters[5].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[4].print() + " "); +// System.out.println(); + } + + private static void showMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[5].print(); + magicsZone[3].print(); + magicsZone[1].print(); + magicsZone[2].print(); + magicsZone[4].print(); + } + + private static void showOpponentMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// System.out.print(monsters[4].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[5].print() + " "); + } + + private static void showOpponentMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[4].print(); + magicsZone[2].print(); + magicsZone[1].print(); + magicsZone[3].print(); + magicsZone[5].print(); + } + + private static void showCardsInHand(Board board) { + for (int i = 0; i < board.getCardsInHand().size(); i++) { + System.out.print("C "); + } + System.out.println(); + } + + private static void showSelectedCard(Board board) { + if (showCardCheck(board)) { + System.out.println(board.getSelectedCard().getName() + " " + board.getSelectedCard().getDescription()); + + } + } + + private static boolean showCardCheck(Board board) { + if (board.getSelectedCard() == null) { + System.out.println("you have not selected card"); + return false; + } + if (!board.isMyCardSelected() && !board.getSelectedCard().getCardFaceUp()) { + System.out.println("you cant see this card!"); + return false; + } + return true; + } + + public void duelMenuView() { + DuelMenuController duelMenuController = new DuelMenuController(); + + DuelMenuMessages resultOfInitialGame = null; + while (resultOfInitialGame == null || !resultOfInitialGame.equals(DuelMenuMessages.SHOW_TURN_PLAYER)) { + resultOfInitialGame = duelMenuController.initialGame(firstPlayer, secondPlayer); + System.out.print(resultOfInitialGame.getMessage()); + } + + while (true) { + String command = Utils.getScanner().nextLine().trim(); + DuelMenuMessages result = duelMenuController.findCommand(command); + + System.out.print(result.getMessage()); + } + } + +} diff --git a/My Part 3/src/main/java/view/ImportExportMenuView.java b/My Part 3/src/main/java/view/ImportExportMenuView.java new file mode 100644 index 0000000..ee91f94 --- /dev/null +++ b/My Part 3/src/main/java/view/ImportExportMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; + +public class ImportExportMenuView { + public void ImportExportMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ImportExportMenuMessages result = ImportExportMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU)) break; + } + } +} diff --git a/My Part 3/src/main/java/view/LoginMenuView.java b/My Part 3/src/main/java/view/LoginMenuView.java new file mode 100644 index 0000000..f094c8b --- /dev/null +++ b/My Part 3/src/main/java/view/LoginMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; + +public class LoginMenuView { + public static void loginMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + LoginMenuMessages result = LoginMenuController.findCommand(command); + + System.out.println(result.getMessage()); + + if (result.equals(LoginMenuMessages.USER_LOGGED_IN)) LoginMenuController.loginUser(command); + } + } +} diff --git a/My Part 3/src/main/java/view/MainMenuView.java b/My Part 3/src/main/java/view/MainMenuView.java new file mode 100644 index 0000000..7dde978 --- /dev/null +++ b/My Part 3/src/main/java/view/MainMenuView.java @@ -0,0 +1,31 @@ +package view; + +import controller.Utils; +import controller.mainmenu.MainMenuController; +import controller.mainmenu.MainMenuMessages; +import model.Player; + +public class MainMenuView { + private Player loggedInPlayer; + + public MainMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void mainMenuView() { + MainMenuController mainMenuController = new MainMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + MainMenuMessages result = mainMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(MainMenuMessages.EXIT_MAIN_MENU) || + result.equals(MainMenuMessages.USER_LOGGED_OUT)) break; + } + } +} diff --git a/My Part 3/src/main/java/view/ProfileMenuView.java b/My Part 3/src/main/java/view/ProfileMenuView.java new file mode 100644 index 0000000..1e1b091 --- /dev/null +++ b/My Part 3/src/main/java/view/ProfileMenuView.java @@ -0,0 +1,25 @@ +package view; + +import controller.profilemenu.ProfileMenuController; +import controller.profilemenu.ProfileMenuMessages; +import controller.Utils; +import model.Player; + +public class ProfileMenuView { + private final Player loggedInPlayer; + + public ProfileMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void profileMenuView() { + ProfileMenuController profileMenuController = new ProfileMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ProfileMenuMessages result = profileMenuController.findCommand(command); + + if (result.equals(ProfileMenuMessages.EXIT_MENU)) break; + else System.out.print(result.getMessage()); + } + } +} diff --git a/My Part 3/src/main/java/view/ScoreboardView.java b/My Part 3/src/main/java/view/ScoreboardView.java new file mode 100644 index 0000000..465468c --- /dev/null +++ b/My Part 3/src/main/java/view/ScoreboardView.java @@ -0,0 +1,37 @@ +package view; + +import controller.scoreboardmenu.Scoreboard; +import controller.scoreboardmenu.ScoreboardOutput; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ScoreboardView { + public static Scanner scanner = new Scanner(System.in); + + public void runScoreboard() { + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + switch (command) { + case "scoreboard show": + Scoreboard.getInstance().showScoreboard(); + break; + case "menu show-current": + ScoreboardOutput.getInstance().showMessage("Scoreboard Menu"); + break; + case "menu exit": + MainMenuView.mainMenuView(); + default: + ScoreboardOutput.getInstance().showMessage("invalid command"); + } + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } +} diff --git a/My Part 3/src/main/java/view/ShopMenuView.java b/My Part 3/src/main/java/view/ShopMenuView.java new file mode 100644 index 0000000..0ed2331 --- /dev/null +++ b/My Part 3/src/main/java/view/ShopMenuView.java @@ -0,0 +1,41 @@ +package view; + +import controller.Utils; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import model.cards.Card; + +import java.util.TreeMap; + +public class ShopMenuView { + private Player loggedInPlayer; + + public ShopMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + private static void showListOfCards() { + TreeMap listOfCards = Card.getListOfCards(); + for (String cardName : listOfCards.keySet()) { + System.out.println(cardName + ": " + listOfCards.get(cardName)); + } + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void shopMenuView() { + ShopMenuController shopMenuController = new ShopMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ShopMenuMessages result = shopMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ShopMenuMessages.EXIT_SHOP_MENU)) break; + else if (result.equals(ShopMenuMessages.SHOW_ALL_CARDS)) showListOfCards(); + } + } +} diff --git a/My Part 3/src/main/java/view/SpellCardView.java b/My Part 3/src/main/java/view/SpellCardView.java new file mode 100644 index 0000000..69bf703 --- /dev/null +++ b/My Part 3/src/main/java/view/SpellCardView.java @@ -0,0 +1,118 @@ +package view; + +import controller.Utils; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class SpellCardView extends DuelMenuView { + private SpellCardView(Player firstPlayer, Player secondPlayer) { + super(firstPlayer, secondPlayer); + } + + public static void showGraveyardsMonsterCards(Player turnPlayer, Player notTurnPlayer) { +// it used for Monster Reborn spell card + System.out.println("your graveyard monster cards:"); + showGraveyardMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent graveyard monster cards:"); + showGraveyardMonsterCards(notTurnPlayer.getBoard(), Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()) + 1); + } + + private static void showGraveyardMonsterCards(Board board, int startNumber) { +// it used for Monster Reborn spell card + int count = startNumber; + for (int i = 0; i < board.getGraveyard().size(); i++) { + if (Card.isMonsterCard(board.getGraveyard().get(i))) { + printCard(count, board.getGraveyard().get(i)); + ++count; + } + } + if (count == startNumber) System.out.println("There isn't any monster card."); + } + + public static String findCardNumber() { + System.out.println("choose a number:"); + return Utils.getScanner().nextLine(); + } + + public static void invalidNumber() { + System.out.println("invalid number"); + } + + public static void showFieldSpellCards(ArrayList magicCards) { + System.out.println("your field spell cards:"); + if (magicCards.size() == 0) System.out.println("There isn't any field spell card."); + else { + for (int i = 1; i <= magicCards.size(); i++) { + printCard(i, magicCards.get(i - 1)); + } + } + } + + public static void showCardsInHand(Player player) { + System.out.println("you have these cards in hand:"); + ArrayList cardsInHand = player.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) System.out.println("There isn't any card in your hand."); + else { + for (int i = 1; i <= cardsInHand.size(); i++) { + printCard(i, cardsInHand.get(i - 1)); + } + } + } + + public static void showMagicsZonesCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your spell and trap zone cards:"); + int endNumber = showMagicsZoneCards(turnPlayer, 1); + System.out.println("opponent spell and trap zone cards:"); + showMagicsZoneCards(notTurnPlayer, endNumber); + } + + private static int showMagicsZoneCards(Player player, int startNumber) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (player.getBoard().isMagicsZoneEmpty()) System.out.println("There isn't any spell and trap card."); + else { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) { + printCard(startNumber, magicsZone[i]); + ++startNumber; + } + } + } + + return startNumber; + } + + public static String findNumberOfCardsToChoose() { + System.out.println("How many cards do you want to choose to destroy?"); + return Utils.getScanner().nextLine(); + } + + public static void showFaceUpMonsterCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your face up monster cards:"); + int endNumber = showEachPlayerFaceUpMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent face up monster cards:"); + showEachPlayerFaceUpMonsterCards(notTurnPlayer.getBoard(), endNumber); + } + + private static int showEachPlayerFaceUpMonsterCards(Board board, int startNumber) { + if (board.getNumberOfFaceUpMonsterCards() == 0) { + System.out.println("There isn't any face up monster card."); + return startNumber; + } + + MonsterCard[] monstersZone = board.getMonstersZone(); + for (int i = 1; i < monstersZone.length; i++) { + MonsterCard monsterCard = monstersZone[i]; + if (monsterCard.getCardFaceUp()) { + printCard(startNumber, monsterCard); + ++startNumber; + } + } + + return startNumber; + } +} diff --git a/My Part 3/src/main/main.iml b/My Part 3/src/main/main.iml new file mode 100644 index 0000000..2185ddd --- /dev/null +++ b/My Part 3/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/My Part 3/src/main/resources/cards/Monster Upgraded.csv b/My Part 3/src/main/resources/cards/Monster Upgraded.csv new file mode 100644 index 0000000..eae794e --- /dev/null +++ b/My Part 3/src/main/resources/cards/Monster Upgraded.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARTH,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARTH,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,FIRE,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My Part 3/src/main/resources/cards/Monster.csv b/My Part 3/src/main/resources/cards/Monster.csv new file mode 100644 index 0000000..8c45a5c --- /dev/null +++ b/My Part 3/src/main/resources/cards/Monster.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARHT,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARHT,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron ,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,Fire,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My Part 3/src/main/resources/cards/SpellTrap.csv b/My Part 3/src/main/resources/cards/SpellTrap.csv new file mode 100644 index 0000000..e536e99 --- /dev/null +++ b/My Part 3/src/main/resources/cards/SpellTrap.csv @@ -0,0 +1,38 @@ +Name,Type ,Icon (Property),Description,Status,Price +Trap Hole,Trap,Normal,When your opponent Normal or Flip Summons 1 monster with 1000 or more ATK: Target that monster; destroy that target.,Unlimited,2000 +Mirror Force,Trap,Normal,When an opponent's monster declares an attack: Destroy all your opponent's Attack Position monsters.,Unlimited,2000 +Magic Cylinder,Trap,Normal,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, and if you do, inflict damage to your opponent equal to its ATK.",Unlimited,2000 +Mind Crush,Trap,Normal,"Declare 1 card name; if that card is in your opponent's hand, they must discard all copies of it, otherwise you discard 1 random card.",Unlimited,2000 +Torrential Tribute,Trap,Normal,When a monster(s) is Summoned: Destroy all monsters on the field.,Unlimited,2000 +Time Seal,Trap,Normal,Skip the Draw Phase of your opponent's next turn.,Limited,2000 +Negate Attack,Trap,Counter,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, then end the Battle Phase.",Unlimited,3000 +Solemn Warning,Trap,Counter,"When a monster(s) would be Summoned, OR when a Spell/Trap Card, or monster effect, is activated that includes an effect that Special Summons a monster(s): Pay 2000 LP; negate the Summon or activation, and if you do, destroy it.",Unlimited,3000 +Magic Jamamer,Trap,Counter,"When a Spell Card is activated: Discard 1 card; negate the activation, and if you do, destroy it.",Unlimited,3000 +Call of The Haunted,Trap,Continuous,"Activate this card by targeting 1 monster in your GY; Special Summon that target in Attack Position. When this card leaves the field, destroy that monster. When that monster is destroyed, destroy this card.",Unlimited,3500 +Vanity's Emptiness,Trap,Continuous,Neither player can Special Summon monsters. If a card is sent from the Deck or the field to your Graveyard: Destroy this card.,Limited,3500 +Wall of Revealing Light,Trap,Continuous,Activate by paying any multiple of 1000 Life Points. Monsters your opponent controls cannot attack if their ATK is less than or equal to the amount you paid.,Limited,3500 +Monster Reborn,Spell,Normal,Target 1 monster in either GY; Special Summon it.,Limited,2500 +Terraforming,Spell,Normal,Add 1 Field Spell from your Deck to your hand.,Limited,2500 +Pot of Greed,Spell,Normal,Draw 2 cards.,Limited,2500 +Raigeki,Spell,Normal,Destroy all monsters your opponent controls.,Limited,2500 +Change of Heart,Spell,Normal,Target 1 monster your opponent controls; take control of it until the End Phase.,Limited,2500 +Swords of Revealing Light,Spell,Normal,"After this card's activation, it remains on the field, but destroy it during the End Phase of your opponent's 3rd turn. When this card is activated: If your opponent controls a face-down monster, flip all monsters they control face-up. While this card is face-up on the field, your opponent's monsters cannot declare an attack.",Unlimited,2500 +Harpie's Feather Duster,Spell,Normal,Destroy all Spells and Traps your opponent controls.,Limited,2500 +Dark Hole,Spell,Normal,Destroy all monsters on the field.,Unlimited,2500 +Supply Squad,Spell,Continuous,"Once per turn, if a monster(s) you control is destroyed by battle or card effect: Draw 1 card.",Unlimited,4000 +Spell Absorption,Spell,Continuous,"Each time a Spell Card is activated, gain 500 Life Points immediately after it resolves.",Unlimited,4000 +Messenger of peace,Spell,Continuous,"Monsters with 1500 or more ATK cannot declare an attack. Once per turn, during your Standby Phase, pay 100 LP or destroy this card.",Unlimited,4000 +Twin Twisters,Spell,Quick-play,"Discard 1 card, then target up to 2 Spells/Traps on the field; destroy them.",Unlimited,3500 +Mystical space typhoon,Spell,Quick-play,Target 1 Spell/Trap on the field; destroy that target.,Unlimited,3500 +Ring of defense,Spell,Quick-play,When a Trap effect that inflicts damage is activated: Make that effect damage 0.,Unlimited,3500 +Yami,Spell,Field,"All Fiend and Spellcaster monsters on the field gain 200 ATK/DEF, also all Fairy monsters on the field lose 200 ATK/DEF.",Unlimited,4300 +Forest,Spell,Field,"All Insect, Beast, Plant, and Beast-Warrior monsters on the field gain 200 ATK/DEF.",Unlimited,4300 +Closed Forest,Spell,Field,All Beast-Type monsters you control gain 100 ATK for each monster in your Graveyard. Field Spell Cards cannot be activated. Field Spell Cards cannot be activated during the turn this card is destroyed.,Unlimited,4300 +Umiiruka,Spell,Field,Increase the ATK of all WATER monsters by 500 points and decrease their DEF by 400 points.,Unlimited,4300 +Sword of dark destruction,Spell,Equip,A DARK monster equipped with this card increases its ATK by 400 points and decreases its DEF by 200 points.,Unlimited,4300 +Black Pendant,Spell,Equip,The equipped monster gains 500 ATK. When this card is sent from the field to the Graveyard: Inflict 500 damage to your opponent.,Unlimited,4300 +United We Stand,Spell,Equip,The equipped monster gains 800 ATK/DEF for each face-up monster you control.,Unlimited,4300 +Magnum Shield,Spell,Equip,"Equip only to a Warrior-Type monster. Apply this effect, depending on its battle position. +● Attack Position: It gains ATK equal to its original DEF. +● Defense Position: It gains DEF equal to its original ATK.",Unlimited,4300 +Advanced Ritual Art,Spell,Ritual,This card can be used to Ritual Summon any 1 Ritual Monster. You must also send Normal Monsters from your Deck to the Graveyard whose total Levels equal the Level of that Ritual Monster.,Unlimited,3000 \ No newline at end of file diff --git a/My Part 3/src/main/resources/players/parsa.json b/My Part 3/src/main/resources/players/parsa.json new file mode 100644 index 0000000..2825eb1 --- /dev/null +++ b/My Part 3/src/main/resources/players/parsa.json @@ -0,0 +1,10 @@ +{ + "boughtCards": [], + "allMainDecks": [], + "sideDeck": {}, + "username": "parsa", + "password": "newPass", + "nickname": "P", + "score": 0, + "money": 100000 +} \ No newline at end of file diff --git a/My Part 3/src/test/java/controller/ImportExportMenuControllerTest.java b/My Part 3/src/test/java/controller/ImportExportMenuControllerTest.java new file mode 100644 index 0000000..aea2298 --- /dev/null +++ b/My Part 3/src/test/java/controller/ImportExportMenuControllerTest.java @@ -0,0 +1,140 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Database; +import controller.MenuTest; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; +import model.cards.Card; +import org.apache.commons.io.FileUtils; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +class ImportExportMenuControllerTest extends MenuTest { + + @Test + void findCommandEnterAMenuMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu exit"); + Assertions.assertEquals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU, result); + + result = ImportExportMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ImportExportMenuMessages.SHOW_MENU, result); + + result = ImportExportMenuController.findCommand("menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandImportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("import cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_FILE, result); + + createCardJsonFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.AVAILABLE_CARD, result); + + Card.getAllCards().remove("Battle OX"); + removeNameValueFromJsonCardFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Battle OX"); + Card.getAllCards().remove("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Battle OX.json")); + + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + removeNameValueFromJsonCardFile("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Trap Hole.json")); + } + + void createCardJsonFile(String cardName) { + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(Card.getCardByName(cardName))); + fileWriter.close(); + } catch (IOException ignored) { + } + } + + void removeNameValueFromJsonCardFile(String cardName) { + JSONParser parser = new JSONParser(); + try { + Object object = parser.parse(new FileReader("src/database/cards/" + cardName + ".json")); + JSONObject jsonObject = (JSONObject) object; + jsonObject.remove("name"); + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(jsonObject)); + fileWriter.close(); + } catch (Exception ignored) { + } + } + + @Test + void findCommandExportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("export cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("export card A"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_CARD, result); + + result = ImportExportMenuController.findCommand("export card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My Part 3/src/test/java/controller/LoginMenuControllerTest.java b/My Part 3/src/test/java/controller/LoginMenuControllerTest.java new file mode 100644 index 0000000..b095e9e --- /dev/null +++ b/My Part 3/src/test/java/controller/LoginMenuControllerTest.java @@ -0,0 +1,87 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; + +class LoginMenuControllerTest extends MenuTest { + @Test + void findCommandEnterAMenuMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_NAVIGATION, result); + + result = LoginMenuController.findCommand("menu enter MaIn MenU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + + result = LoginMenuController.findCommand("menu enter DUEL MENU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + } + + @Test + void findCommandCheckCreateUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user create --username John 1 --nickname Johny --password 12345"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user create --U John1 --nickname Johny1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --username John2 --P 12345 --nickname Johny2"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny3 --username John3 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny4 --password 12345 --U John4"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --username John5 --nickname Johny5"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --nickname Johny6 --username John6"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John6 --N Johny6"); + Assertions.assertEquals(LoginMenuMessages.USERNAME_EXISTS, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John7 --nickname Johny6"); + Assertions.assertEquals(LoginMenuMessages.NICKNAME_EXISTS, result); + } + + @Test + void findCommandCheckLoginUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user login --username John 12 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user login --username John12 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + + result = LoginMenuController.findCommand("user login --username John2 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + result = LoginMenuController.findCommand("user login --username John1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + + result = LoginMenuController.findCommand("user login --password 12345 --username John1"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + } + + @Test + void loginUser() { + Utils.resetScanner("user logout\n"); + ByteArrayOutputStream outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --password 12345 --username John1"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + + Utils.resetScanner("user logout\n"); + outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --username John1 --password 12345"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + } +} \ No newline at end of file diff --git a/My Part 3/src/test/java/controller/MenuTest.java b/My Part 3/src/test/java/controller/MenuTest.java new file mode 100644 index 0000000..5df1b3c --- /dev/null +++ b/My Part 3/src/test/java/controller/MenuTest.java @@ -0,0 +1,20 @@ +package controller; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +import java.io.File; +import java.io.IOException; + +public class MenuTest { + @BeforeAll + static void prepareGame() { + Database.prepareGame(); + } + + @AfterAll + static void deletePlayersDirectory() throws IOException { + FileUtils.deleteDirectory(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/main/resources/players")); + } +} \ No newline at end of file diff --git a/My Part 3/src/test/java/controller/ProfileMenuTest.java b/My Part 3/src/test/java/controller/ProfileMenuTest.java new file mode 100644 index 0000000..ddad54d --- /dev/null +++ b/My Part 3/src/test/java/controller/ProfileMenuTest.java @@ -0,0 +1,57 @@ +package controller; + +import controller.profilemenu.ProfileMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import controller.profilemenu.ProfileMenuController; + +public class ProfileMenuTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + String userName = "parsa"; + String password = "123"; + String nickname = "P"; + new Player(userName, password, nickname); + } + + @Test + public void changeName() { + Player player = Player.getPlayerByUsername("parsa"); + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --nickname newname"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + Assertions.assertEquals("newname", player.getNickname()); + result = profileMenuController.findCommand("profile change --nickname P"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + } + + @Test + public void changePassword() { + Player player = Player.getPlayerByUsername("parsa"); + + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --password --current 12 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.WRONG_CURRENT_PASSWORD, result); + Assertions.assertEquals("123", player.getPassword()); + + result = profileMenuController.findCommand("profile change --password --current 123 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_PASSWORD_DONE, result); + Assertions.assertEquals("newPass", player.getPassword()); + } + + @Test + public void allError() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.INVALID_COMMAND, profileMenuController.findCommand("profile")); + Assertions.assertEquals(ProfileMenuMessages.CANT_NAVIGATE_MENU, profileMenuController.findCommand("loginmenu enter")); + } + + @Test + public void checkExit() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.EXIT_MENU , profileMenuController.findCommand("menu exit")); + } +} diff --git a/My Part 3/src/test/java/controller/ShopMenuControllerTest.java b/My Part 3/src/test/java/controller/ShopMenuControllerTest.java new file mode 100644 index 0000000..58d998d --- /dev/null +++ b/My Part 3/src/test/java/controller/ShopMenuControllerTest.java @@ -0,0 +1,77 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ShopMenuControllerTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + LoginMenuController.findCommand("user create --username John --P 12345 --nickname Johny"); + } + + @Test + void findCommandEnterAMenuMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu exit"); + Assertions.assertEquals(ShopMenuMessages.EXIT_SHOP_MENU, result); + + result = shopMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ShopMenuMessages.SHOW_MENU, result); + + result = shopMenuController.findCommand("menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandBuyACardMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("shop buy:)"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("shop buy A"); + Assertions.assertEquals(ShopMenuMessages.UNAVAILABLE_CARD, result); + + result = shopMenuController.findCommand("shop buy Battle OX"); + Assertions.assertEquals(ShopMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My Part 3/src/test/test.iml b/My Part 3/src/test/test.iml new file mode 100644 index 0000000..c2315e9 --- /dev/null +++ b/My Part 3/src/test/test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/My Part 5/main/java/controller/AIClass.java b/My Part 5/main/java/controller/AIClass.java new file mode 100644 index 0000000..5e41136 --- /dev/null +++ b/My Part 5/main/java/controller/AIClass.java @@ -0,0 +1,60 @@ +package controller; + +import model.Board; +import model.cards.monstercard.MonsterCard; +import model.Player; + +public class AIClass { + +// public static String getOrder(Board machineBoard, Board playerBoard, Player AIPlayer, Player humanPlayer, Enum phaseOfGame) { +// if () {//TODO PUT A CONDITION THAT PHASE IS BATTLE PHASE +// int numberOfMonsterToAttack = -1; +// selectMachineMonsterCardToAttack(machineBoard, AIPlayer); +// if (canAttackToFaceUpMonster(machineBoard, playerBoard) != -1) { +// return "attack" + canAttackToFaceUpMonster(machineBoard, playerBoard); +// } else if (canAttackToFaceDownCard(playerBoard) != -1) { +// return "attack" + canAttackToFaceDownCard(playerBoard); +// } +// } +// } +// +// private static int canAttackToFaceDownCard(Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DH")) +// return i; +// } +// return -1; +// } +// +// private static void selectMachineMonsterCardToAttack(Board board, Player player) { +// MonsterCard[] monsterArray = board.getMonstersZone(); +// MonsterCard monsterCard = monsterArray[1]; +// for (int i = 2; i <= 5; i++) { +// if (monsterCard.getAttackLevel() < monsterArray[i].getAttackLevel()) +// monsterCard = monsterArray[i]; +// board.setMyCardSelected(true); +// board.setSelectedCard(monsterCard); +// } +// } +// +// private static int canAttackToFaceUpMonster(Board machineBoard, Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// MonsterCard monsterToAttack = (MonsterCard) machineBoard.getSelectedCard(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("OO") && monsterArray[i].getAttackLevel() < monsterToAttack.getAttackLevel()) +// return i; +// } +// +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DO") && monsterArray[i].getDefenseLevel() < monsterToAttack.getAttackLevel()) { +// } +// return i; +// } +// return -1; +// } +// +// public static String getRandomMove() { +// +// } +} diff --git a/My Part 5/main/java/controller/Database.java b/My Part 5/main/java/controller/Database.java new file mode 100644 index 0000000..e5d87af --- /dev/null +++ b/My Part 5/main/java/controller/Database.java @@ -0,0 +1,120 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.magiccard.MagicCardStatuses; +import model.cards.monstercard.MonsterCard; +import model.cards.monstercard.MonsterCardAttributes; + +import java.io.*; +import java.util.ArrayList; + +public class Database { + public static void prepareGame() { + new File("src/main/resources/players").mkdirs(); + addCardsToGame(); + readPlayersDataFromDatabase(); + } + + private static void addCardsToGame() { + try { + FileReader monsterCardFileReader = new FileReader("src/main/resources/cards/Monster Upgraded.csv"); + CSVReader monsterCardCSVReader = new CSVReaderBuilder(monsterCardFileReader).withSkipLines(1).build(); + + String[] monsterCardData; + while ((monsterCardData = monsterCardCSVReader.readNext()) != null) { + createNewMonsterCard(monsterCardData); + } + + + FileReader magicCardFileReader = new FileReader("src/main/resources/cards/SpellTrap.csv"); + CSVReader magicCardCSVReader = new CSVReaderBuilder(magicCardFileReader).withSkipLines(1).build(); + + String[] magicCardData; + while ((magicCardData = magicCardCSVReader.readNext()) != null) { + createNewMagicCard(magicCardData); + } + + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + } + + private static void createNewMonsterCard(String[] data) { + String name = data[0]; + short level = Short.parseShort(data[1]); + MonsterCardAttributes monsterCardAttributes = MonsterCardAttributes.valueOf(data[2]); + String monsterType = data[3]; + CardTypes cardType = CardTypes.valueOf(data[4].toUpperCase()); + int attackPoints = Integer.parseInt(data[5]); + int defensePoints = Integer.parseInt(data[6]); + String description = data[7]; + int price = Integer.parseInt(data[8]); + + new MonsterCard(name, level, monsterCardAttributes, monsterType, cardType, attackPoints, defensePoints, description, price); + } + + private static void createNewMagicCard(String[] data) { + String name = data[0]; + CardTypes cardType = CardTypes.valueOf(data[1].toUpperCase()); + String icon = data[2]; + String description = data[3]; + MagicCardStatuses status = MagicCardStatuses.valueOf(data[4].toUpperCase()); + int price = Integer.parseInt(data[5]); + + new MagicCard(name, cardType, icon, description, status,price); + } + + public static void readPlayersDataFromDatabase() { +// TODO: complete it by Iman's code + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + File file = new File("src/main/resources/players"); + FilenameFilter filenameFilter = (direction, name) -> name.endsWith(".json"); + String[] filesName = file.list(filenameFilter); + + if (filesName == null) return; + for (String fileName : filesName) { + try { + FileReader fileReader = new FileReader("src/main/resources/players/" + fileName); + Player player = gson.fromJson(fileReader, Player.class); + fileReader.close(); + Player.addPlayerToAllPlayers(player); + addCardsToPlayer(player); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + private static void addCardsToPlayer(Player player) { + ArrayList boughtCards = player.getBoughtCards(); + for (int i = 0; i < boughtCards.size(); i++) { + Card fakeCard = boughtCards.get(0); + Card originalCard = Card.getCardByName(fakeCard.getName()); + boughtCards.remove(fakeCard); + player.addCardToBoughtCards(originalCard); + } + } + + public static void updatePlayerInformationInDatabase(Player player) { + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + try { + FileWriter fileWriter = new FileWriter("src/main/resources/players/" + player.getUsername() + ".json"); + fileWriter.write(gson.toJson(player)); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/My Part 5/main/java/controller/Main.java b/My Part 5/main/java/controller/Main.java new file mode 100644 index 0000000..274e490 --- /dev/null +++ b/My Part 5/main/java/controller/Main.java @@ -0,0 +1,10 @@ +package controller; + +import view.LoginMenuView; + +public class Main { + public static void main(String[] args) { + Database.prepareGame(); + LoginMenuView.loginMenuView(); + } +} \ No newline at end of file diff --git a/My Part 5/main/java/controller/SpellCardController.java b/My Part 5/main/java/controller/SpellCardController.java new file mode 100644 index 0000000..6080ef6 --- /dev/null +++ b/My Part 5/main/java/controller/SpellCardController.java @@ -0,0 +1,537 @@ +package controller; + +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.SpellCardView; + +import java.util.ArrayList; +import java.util.Collections; + +public class SpellCardController { +// this method doesn't handle field spell cards + public static boolean doSpellCardEffect(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { +// handle every kind of spell cards except field and equip + String cardName = spellCard.getName(); + switch (cardName) { + case "Monster Reborn": + return doMonsterRebornEffect(turnPlayer, notTurnPlayer); + case "Terraforming": + return doTerraformingEffect(turnPlayer); + case "Pot of Greed": + return doPotOfGreedEffect(turnPlayer); + case "Raigeki": + return doRaigekiEffect(notTurnPlayer); + case "Change of Heart": + return doChangeOfHeartEffect(); + case "Harpie's Feather Duster": + return doHarpieFeatherDusterEffect(notTurnPlayer); + case "Swords of Revealing Light": + return doSwordsOfRevealingLight(); + case "Dark Hole": + return doDarkHoleEffect(turnPlayer, notTurnPlayer); + case "Supply Squad": +// TODO: i should know how turn changes, then handle it --> it shouldn't handle here + break; + case "Spell Absorption": + return true; + case "Messenger of peace": +// TODO: handle it base on Parsa code + break; + case "Twin Twisters": + return doTwinTwistersEffect(turnPlayer, notTurnPlayer); + case "Mystical space typhoon": + return doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + case "Ring of defense": +// TODO: handle it base trap and monster code + break; +// it's the only ritual spell card + case "Advanced Ritual Art": + return doAdvancedRitualArtEffect(); + } + +// handle equip spell cards + return chooseMonsterToEquip(turnPlayer, notTurnPlayer, spellCard); +// any other kind of card doesn't enter to this method + } + + +// handle every kind of spell cards except field and equip + private static boolean doMonsterRebornEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showGraveyardsMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(turnPlayer.getBoard().getGraveyard()); + int notTurnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()); + if (turnPlayerGraveyardMonsterCardsSize + notTurnPlayerGraveyardMonsterCardsSize == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findMonsterRebornChosenCard(turnPlayer, notTurnPlayer, cardNumber); + if (chosenCard != null) break; + SpellCardView.invalidNumber(); + } + +// TODO: how to handle special summon + return true; + } + + private static int getCardNumber() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findCardNumber()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static MonsterCard findMonsterRebornChosenCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + ArrayList turnPlayerGraveyard = turnPlayer.getBoard().getGraveyard(); + ArrayList notTurnPlayerGraveyard = notTurnPlayer.getBoard().getGraveyard(); + + for (Card card : turnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + for (Card card : notTurnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + + return null; + } + + private static boolean doTerraformingEffect(Player player) { +// TODO: do Iman handle with main cards? + ArrayList cards = player.getBoard().getDeck().getMainCards(); + ArrayList fieldSpellCards = findFieldSpellCards(cards); + + SpellCardView.showFieldSpellCards(fieldSpellCards); + if (fieldSpellCards.size() == 0) return false; + + MagicCard chosenFieldSpellCard; + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= fieldSpellCards.size()) { + chosenFieldSpellCard = fieldSpellCards.get(cardNumber - 1); + player.getBoard().getCardsInHand().add(chosenFieldSpellCard); + cards.remove(chosenFieldSpellCard); + break; + } + SpellCardView.invalidNumber(); + } + + Collections.shuffle(cards); + return true; + } + + private static ArrayList findFieldSpellCards(ArrayList cards) { +// create array list of field spell cards + ArrayList fieldSpellCards = new ArrayList<>(); + for (Card card : cards) { + if (!Card.isMonsterCard(card)) { + MagicCard magicCard = (MagicCard) card; + if (magicCard.getIcon().equals("Field")) fieldSpellCards.add(magicCard); + } + } + return fieldSpellCards; + } + + private static boolean doPotOfGreedEffect(Player player) { + Board board = player.getBoard(); + ArrayList deckCards = board.getDeck().getMainCards(); + if (deckCards.size() < 2) return false; + + Card firstCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + Card secondCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + board.getCardsInHand().add(firstCard); + board.getCardsInHand().add(secondCard); + + return true; + } + + private static boolean doRaigekiEffect(Player player) { + MonsterCard[] monstersZone = player.getBoard().getMonstersZone(); + if (isCardArrayNull(monstersZone)) return false; + emptyAZone(player, monstersZone); + return true; + } + + private static boolean isCardArrayNull(Card[] cards) { + for (Card card : cards) { + if (card != null) return false; + } + return true; + } + + private static void emptyAZone(Player player, Card[] cards) { + for (int i = 0; i < cards.length; ++i) { + if (cards[i] != null) { + player.getBoard().getGraveyard().add(cards[i]); + cards[i] = null; + } + } + } + + private static boolean doChangeOfHeartEffect() { +// TODO: handle it! + return true; + } + + private static boolean doHarpieFeatherDusterEffect(Player player) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (isCardArrayNull(magicsZone)) return false; + emptyAZone(player, magicsZone); + return true; + } + + private static boolean doSwordsOfRevealingLight() { +// TODO: handle it! + return true; + } + + private static boolean doDarkHoleEffect(Player turnPlayer, Player notTurnPlayer) { + return doRaigekiEffect(turnPlayer) || doRaigekiEffect(notTurnPlayer); + } + + public static void doSpellAbsorptionEffect(Player player) { + if (player.getBoard().isCardFaceUp("Spell Absorption")) player.increaseLifePoint(500); + } + + private static boolean doTwinTwistersEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showCardsInHand(turnPlayer); + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= cardsInHand.size()) { + turnPlayer.getBoard().getGraveyard().add(cardsInHand.get(cardNumber - 1)); + cardsInHand.remove(cardNumber - 1); + break; + } + SpellCardView.invalidNumber(); + } + + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return true; + + int numberOfChosenCards; + while (true) { + numberOfChosenCards = getNumberOfCardsToChoose(); + if (0 <= numberOfChosenCards && numberOfChosenCards <= 2 && + numberOfChosenCards <= turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards) { + break; + } + SpellCardView.invalidNumber(); + } + + for (int i = 0; i < numberOfChosenCards; i++) { + doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + } + + return true; + } + + private static int getNumberOfCardsToChoose() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findNumberOfCardsToChoose()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static boolean destroyAMagicCardFromMagicZone(Player player, int cardNumber, int startNumber) { + MagicCard[] playerMagicsZone = player.getBoard().getMagicsZone(); + for (int i = 1; i < playerMagicsZone.length; i++) { + if (playerMagicsZone[i] != null) { + if (startNumber == cardNumber) { + player.getBoard().getGraveyard().add(playerMagicsZone[i]); + playerMagicsZone[i] = null; + return true; + } + ++startNumber; + } + } + + return false; + } + + private static boolean doMysticalSpaceTyphoonEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (destroyAMagicCardFromMagicZone(turnPlayer, cardNumber, 1) || + destroyAMagicCardFromMagicZone(notTurnPlayer, cardNumber, turnPlayerNumberOfMagicCards + 1)) + break; + SpellCardView.invalidNumber(); + } + + return true; + } + +// it's the only ritual spell card + private static boolean doAdvancedRitualArtEffect() { +// TODO: handle it based on Iman's code + return false; + } + + +// handle field spell cards + public static void handleFieldSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + MagicCard firstPlayerFieldZoneCard = firstPlayer.getBoard().getFieldZone(); + MagicCard secondPlayerFieldZoneCard = secondPlayer.getBoard().getFieldZone(); + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, firstPlayerFieldZoneCard, doEffect); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, secondPlayerFieldZoneCard, doEffect); + } + + private static Player findMonsterCardOwner(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard) { + if (firstPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return firstPlayer; + if (secondPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return secondPlayer; + +// this will never happen, just for assurance + return null; + } + + private static void handleEachFieldSpellCardEffect(Player monsterCardOwner, MonsterCard monsterCard, MagicCard fieldZoneCard, + boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + if (fieldZoneCard == null || !fieldZoneCard.getCardFaceUp()) return; + + switch (fieldZoneCard.getName()) { + case "Yami": + handleYamiEffect(monsterCard, doEffect); + break; + case "Forest": + handleForestEffect(monsterCard, doEffect); + break; + case "Closed Forest": + handleClosedForestEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Umiiruka": + handleUmiirukaEffect(monsterCard, doEffect); + break; + } + } + + private static void handleYamiEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } else if (monsterCard.getMonsterType().equals("Fairy")) { + if (doEffect) { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } + } + } + + private static void handleForestEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Insect") || monsterCardType.equals("Beast") || + monsterCardType.equals("Beast-Warrior")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } + } + + private static void handleClosedForestEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int graveyardMonsterCardsSize = Card.findNumberOfMonsterCards(monsterCardOwner.getBoard().getGraveyard()); + MonsterCard[] monstersZone = monsterCardOwner.getBoard().getMonstersZone(); + + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null && monstersZone[i].getMonsterType().equals("Beast-Type")) { + if (doEffect) monsterCard.increaseAttackPoints(100 * graveyardMonsterCardsSize); + else monsterCard.decreaseAttackPoints(100 * graveyardMonsterCardsSize); + } + } + + } + + private static void handleUmiirukaEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (monsterCard.getMonsterType().equals("Aqua")) { + if (doEffect) { + monsterCard.increaseAttackPoints(500); + monsterCard.decreaseDefencePoints(400); + } else { + monsterCard.decreaseAttackPoints(500); + monsterCard.increaseDefencePoints(400); + } + } + } + + +// handle equip spell cards + private static boolean chooseMonsterToEquip(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { + SpellCardView.showFaceUpMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerFaceUpMonsterCardsNumber = turnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + int notTurnPlayerFaceUpMonsterCardsNumber = notTurnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + Board turnPlayerBoard = turnPlayer.getBoard(); + if (turnPlayerFaceUpMonsterCardsNumber + notTurnPlayerFaceUpMonsterCardsNumber == 0 || + !turnPlayerBoard.isMagicsZoneFull()) return false; + if (spellCard.getName().equals("Magnum Shield") && turnPlayerBoard.getNumberOfWarriorMonsterCards() == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findFaceUpMonsterCard(turnPlayer, notTurnPlayer, cardNumber); +// second and third condition assure me that Magnum Shield just equipped Warrior Monster Cards + if (chosenCard != null && + (!spellCard.getName().equals("Magnum Shield") || chosenCard.getMonsterType().equals("Warrior"))) break; + SpellCardView.invalidNumber(); + } + + chosenCard.addToEquippedBy(spellCard); + turnPlayerBoard.addMagicCardToMagicsZone(spellCard); + return true; + } + + private static MonsterCard findFaceUpMonsterCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + MonsterCard[] turnPlayerFaceUpMonsterCards = turnPlayer.getBoard().getMonstersZone(); + MonsterCard[] notTurnPlayerFaceUpMonsterCards = notTurnPlayer.getBoard().getMonstersZone(); + + for (int i = 1; i < turnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = turnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + for (int i = 1; i < notTurnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = notTurnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + + return null; + } + + public static void handleEquipSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + for (MagicCard spellCard : monsterCard.getEquippedBy()) { + switch (spellCard.getName()) { + case "Sword of dark destruction": + handleSwordOfDarkDestructionEffect(monsterCard, doEffect); + break; + case "Black Pendant": + handleBlackPendantEffect(monsterCard, doEffect); + break; + case "United We Stand": + handleUnitedWeStandEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Magnum Shield": + handleMagnumShieldEffect(monsterCard, doEffect); + break; + } + } + } + + private static void handleSwordOfDarkDestructionEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(400); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(400); + monsterCard.increaseDefencePoints(200); + } + } + + } + + private static void handleBlackPendantEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (doEffect) monsterCard.increaseAttackPoints(500); + else monsterCard.decreaseAttackPoints(500); + } + + private static void handleUnitedWeStandEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int numberOfFaceUpMonsterCards = monsterCardOwner.getBoard().getNumberOfFaceUpMonsterCards(); + if (doEffect) { + monsterCard.increaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.increaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } else { + monsterCard.decreaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.decreaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } + } + + private static void handleMagnumShieldEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + +// I know that Magnum Shield just equipped Warrior monster cards + if (monsterCard.isDefensePosition()) { + if (doEffect) monsterCard.increaseDefencePoints(monsterCard.getAttackPoints()); + else monsterCard.decreaseDefencePoints(monsterCard.getAttackPoints()); + } else { + if (doEffect) monsterCard.increaseAttackPoints(monsterCard.getDefensePoints()); + else monsterCard.decreaseAttackPoints(monsterCard.getDefensePoints()); + } + } +} diff --git a/My Part 5/main/java/controller/Utils.java b/My Part 5/main/java/controller/Utils.java new file mode 100644 index 0000000..05df0d8 --- /dev/null +++ b/My Part 5/main/java/controller/Utils.java @@ -0,0 +1,34 @@ +package controller; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Utils { + private static Scanner scanner; + + static { + scanner = new Scanner(System.in); + } + + public static Scanner getScanner() { + return scanner; + } + + public static void resetScanner(String input) { + scanner = new Scanner(new ByteArrayInputStream(input.getBytes())); + } + + public static ByteArrayOutputStream setByteArrayOutputStream() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + return outContent; + } + + public static Matcher getMatcher(String regex, String command) { + return Pattern.compile(regex).matcher(command); + } +} diff --git a/My Part 5/main/java/controller/deckmenu/DeckMenuController.java b/My Part 5/main/java/controller/deckmenu/DeckMenuController.java new file mode 100644 index 0000000..184bf48 --- /dev/null +++ b/My Part 5/main/java/controller/deckmenu/DeckMenuController.java @@ -0,0 +1,100 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +import java.util.Objects; + +public class DeckMenuController { + + private static DeckMenuController instance = null; + + private DeckMenuController() { + } + + public static DeckMenuController getInstance() { + return Objects.requireNonNullElseGet(instance, () -> (instance = new DeckMenuController())); + } + + public void createDeck(String name, Player owner) { + if (!DeckMenuTools.isDeckNameUnique(name)) + return; + + new Deck(name, owner , true , true); + DeckMenuOutput.getInstance().showMessage("deck created successfully!"); + } + + public void deleteDeck(String name) { + if (!DeckMenuTools.doesDeckExist(name)) {return;} + // if (DeckMenuTools.isDeckNameUnique(name)) return; + + DeckMenuDatabase.removeDeck(name); + DeckMenuOutput.getInstance().showMessage("deck deleted successfully!"); + + } + + + public void setActiveDeck(String name, Player player) { + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesDeckExist(name) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(name), player); + if (isPermitted) { + player.activateADeck(deck); + + DeckMenuOutput.getInstance().showMessage("deck activated successfully!"); + } + + } + + public void addCardToDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card = null; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player) + && ((isMain) ? DeckMenuTools.doesDeckHaveSpace(deck) : DeckMenuTools.doesSideDeckHaveSpace(deck)) + && DeckMenuTools.isNumberOfCardsInDeckLessThanFour(deck, card = DeckMenuDatabase.getInstance().getCardByName(cardName)) + && DeckMenuTools.doesPlayerHaveEnoughCards(card , player); + if (isPermitted) { + player.removeCardFromBoughtCards(card); + deck.addCard(card, isMain); + DeckMenuOutput.getInstance().showMessage("card added to deck successfully!"); + } + } + + public void removeCardFromDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player); + if (isPermitted) { + card = DeckMenuDatabase.getInstance().getCardByName(cardName); + player.addCardToBoughtCards(card); + deck.moveCardTo(player.getAllPlayerCard(),card, isMain , true); + DeckMenuOutput.getInstance().showMessage("card removed from deck successfully!"); + } + } + + public void showAllDecks(Player player) { + for (Deck deck : player.getAllDeck()) + DeckMenuOutput.getInstance().showMessage(deck.toString()); + + } + + public void showDeck(String name, Player player, boolean isMain) { + if (!DeckMenuTools.doesDeckExist(name)) + return; + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (!DeckMenuTools.doesDeckBelongToPlayer(deck, player)) + return; + String message; + if (isMain) + message = "true"; + else + message = "false"; + DeckMenuOutput.getInstance().showMessage(message); + + + } +} diff --git a/My Part 5/main/java/controller/deckmenu/DeckMenuDatabase.java b/My Part 5/main/java/controller/deckmenu/DeckMenuDatabase.java new file mode 100644 index 0000000..d16b03f --- /dev/null +++ b/My Part 5/main/java/controller/deckmenu/DeckMenuDatabase.java @@ -0,0 +1,50 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; +import java.util.ArrayList; + +public class DeckMenuDatabase { + + public static ArrayList allPlayers = new ArrayList<>(); + public static ArrayList allCards = new ArrayList<>(); + public static ArrayList allDecks = new ArrayList<>(); + + private DeckMenuDatabase() { + } + + private static DeckMenuDatabase instance; + + public static DeckMenuDatabase getInstance() { + if (instance == null) + instance = new DeckMenuDatabase(); + return instance; + } + + public static void removeDeck(String name) { + allDecks.removeIf(deck -> deck.getName().equals(name)); + } + + public Card getCardByName(String name) { + for (Card card : allCards) { + if (card.getName().equals(name)) + return card; + } + return null; + + } + + public Deck getDeckByName(String name) { + for (Deck deck : allDecks) { + if (deck.getName().equals(name)) + return deck; + } + return null; + + } + // setPlayers() {file v Jason} + // setDecks() {file v Jason} + // loadingDatabase() + // updatingDatabase() + +} diff --git a/My Part 5/main/java/controller/deckmenu/DeckMenuOutput.java b/My Part 5/main/java/controller/deckmenu/DeckMenuOutput.java new file mode 100644 index 0000000..92896b1 --- /dev/null +++ b/My Part 5/main/java/controller/deckmenu/DeckMenuOutput.java @@ -0,0 +1,23 @@ +package controller.deckmenu; + +public class DeckMenuOutput { + + private DeckMenuOutput() { + } + + private static DeckMenuOutput instance; + + public static DeckMenuOutput getInstance() { + if (instance == null) + instance = new DeckMenuOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My Part 5/main/java/controller/deckmenu/DeckMenuTools.java b/My Part 5/main/java/controller/deckmenu/DeckMenuTools.java new file mode 100644 index 0000000..20266b2 --- /dev/null +++ b/My Part 5/main/java/controller/deckmenu/DeckMenuTools.java @@ -0,0 +1,70 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +public class DeckMenuTools { + public static boolean isDeckNameUnique(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck == null) + return true; + + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " already exists"); + return false; + + } + public static boolean doesDeckExist(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck != null) + return true; + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " does not exist"); + return false; + + } + public static boolean doesDeckBelongToPlayer(Deck deck, Player player) { + if (deck.getOwner().getUsername().equals(player.getUsername())) + return true; + DeckMenuOutput.getInstance().showMessage("this deck doesn't belong to you!"); + return false; + } + public static boolean doesDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getMainCards().size() < 60) + return true; + DeckMenuOutput.getInstance().showMessage("main deck is full!"); + return false; + } + public static boolean doesSideDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getSideCards().size() < 15) + return true; + DeckMenuOutput.getInstance().showMessage("side deck is full!"); + return false; + } + public static boolean isNumberOfCardsInDeckLessThanFour(Deck deck, Card card) { + if (deck.getNumberOfCardsInDeck(card) < 3) + return true; + DeckMenuOutput.getInstance().showMessage("there are already three cards with name " + card.getName() + + " in deck " + deck.getName() + " !"); + return false; + } + public static boolean isDeckAllowed(Deck deck) { + int numberOfCardsInSideDeck = deck.getNumberOfCardsInSideDeck(); + int numberOfCardsInMainDeck = deck.getNumberOfCardsInMainDeck(); + return numberOfCardsInMainDeck <= 60 && numberOfCardsInMainDeck >= 40 && numberOfCardsInSideDeck <= 15; + } + public static boolean doesPlayerHaveEnoughCards(Card card, Player player) { + if (player.hasCard(card)) + return true; + DeckMenuOutput.getInstance().showMessage("you dont have this type of card anymore!"); + return false; + } + public static boolean doesCardExist(String cardName) { + Card card = Card.getCardByName(cardName); + if (card != null) + return true; + DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist"); + return false; + } + +} diff --git a/My Part 5/main/java/controller/duelmenu/DuelMenuController.java b/My Part 5/main/java/controller/duelmenu/DuelMenuController.java new file mode 100644 index 0000000..c4ca63b --- /dev/null +++ b/My Part 5/main/java/controller/duelmenu/DuelMenuController.java @@ -0,0 +1,726 @@ +package controller.duelmenu; + +import controller.SpellCardController; +import controller.Utils; +import model.Board; +import model.Deck; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.DuelMenuView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.regex.Matcher; + +public class DuelMenuController { + private Player turnPlayer; + private Player notTurnPlayer; + private Player helpTurnPlayer; + private Phases phase; + private boolean isAITurn; + private int isSummoned = 0; //0 : is not summoned before, 1 : is summoned before + + public static String specifyTurnPlayer(Player firstPlayer, Player secondPlayer) { + String firstPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(firstPlayer); + if (!isMiniGameChoiceValid(firstPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices firstPlayerChoice = MiniGameChoices.valueOf(firstPlayerChoiceInString.toUpperCase()); + + String secondPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(secondPlayer); + if (!isMiniGameChoiceValid(secondPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices secondPlayerChoice = MiniGameChoices.valueOf(secondPlayerChoiceInString.toUpperCase()); + + if (firstPlayerChoice.equals(secondPlayerChoice)) return "draw"; + + return findMiniGameWinner(firstPlayer, secondPlayer, firstPlayerChoice, secondPlayerChoice); + } + + private static boolean isMiniGameChoiceValid(String choice) { + try { + MiniGameChoices.valueOf(choice.toUpperCase()); + return true; + } catch (Exception exception) { + return false; + } + } + + private static String findMiniGameWinner(Player firstPlayer, Player secondPlayer, + MiniGameChoices firstPlayerChoice, MiniGameChoices secondPlayerChoice) { + switch (firstPlayerChoice) { + case STONE: + if (secondPlayerChoice.equals(MiniGameChoices.PAPER)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case PAPER: + if (secondPlayerChoice.equals(MiniGameChoices.SCISSOR)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case SCISSOR: + if (secondPlayerChoice.equals(MiniGameChoices.STONE)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + } + +// this is never happen + return null; + } + + public DuelMenuMessages initialGame(Player firstPlayer, Player secondPlayer) { +// TODO: handle it for ai + String result = specifyTurnPlayer(firstPlayer, secondPlayer); + if (result.equals("invalid choice")) return DuelMenuMessages.MINI_GAME_INVALID_CHOICE; + else if (result.equals("draw")) return DuelMenuMessages.DRAW; + else turnPlayer = Player.getPlayerByUsername(result); + + if (turnPlayer.equals(firstPlayer)) notTurnPlayer = secondPlayer; + else notTurnPlayer = firstPlayer; + + turnPlayer.createBoard(); + notTurnPlayer.createBoard(); + + turnPlayer.getBoard().setDeck(turnPlayer.getActivatedDeck()); + notTurnPlayer.getBoard().setDeck(notTurnPlayer.getActivatedDeck()); + + Collections.shuffle(turnPlayer.getActivatedDeck().getMainCards()); + Collections.shuffle(notTurnPlayer.getActivatedDeck().getMainCards()); + + return DuelMenuMessages.SHOW_TURN_PLAYER; + } + + public DuelMenuMessages findCommand(String command) { +// TODO: handle menu commands --> menu exit and ... + if (command.startsWith("decrease ")) return cheatCodeDecreaseOpponentLifePont(command); + else if (command.startsWith("increase ")) return cheatCodeIncreaseLifePoint(command); + else if (command.startsWith("duel set-winner ")) return cheatCodeSetWinner(command); + else if (command.startsWith("select ")) return checkSelectCard(command); + else if (command.equals("select -d")) return deselectCard(); + else if (command.equals("summon")) ;//return checkSummonMonster(); + else if (command.equals("set")) return checkSetACard(); + else if (command.startsWith("set --position")) ;// return checkChangePosition(command); + else if (command.equals("flip-summon")) return flipSummon(); + else if (command.equals("attack direct")) return directAttack(); + else if (command.startsWith("attack")) return attack(command); + else if (command.equals("activate effect")) return checkActiveASpellCard(); + else if (command.equals("show graveyard")) { + DuelMenuView.showGraveyard(turnPlayer.getBoard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("back")) ;//checkBack(); + else if (command.equals("card show --selected")) { + DuelMenuView.printCard(1, turnPlayer.getBoard().getSelectedCard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("cancel")) ;//cancelCommand(); + else if (command.equals("surrender")) /*TODO*/ ; + +// TODO: handle cheat/debug commands + + return DuelMenuMessages.INVALID_COMMAND; + } + + private DuelMenuMessages cheatCodeDecreaseOpponentLifePont(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_DECREASE_OPPONENT_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + notTurnPlayer.decreaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + } + + private DuelMenuMessages cheatCodeIncreaseLifePoint(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_INCREASE_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + turnPlayer.increaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + } + + private DuelMenuMessages cheatCodeSetWinner(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_SET_WINNER.getRegex(), command); + if (matcher.find()) { + String nickname = matcher.group(1); + if (turnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/ ; + else if (notTurnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/ ; + else return DuelMenuMessages.WRONG_NICKNAME_CHEAT_CODE; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + return DuelMenuMessages.EMPTY; + } + + //Iman's Code + private void changePhase() { + phase = phase.next(); + DuelMenuMessages.changephase(phase); + if (phase == Phases.DRAW_PHASE){ + drawPhase(); + } + + } + + private void changeGameTurn(Player firstPlayer, Player secondPlayer) { + if (turnPlayer == firstPlayer) { + turnPlayer = secondPlayer; + notTurnPlayer = firstPlayer; + } + if (turnPlayer == secondPlayer) { + turnPlayer = firstPlayer; + notTurnPlayer = secondPlayer; + } + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void changeGameTurn() { + helpTurnPlayer = turnPlayer; + turnPlayer = notTurnPlayer; + notTurnPlayer = helpTurnPlayer; + isSummoned = 0; + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void drawPhase() { + changeGameTurn(); + DuelMenuMessages.playerTurn(turnPlayer); + cardDraw(); + } + + public void cardDraw() { + Deck deck = turnPlayer.getBoard().getDeck(); + if (deck.getNumberOfCardsInMainDeck() == 0) { + turnPlayer.setLifePoint(0); + return; + } + turnPlayer.getBoard().drawCard(); + } + + private void summonMonster() { + int position = 0; // TODO fix this + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + + if (selectedMonster.getLevel() == 5 || selectedMonster.getLevel() == 6) { + summonWithOneTribute(position); + } else if (selectedMonster.getLevel() == 7 || selectedMonster.getLevel() == 8) { + summonWithTwoTribute(position); + } else { + selectedCard.getCardFaceUp(); + selectedMonster.settoOO(selectedMonster); + turnPlayer.getBoard().addMonsterCardToMonsterZone(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + DuelMenuMessages.summonedSuccessfully(); + } + } + + private DuelMenuMessages checkSummonMonster() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard) || selectedCard.getCardType() == CardTypes.RITUAL) { + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + else if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + else if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + else if (isSummoned == 1) { + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + + else { + summonMonster(); + return DuelMenuMessages.EMPTY; + } + } + +// public void tributeCardFromMonsterZone(int position) { +// graveyardCards.add(monstesrZones.get(position).getCurrentMonster()); +// monsterZones.get(position).removeCard(); +// } + + private DuelMenuMessages summonWithOneTribute(int position) { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (!turnPlayer.getBoard().isThereOneMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + return DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE; + } + String addressString = Utils.getScanner().nextLine().trim(); + if (addressString.equals("")) return null; // TODO fix this + int address = setCardAddressInMyBoard(Integer.parseInt(addressString)); + if (address < 1 || address > 5) { + return DuelMenuMessages.NO_MONSTER_ON_ADDRESS; + } + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address)) { + return DuelMenuMessages.NO_MONSTER_ON_THIS_ADDRESS; + } + else { + monstersZone[address] = null; + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + cardsInHand.remove(selectedCard); + isSummoned = 1; + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + } + } + + private void summonWithTwoTribute(int position) { + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (!turnPlayer.getBoard().isThereTwoMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + DuelMenuMessages.NotEnoughCardForTribute(); + } + String addressString1 = Utils.getScanner().nextLine().trim(); + if (addressString1.equals("surrender")) return; + String addressString2 = Utils.getScanner().nextLine().trim(); + if (addressString2.equals("surrender")) return; + int address1 = setCardAddressInMyBoard(Integer.parseInt(addressString1)); + int address2 = setCardAddressInMyBoard(Integer.parseInt(addressString2)); + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address1)) return; + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address2)) return; + monstersZone[address1] = null; + monstersZone[address2] = null; + isSummoned = 1; + + } + + private int setCardAddressInMyBoard(int address) { + if (address == 5) return 5; + if (address == 3) return 3; + if (address == 1) return 2; + if (address == 2) return 2; + if (address == 4) return 4; + return -1; + } + + private DuelMenuMessages set() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + // int position = selectedCardIndex; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected()) { + return DuelMenuMessages.SET_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + if (isSummoned == 1){ + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + isSummoned = 1; + if (model.cards.Card.isMonsterCard(selectedCard)) { + MonsterCard selectedMonster = (MonsterCard) selectedCard; + setAMonsterCard(selectedMonster); + } + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + + + } + + private DuelMenuMessages checkSetACard() { + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (board.getSelectedCard() == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!board.isACardInHandSelected()) return DuelMenuMessages.CANT_SET; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.NOT_TRUE_PHASE; + else if (Card.isMonsterCard(selectedCard)) return setAMonsterCard(selectedCard); + + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + } + + + private DuelMenuMessages setAMonsterCard(Card selectedCard) { + MonsterCard monsterCard = (MonsterCard) selectedCard; + if (turnPlayer.getBoard().isMonsterZoneFull()) return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + else turnPlayer.getBoard().addMonsterCardToMonsterZone(monsterCard); + monsterCard.settoDH(monsterCard); + return DuelMenuMessages.SET_SUCCESSFULLY; + } + + private DuelMenuMessages setPositionAttack() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (!selectedMonster.isDefensePosition() || !selectedMonster.toString().equals("DO")) { + return DuelMenuMessages.ALREADY_IN_WANTED_POSITION; + } + if (isSummoned == 1){ //TODO Already changed position? + return DuelMenuMessages.ALREADY_CHANGED_POSITION; + } + selectedMonster.settoOO(selectedMonster); + return DuelMenuMessages.MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY; + } + + private DuelMenuMessages setPositionDefence() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (selectedMonster.isDefensePosition() || !selectedMonster.toString().equals("OO")) { + return DuelMenuMessages.ALREADY_IN_WANTED_POSITION; + } + if (isSummoned == 1){ //TODO Already changed position? + return DuelMenuMessages.ALREADY_CHANGED_POSITION; + } + selectedMonster.settoDO(selectedMonster); + return DuelMenuMessages.MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY; + } + + private DuelMenuMessages flipSummon() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard)) { // check type of monsters + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (selectedMonster.toString().equals("DH") || isSummoned != 0) { + return DuelMenuMessages.FLIP_SUMMON_NOT_POSSIBLE; + } + selectedMonster.settoDO(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + + } + + private DuelMenuMessages ritualSummon() { +// TODO: complete it! + return DuelMenuMessages.EMPTY; + } + + private DuelMenuMessages specialSummon() { +// TODO: complete it! + return DuelMenuMessages.EMPTY; + } + + private DuelMenuMessages checkSelectCard(String command) { +// TODO: handle --> if there isn't any card in main deck, he/she loses +// TODO: maybe clean it more + Matcher matcher; + if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MONSTER_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MAGIC_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_FIELD_ZONE.getRegex(), command).find()) { + if (turnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(true); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_CARDS_IN_HAND.getRegex(), command)).find() ) { + int number = Integer.parseInt(matcher.group(1)); + if (number > turnPlayer.getBoard().getCardsInHand().size()) { + return DuelMenuMessages.INVALID_SELECTION; + } + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getCardsInHand().get(number - 1)); + turnPlayer.getBoard().setMyCardSelected(true); + turnPlayer.getBoard().setACardInHandSelected(true); + + } else { + turnPlayer.getBoard().setSelectedCard(null); + turnPlayer.getBoard().setMyCardSelected(false); + return DuelMenuMessages.INVALID_SELECTION; + } + + return DuelMenuMessages.CARD_SELECTED; + } + + private boolean isSelectionValid(Matcher matcher) { + int number = Integer.parseInt(matcher.group(1)); + return number <= 5 && number >= 1; + } + + private boolean isCardAvailableInMonstersZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMonstersZone()[number] != null; + } + + private boolean isCardAvailableInMagicsZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMagicsZone()[number] != null; + } + + private void selectCardFromMonstersZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMonstersZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMonstersZone()[number]); + } + } + + private void selectCardFromMagicsZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMagicsZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMagicsZone()[number]); + } + } + + private void selectCardFromFieldZone(boolean isMyCardSelected) { + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getFieldZone()); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getSelectedCard()); + } + } + + private DuelMenuMessages deselectCard() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages result = checkDeselectCard(); + if (result == null) { + board.setSelectedCard(null); + return DuelMenuMessages.DESELECTED; + } else return result; + } + + private DuelMenuMessages checkDeselectCard() { + Board board = turnPlayer.getBoard(); + if (board.getSelectedCard() == null) + return DuelMenuMessages.NOT_SELECTED_CARD; + return null; + } +// +// +// private void victimize() { +//// TODO: handle it! +// } +// + +// +// private DuelMenuMessages checkChangePosition(String command) { +// +// } +// +// private DuelMenuMessages changePosition(String command) { +// +// } +// +// private void updateGraveyard() { +//// TODO: handle it! +// } +// + + private DuelMenuMessages attack(String command) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.ATTACK.getRegex(), command); + if (matcher.find()) { + int numberOfChosenCard = Integer.parseInt(matcher.group(1)); + + DuelMenuMessages result = checkAttack(numberOfChosenCard); + if (result == null) { + MonsterCard attackingMonster = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentMonster = opponentPlayerBoard.getMonstersZone()[numberOfChosenCard]; + + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + DuelMenuMessages tempResult = attackingMonster.attack(turnPlayer, notTurnPlayer, numberOfChosenCard); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + + return tempResult; + } + return result; + + } else return DuelMenuMessages.INVALID_CARD_SELECT; + } + + private DuelMenuMessages checkAttack(int numberOfChosenCard) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + if (attackingPlayerBoard.getSelectedCard() == null || !attackingPlayerBoard.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (attackingPlayerBoard.getSelectedCard() instanceof MonsterCard) + return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + //TODO check battle phase + MonsterCard card = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + if (card.isAttacked()) + return DuelMenuMessages.ATTACKED_BEFORE; + if (opponentPlayerBoard.getMonstersZone()[numberOfChosenCard] == null) + return DuelMenuMessages.NO_CARD_FOUND_IN_THE_POSITION; + return null; + } + + private DuelMenuMessages directAttack() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages messages = checkDirectAttack(); + if (messages != null) + return messages; + else { + MonsterCard card = (MonsterCard) board.getSelectedCard(); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + notTurnPlayer.decreaseLifePoint(card.getAttackPoints()); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + + DuelMenuMessages.setDamageAmount(card.getAttackPoints()); + return DuelMenuMessages.DIRECT_ATTACK_DONE; + } + } + + private DuelMenuMessages checkDirectAttack() { + Board board = turnPlayer.getBoard(); + + if (board.getSelectedCard() == null || !board.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (phase.equals(Phases.BATTLE_PHASE)) + return DuelMenuMessages.NOT_SUITABLE_PHASE; + if (board.getSelectedCard() instanceof MonsterCard) { + MonsterCard card = (MonsterCard) board.getSelectedCard();//TODO: handle cast exception!! + if (card.isAttacked()) return DuelMenuMessages.ATTACKED_BEFORE; + } else return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + + return null; + } + + private DuelMenuMessages checkActiveASpellCard() { +// TODO: clean it! + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (selectedCard == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!selectedCard.getCardType().equals(CardTypes.SPELL)) return DuelMenuMessages.NOT_SPELL_CARD; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.CANT_ACTIVATE_SPELL_EFFECT; + else if (selectedCard.isPowerUsed()) return DuelMenuMessages.CARD_ACTIVATED_BEFORE; + else if (!turnPlayer.getBoard().isMyCardSelected()) return DuelMenuMessages.NOT_OWNER; + + MagicCard spellCard = (MagicCard) selectedCard; + if (spellCard.getIcon().equals("Field")) { + turnPlayer.getBoard().addSpellCardToFieldZone(spellCard); + spellCard.setPowerUsed(true); + spellCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } else if (board.isMagicsZoneFull() && board.isACardInHandSelected()) return DuelMenuMessages.FULL_MAGICS_ZONE; + + if (!SpellCardController.doSpellCardEffect(turnPlayer, notTurnPlayer, spellCard)) return DuelMenuMessages.UNDONE_PREPARATIONS; + if (board.isACardInHandSelected()) board.addMagicCardToMagicsZone(spellCard); + selectedCard.setPowerUsed(true); + selectedCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } + + private DuelMenuMessages setAMagicCard(MagicCard magicCard) { + Board board = turnPlayer.getBoard(); + if (magicCard.getIcon().equals("Field")) board.addSpellCardToFieldZone(magicCard); + else if (board.isMagicsZoneFull()) return DuelMenuMessages.FULL_MAGICS_ZONE; + else board.addMagicCardToMagicsZone(magicCard); + magicCard.setPowerUsed(false); + magicCard.setCardFaceUp(false); + + return DuelMenuMessages.SET_SUCCESSFULLY; + } + +// private DuelMenuMessages checkBack() { +// +// } +// +// private void cancelCommand() { +// +// } +// +// private Player/*or Enum*/ checkWinner() { +// +// } +// +// TODO: ----------------------------------------------- + +} diff --git a/My Part 5/main/java/controller/duelmenu/DuelMenuMessages.java b/My Part 5/main/java/controller/duelmenu/DuelMenuMessages.java new file mode 100644 index 0000000..bf50377 --- /dev/null +++ b/My Part 5/main/java/controller/duelmenu/DuelMenuMessages.java @@ -0,0 +1,112 @@ +package controller.duelmenu; + +import model.Player; + +public enum DuelMenuMessages { + MINI_GAME_INVALID_CHOICE("please enter a valid option\n"), + DRAW("draw\nplease try again:\n"), + SHOW_TURN_PLAYER(" should start first\n"), + INVALID_SELECTION("invalid selection\n"), + CARD_SELECTED("card selected\n"), + CARD_NOT_FOUND("no card found in the given position\n"), + UNAVAILABLE_SELECTED_CARD("no card is selected yet\n"), + NOT_SPELL_CARD("activate effect is only for spell cards.\n"), + CANT_ACTIVATE_SPELL_EFFECT("you can’t activate an effect on this turn\n"), + CARD_ACTIVATED_BEFORE("you have already activated this card\n"), + FULL_MAGICS_ZONE("spell card zone is full\n"), + UNDONE_PREPARATIONS("preparations of this spell are not done yet\n"), + SPELL_ACTIVATED("spell activated\n"), + NOT_OWNER("you aren't owner of selected card\n"), + CANT_SET("you can’t set this card\n"), + NOT_TRUE_PHASE("you can’t do this action in this phase\n"), + SET_SUCCESSFULLY("set successfully\n"), + NOT_SELECTED_CARD("no card is selected yet\n"), + ATTACKED_BEFORE("this card already attacked\n"), + NOT_SUITABLE_PHASE("you can’t do this action in this phase\n"), + INVALID_CARD_SELECT("invalid selection\n"), + NO_CARD_FOUND_IN_THE_POSITION("no card found in the given position\n"), + CANT_ATTACK_WITH_CARD("you can’t attack with this card\n"), + YOU_CANT_ATTACK_TO_THIS_CARD("you cant attack to this card\n"), + ATTACK_CANCELED("attack to this card was canceled\n"), + DIRECT_ATTACK_DONE("you opponent receives battle damage\n"), + DESELECTED("card deselected\n"), + INVALID_COMMAND_CHEAT_CODE("invalid command\n"), + OPPONENT_GOT_DAMAGE_IN_ATTACK("your opponent’s monster is destroyed and your opponent receives battle damage\n"), + ATTACKING_PLAYER_CARD_DESTROYED("Your monster card is destroyed and you received battle damage\n"), + DEFENSE_POSITION_MONSTER_DESTROYED("the defense position monster is destroyed\n"), + NO_CARD_DESTROYED("no card is destroyed\n"), + RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD("no card is destroyed and you received battle damage\n"), + BOTH_CARDS_GET_DESTROYED("both you and your opponent monster cards are destroyed and no one receives damage\n"), + WRONG_NICKNAME_CHEAT_CODE("your entered nickname is wrong\n"), + EMPTY(""), + NO_CARD_SELECTED("no card is selected yet\n"), + SUMMON_NOT_POSSIBLE("you can’t summon this card\n"), + FLIP_SUMMON_NOT_POSSIBLE("you can’t flip summon this card\n"), + SET_NOT_POSSIBLE("you can’t set this card\n"), + PLAYER_TURN("it's 's turn"), + PHASE_IS_CHANGED("phase: \n"), + ALREADY_SUMMONED_OR_SET("you already summoned/set on this turn\n"), + NOT_ENOUGH_CARD_FOR_TRIBUTE("there are not enough card for tribute\n"), + NO_MONSTER_ON_THIS_ADDRESS("there are no monster one this address\n"), + MONSTER_ZONE_IS_FULL("monster card zone is full\n"), + SUMMONED_SUCCESSFULLY("summoned successfully\n"), + NO_MONSTER_ON_ADDRESS("there no monsters on this address"), + MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY("monster card position changed successfully\n"), + ALREADY_CHANGED_POSITION("you already changed this card position in this turn\n"), + ALREADY_IN_WANTED_POSITION("this card is already in the wanted position\n"), + CHANG_POSITION_NOT_POSSIBLE("you can’t change this card position\n"), + INVALID_COMMAND("invalid command\n"); + private String message; + + DuelMenuMessages(String message) { + this.message = message; + } + + public static void setShowTurnPlayer(Player player) { + DuelMenuMessages.SHOW_TURN_PLAYER.message = player.getUsername() + " should start first\n"; + } + + public static void summonedSuccessfully() { + System.out.print("summoned successfully\n"); + } + + public static void NotEnoughCardForTribute(){ + DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE.message = "there are not enough card for tribute\n"; + System.out.print("there are not enough card for tribute\n"); + } + + public static void noCardSelected() { + DuelMenuMessages.NO_CARD_SELECTED.message = "no card is selected yet"; + } + + public static void playerTurn(Player player) { + DuelMenuMessages.PLAYER_TURN.message = "it's + player.getUsername() + 's turn"; + } + + public static void changephase(Phases phase) { + DuelMenuMessages.PHASE_IS_CHANGED.message = "phase: " + phase; + } + + public static void setDamageAmount(int damageAmount) { + DuelMenuMessages.DIRECT_ATTACK_DONE.message = "you opponent receives " + damageAmount + " battle damage\n"; + } + + public static void setOpponentGotDamageInAttack(int damage) { + DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK.message = + "your opponent’s monster is destroyed and your opponent receives" + damage + " battle damage\n"; + } + + public static void setAttackingPlayerCardDestroyed(int damage) { + DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED.message = + "Your monster card is destroyed and you received " + damage + " battle damage\n"; + } + + public static void setReceiveDamageByAttackingToDefenseCard(int damage) { + DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD.message = + "no card is destroyed and you received " + damage + " battle damage\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 5/main/java/controller/duelmenu/DuelMenuRegexes.java b/My Part 5/main/java/controller/duelmenu/DuelMenuRegexes.java new file mode 100644 index 0000000..9450450 --- /dev/null +++ b/My Part 5/main/java/controller/duelmenu/DuelMenuRegexes.java @@ -0,0 +1,28 @@ +package controller.duelmenu; + +public enum DuelMenuRegexes { + SELECT_MONSTER_ZONE("^select --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_MAGIC_ZONE("^select --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN("^select --(?:monster|M) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN("^select --(?:spell|S) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_FIELD_ZONE("^select --(?:field|F)$"), + SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN("^select --(?:field|F) --(?:opponent|O)$"), + SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:field|F)$"), + SELECT_CARDS_IN_HAND("^select --(?:hand|H) ((?:-|)\\d+)$"), + CHEAT_DECREASE_OPPONENT_LIFE_POINT("^decrease --opponentLP ([0-9]+)$"), + CHEAT_INCREASE_LIFE_POINT("^increase --LP ([0-9]+)$"), + CHEAT_SET_WINNER("^duel set-winner (\\S+)$"), + ATTACK("^attack ([0-9]+)$"); + + private final String regex; + + DuelMenuRegexes(String message) { + this.regex = message; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 5/main/java/controller/duelmenu/MiniGameChoices.java b/My Part 5/main/java/controller/duelmenu/MiniGameChoices.java new file mode 100644 index 0000000..57881a4 --- /dev/null +++ b/My Part 5/main/java/controller/duelmenu/MiniGameChoices.java @@ -0,0 +1,17 @@ +package controller.duelmenu; + +public enum MiniGameChoices { + STONE("stone"), + PAPER("paper"), + SCISSOR("scissor"); + + private final String choice; + + MiniGameChoices(String choice) { + this.choice = choice; + } + + public String getChoice() { + return choice; + } +} diff --git a/My Part 5/main/java/controller/duelmenu/Phases.java b/My Part 5/main/java/controller/duelmenu/Phases.java new file mode 100644 index 0000000..14000bb --- /dev/null +++ b/My Part 5/main/java/controller/duelmenu/Phases.java @@ -0,0 +1,15 @@ +package controller.duelmenu; + +public enum Phases { + DRAW_PHASE, + STANDBY_PHASE, + MAIN_PHASE_1, + BATTLE_PHASE, + MAIN_PHASE_2, + END_PHASE; + private static Phases[] values = values(); + + public Phases next() { + return values[(this.ordinal() + 1) % values.length]; + } +} diff --git a/My Part 5/main/java/controller/importexportmenu/ImportExportMenuController.java b/My Part 5/main/java/controller/importexportmenu/ImportExportMenuController.java new file mode 100644 index 0000000..cde2f83 --- /dev/null +++ b/My Part 5/main/java/controller/importexportmenu/ImportExportMenuController.java @@ -0,0 +1,100 @@ +package controller.importexportmenu; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Utils; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.regex.Matcher; + +public class ImportExportMenuController { + public static ImportExportMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU; + else if (command.equals("menu show-current")) return ImportExportMenuMessages.SHOW_MENU; + else if (command.startsWith("import card")) return importCard(command); + else if (command.startsWith("export card")) return exportCard(command); + + return ImportExportMenuMessages.INVALID_COMMAND; + } + + private static ImportExportMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + return ImportExportMenuMessages.INVALID_NAVIGATION; + } + + private static ImportExportMenuMessages importCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.IMPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + try { + FileReader fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + MonsterCard monsterCard = gson.fromJson(fileReader, MonsterCard.class); + + if (Card.getCardByName(cardName) != null) return ImportExportMenuMessages.AVAILABLE_CARD; + if (monsterCard.getAttribute() == null) { +// so we understand that the card is a magic card + fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + MagicCard magicCard = gson.fromJson(fileReader, MagicCard.class); + Card.addCardToAllCards(magicCard); + if (isCardIncomplete(magicCard) || isMagicCardIncomplete(magicCard)) + return ImportExportMenuMessages.INVALID_FILE; + } else { +// so we understand that the card is a monster card + monsterCard.createEquippedByArrayList(); + Card.addCardToAllCards(monsterCard); + if (isCardIncomplete(monsterCard) || isMonsterCardIncomplete(monsterCard)) + return ImportExportMenuMessages.INVALID_FILE; + } + fileReader.close(); + } catch (IOException ignore) { + return ImportExportMenuMessages.UNAVAILABLE_FILE; + } + + + return ImportExportMenuMessages.EMPTY; + } + + private static boolean isCardIncomplete(Card card) { + return card.getName() == null || card.getDescription() == null || card.getCardType() == null; + } + + private static boolean isMonsterCardIncomplete(MonsterCard monsterCard) { + return monsterCard.getAttribute() == null || monsterCard.getMonsterType() == null; + } + + private static boolean isMagicCardIncomplete(MagicCard magicCard) { + return magicCard.getIcon() == null || magicCard.getStatus() == null; + } + + private static ImportExportMenuMessages exportCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.EXPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card card = Card.getCardByName(cardName); + if (card == null) return ImportExportMenuMessages.UNAVAILABLE_CARD; + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(card)); + fileWriter.close(); + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + + + return ImportExportMenuMessages.EMPTY; + } +} diff --git a/My Part 5/main/java/controller/importexportmenu/ImportExportMenuMessages.java b/My Part 5/main/java/controller/importexportmenu/ImportExportMenuMessages.java new file mode 100644 index 0000000..8f83021 --- /dev/null +++ b/My Part 5/main/java/controller/importexportmenu/ImportExportMenuMessages.java @@ -0,0 +1,23 @@ +package controller.importexportmenu; + +public enum ImportExportMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_IMPORT_EXPORT_MENU(""), + SHOW_MENU("Import/Export Menu\n"), + INVALID_COMMAND("invalid command\n"), + UNAVAILABLE_FILE("there isn't any file with your entered card name\n"), + INVALID_FILE("your card file is not valid to import\n"), + AVAILABLE_CARD("your entered card name is available\n"), + UNAVAILABLE_CARD("your entered card name is not available\n"), + EMPTY(""); + + private final String message; + + ImportExportMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 5/main/java/controller/importexportmenu/ImportExportMenuRegexes.java b/My Part 5/main/java/controller/importexportmenu/ImportExportMenuRegexes.java new file mode 100644 index 0000000..65c74dc --- /dev/null +++ b/My Part 5/main/java/controller/importexportmenu/ImportExportMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.importexportmenu; + +public enum ImportExportMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + IMPORT_CARD("^import card ([^\n]+)$"), + EXPORT_CARD("^export card ([^\n]+)$"); + + private final String regex; + + ImportExportMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 5/main/java/controller/loginmenu/LoginMenuController.java b/My Part 5/main/java/controller/loginmenu/LoginMenuController.java new file mode 100644 index 0000000..178d000 --- /dev/null +++ b/My Part 5/main/java/controller/loginmenu/LoginMenuController.java @@ -0,0 +1,120 @@ +package controller.loginmenu; + +import controller.Utils; +import model.Player; +import view.MainMenuView; + +import java.util.regex.Matcher; + +public class LoginMenuController { + public static LoginMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) System.exit(0); + else if (command.equals("menu show-current")) return LoginMenuMessages.SHOW_MENU; + else if (command.startsWith("user create")) { + return checkCreateUser(command); + } else if (command.startsWith("user login")) { + return checkLoginUser(command); + } + + return LoginMenuMessages.INVALID_COMMAND; + } + + private static LoginMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(LoginMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return LoginMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return LoginMenuMessages.INVALID_NAVIGATION; + } + + return LoginMenuMessages.FIRST_LOGIN; + } + + private static LoginMenuMessages checkCreateUser(String command) { + Matcher matcher; + String username, nickname, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIRST_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(2); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SECOND_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(3); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_THIRD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(1); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FOURTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIFTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(3); + password = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SIXTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (Player.getPlayerByUsername(username) != null) { + LoginMenuMessages.setUsername(username); + return LoginMenuMessages.USERNAME_EXISTS; + } + if (Player.isNicknameExist(nickname)) { + LoginMenuMessages.setNickname(nickname); + return LoginMenuMessages.NICKNAME_EXISTS; + } + +// TODO: handle to have "strong password" error + createUser(username, password, nickname); + return LoginMenuMessages.USER_CREATED; + } + + private static void createUser(String username, String password, String nickname) { + new Player(username, password, nickname); + } + + private static LoginMenuMessages checkLoginUser(String command) { + Matcher matcher; + String username, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (!Player.isPasswordCorrect(username, password)) { + return LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD; + } + + return LoginMenuMessages.USER_LOGGED_IN; + } + + public static void loginUser(String command) { + Matcher matcher; + String username = null; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + } + + + MainMenuView mainMenuView = new MainMenuView(Player.getPlayerByUsername(username)); + mainMenuView.mainMenuView(); + } +} diff --git a/My Part 5/main/java/controller/loginmenu/LoginMenuMessages.java b/My Part 5/main/java/controller/loginmenu/LoginMenuMessages.java new file mode 100644 index 0000000..167c111 --- /dev/null +++ b/My Part 5/main/java/controller/loginmenu/LoginMenuMessages.java @@ -0,0 +1,31 @@ +package controller.loginmenu; + +public enum LoginMenuMessages { + FIRST_LOGIN("please login first"), + INVALID_NAVIGATION("menu navigation is not possible"), + SHOW_MENU("Login Menu"), + USER_CREATED("user created successfully!"), + USERNAME_EXISTS("user with username already exists"), + NICKNAME_EXISTS("user with nickname already exists"), + USER_LOGGED_IN("user logged in successfully!"), + UNMATCHED_USERNAME_AND_PASSWORD("Username and password didn’t match!"), + INVALID_COMMAND("invalid command"); + + private String message; + + LoginMenuMessages(String message) { + this.message = message; + } + + public static void setUsername(String username) { + USERNAME_EXISTS.message = "user with username " + username + " already exists"; + } + + public static void setNickname(String nickname) { + NICKNAME_EXISTS.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 5/main/java/controller/loginmenu/LoginMenuRegexes.java b/My Part 5/main/java/controller/loginmenu/LoginMenuRegexes.java new file mode 100644 index 0000000..f518551 --- /dev/null +++ b/My Part 5/main/java/controller/loginmenu/LoginMenuRegexes.java @@ -0,0 +1,23 @@ +package controller.loginmenu; + +public enum LoginMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + CREATE_USER_FIRST_PATTERN("^user create --(?:username|U) (\\S+) --(?:nickname|N) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_SECOND_PATTERN("^user create --(?:username|U) (\\S+) --(?:password|P) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_THIRD_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_FOURTH_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"), + CREATE_USER_FIFTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:username|U) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_SIXTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:nickname|N) (\\S+) --(?:username|U) (\\S+)$"), + LOGIN_USER_USERNAME_PATTERN("^user login --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + LOGIN_USER_PASSWORD_PATTERN("^user login --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"); + + private final String regex; + + LoginMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 5/main/java/controller/mainmenu/MainMenuController.java b/My Part 5/main/java/controller/mainmenu/MainMenuController.java new file mode 100644 index 0000000..e6be9bd --- /dev/null +++ b/My Part 5/main/java/controller/mainmenu/MainMenuController.java @@ -0,0 +1,114 @@ +package controller.mainmenu; + +import controller.Utils; +import model.Player; +import view.*; + +import java.util.regex.Matcher; + +public class MainMenuController { + private final Player loggedInPlayer; + + public MainMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public MainMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return MainMenuMessages.EXIT_MAIN_MENU; + else if (command.equals("menu show-current")) return MainMenuMessages.SHOW_MENU; + else if (command.equals("user logout")) return MainMenuMessages.USER_LOGGED_OUT; + else if (command.startsWith("duel")) return enterDuelMenu(command); + + return MainMenuMessages.INVALID_COMMAND; + } + + private MainMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(MainMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return MainMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Main")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Duel")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Deck")) { + DeckMenuView deckMenuView = new DeckMenuView(loggedInPlayer); + deckMenuView.runDeckMenu(); + } else if (menu.equalsIgnoreCase("Scoreboard")) { + ScoreboardMenuView scoreboardMenuView = new ScoreboardMenuView(); + scoreboardMenuView.runScoreboard(); + } else if (menu.equalsIgnoreCase("Profile")) { + ProfileMenuView profileMenuView = new ProfileMenuView(loggedInPlayer); + profileMenuView.profileMenuView(); + } else if (menu.equalsIgnoreCase("Shop")) { + ShopMenuView shopMenuView = new ShopMenuView(loggedInPlayer); + shopMenuView.shopMenuView(); + } else if (menu.equalsIgnoreCase("ImportExport")) { + ImportExportMenuView importExportMenuView = new ImportExportMenuView(); + importExportMenuView.ImportExportMenuView(); + } + + return MainMenuMessages.EMPTY; + } + + private MainMenuMessages enterDuelMenu(String command) { +// TODO: clean and optimise this code according to AI + Matcher matcher; + String opponentPlayerCommand, rounds; + if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIRST_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_THIRD_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FOURTH_PATTERN.getRegex(), command) ).find()) { + opponentPlayerCommand = matcher.group(1); + rounds = matcher.group(2); + } else if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SECOND_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIFTH_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SIXTH_PATTERN.getRegex(), command) ).find()) { + rounds = matcher.group(1); + opponentPlayerCommand = matcher.group(2); + } else { + return MainMenuMessages.INVALID_COMMAND; + } + + if (opponentPlayerCommand.startsWith("second-player")) { + String opponentPlayerUsername = opponentPlayerCommand.substring(14); + Player opponentPlayer = Player.getPlayerByUsername(opponentPlayerUsername); + if (opponentPlayer == null) { + return MainMenuMessages.UNAVAILABLE_USERNAME; + } + + if (opponentPlayer.equals(loggedInPlayer)) return MainMenuMessages.SAME_USERNAME; + + if (loggedInPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(loggedInPlayer.getUsername()); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } else if (opponentPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(opponentPlayerUsername); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } + +// TODO: handle MainMenuMessages.INVALID_DECK message +// TODO: MainMenuMessages.setInvalidDeck(opponentPlayerUsername or loggedInPlayer.getUsername()); +// TODO: return MainMenuMessages.INVALID_DECK; + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + +// TODO: handle 1 or 3 turn game + DuelMenuView duelMenuView = new DuelMenuView(loggedInPlayer, opponentPlayer); + duelMenuView.duelMenuView(); + } else { +// TODO: handle entering to enter duel menu by AI + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + } + + return MainMenuMessages.EMPTY; + } +} diff --git a/My Part 5/main/java/controller/mainmenu/MainMenuMessages.java b/My Part 5/main/java/controller/mainmenu/MainMenuMessages.java new file mode 100644 index 0000000..85fa672 --- /dev/null +++ b/My Part 5/main/java/controller/mainmenu/MainMenuMessages.java @@ -0,0 +1,33 @@ +package controller.mainmenu; + +public enum MainMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_MAIN_MENU(""), + SHOW_MENU("Main Menu\n"), + USER_LOGGED_OUT("user logged out successfully!\n"), + UNAVAILABLE_USERNAME("there is no player with this username\n"), + SAME_USERNAME("please enter another username\n"), + UNAVAILABLE_ACTIVE_DECK(" has no active deck\n"), + INVALID_DECK("’s deck is invalid\n"), + INVALID_ROUNDS_NUMBER("number of rounds is not supported\n"), + INVALID_COMMAND("invalid command\n"), + EMPTY(""); + + private String message; + + MainMenuMessages(String message) { + this.message = message; + } + + public static void setUnavailableActiveDeck(String username) { + UNAVAILABLE_ACTIVE_DECK.message = username + " has no active deck\n"; + } + + public static void setInvalidDeck(String username) { + INVALID_DECK.message = username + "’s deck is invalid\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 5/main/java/controller/mainmenu/MainMenuRegexes.java b/My Part 5/main/java/controller/mainmenu/MainMenuRegexes.java new file mode 100644 index 0000000..210780f --- /dev/null +++ b/My Part 5/main/java/controller/mainmenu/MainMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.mainmenu; + +public enum MainMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + ENTER_DUEL_MENU_FIRST_PATTERN("^duel --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_SECOND_PATTERN("^duel --(?:new|N) --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_THIRD_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_FOURTH_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+) --(?:new|N)$"), + ENTER_DUEL_MENU_FIFTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_SIXTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N)$"); + + private final String regex; + + MainMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 5/main/java/controller/profilemenu/ProfileMenuController.java b/My Part 5/main/java/controller/profilemenu/ProfileMenuController.java new file mode 100644 index 0000000..5384e86 --- /dev/null +++ b/My Part 5/main/java/controller/profilemenu/ProfileMenuController.java @@ -0,0 +1,99 @@ +package controller.profilemenu; + +import controller.Database; +import controller.Utils; +import model.Player; + +import java.util.regex.Matcher; + +public class ProfileMenuController { + private final Player loggedInPlayer; + + public ProfileMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ProfileMenuMessages findCommand(String command) { + String[] split = command.split("\\s+"); + if (split.length < 2) { + return ProfileMenuMessages.INVALID_COMMAND; + } else if (split[1].equals("enter")) { + return ProfileMenuMessages.CANT_NAVIGATE_MENU; + } else if (split[1].equals("exit")) { + return ProfileMenuMessages.EXIT_MENU; + } else if (split[1].equals("show")) { + return ProfileMenuMessages.PROFILE_MENU; + } else if (split[2].equals("--nickname")) { + return changeNickname(command); + } else if (command.startsWith("profile change")) { + return changePassword(command); + } + + return ProfileMenuMessages.INVALID_COMMAND; + } + + public ProfileMenuMessages changeNickname(String command) { + Matcher matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_NICKNAME.getRegex(), command); + + ProfileMenuMessages holdEnum = checkChangeNickName(matcher); + + if (holdEnum == null) { + loggedInPlayer.setNickname(matcher.group(1)); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_NICKNAME_DONE; + } + return holdEnum; + } + + public ProfileMenuMessages checkChangeNickName(Matcher matcher) { + if (matcher.find()) { + String nickname = matcher.group(1); + if (Player.isNicknameExist(nickname)) { + ProfileMenuMessages.setNickname(nickname); + return ProfileMenuMessages.NOT_UNIQUE_NICKNAME; + } + return null; + } else return ProfileMenuMessages.INVALID_COMMAND; + + } + + public ProfileMenuMessages changePassword(String command) { + String currentPassword, newPassword; + Matcher matcher; + if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIRST_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SECOND_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_THIRD_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FOURTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIFTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SIXTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else return ProfileMenuMessages.INVALID_COMMAND; + + ProfileMenuMessages holdEnum = checkChangePassword(currentPassword, newPassword); + + if (holdEnum == null) { + loggedInPlayer.setPassword(newPassword); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_PASSWORD_DONE; + } + + return holdEnum; + } + + public ProfileMenuMessages checkChangePassword(String currentPassword, String newPassword) { + if (!loggedInPlayer.getPassword().equals(currentPassword)) return ProfileMenuMessages.WRONG_CURRENT_PASSWORD; + if (currentPassword.equals(newPassword)) return ProfileMenuMessages.SAME_PASSWORD; + return null; + } +} diff --git a/My Part 5/main/java/controller/profilemenu/ProfileMenuMessages.java b/My Part 5/main/java/controller/profilemenu/ProfileMenuMessages.java new file mode 100644 index 0000000..4c0895f --- /dev/null +++ b/My Part 5/main/java/controller/profilemenu/ProfileMenuMessages.java @@ -0,0 +1,27 @@ +package controller.profilemenu; + +public enum ProfileMenuMessages { + NOT_UNIQUE_NICKNAME("user with nickname already exists"), + CHANGE_NICKNAME_DONE("nickname changed successfully!"), + CHANGE_PASSWORD_DONE("password changed successfully!"), + WRONG_CURRENT_PASSWORD("current password is invalid"), + INVALID_COMMAND("invalid command"), + PROFILE_MENU("profile menu"), + EXIT_MENU("exit"), + CANT_NAVIGATE_MENU("menu navigation is not possible"), + SAME_PASSWORD("please enter a new password"); + + private String message; + + ProfileMenuMessages(String message) { + this.message = message; + } + + public static void setNickname(String nickname) { + ProfileMenuMessages.NOT_UNIQUE_NICKNAME.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 5/main/java/controller/profilemenu/ProfileMenuRegexes.java b/My Part 5/main/java/controller/profilemenu/ProfileMenuRegexes.java new file mode 100644 index 0000000..ba8630d --- /dev/null +++ b/My Part 5/main/java/controller/profilemenu/ProfileMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.profilemenu; + +public enum ProfileMenuRegexes { + CHANGE_NICKNAME("^profile change --nickname (\\S+)$"), + CHANGE_PASSWORD_FIRST_PATTERN("^profile change --(?:password|P) --(?:current|C) (\\S+) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_SECOND_PATTERN("^profile change --(?:password|P) --(?:new|N) (\\S+) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_THIRD_PATTERN("^profile change --(?:current|C) (\\S+) --(?:password|P) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_FOURTH_PATTERN("^profile change --(?:current|C) (\\S+) --(?:new|N) (\\S+) --(?:password$|P)"), + CHANGE_PASSWORD_FIFTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:password|P) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_SIXTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:current|C) (\\S+) --(?:password$|P)"); + + private final String regex; + + ProfileMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 5/main/java/controller/scoreboardmenu/Scoreboard.java b/My Part 5/main/java/controller/scoreboardmenu/Scoreboard.java new file mode 100644 index 0000000..cb725a7 --- /dev/null +++ b/My Part 5/main/java/controller/scoreboardmenu/Scoreboard.java @@ -0,0 +1,40 @@ +package controller.scoreboardmenu; + +import java.util.ArrayList; +import model.*; + +public class Scoreboard { + + private Scoreboard() { + } + + private static Scoreboard instance; + + public static Scoreboard getInstance() { + if (instance == null) + instance = new Scoreboard(); + return instance; + } + + public void showScoreboard() { + int counter = 1; + int index = 0; + long previousScore = -1; + StringBuilder output = new StringBuilder(); + ArrayList allUsers = Player.getAllPlayers(); + allUsers.sort(Player::compareTo); + for (Player player : allUsers) { + + + if (player.getScore() != previousScore) { + index += counter; + counter = 1; + } else counter++; + output.append(index).append(". ").append(player.getNickname()).append(": ").append(player.getScore()).append("\n"); + previousScore = player.getScore(); + + } + ScoreboardOutput.getInstance().showMessage(output.toString()); + } + +} diff --git a/My Part 5/main/java/controller/scoreboardmenu/ScoreboardOutput.java b/My Part 5/main/java/controller/scoreboardmenu/ScoreboardOutput.java new file mode 100644 index 0000000..c77252d --- /dev/null +++ b/My Part 5/main/java/controller/scoreboardmenu/ScoreboardOutput.java @@ -0,0 +1,23 @@ +package controller.scoreboardmenu; + +public class ScoreboardOutput { + + private ScoreboardOutput() { + } + + private static ScoreboardOutput instance; + + public static ScoreboardOutput getInstance() { + if (instance == null) + instance = new ScoreboardOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My Part 5/main/java/controller/shopmenu/ShopMenuController.java b/My Part 5/main/java/controller/shopmenu/ShopMenuController.java new file mode 100644 index 0000000..11dc61c --- /dev/null +++ b/My Part 5/main/java/controller/shopmenu/ShopMenuController.java @@ -0,0 +1,63 @@ +package controller.shopmenu; + +import controller.Database; +import controller.Utils; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.DuelMenuRegexes; +import model.Player; +import model.cards.Card; + +import java.util.regex.Matcher; + +public class ShopMenuController { + private final Player loggedInPlayer; + + public ShopMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ShopMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ShopMenuMessages.EXIT_SHOP_MENU; + else if (command.equals("menu show-current")) return ShopMenuMessages.SHOW_MENU; + else if (command.startsWith("shop buy")) return buyACard(command); + else if (command.equals("shop show --all")) return ShopMenuMessages.SHOW_ALL_CARDS; + else if (command.startsWith("increase ")) return cheatCodeIncreaseMoney(command); + + return ShopMenuMessages.INVALID_COMMAND; + } + + private ShopMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + return ShopMenuMessages.INVALID_NAVIGATION; + } + + private ShopMenuMessages buyACard(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.BUY_CARD.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card boughtCard = Card.getCardByName(cardName); + if (boughtCard == null) return ShopMenuMessages.UNAVAILABLE_CARD; + + int boughtCardPrice = boughtCard.getPrice(); + if (boughtCardPrice > loggedInPlayer.getMoney()) return ShopMenuMessages.NOT_ENOUGH_MONEY; + + loggedInPlayer.decreaseMoney(boughtCardPrice); + loggedInPlayer.addCardToBoughtCards(boughtCard); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ShopMenuMessages.EMPTY; + } + + private ShopMenuMessages cheatCodeIncreaseMoney(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.CHEAT_INCREASE_MONEY.getRegex(), command); + if (matcher.find()) { + loggedInPlayer.increaseMoney(Integer.parseInt(matcher.group(1))); + return ShopMenuMessages.EMPTY; + } else return ShopMenuMessages.INVALID_COMMAND; + + } +} diff --git a/My Part 5/main/java/controller/shopmenu/ShopMenuMessages.java b/My Part 5/main/java/controller/shopmenu/ShopMenuMessages.java new file mode 100644 index 0000000..339bd0a --- /dev/null +++ b/My Part 5/main/java/controller/shopmenu/ShopMenuMessages.java @@ -0,0 +1,22 @@ +package controller.shopmenu; + +public enum ShopMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_SHOP_MENU(""), + SHOW_MENU("Shop Menu\n"), + UNAVAILABLE_CARD("there is no card with this name\n"), + NOT_ENOUGH_MONEY("not enough money\n"), + EMPTY(""), + SHOW_ALL_CARDS(""), + INVALID_COMMAND("invalid command\n"); + + private final String message; + + ShopMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My Part 5/main/java/controller/shopmenu/ShopMenuRegexes.java b/My Part 5/main/java/controller/shopmenu/ShopMenuRegexes.java new file mode 100644 index 0000000..0f4dd79 --- /dev/null +++ b/My Part 5/main/java/controller/shopmenu/ShopMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.shopmenu; + +public enum ShopMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + BUY_CARD("^shop buy ([^\n]+)$"), + CHEAT_INCREASE_MONEY("^increase --money ([0-9]+)$"); + + private final String regex; + + ShopMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 5/main/java/model/Board.java b/My Part 5/main/java/model/Board.java new file mode 100644 index 0000000..e083cda --- /dev/null +++ b/My Part 5/main/java/model/Board.java @@ -0,0 +1,211 @@ +package model; + +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Board { + private MonsterCard[] monstersZone; + private MagicCard[] magicsZone; + private ArrayList graveyard; + private ArrayList cardsInHand; + private Deck deck; + private MagicCard fieldZone;//TODO: maybe it should be from these classes --> Spell / fieldSpell + private Card selectedCard; +// if this boolean equals "false" so we can conclude that opponent card selected or nothing selected + private boolean isMyCardSelected; + private boolean isACardInHandSelected; + + { + monstersZone = new MonsterCard[6]; + magicsZone = new MagicCard[6]; + graveyard = new ArrayList<>(); + cardsInHand = new ArrayList<>(); + fieldZone = null; + isMyCardSelected = false; + isACardInHandSelected = false; + } + + public void setDeck(Deck deck) { + this.deck = deck;//TODO: maybe we should have a copy of deck in duel menu --> if all changes don't apply in main deck + } + + public MonsterCard[] getMonstersZone() { + return monstersZone; + } + + public MagicCard[] getMagicsZone() { + return magicsZone; + } + + public ArrayList getGraveyard() { + return graveyard; + } + + public ArrayList getCardsInHand() { + return cardsInHand; + } + + public MagicCard getFieldZone() { + return fieldZone; + } + + public Card getSelectedCard() { + return selectedCard; + } + + public Deck getDeck() { + return deck; + } + + public void setSelectedCard(Card selectedCard) { + this.selectedCard = selectedCard; + } + + public void setFieldZone(MagicCard fieldZone) { this.fieldZone = fieldZone; } + + public boolean isMyCardSelected() { + return isMyCardSelected; + } + + public void setMyCardSelected(boolean myCardSelected) { + isMyCardSelected = myCardSelected; + } + + public boolean isACardInHandSelected() { + return isACardInHandSelected; + } + + public void setACardInHandSelected(boolean ACardInHandSelected) { + isACardInHandSelected = ACardInHandSelected; + } + + public boolean isMagicsZoneFull() { + return getNumberOfFullPartsOfMagicsZone() == 5; + } + + public boolean isMonsterZoneFull() { + return getNumberOfFullPartsOfMonstersZone() == 5; + } + + public boolean isMagicsZoneEmpty() { + return getNumberOfFullPartsOfMagicsZone() == 0; + } + + public int getNumberOfFullPartsOfMagicsZone() { + int numberOfFullPartsOfMagicsZone = 0; + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) ++numberOfFullPartsOfMagicsZone; + } + return numberOfFullPartsOfMagicsZone; + } + + public int getNumberOfFullPartsOfMonstersZone() { + int getNumberOfFullPartsOfMonstersZone = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null) ++getNumberOfFullPartsOfMonstersZone; + } + return getNumberOfFullPartsOfMonstersZone; + } + + public boolean isCardFaceUp(String cardName) { +// if cardName isn't available, then this method returns false + boolean isCardFaceUp = false; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = monstersZone[i].getCardFaceUp(); + } + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = magicsZone[i].getCardFaceUp(); + } + return isCardFaceUp; + } + + public void addSpellCardToFieldZone(MagicCard spellCard) { + MagicCard previousFieldZone = fieldZone; + if (previousFieldZone != null) graveyard.add(previousFieldZone); + setFieldZone(spellCard); + cardsInHand.remove(spellCard); + } + + public boolean addMagicCardToMagicsZone(MagicCard magicCard) { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] == null) { + magicsZone[i] = magicCard; + cardsInHand.remove(magicCard); + return true; + } + } + return false; + } + + public boolean addMonsterCardToMonsterZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] == null) { + monstersZone[i] = monsterCard; + cardsInHand.remove(monsterCard); + return true; + } + } + return false; + } + + public boolean isCardAvailableInMonstersZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monsterCard)) return true; + } + return false; + } + + public int getNumberOfFaceUpMonsterCards() { + int numberOfFaceUpMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getCardFaceUp()) ++numberOfFaceUpMonsterCards; + } + + return numberOfFaceUpMonsterCards; + } + + public int getNumberOfWarriorMonsterCards() { + int numberOfWarriorMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getMonsterType().equals("Warrior")) ++numberOfWarriorMonsterCards; + } + + return numberOfWarriorMonsterCards; + } + + public boolean isThereCardInAddress(MonsterCard[] monsterZone, int address) { + if (monsterZone[address] != null) return true; + return false; + } + + public boolean isThereOneMonsterForTribute(MonsterCard[] monsterZone) { + for (Card card : monsterZone) { + if (card != null) return true; + } + return false; + } + + public boolean isThereTwoMonsterForTribute(MonsterCard[] monstersZone) { + int counter = 0; + for (Card card : monstersZone) { + if (card != null) counter++; + } + if (counter < 2) { + return false; + } + return true; + } + + + public void drawCard() { + Card card = deck.getNumberOfCardsInDeck(deck.getNumberOfCardsInDeck() - 1); + cardsInHand.add(card); + deck.remove(deck.size() - 1); + System.out.println("new card added to the hand: " + card.getName()); + } + + +} diff --git a/My Part 5/main/java/model/Deck.java b/My Part 5/main/java/model/Deck.java new file mode 100644 index 0000000..217f43b --- /dev/null +++ b/My Part 5/main/java/model/Deck.java @@ -0,0 +1,195 @@ +package model; + +import controller.deckmenu.DeckMenuDatabase; +import model.*; +import controller.deckmenu.*; +import model.cards.Card; + +import java.util.ArrayList; + +public class Deck { + public ArrayList mainCards = new ArrayList<>(); + public ArrayList sideCards = new ArrayList<>(); + Player owner; + String name; + DeckType type; + Boolean isActive = false; + Boolean IsValid; + + public Deck(String name, Player owner, boolean hasSideDeck, boolean shouldBeSaved) { + this.name = name; + if (shouldBeSaved) + DeckMenuDatabase.allDecks.add(this); + if (!hasSideDeck) + sideCards = null; + this.owner = owner; + } + + public Deck(String name, Player owner) { + this.name = name; + sideCards = null; + this.owner = owner; + } + + public Deck(String name) { + this.name = name; + sideCards = null; + } + public Deck() { + sideCards = null; + } + + public void updateOwnerDecks() { + String deckType = (name.length() > 16) ? name.substring(name.length() - 16) : ""; + if (deckType.equals(".purchased-cards")) + owner.setAllPlayerCard(this); + else { + owner.getAllDeck().add(this); + if (this.isActive) + owner.setActiveDeck(this); + } + } + + public ArrayList getMainCards() { + if (mainCards == null) + return (mainCards = new ArrayList<>()); + return mainCards; + } + + public void setMainCards(ArrayList mainCards) { + this.mainCards = mainCards; + } + + public ArrayList getSideCards() { + return sideCards; + } + + public void setSideCards(ArrayList sideCards) { + this.sideCards = sideCards; + } + + public Player getOwner() { + return owner; + } + + public void setOwner(Player owner) { + this.owner = owner; + } + + public void setActive(Boolean active) { + isActive = active; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setActivation(Boolean active) { + isActive = active; + } + + public void setValid(Boolean valid) { + IsValid = valid; + } + + public void setType(DeckType type) { + this.type = type; + } + + public void addCard(Card card, boolean shouldBeAddedToMain) { + if (shouldBeAddedToMain) + mainCards.add(card); + else + sideCards.add(card); + if (card != null) + card.setCurrentDeck(this); + } + + public void addCard(Card card) { + mainCards.add(card); + if (card != null && !name.equals("selected collected deck")) + card.setCurrentDeck(this); + } + + public void moveCardTo(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCard(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public void moveCardToForGame(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCardForGame(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public boolean hasCard(Card card, boolean isMain) { + if (isMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) + return true; + + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + return true; + } + return false; + } + + public void removeCard(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) { + mainCards.remove(cardInMain); + return; + } + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + sideCards.remove(cardInSide); + return; + } + } + + public void removeCardForGame(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) + mainCards.remove(card); + else + sideCards.remove(card); + } + + public int getNumberOfCardsInDeck(Card card) { + int count = 0; + for (Card cardInDeck : mainCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + for (Card cardInDeck : sideCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + return count; + } + + public int getNumberOfCardsInMainDeck() { + return mainCards.size(); + } + + public int getNumberOfCardsInSideDeck() { + return sideCards.size(); + } + + public void updateCurrentDeck() { + if (mainCards != null) + for (Card card : mainCards) + if (card != null) + card.setCurrentDeck(this); + if (sideCards != null) + for (Card card : sideCards) + if (card != null) + card.setCurrentDeck(this); + } +} \ No newline at end of file diff --git a/My Part 5/main/java/model/DeckType.java b/My Part 5/main/java/model/DeckType.java new file mode 100644 index 0000000..2d1643c --- /dev/null +++ b/My Part 5/main/java/model/DeckType.java @@ -0,0 +1,8 @@ +package model; + +public enum DeckType { + regulardeck, + inactivedeck, + graveyarddeck, + selectedcarddeck +} diff --git a/My Part 5/main/java/model/Player.java b/My Part 5/main/java/model/Player.java new file mode 100644 index 0000000..28c2187 --- /dev/null +++ b/My Part 5/main/java/model/Player.java @@ -0,0 +1,289 @@ +package model; + +import com.google.gson.annotations.Expose; +import controller.Database; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Player { + private static ArrayList allPlayers; + + static { + allPlayers = new ArrayList<>(); + } + + @Expose + private ArrayList boughtCards; + @Expose + private ArrayList allMainDecks; + private Board board; + @Expose + private Deck sideDeck; + @Expose + private Deck activatedDeck; + @Expose + private String username; + @Expose + private String password; + @Expose + private String nickname; + @Expose + private long score; + @Expose + private long money; + private int lifePoint; + private transient Deck allPlayerCard; + private transient ArrayList allDeck = new ArrayList<>(); + private transient ArrayList gameDecks = new ArrayList<>(); + + { + boughtCards = new ArrayList<>(); + allMainDecks = new ArrayList<>(); + board = null; + sideDeck = new Deck(); + activatedDeck = null; + score = 0; + money = 100000; + lifePoint = 8000; + } + + public Player(String username, String password, String nickname) { + setUsername(username); + setPassword(password); + setNickname(nickname); + addPlayerToAllPlayers(this); + allPlayers.add(this); + Database.updatePlayerInformationInDatabase(this); + } + + public static Boolean isNicknameExist(String nickname) { + for (Player player : allPlayers) { + if (player.nickname.equals(nickname)) return true; + } + return false; + } + + public static Boolean isPasswordCorrect(String username, String password) { + Player player = getPlayerByUsername(username); + if (player == null) return false; + + return player.password.equals(password); + } + + public static Player getPlayerByUsername(String username) { + for (Player player : allPlayers) { + if (player.username.equals(username)) return player; + } + return null; + } + + public void setBoughtCards(ArrayList boughtCards) { + this.boughtCards = boughtCards; + } + + public Deck getActiveDeck() { + return activatedDeck; + } + + public void setActiveDeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public ArrayList getAllDeck() { + if (allDeck == null) + return (allDeck = new ArrayList<>()); + return allDeck; + } + + public void setAllDeck(ArrayList allDeck) { + this.allDeck = allDeck; + } + + public Deck getAllPlayerCard() { + return allPlayerCard; + } + + public static ArrayList getAllPlayers() { + return allPlayers; + } + + public void addCardToAllPlayerCard(Card card) { + this.allPlayerCard.getMainCards().add(card); + } + + public void setAllPlayerCard(Deck allPlayerCard) { + this.allPlayerCard = allPlayerCard; + } + + public static void addPlayerToAllPlayers(Player player) { + allPlayers.add(player); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public long getScore() { + return score; + } + + public long getMoney() { + return money; + } + + public Deck getActivatedDeck() { + return activatedDeck; + } + + public ArrayList getBoughtCards() { + return boughtCards; + } + + public void increaseScore(long score) { + this.score += score; + } + + public void decreaseScore(long score) { + this.score -= score; + } + + public void increaseMoney(long money) { + this.money += money; + } + + public void decreaseMoney(long money) { + this.money -= money; + } + + public void addCardToBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.add(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.add(new MagicCard((MagicCard) card)); + } + } + + public void addMainDeck(String deckName) { + Deck mainDeck = new Deck(deckName); + this.allMainDecks.add(mainDeck); + } + + public Boolean isMainDeckExist(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return true; + } + return false; + } + + public void deleteMainDeck(String deckName) { + Deck mainDeck = getDeckByName(deckName); + if (mainDeck != null) { + boughtCards.addAll(mainDeck.getMainCards()); + allMainDecks.remove(mainDeck); + } + } + + public Deck getDeckByName(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return deck; + } + return null; + } + + public int compareTo(Player player) { + if (this.score > player.score) + return -1; + if (this.score < player.score) + return 1; + if (this.nickname.compareTo(player.getNickname()) > 0) + return -1; + if (this.nickname.compareTo(player.getNickname()) < 0) + return 1; + return 0; + } + + public void activateADeck(String deckName) { + Deck deck = getDeckByName(deckName); + if (deck != null) activatedDeck = deck; + } + public void activateADeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public void addCardToMainDeck() { +// TODO: ???? but remember to remove this card from boughtCards :) + } + + public void removeACard() { +// TODO: ???? but remember to add this card from boughtCards :) + } + + public void decreaseLifePoint(int amount) { + this.lifePoint -= amount; + } + + public void increaseLifePoint(int amount) { + this.lifePoint += amount; + } + + public void setLifePoint(int lifePoint) { + this.lifePoint = lifePoint; + } + + public int getLifePoint() { + return lifePoint; + } + + public void createBoard() { + board = new Board(); + } + + public Board getBoard() { + return board; + } + + public boolean hasCard(Card card){ + for (Card boughtCard : boughtCards) { + if (card.getName().equals(boughtCard.getName())) + return true; + } + return false; + } + + public void removeCardFromBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.remove(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.remove(new MagicCard((MagicCard) card)); + } + } +} \ No newline at end of file diff --git a/My Part 5/main/java/model/cards/Card.java b/My Part 5/main/java/model/cards/Card.java new file mode 100644 index 0000000..9ebd536 --- /dev/null +++ b/My Part 5/main/java/model/cards/Card.java @@ -0,0 +1,115 @@ +package model.cards; + +import com.google.gson.annotations.Expose; +import model.Deck; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.TreeMap; + +public class Card { + protected static HashMap allCards; + + static { + allCards = new HashMap<>(); + } + + @Expose + protected final String name; + protected final String description; + protected final CardTypes cardType; + protected final int price; +// if this boolean equals "false" so we can conclude that card is "face down" + protected transient boolean isCardFaceUp; + protected transient boolean isPowerUsed; + protected transient Deck currentDeck; + + { + isCardFaceUp = false; + isPowerUsed = false; + } + + public Card(String name, String description, CardTypes cardType, int price) { + this.name = name; + this.description = description; + this.cardType = cardType; + this.price = price; + } + + public static Card getCardByName(String name) { + return allCards.get(name); + } + + public static TreeMap getListOfCards() { + TreeMap listOfCards = new TreeMap<>(); + for (String cardName : allCards.keySet()) { + Integer cardPrice = allCards.get(cardName).getPrice(); + listOfCards.put(cardName, cardPrice); + } + return listOfCards; + } + + public static boolean isMonsterCard(Card card) { + try { + MonsterCard monsterCard = (MonsterCard) card; + return true; + } catch (Exception exception) { + return false; + } + } + + public static int findNumberOfMonsterCards(ArrayList cards) { + int numberOfMonsterCards = 0; + for (Card card : cards) { + if (Card.isMonsterCard(card)) ++numberOfMonsterCards; + } + return numberOfMonsterCards; + } + + public static void addCardToAllCards(Card card) { + allCards.put(card.getName(), card); + } + + public static HashMap getAllCards() { + return allCards; + } + + public String getName() { + return name; + } + + public void setCurrentDeck(Deck currentDeck) { this.currentDeck = currentDeck; } + + public Deck getCurrentDeck() { + return currentDeck; + } + + public CardTypes getCardType() { + return cardType; + } + + public int getPrice() { + return price; + } + + public void setPowerUsed(boolean powerUsed) { + isPowerUsed = powerUsed; + } + + public boolean isPowerUsed() { + return isPowerUsed; + } + + public String getDescription() { + return description; + } + + public Boolean getCardFaceUp() { + return isCardFaceUp; + } + + public void setCardFaceUp(Boolean cardFaceUp) { + isCardFaceUp = cardFaceUp; + } +} diff --git a/My Part 5/main/java/model/cards/CardTypes.java b/My Part 5/main/java/model/cards/CardTypes.java new file mode 100644 index 0000000..520056f --- /dev/null +++ b/My Part 5/main/java/model/cards/CardTypes.java @@ -0,0 +1,26 @@ +package model.cards; + +import com.google.gson.annotations.SerializedName; + +public enum CardTypes { + @SerializedName("Normal") + NORMAL("Normal"), + @SerializedName("Effect") + EFFECT("Effect"), + @SerializedName("Ritual") + RITUAL("Ritual"), + @SerializedName("Spell") + SPELL("Spell"), + @SerializedName("Trap") + TRAP("Trap"); + + private final String regex; + + CardTypes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 5/main/java/model/cards/magiccard/MagicCard.java b/My Part 5/main/java/model/cards/magiccard/MagicCard.java new file mode 100644 index 0000000..396faf8 --- /dev/null +++ b/My Part 5/main/java/model/cards/magiccard/MagicCard.java @@ -0,0 +1,39 @@ +package model.cards.magiccard; + +import model.cards.Card; +import model.cards.CardTypes; + +public class MagicCard extends Card { + protected final String icon; + protected final MagicCardStatuses status; + + public MagicCard(String name, CardTypes cardType, String icon, String description, MagicCardStatuses status, int price) { + super(name, description, cardType, price); + this.icon = icon; + this.status = status; + allCards.put(name, this); + } + + public MagicCard(MagicCard magicCard) { + super(magicCard.name, magicCard.description, magicCard.cardType, magicCard.price); + this.icon = magicCard.icon; + this.status = magicCard.status; + } + + public String getIcon() { + return icon; + } + + public MagicCardStatuses getStatus() { + return status; + } + + public void print() { +// TODO: handle it --> «this.equals(null)» have error and «System.out.print» should be in the view +// if (this.equals(null)) +// System.out.print("E "); +// else if (isCardFaceUp) +// System.out.print("O "); +// else System.out.print("H "); + } +} diff --git a/My Part 5/main/java/model/cards/magiccard/MagicCardStatuses.java b/My Part 5/main/java/model/cards/magiccard/MagicCardStatuses.java new file mode 100644 index 0000000..a2540c9 --- /dev/null +++ b/My Part 5/main/java/model/cards/magiccard/MagicCardStatuses.java @@ -0,0 +1,20 @@ +package model.cards.magiccard; + +import com.google.gson.annotations.SerializedName; + +public enum MagicCardStatuses { + @SerializedName("Limited") + LIMITED("Limited"), + @SerializedName("Unlimited") + UNLIMITED("Unlimited"); + + private final String regex; + + MagicCardStatuses(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My Part 5/main/java/model/cards/monstercard/MonsterCard.java b/My Part 5/main/java/model/cards/monstercard/MonsterCard.java new file mode 100644 index 0000000..d72dedd --- /dev/null +++ b/My Part 5/main/java/model/cards/monstercard/MonsterCard.java @@ -0,0 +1,139 @@ +package model.cards.monstercard; + +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; + +import java.util.ArrayList; + +public class MonsterCard extends Card implements SpecialMonstersFunction { + protected final short level; + protected final MonsterCardAttributes attribute; + protected final String monsterType; + protected int attackPoints; + protected int defensePoints; + protected transient ArrayList equippedBy; +// if this boolean equals "false" so we can conclude that card is in attack position + protected transient boolean isDefensePosition; + protected transient boolean isAttacked = false; + + { + equippedBy = new ArrayList<>(); + isDefensePosition = false; + } + + public MonsterCard(String name, short level, MonsterCardAttributes attribute, String monsterType, CardTypes cardType, + int attackPoints, int defensePoints, String description, int price) { + super(name, description, cardType, price); + this.level = level; + this.attribute = attribute; + this.monsterType = monsterType; + setAttackPoints(attackPoints); + setDefensePoints(defensePoints); + allCards.put(name, this); + } + + public MonsterCard(MonsterCard monsterCard) { + super(monsterCard.name, monsterCard.description, monsterCard.cardType, monsterCard.price); + this.level = monsterCard.level; + this.attribute = monsterCard.attribute; + this.monsterType = monsterCard.monsterType; + this.attackPoints = monsterCard.attackPoints; + this.defensePoints = monsterCard.defensePoints; + } + + public short getLevel() { + return level; + } + + public MonsterCardAttributes getAttribute() { + return attribute; + } + + public String getMonsterType() { + return monsterType; + } + + public int getAttackPoints() { + return attackPoints; + } + + public void setAttackPoints(int attackPoints) { + this.attackPoints = attackPoints; + } + + public int getDefensePoints() { + return defensePoints; + } + + public void setDefensePoints(int defensePoints) { + this.defensePoints = defensePoints; + } + + public boolean isAttacked() { + return isAttacked; + } + + public void setAttacked(boolean attacked) { + isAttacked = attacked; + } + + public boolean isDefensePosition() { + return isDefensePosition; + } + + public void setDefensePosition(boolean defensePosition) { + isDefensePosition = defensePosition; + } + + public ArrayList getEquippedBy() { + return equippedBy; + } + + public void addToEquippedBy(MagicCard equippedBy) { + this.equippedBy.add(equippedBy); + } + + public void increaseAttackPoints(int amount) { + attackPoints += amount; + } + + public void decreaseAttackPoints(int amount) { + attackPoints -= amount; + } + + public void increaseDefencePoints(int amount) { + defensePoints += amount; + } + + public void decreaseDefencePoints(int amount) { + defensePoints -= amount; + } + + public void createEquippedByArrayList() { + equippedBy = new ArrayList<>(); + } + + public void settoDO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoDH(MonsterCard selectedMonster) { + this.setCardFaceUp(!isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoOO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = false; + } + + @Override + public String toString() { + if (!this.getCardFaceUp() && this.isDefensePosition) return "DH"; + else if (this.getCardFaceUp() && this.isDefensePosition) return "DO"; + else if (this.getCardFaceUp() && !this.isDefensePosition) return "OO"; + return "E "; + } +} diff --git a/My Part 5/main/java/model/cards/monstercard/MonsterCardAttributes.java b/My Part 5/main/java/model/cards/monstercard/MonsterCardAttributes.java new file mode 100644 index 0000000..4677550 --- /dev/null +++ b/My Part 5/main/java/model/cards/monstercard/MonsterCardAttributes.java @@ -0,0 +1,10 @@ +package model.cards.monstercard; + +public enum MonsterCardAttributes { + DARK, + EARTH, + FIRE, + LIGHT, + WATER, + WIND; +} diff --git a/My Part 5/main/java/model/cards/monstercard/SpecialMonstersFunction.java b/My Part 5/main/java/model/cards/monstercard/SpecialMonstersFunction.java new file mode 100644 index 0000000..0b73141 --- /dev/null +++ b/My Part 5/main/java/model/cards/monstercard/SpecialMonstersFunction.java @@ -0,0 +1,157 @@ +package model.cards.monstercard; + +import controller.duelmenu.DuelMenuMessages; +import model.Board; +import model.Player; + +public interface SpecialMonstersFunction { + default DuelMenuMessages attack(Player attackingPlayer, Player opponentPlayer, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + MonsterCard attackingCard = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentCard = opponentPlayerBoard.getMonstersZone()[numberToAttack]; + + if (opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack) != null) { + + switch (opponentCard.toString()) { + case "OO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayer.decreaseLifePoint(attackingCard.attackPoints - opponentCard.attackPoints); + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + DuelMenuMessages.setOpponentGotDamageInAttack(attackingCard.attackPoints - opponentCard.attackPoints); + return DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setAttackingPlayerCardDestroyed(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED; + } + + case "DO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + return DuelMenuMessages.DEFENSE_POSITION_MONSTER_DESTROYED; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + return DuelMenuMessages.NO_CARD_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setReceiveDamageByAttackingToDefenseCard(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD; + } + case "DH": + break; + } + + return null; + + } else + return opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + + default DuelMenuMessages defense(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + switch (opponentCard.getName()) { + case "Command knight": + commandKnightFunction(opponentPlayerBoard); + break; + case "Yomi Ship": + return yomiShipFunction(attackingPlayerBoard, attackingCard, opponentCard); + case "Suijin": + return suijinFunction(attackingCard); + case "Marshmallon": + return marshmallonFunction(attackingPlayer); + case "Texchanger": + return texchangerFunction(opponentCard); + case "Exploder Dragon": + return exploderDragon(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + return null; + } + + default DuelMenuMessages texchangerFunction(MonsterCard opponentCard) { + if (!opponentCard.isPowerUsed()) { + opponentCard.setPowerUsed(true); + // choosing a card ehzar??????? + return DuelMenuMessages.ATTACK_CANCELED; + } + return null; + } + + default DuelMenuMessages commandKnightFunction(Board opponentPlayerBoard) { + for (int i = 1; i <= 5; i++) { + if (opponentPlayerBoard.getMonstersZone()[i] != null && !opponentPlayerBoard.getMonstersZone()[i].getName().equals("Command knight")) { + return DuelMenuMessages.YOU_CANT_ATTACK_TO_THIS_CARD; + } + } + return null; + } + + default DuelMenuMessages yomiShipFunction(Board attackingPlayerBoard, MonsterCard attackingCard, MonsterCard opponentCard) { + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + return null; + } + + default DuelMenuMessages suijinFunction(MonsterCard attackingCard) { +// attackingCard.setAttackLevel(0);//TODO: undo it!! + return null; + } + + default DuelMenuMessages marshmallonFunction(Player attackingPlayer) { + attackingPlayer.decreaseLifePoint(1000); + return null; + } + + default DuelMenuMessages exploderDragon(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int number) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + return null; + } + + default void deleteMonsterFromZone(MonsterCard monster, MonsterCard[] monstersZone) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monster)) { + monstersZone[i] = null; + break; + } + } + } +} diff --git a/My Part 5/main/java/view/DeckMenuView.java b/My Part 5/main/java/view/DeckMenuView.java new file mode 100644 index 0000000..5341692 --- /dev/null +++ b/My Part 5/main/java/view/DeckMenuView.java @@ -0,0 +1,137 @@ +package view; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import controller.Utils; +import controller.deckmenu.DeckMenuController; +import controller.deckmenu.DeckMenuOutput; +import model.*; + +public class DeckMenuView { + public static Scanner scanner = Utils.getScanner(); + + private final Player loggedInPlayer; + + public DeckMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + private final String[] deckMenuRegexes = { + "^deck create (?\\w+)$", + "^deck delete (?\\w+)$", + "^deck set-activate (?\\w+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck add-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck show (?:--all|-a)$", + "^deck show (?:--deck-name|-d) (?.+) (?:--side|-s)$", + "^deck show (?:--side|-s) (?:--deck-name|-d) (?.+)$", + "^deck show (?:--deck-name|-d) (?.+)$", + "^menu show-current$", + "^menu exit$" + }; + + public void runDeckMenu() { + Matcher commandMatcher; + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + int whichCommand; + for (whichCommand = 0; whichCommand < deckMenuRegexes.length; whichCommand++) { + commandMatcher = findMatcher(command, deckMenuRegexes[whichCommand]); + if (commandMatcher.find()) { + executeDeckMenuCommands(commandMatcher, whichCommand); + break; + } else if (whichCommand == deckMenuRegexes.length - 1) + DeckMenuOutput.getInstance().showMessage("invalid command"); + } + + } + } + + private void executeDeckMenuCommands(Matcher commandMatcher, int whichCommand) { + DeckMenuController controller = DeckMenuController.getInstance(); + switch (whichCommand) { + case 0: + controller.createDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 1: + controller.deleteDeck(commandMatcher.group("name")); + break; + case 2: + controller.setActiveDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + String cardName = commandMatcher.group("cardName"), + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, false); + break; + case 9: + case 10: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, true); + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, false); + break; + case 17: + case 18: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, true); + break; + case 19: + controller.showAllDecks(loggedInPlayer); + break; + case 20: + case 21: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, false); + break; + case 22: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, true); + break; + case 23: + DeckMenuOutput.getInstance().showMessage("Deck Menu"); + break; + case 24: + MainMenuView mainMenuView = new MainMenuView(loggedInPlayer); + mainMenuView.mainMenuView(); + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } + + +} diff --git a/My Part 5/main/java/view/DuelMenuView.java b/My Part 5/main/java/view/DuelMenuView.java new file mode 100644 index 0000000..24661b5 --- /dev/null +++ b/My Part 5/main/java/view/DuelMenuView.java @@ -0,0 +1,140 @@ +package view; + +import controller.Utils; +import controller.duelmenu.DuelMenuController; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.Phases; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +public class DuelMenuView { + private Player firstPlayer; + private Player secondPlayer; + private Phases phase; + + public DuelMenuView(Player firstPlayer, Player secondPlayer) { + this.firstPlayer = firstPlayer; + this.secondPlayer = secondPlayer; + } + + public static String findChooseOfPlayerInMiniGame(Player player) { + System.out.println(player.getUsername() + ", please choose between stone, paper and scissor:"); + return Utils.getScanner().nextLine().trim(); + } + + public static void showGraveyard(Board board) { + if (board.getGraveyard().size() != 0) { + for (int i = 1; i <= board.getGraveyard().size(); i++) { + printCard(i , board.getGraveyard().get(i)); + } + } else System.out.println("graveyard empty"); + while (true) { + String input = Utils.getScanner().nextLine(); + if (input.equals("back")) + break; + } + } + + public static void printCard(int number, Card card) { + System.out.println(number + ". " + card.getName() + ": " + card.getDescription()); + } + + private static void showBoard(Board playerBoard, Board opponentBoard) { + showCardsInHand(opponentBoard); +// showLeftCardDeck(opponentBoard);//?????????????????????? + showOpponentMagicsZone(opponentBoard); + showOpponentMonstersZone(opponentBoard); + showGraveyard(opponentBoard); + System.out.println("--------------------------"); + showCardsInHand(playerBoard); +// showLeftCardDeck(playerBoard);//???????? + showMagicsZone(playerBoard); + showMonstersZone(playerBoard); + showGraveyard(playerBoard); + } + + private static void showMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// monsters[5].print(); +// System.out.print(monsters[5].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[4].print() + " "); +// System.out.println(); + } + + private static void showMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[5].print(); + magicsZone[3].print(); + magicsZone[1].print(); + magicsZone[2].print(); + magicsZone[4].print(); + } + + private static void showOpponentMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// System.out.print(monsters[4].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[5].print() + " "); + } + + private static void showOpponentMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[4].print(); + magicsZone[2].print(); + magicsZone[1].print(); + magicsZone[3].print(); + magicsZone[5].print(); + } + + private static void showCardsInHand(Board board) { + for (int i = 0; i < board.getCardsInHand().size(); i++) { + System.out.print("C "); + } + System.out.println(); + } + + private static void showSelectedCard(Board board) { + if (showCardCheck(board)) { + System.out.println(board.getSelectedCard().getName() + " " + board.getSelectedCard().getDescription()); + + } + } + + private static boolean showCardCheck(Board board) { + if (board.getSelectedCard() == null) { + System.out.println("you have not selected card"); + return false; + } + if (!board.isMyCardSelected() && !board.getSelectedCard().getCardFaceUp()) { + System.out.println("you cant see this card!"); + return false; + } + return true; + } + + public void duelMenuView() { + DuelMenuController duelMenuController = new DuelMenuController(); + + DuelMenuMessages resultOfInitialGame = null; + while (resultOfInitialGame == null || !resultOfInitialGame.equals(DuelMenuMessages.SHOW_TURN_PLAYER)) { + resultOfInitialGame = duelMenuController.initialGame(firstPlayer, secondPlayer); + System.out.print(resultOfInitialGame.getMessage()); + } + + while (true) { + String command = Utils.getScanner().nextLine().trim(); + DuelMenuMessages result = duelMenuController.findCommand(command); + + System.out.print(result.getMessage()); + } + } + +} diff --git a/My Part 5/main/java/view/ImportExportMenuView.java b/My Part 5/main/java/view/ImportExportMenuView.java new file mode 100644 index 0000000..ee91f94 --- /dev/null +++ b/My Part 5/main/java/view/ImportExportMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; + +public class ImportExportMenuView { + public void ImportExportMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ImportExportMenuMessages result = ImportExportMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU)) break; + } + } +} diff --git a/My Part 5/main/java/view/LoginMenuView.java b/My Part 5/main/java/view/LoginMenuView.java new file mode 100644 index 0000000..f094c8b --- /dev/null +++ b/My Part 5/main/java/view/LoginMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; + +public class LoginMenuView { + public static void loginMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + LoginMenuMessages result = LoginMenuController.findCommand(command); + + System.out.println(result.getMessage()); + + if (result.equals(LoginMenuMessages.USER_LOGGED_IN)) LoginMenuController.loginUser(command); + } + } +} diff --git a/My Part 5/main/java/view/MainMenuView.java b/My Part 5/main/java/view/MainMenuView.java new file mode 100644 index 0000000..7dde978 --- /dev/null +++ b/My Part 5/main/java/view/MainMenuView.java @@ -0,0 +1,31 @@ +package view; + +import controller.Utils; +import controller.mainmenu.MainMenuController; +import controller.mainmenu.MainMenuMessages; +import model.Player; + +public class MainMenuView { + private Player loggedInPlayer; + + public MainMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void mainMenuView() { + MainMenuController mainMenuController = new MainMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + MainMenuMessages result = mainMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(MainMenuMessages.EXIT_MAIN_MENU) || + result.equals(MainMenuMessages.USER_LOGGED_OUT)) break; + } + } +} diff --git a/My Part 5/main/java/view/ProfileMenuView.java b/My Part 5/main/java/view/ProfileMenuView.java new file mode 100644 index 0000000..1e1b091 --- /dev/null +++ b/My Part 5/main/java/view/ProfileMenuView.java @@ -0,0 +1,25 @@ +package view; + +import controller.profilemenu.ProfileMenuController; +import controller.profilemenu.ProfileMenuMessages; +import controller.Utils; +import model.Player; + +public class ProfileMenuView { + private final Player loggedInPlayer; + + public ProfileMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void profileMenuView() { + ProfileMenuController profileMenuController = new ProfileMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ProfileMenuMessages result = profileMenuController.findCommand(command); + + if (result.equals(ProfileMenuMessages.EXIT_MENU)) break; + else System.out.print(result.getMessage()); + } + } +} diff --git a/My Part 5/main/java/view/ScoreboardMenuView.java b/My Part 5/main/java/view/ScoreboardMenuView.java new file mode 100644 index 0000000..57e679c --- /dev/null +++ b/My Part 5/main/java/view/ScoreboardMenuView.java @@ -0,0 +1,40 @@ +package view; + +import controller.Utils; +import controller.scoreboardmenu.Scoreboard; +import controller.scoreboardmenu.ScoreboardOutput; +import model.Player; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ScoreboardMenuView { + public static Scanner scanner = Utils.getScanner(); + + public void runScoreboard() { + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + switch (command) { + case "scoreboard show": + Scoreboard.getInstance().showScoreboard(); + break; + case "menu show-current": + ScoreboardOutput.getInstance().showMessage("Scoreboard Menu"); + break; + case "menu exit": +// MainMenuView mainMenuView = new MainMenuView(); +// mainMenuView.mainMenuView(); + default: + ScoreboardOutput.getInstance().showMessage("invalid command"); + } + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } +} diff --git a/My Part 5/main/java/view/ShopMenuView.java b/My Part 5/main/java/view/ShopMenuView.java new file mode 100644 index 0000000..0ed2331 --- /dev/null +++ b/My Part 5/main/java/view/ShopMenuView.java @@ -0,0 +1,41 @@ +package view; + +import controller.Utils; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import model.cards.Card; + +import java.util.TreeMap; + +public class ShopMenuView { + private Player loggedInPlayer; + + public ShopMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + private static void showListOfCards() { + TreeMap listOfCards = Card.getListOfCards(); + for (String cardName : listOfCards.keySet()) { + System.out.println(cardName + ": " + listOfCards.get(cardName)); + } + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void shopMenuView() { + ShopMenuController shopMenuController = new ShopMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ShopMenuMessages result = shopMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ShopMenuMessages.EXIT_SHOP_MENU)) break; + else if (result.equals(ShopMenuMessages.SHOW_ALL_CARDS)) showListOfCards(); + } + } +} diff --git a/My Part 5/main/java/view/SpellCardView.java b/My Part 5/main/java/view/SpellCardView.java new file mode 100644 index 0000000..69bf703 --- /dev/null +++ b/My Part 5/main/java/view/SpellCardView.java @@ -0,0 +1,118 @@ +package view; + +import controller.Utils; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class SpellCardView extends DuelMenuView { + private SpellCardView(Player firstPlayer, Player secondPlayer) { + super(firstPlayer, secondPlayer); + } + + public static void showGraveyardsMonsterCards(Player turnPlayer, Player notTurnPlayer) { +// it used for Monster Reborn spell card + System.out.println("your graveyard monster cards:"); + showGraveyardMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent graveyard monster cards:"); + showGraveyardMonsterCards(notTurnPlayer.getBoard(), Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()) + 1); + } + + private static void showGraveyardMonsterCards(Board board, int startNumber) { +// it used for Monster Reborn spell card + int count = startNumber; + for (int i = 0; i < board.getGraveyard().size(); i++) { + if (Card.isMonsterCard(board.getGraveyard().get(i))) { + printCard(count, board.getGraveyard().get(i)); + ++count; + } + } + if (count == startNumber) System.out.println("There isn't any monster card."); + } + + public static String findCardNumber() { + System.out.println("choose a number:"); + return Utils.getScanner().nextLine(); + } + + public static void invalidNumber() { + System.out.println("invalid number"); + } + + public static void showFieldSpellCards(ArrayList magicCards) { + System.out.println("your field spell cards:"); + if (magicCards.size() == 0) System.out.println("There isn't any field spell card."); + else { + for (int i = 1; i <= magicCards.size(); i++) { + printCard(i, magicCards.get(i - 1)); + } + } + } + + public static void showCardsInHand(Player player) { + System.out.println("you have these cards in hand:"); + ArrayList cardsInHand = player.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) System.out.println("There isn't any card in your hand."); + else { + for (int i = 1; i <= cardsInHand.size(); i++) { + printCard(i, cardsInHand.get(i - 1)); + } + } + } + + public static void showMagicsZonesCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your spell and trap zone cards:"); + int endNumber = showMagicsZoneCards(turnPlayer, 1); + System.out.println("opponent spell and trap zone cards:"); + showMagicsZoneCards(notTurnPlayer, endNumber); + } + + private static int showMagicsZoneCards(Player player, int startNumber) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (player.getBoard().isMagicsZoneEmpty()) System.out.println("There isn't any spell and trap card."); + else { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) { + printCard(startNumber, magicsZone[i]); + ++startNumber; + } + } + } + + return startNumber; + } + + public static String findNumberOfCardsToChoose() { + System.out.println("How many cards do you want to choose to destroy?"); + return Utils.getScanner().nextLine(); + } + + public static void showFaceUpMonsterCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your face up monster cards:"); + int endNumber = showEachPlayerFaceUpMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent face up monster cards:"); + showEachPlayerFaceUpMonsterCards(notTurnPlayer.getBoard(), endNumber); + } + + private static int showEachPlayerFaceUpMonsterCards(Board board, int startNumber) { + if (board.getNumberOfFaceUpMonsterCards() == 0) { + System.out.println("There isn't any face up monster card."); + return startNumber; + } + + MonsterCard[] monstersZone = board.getMonstersZone(); + for (int i = 1; i < monstersZone.length; i++) { + MonsterCard monsterCard = monstersZone[i]; + if (monsterCard.getCardFaceUp()) { + printCard(startNumber, monsterCard); + ++startNumber; + } + } + + return startNumber; + } +} diff --git a/My Part 5/main/main.iml b/My Part 5/main/main.iml new file mode 100644 index 0000000..2185ddd --- /dev/null +++ b/My Part 5/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/My Part 5/main/resources/cards/Monster Upgraded.csv b/My Part 5/main/resources/cards/Monster Upgraded.csv new file mode 100644 index 0000000..eae794e --- /dev/null +++ b/My Part 5/main/resources/cards/Monster Upgraded.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARTH,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARTH,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,FIRE,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My Part 5/main/resources/cards/Monster.csv b/My Part 5/main/resources/cards/Monster.csv new file mode 100644 index 0000000..8c45a5c --- /dev/null +++ b/My Part 5/main/resources/cards/Monster.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARHT,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARHT,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron ,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,Fire,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My Part 5/main/resources/cards/SpellTrap.csv b/My Part 5/main/resources/cards/SpellTrap.csv new file mode 100644 index 0000000..e536e99 --- /dev/null +++ b/My Part 5/main/resources/cards/SpellTrap.csv @@ -0,0 +1,38 @@ +Name,Type ,Icon (Property),Description,Status,Price +Trap Hole,Trap,Normal,When your opponent Normal or Flip Summons 1 monster with 1000 or more ATK: Target that monster; destroy that target.,Unlimited,2000 +Mirror Force,Trap,Normal,When an opponent's monster declares an attack: Destroy all your opponent's Attack Position monsters.,Unlimited,2000 +Magic Cylinder,Trap,Normal,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, and if you do, inflict damage to your opponent equal to its ATK.",Unlimited,2000 +Mind Crush,Trap,Normal,"Declare 1 card name; if that card is in your opponent's hand, they must discard all copies of it, otherwise you discard 1 random card.",Unlimited,2000 +Torrential Tribute,Trap,Normal,When a monster(s) is Summoned: Destroy all monsters on the field.,Unlimited,2000 +Time Seal,Trap,Normal,Skip the Draw Phase of your opponent's next turn.,Limited,2000 +Negate Attack,Trap,Counter,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, then end the Battle Phase.",Unlimited,3000 +Solemn Warning,Trap,Counter,"When a monster(s) would be Summoned, OR when a Spell/Trap Card, or monster effect, is activated that includes an effect that Special Summons a monster(s): Pay 2000 LP; negate the Summon or activation, and if you do, destroy it.",Unlimited,3000 +Magic Jamamer,Trap,Counter,"When a Spell Card is activated: Discard 1 card; negate the activation, and if you do, destroy it.",Unlimited,3000 +Call of The Haunted,Trap,Continuous,"Activate this card by targeting 1 monster in your GY; Special Summon that target in Attack Position. When this card leaves the field, destroy that monster. When that monster is destroyed, destroy this card.",Unlimited,3500 +Vanity's Emptiness,Trap,Continuous,Neither player can Special Summon monsters. If a card is sent from the Deck or the field to your Graveyard: Destroy this card.,Limited,3500 +Wall of Revealing Light,Trap,Continuous,Activate by paying any multiple of 1000 Life Points. Monsters your opponent controls cannot attack if their ATK is less than or equal to the amount you paid.,Limited,3500 +Monster Reborn,Spell,Normal,Target 1 monster in either GY; Special Summon it.,Limited,2500 +Terraforming,Spell,Normal,Add 1 Field Spell from your Deck to your hand.,Limited,2500 +Pot of Greed,Spell,Normal,Draw 2 cards.,Limited,2500 +Raigeki,Spell,Normal,Destroy all monsters your opponent controls.,Limited,2500 +Change of Heart,Spell,Normal,Target 1 monster your opponent controls; take control of it until the End Phase.,Limited,2500 +Swords of Revealing Light,Spell,Normal,"After this card's activation, it remains on the field, but destroy it during the End Phase of your opponent's 3rd turn. When this card is activated: If your opponent controls a face-down monster, flip all monsters they control face-up. While this card is face-up on the field, your opponent's monsters cannot declare an attack.",Unlimited,2500 +Harpie's Feather Duster,Spell,Normal,Destroy all Spells and Traps your opponent controls.,Limited,2500 +Dark Hole,Spell,Normal,Destroy all monsters on the field.,Unlimited,2500 +Supply Squad,Spell,Continuous,"Once per turn, if a monster(s) you control is destroyed by battle or card effect: Draw 1 card.",Unlimited,4000 +Spell Absorption,Spell,Continuous,"Each time a Spell Card is activated, gain 500 Life Points immediately after it resolves.",Unlimited,4000 +Messenger of peace,Spell,Continuous,"Monsters with 1500 or more ATK cannot declare an attack. Once per turn, during your Standby Phase, pay 100 LP or destroy this card.",Unlimited,4000 +Twin Twisters,Spell,Quick-play,"Discard 1 card, then target up to 2 Spells/Traps on the field; destroy them.",Unlimited,3500 +Mystical space typhoon,Spell,Quick-play,Target 1 Spell/Trap on the field; destroy that target.,Unlimited,3500 +Ring of defense,Spell,Quick-play,When a Trap effect that inflicts damage is activated: Make that effect damage 0.,Unlimited,3500 +Yami,Spell,Field,"All Fiend and Spellcaster monsters on the field gain 200 ATK/DEF, also all Fairy monsters on the field lose 200 ATK/DEF.",Unlimited,4300 +Forest,Spell,Field,"All Insect, Beast, Plant, and Beast-Warrior monsters on the field gain 200 ATK/DEF.",Unlimited,4300 +Closed Forest,Spell,Field,All Beast-Type monsters you control gain 100 ATK for each monster in your Graveyard. Field Spell Cards cannot be activated. Field Spell Cards cannot be activated during the turn this card is destroyed.,Unlimited,4300 +Umiiruka,Spell,Field,Increase the ATK of all WATER monsters by 500 points and decrease their DEF by 400 points.,Unlimited,4300 +Sword of dark destruction,Spell,Equip,A DARK monster equipped with this card increases its ATK by 400 points and decreases its DEF by 200 points.,Unlimited,4300 +Black Pendant,Spell,Equip,The equipped monster gains 500 ATK. When this card is sent from the field to the Graveyard: Inflict 500 damage to your opponent.,Unlimited,4300 +United We Stand,Spell,Equip,The equipped monster gains 800 ATK/DEF for each face-up monster you control.,Unlimited,4300 +Magnum Shield,Spell,Equip,"Equip only to a Warrior-Type monster. Apply this effect, depending on its battle position. +● Attack Position: It gains ATK equal to its original DEF. +● Defense Position: It gains DEF equal to its original ATK.",Unlimited,4300 +Advanced Ritual Art,Spell,Ritual,This card can be used to Ritual Summon any 1 Ritual Monster. You must also send Normal Monsters from your Deck to the Graveyard whose total Levels equal the Level of that Ritual Monster.,Unlimited,3000 \ No newline at end of file diff --git a/My Part 5/main/resources/players/amir.json b/My Part 5/main/resources/players/amir.json new file mode 100644 index 0000000..867f62c --- /dev/null +++ b/My Part 5/main/resources/players/amir.json @@ -0,0 +1,17 @@ +{ + "boughtCards": [ + { + "name": "Battle OX" + }, + { + "name": "Suijin" + } + ], + "allMainDecks": [], + "sideDeck": {}, + "username": "amir", + "password": "12345", + "nickname": "amir", + "score": 0, + "money": 88400 +} \ No newline at end of file diff --git a/My Part 5/main/resources/players/parsa.json b/My Part 5/main/resources/players/parsa.json new file mode 100644 index 0000000..2825eb1 --- /dev/null +++ b/My Part 5/main/resources/players/parsa.json @@ -0,0 +1,10 @@ +{ + "boughtCards": [], + "allMainDecks": [], + "sideDeck": {}, + "username": "parsa", + "password": "newPass", + "nickname": "P", + "score": 0, + "money": 100000 +} \ No newline at end of file diff --git a/My Part 5/test/java/controller/ImportExportMenuControllerTest.java b/My Part 5/test/java/controller/ImportExportMenuControllerTest.java new file mode 100644 index 0000000..aea2298 --- /dev/null +++ b/My Part 5/test/java/controller/ImportExportMenuControllerTest.java @@ -0,0 +1,140 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Database; +import controller.MenuTest; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; +import model.cards.Card; +import org.apache.commons.io.FileUtils; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +class ImportExportMenuControllerTest extends MenuTest { + + @Test + void findCommandEnterAMenuMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu exit"); + Assertions.assertEquals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU, result); + + result = ImportExportMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ImportExportMenuMessages.SHOW_MENU, result); + + result = ImportExportMenuController.findCommand("menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandImportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("import cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_FILE, result); + + createCardJsonFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.AVAILABLE_CARD, result); + + Card.getAllCards().remove("Battle OX"); + removeNameValueFromJsonCardFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Battle OX"); + Card.getAllCards().remove("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Battle OX.json")); + + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + removeNameValueFromJsonCardFile("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Trap Hole.json")); + } + + void createCardJsonFile(String cardName) { + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(Card.getCardByName(cardName))); + fileWriter.close(); + } catch (IOException ignored) { + } + } + + void removeNameValueFromJsonCardFile(String cardName) { + JSONParser parser = new JSONParser(); + try { + Object object = parser.parse(new FileReader("src/database/cards/" + cardName + ".json")); + JSONObject jsonObject = (JSONObject) object; + jsonObject.remove("name"); + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(jsonObject)); + fileWriter.close(); + } catch (Exception ignored) { + } + } + + @Test + void findCommandExportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("export cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("export card A"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_CARD, result); + + result = ImportExportMenuController.findCommand("export card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My Part 5/test/java/controller/LoginMenuControllerTest.java b/My Part 5/test/java/controller/LoginMenuControllerTest.java new file mode 100644 index 0000000..b095e9e --- /dev/null +++ b/My Part 5/test/java/controller/LoginMenuControllerTest.java @@ -0,0 +1,87 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; + +class LoginMenuControllerTest extends MenuTest { + @Test + void findCommandEnterAMenuMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_NAVIGATION, result); + + result = LoginMenuController.findCommand("menu enter MaIn MenU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + + result = LoginMenuController.findCommand("menu enter DUEL MENU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + } + + @Test + void findCommandCheckCreateUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user create --username John 1 --nickname Johny --password 12345"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user create --U John1 --nickname Johny1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --username John2 --P 12345 --nickname Johny2"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny3 --username John3 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny4 --password 12345 --U John4"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --username John5 --nickname Johny5"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --nickname Johny6 --username John6"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John6 --N Johny6"); + Assertions.assertEquals(LoginMenuMessages.USERNAME_EXISTS, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John7 --nickname Johny6"); + Assertions.assertEquals(LoginMenuMessages.NICKNAME_EXISTS, result); + } + + @Test + void findCommandCheckLoginUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user login --username John 12 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user login --username John12 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + + result = LoginMenuController.findCommand("user login --username John2 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + result = LoginMenuController.findCommand("user login --username John1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + + result = LoginMenuController.findCommand("user login --password 12345 --username John1"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + } + + @Test + void loginUser() { + Utils.resetScanner("user logout\n"); + ByteArrayOutputStream outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --password 12345 --username John1"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + + Utils.resetScanner("user logout\n"); + outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --username John1 --password 12345"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + } +} \ No newline at end of file diff --git a/My Part 5/test/java/controller/MenuTest.java b/My Part 5/test/java/controller/MenuTest.java new file mode 100644 index 0000000..5df1b3c --- /dev/null +++ b/My Part 5/test/java/controller/MenuTest.java @@ -0,0 +1,20 @@ +package controller; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +import java.io.File; +import java.io.IOException; + +public class MenuTest { + @BeforeAll + static void prepareGame() { + Database.prepareGame(); + } + + @AfterAll + static void deletePlayersDirectory() throws IOException { + FileUtils.deleteDirectory(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/main/resources/players")); + } +} \ No newline at end of file diff --git a/My Part 5/test/java/controller/ProfileMenuTest.java b/My Part 5/test/java/controller/ProfileMenuTest.java new file mode 100644 index 0000000..ddad54d --- /dev/null +++ b/My Part 5/test/java/controller/ProfileMenuTest.java @@ -0,0 +1,57 @@ +package controller; + +import controller.profilemenu.ProfileMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import controller.profilemenu.ProfileMenuController; + +public class ProfileMenuTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + String userName = "parsa"; + String password = "123"; + String nickname = "P"; + new Player(userName, password, nickname); + } + + @Test + public void changeName() { + Player player = Player.getPlayerByUsername("parsa"); + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --nickname newname"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + Assertions.assertEquals("newname", player.getNickname()); + result = profileMenuController.findCommand("profile change --nickname P"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + } + + @Test + public void changePassword() { + Player player = Player.getPlayerByUsername("parsa"); + + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --password --current 12 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.WRONG_CURRENT_PASSWORD, result); + Assertions.assertEquals("123", player.getPassword()); + + result = profileMenuController.findCommand("profile change --password --current 123 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_PASSWORD_DONE, result); + Assertions.assertEquals("newPass", player.getPassword()); + } + + @Test + public void allError() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.INVALID_COMMAND, profileMenuController.findCommand("profile")); + Assertions.assertEquals(ProfileMenuMessages.CANT_NAVIGATE_MENU, profileMenuController.findCommand("loginmenu enter")); + } + + @Test + public void checkExit() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.EXIT_MENU , profileMenuController.findCommand("menu exit")); + } +} diff --git a/My Part 5/test/java/controller/ShopMenuControllerTest.java b/My Part 5/test/java/controller/ShopMenuControllerTest.java new file mode 100644 index 0000000..58d998d --- /dev/null +++ b/My Part 5/test/java/controller/ShopMenuControllerTest.java @@ -0,0 +1,77 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ShopMenuControllerTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + LoginMenuController.findCommand("user create --username John --P 12345 --nickname Johny"); + } + + @Test + void findCommandEnterAMenuMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu exit"); + Assertions.assertEquals(ShopMenuMessages.EXIT_SHOP_MENU, result); + + result = shopMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ShopMenuMessages.SHOW_MENU, result); + + result = shopMenuController.findCommand("menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandBuyACardMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("shop buy:)"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("shop buy A"); + Assertions.assertEquals(ShopMenuMessages.UNAVAILABLE_CARD, result); + + result = shopMenuController.findCommand("shop buy Battle OX"); + Assertions.assertEquals(ShopMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My Part 5/test/test.iml b/My Part 5/test/test.iml new file mode 100644 index 0000000..c2315e9 --- /dev/null +++ b/My Part 5/test/test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/My Part/My Part.iml b/My Part/My Part.iml new file mode 100644 index 0000000..9465dd8 --- /dev/null +++ b/My Part/My Part.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/My Part/src/My Part.iml b/My Part/src/My Part.iml new file mode 100644 index 0000000..1de981c --- /dev/null +++ b/My Part/src/My Part.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/My Part/src/deckmenu/DeckMenuController.java b/My Part/src/deckmenu/DeckMenuController.java new file mode 100644 index 0000000..6d5dff3 --- /dev/null +++ b/My Part/src/deckmenu/DeckMenuController.java @@ -0,0 +1,91 @@ +package deckmenu; + +import model.*; +import java.util.Objects; + +public class DeckMenuController { + + private static DeckMenuController instance = null; + + private DeckMenuController() { + } + + public static DeckMenuController getInstance() { + return Objects.requireNonNullElseGet(instance, () -> (instance = new DeckMenuController())); + } + + public void createDeck(String name, Player owner) { + if (!DeckMenuTools.isDeckNameUnique(name)) + return; + + new Deck(name, owner , true , true); + DeckMenuOutput.getInstance().showMessage("deck created successfully!"); + } + + public void deleteDeck(String name) { + if (DeckMenuTools.isDeckNameUnique(name)) + return; + + DeckMenuDatabase.removeDeck(name); + DeckMenuOutput.getInstance().showMessage("deck deleted successfully!"); + + } + + + public void setActiveDeck(String name, Player player) { + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesDeckExist(name) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(name), player); + if (isPermitted) { + player.activateADeck(deck); + + DeckMenuOutput.getInstance().showMessage("deck activated successfully!"); + } + + } + + public void addCardToDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card = null; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player) + && ((isMain) ? DeckMenuTools.doesDeckHaveSpace(deck) : DeckMenuTools.doesSideDeckHaveSpace(deck)) + && DeckMenuTools.isNumberOfCardsInDeckLessThanFour(deck, card = DeckMenuDatabase.getInstance().getCardByName(cardName)) + && DeckMenuTools.doesPlayerHaveEnoughCards(card , player); + if (isPermitted) { + player.getAllPlayerCard().moveCardTo(deck , card , true , isMain); + DeckMenuOutput.getInstance().showMessage("card added to deck successfully!"); + } + } + + public void removeCardFromDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player); + if (isPermitted) { + card = DeckMenuDatabase.getInstance().getCardByName(cardName); + deck.moveCardTo(player.getAllPlayerCard(),card, isMain , true); + DeckMenuOutput.getInstance().showMessage("card removed from deck successfully!"); + } + } + + public void showAllDecks(Player player) { + for (Deck deck : player.getAllDeck()) + DeckMenuOutput.getInstance().showMessage(deck.toString()); + + } + + public void showDeck(String name, Player player, boolean isMain) { + if (!DeckMenuTools.doesDeckExist(name)) + return; + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (!DeckMenuTools.doesDeckBelongToPlayer(deck, player)) + return; + DeckMenuOutput.getInstance().showMessage(deck.toString(isMain)); + + + } +} diff --git a/My Part/src/deckmenu/DeckMenuDatabase.java b/My Part/src/deckmenu/DeckMenuDatabase.java new file mode 100644 index 0000000..a6da2e3 --- /dev/null +++ b/My Part/src/deckmenu/DeckMenuDatabase.java @@ -0,0 +1,49 @@ +package deckmenu; + +import model.*; +import java.util.ArrayList; + +public class DeckMenuDatabase { + + public static ArrayList allPlayers = new ArrayList<>(); + public static ArrayList allCards = new ArrayList<>(); + public static ArrayList allDecks = new ArrayList<>(); + + private DeckMenuDatabase() { + } + + private static DeckMenuDatabase instance; + + public static DeckMenuDatabase getInstance() { + if (instance == null) + instance = new DeckMenuDatabase(); + return instance; + } + + public static void removeDeck(String name) { + allDecks.removeIf(deck -> deck.getName().equals(name)); + } + + public Card getCardByName(String name) { + for (Card card : allCards) { + if (card.getName().equals(name)) + return card; + } + return null; + + } + + public Deck getDeckByName(String name) { + for (Deck deck : allDecks) { + if (deck.getName().equals(name)) + return deck; + } + return null; + + } + // setPlayers() {file v Jason} + // setDecks() {file v Jason} + // loadingDatabase() + // updatingDatabase() + +} diff --git a/My Part/src/deckmenu/DeckMenuOutput.java b/My Part/src/deckmenu/DeckMenuOutput.java new file mode 100644 index 0000000..9414258 --- /dev/null +++ b/My Part/src/deckmenu/DeckMenuOutput.java @@ -0,0 +1,23 @@ +package deckmenu; + +public class DeckMenuOutput { + + private DeckMenuOutput() { + } + + private static DeckMenuOutput instance; + + public static DeckMenuOutput getInstance() { + if (instance == null) + instance = new DeckMenuOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My Part/src/deckmenu/DeckMenuTools.java b/My Part/src/deckmenu/DeckMenuTools.java new file mode 100644 index 0000000..fa685d7 --- /dev/null +++ b/My Part/src/deckmenu/DeckMenuTools.java @@ -0,0 +1,69 @@ +package deckmenu; + +import model.*; + +public class DeckMenuTools { + public static boolean isDeckNameUnique(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck == null) + return true; + + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " already exists"); + return false; + + } + public static boolean doesDeckExist(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck != null) + return true; + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " does not exist"); + return false; + + } + public static boolean doesDeckBelongToPlayer(Deck deck, Player player) { + if (deck.getOwner().getUsername().equals(player.getUsername())) + return true; + DeckMenuOutput.getInstance().showMessage("this deck doesn't belong to you!"); + return false; + } + public static boolean doesDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getMainCards().size() < 60) + return true; + DeckMenuOutput.getInstance().showMessage("main deck is full!"); + return false; + } + public static boolean doesSideDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getSideCards().size() < 15) + return true; + DeckMenuOutput.getInstance().showMessage("side deck is full!"); + return false; + } + public static boolean isNumberOfCardsInDeckLessThanFour(Deck deck, Card card) { + if (deck.getNumberOfCardsInDeck(card) < 3) + return true; + DeckMenuOutput.getInstance().showMessage("there are already three cards with name " + card.getName() + + " in deck " + deck.getName() + " !"); + return false; + } + public static boolean isDeckAllowed(Deck deck) { + int numberOfCardsInSideDeck = deck.getNumberOfCardsInSideDeck(); + int numberOfCardsInMainDeck = deck.getNumberOfCardsInMainDeck(); + return numberOfCardsInMainDeck <= 60 && numberOfCardsInMainDeck >= 40 && numberOfCardsInSideDeck <= 15; + } + public static boolean doesPlayerHaveEnoughCards(Card card, Player player) { + if (player.getAllPlayerCard().hasCard(card, true)) + return true; + DeckMenuOutput.getInstance().showMessage("you dont have this type of card anymore!"); + return false; + } + public static boolean doesCardExist(String cardName) { + Card card = DeckMenuDatabase.getInstance().getCardByName(cardName); + if (card != null) + return true; + DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist"); + return false; + } + +} diff --git a/My Part/src/deckmenu/DeckMenuView.java b/My Part/src/deckmenu/DeckMenuView.java new file mode 100644 index 0000000..66c3c8b --- /dev/null +++ b/My Part/src/deckmenu/DeckMenuView.java @@ -0,0 +1,140 @@ +package deckmenu; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import model.*; + +public class DeckMenuView { + public static Scanner scanner = new Scanner(System.in); + + private static DeckMenuView instance; + + private DeckMenuView() { + } + + public static DeckMenuView getInstance() { + if (instance == null) + instance = new DeckMenuView(); + return instance; + } + + private final String[] deckMenuRegexes = { + "^deck create (?\\w+)$", + "^deck delete (?\\w+)$", + "^deck set-activate (?\\w+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck add-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck show (?:--all|-a)$", + "^deck show (?:--deck-name|-d) (?.+) (?:--side|-s)$", + "^deck show (?:--side|-s) (?:--deck-name|-d) (?.+)$", + "^deck show (?:--deck-name|-d) (?.+)$", + "^menu show-current$", + "^menu exit$" + }; + + public void runDeckMenu() { + Matcher commandMatcher; + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + int whichCommand; + for (whichCommand = 0; whichCommand < deckMenuRegexes.length; whichCommand++) { + commandMatcher = findMatcher(command, deckMenuRegexes[whichCommand]); + if (commandMatcher.find()) { + executeDeckMenuCommands(commandMatcher, whichCommand); + break; + } else if (whichCommand == deckMenuRegexes.length - 1) + DeckMenuOutput.getInstance().showMessage("invalid command"); + } + + } + } + + private void executeDeckMenuCommands(Matcher commandMatcher, int whichCommand) { + DeckMenuController controller = DeckMenuController.getInstance(); + Player loggedInPlayer = MainMenu.getInstance().getPlayerLoggedIn(); + switch (whichCommand) { + case 0: + controller.createDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 1: + controller.deleteDeck(commandMatcher.group("name")); + break; + case 2: + controller.setActiveDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + String cardName = commandMatcher.group("cardName"), + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, false); + break; + case 9: + case 10: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, true); + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, false); + break; + case 17: + case 18: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, true); + break; + case 19: + controller.showAllDecks(loggedInPlayer); + break; + case 20: + case 21: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, false); + break; + case 22: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, true); + break; + case 23: + DeckMenuOutput.getInstance().showMessage("Deck Menu"); + break; + case 24: + MainMenuView.mainMenuView; +// go to main menu; + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } + + +} diff --git a/My Part/src/model/Card.java b/My Part/src/model/Card.java new file mode 100644 index 0000000..d9f7a94 --- /dev/null +++ b/My Part/src/model/Card.java @@ -0,0 +1,84 @@ +package model; + +import java.util.ArrayList; +import java.util.TreeMap; + +public class Card { + protected static ArrayList allCards = new ArrayList<>(); + protected String cardType; + protected String name; + protected String description; + protected Deck currentDeck; + // protected String upDown; + protected boolean isPowerUsed = false; + protected transient boolean isCardFaceUp = false; + public Card(String cardType, String name, String description, String upDown) { + setCardType(cardType); + setName(name); + setDescription(description); + allCards.add(this); + } + public void setCurrentDeck(Deck currentDeck) { this.currentDeck = currentDeck; } + public Deck getCurrentDeck() { + return currentDeck; + } + + + public static ArrayList getAllCards() { + return allCards; + } + + public static void setAllCards(ArrayList allCards) { + Card.allCards = allCards; + } + + public static Card getCardByName(String name) { + for (Card card : allCards) { + if (card.getName().equals(name)) return card; + } + return null; + } + + + public String getDescription() { + return description; + } + + public void setPowerUsed(boolean powerUsed) { + isPowerUsed = powerUsed; + } + public boolean getIsPowerUsed(){ + return this.isPowerUsed; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getCardType() { + return cardType; + } + + public void setCardType(String cardType) { + this.cardType = cardType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setCardFaceUp(boolean b){ + isCardFaceUp = b; + } + + public boolean isCardFaceUp() { + return isCardFaceUp; + } + + //public void callCard(){} + +} \ No newline at end of file diff --git a/My Part/src/model/Deck.java b/My Part/src/model/Deck.java new file mode 100644 index 0000000..f0baa92 --- /dev/null +++ b/My Part/src/model/Deck.java @@ -0,0 +1,194 @@ +package model; + +import model.*; +import deckmenu.*; + +import java.util.ArrayList; + +public class Deck { + public ArrayList mainCards = new ArrayList<>(); + public ArrayList sideCards = new ArrayList<>(); + Player owner; + String name; + DeckType type; + Boolean isActive = false; + Boolean IsValid; + + public Deck(String name, Player owner, boolean hasSideDeck, boolean shouldBeSaved) { + this.name = name; + if (shouldBeSaved) + DeckMenuDatabase.allDecks.add(this); + if (!hasSideDeck) + sideCards = null; + this.owner = owner; + } + + public Deck(String name, Player owner) { + this.name = name; + sideCards = null; + this.owner = owner; + } + + public Deck(String name) { + this.name = name; + sideCards = null; + } + public Deck() { + sideCards = null; + } + + public void updateOwnerDecks() { + String deckType = (name.length() > 16) ? name.substring(name.length() - 16) : ""; + if (deckType.equals(".purchased-cards")) + owner.setAllPlayerCard(this); + else { + owner.getAllDeck().add(this); + if (this.isActive) + owner.setActiveDeck(this); + } + } + + public ArrayList getMainCards() { + if (mainCards == null) + return (mainCards = new ArrayList<>()); + return mainCards; + } + + public void setMainCards(ArrayList mainCards) { + this.mainCards = mainCards; + } + + public ArrayList getSideCards() { + return sideCards; + } + + public void setSideCards(ArrayList sideCards) { + this.sideCards = sideCards; + } + + public Player getOwner() { + return owner; + } + + public void setOwner(Player owner) { + this.owner = owner; + } + + public void setActive(Boolean active) { + isActive = active; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setActivation(Boolean active) { + isActive = active; + } + + public void setValid(Boolean valid) { + IsValid = valid; + } + + public void setType(DeckType type) { + this.type = type; + } + + public void addCard(Card card, boolean shouldBeAddedToMain) { + if (shouldBeAddedToMain) + mainCards.add(card); + else + sideCards.add(card); + if (card != null) + card.setCurrentDeck(this); + } + + public void addCard(Card card) { + mainCards.add(card); + if (card != null && !name.equals("selected collected deck")) + card.setCurrentDeck(this); + } + + public void moveCardTo(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCard(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public void moveCardToForGame(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCardForGame(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public boolean hasCard(Card card, boolean isMain) { + if (isMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) + return true; + + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + return true; + } + return false; + } + + public void removeCard(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) { + mainCards.remove(cardInMain); + return; + } + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + sideCards.remove(cardInSide); + return; + } + } + + public void removeCardForGame(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) + mainCards.remove(card); + else + sideCards.remove(card); + } + + public int getNumberOfCardsInDeck(Card card) { + int count = 0; + for (Card cardInDeck : mainCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + for (Card cardInDeck : sideCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + return count; + } + + public int getNumberOfCardsInMainDeck() { + return mainCards.size(); + } + + public int getNumberOfCardsInSideDeck() { + return sideCards.size(); + } + + public void updateCurrentDeck() { + if (mainCards != null) + for (Card card : mainCards) + if (card != null) + card.setCurrentDeck(this); + if (sideCards != null) + for (Card card : sideCards) + if (card != null) + card.setCurrentDeck(this); + } +} + diff --git a/My Part/src/model/DeckType.java b/My Part/src/model/DeckType.java new file mode 100644 index 0000000..dd8e3af --- /dev/null +++ b/My Part/src/model/DeckType.java @@ -0,0 +1,9 @@ +package model; + +public enum DeckType { + regulardeck, + inactivedeck, + graveyarddeck, + selectedcarddeck +} + diff --git a/My Part/src/model/Player.java b/My Part/src/model/Player.java new file mode 100644 index 0000000..2b5d745 --- /dev/null +++ b/My Part/src/model/Player.java @@ -0,0 +1,242 @@ +package model; + +import java.util.ArrayList; + +public class Player { + private static ArrayList allPlayers; + + static { + allPlayers = new ArrayList<>(); + } + + private ArrayList boughtCards; + private ArrayList allMainDecks; + private Deck sideDeck; + private Deck activatedDeck; + private String username; + private String password; + private String nickname; + private transient Deck allPlayerCard; + private transient ArrayList allDeck = new ArrayList<>(); + private transient ArrayList gameDecks = new ArrayList<>(); + private long score; + private long money; + private int lifePoint; + + { + boughtCards = new ArrayList<>(); + allMainDecks = new ArrayList<>(); + sideDeck = new Deck(); + activatedDeck = null; + score = 0; + money = 0; + } + + public Player(String username, String password, String nickname) { + setUsername(username); + setPassword(password); + setNickname(nickname); + allPlayers.add(this); + addPlayerToDataBase(this); + } + + private static void addPlayerToDataBase(Player player) { + + } + + public void setLifePoint(int lifePoint) { + this.lifePoint = lifePoint; + } + + public int getLifePoint() { + return lifePoint; + } + + public static Boolean isNicknameExist(String nickname) { + for (Player player : allPlayers) { + if (player.nickname.equals(nickname)) return true; + } + return false; + } + + public static Boolean isPasswordCorrect(String username, String password) { + Player player = getPlayerByUsername(username); + if (player == null) return false; + + return player.password.equals(password); + } + + public static Player getPlayerByUsername(String username) { + for (Player player : allPlayers) { + if (player.username.equals(username)) return player; + } + return null; + } + + + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public long getScore() { + return score; + } + + public void increaseScore(long score) { + this.score += score; + } + + public void decreaseScore(long score) { + this.score -= score; + } + + public void increaseMoney(long money) { + this.money += money; + } + + public void decreaseMoney(long money) { + this.money -= money; + } + + public void addCardToBoughtCards(Card card) { + this.boughtCards.add(card); + } + + public void addAmountToLifePoint(int amount){ + this.lifePoint+=amount; + } + + public void addMainDeck(String deckName) { + Deck mainDeck = new Deck(deckName); + this.allMainDecks.add(mainDeck); + } + + public Boolean isMainDeckExist(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return true; + } + return false; + } + + public Deck getActiveDeck() { + return activatedDeck; + } + + public void setActiveDeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public ArrayList getAllDeck() { + if (allDeck == null) + return (allDeck = new ArrayList<>()); + return allDeck; + } + + public void setAllDeck(ArrayList allDeck) { + this.allDeck = allDeck; + } + + public Deck getAllPlayerCard() { + return allPlayerCard; + } + + public void addCardToAllPlayerCard(Card card) { + this.allPlayerCard.getMainCards().add(card); + } + + public int getMoney() { + return money; + } + + public void setAllPlayerCard(Deck allPlayerCard) { + this.allPlayerCard = allPlayerCard; + } + + public void setMoney(int money) { + this.money = money; + } + + public void deleteDeck(Deck deck) { + allDeck.remove(deck); + } + + public Board getBoard() { + return board; + } + + public void setBoard(Board board) { + this.board = board; + } + + + public void deleteMainDeck(String deckName) { + Deck mainDeck = getDeckByName(deckName); + if (mainDeck != null) { + boughtCards.addAll(mainDeck.getMainCards()); + allMainDecks.remove(mainDeck); + } + } + + public Deck getDeckByName(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return deck; + } + return null; + } + + public int compareTo(Player player) { + if (this.score > player.score) + return -1; + if (this.score < player.score) + return 1; + if (this.nickname.compareTo(player.getNickname()) > 0) + return -1; + if (this.nickname.compareTo(player.getNickname()) < 0) + return 1; + return 0; + } + + public void activateADeck(String deckName) { + Deck deck = getDeckByName(deckName); + if (deck != null) activatedDeck = deck; + } + public void activateADeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public void addCardToMainDeck() { +// TODO: ???? but remember to remove this card from boughtCards :) + } + + public void removeACard() { +// TODO: ???? but remember to add this card from boughtCards :) + } +} + diff --git a/My Part/src/scoreboardmenu/Scoreboard.java b/My Part/src/scoreboardmenu/Scoreboard.java new file mode 100644 index 0000000..4cb2a71 --- /dev/null +++ b/My Part/src/scoreboardmenu/Scoreboard.java @@ -0,0 +1,40 @@ +package scoreboardmenu; + +import java.util.ArrayList; +import model.*; + +public class Scoreboard { + + private Scoreboard() { + } + + private static Scoreboard instance; + + public static Scoreboard getInstance() { + if (instance == null) + instance = new Scoreboard(); + return instance; + } + + public void showScoreboard() { + int counter = 1; + int index = 0; + long previousScore = -1; + StringBuilder output = new StringBuilder(); + ArrayList allUsers = Player.allPlayers; + allUsers.sort(Player::compareTo); + for (Player player : allUsers) { + + + if (player.getScore() != previousScore) { + index += counter; + counter = 1; + } else counter++; + output.append(index).append(". ").append(player.getNickname()).append(": ").append(player.getScore()).append("\n"); + previousScore = player.getScore(); + + } + ScoreboardOutput.getInstance().showMessage(output.toString()); + } + +} diff --git a/My Part/src/scoreboardmenu/ScoreboardOutput.java b/My Part/src/scoreboardmenu/ScoreboardOutput.java new file mode 100644 index 0000000..31028b7 --- /dev/null +++ b/My Part/src/scoreboardmenu/ScoreboardOutput.java @@ -0,0 +1,23 @@ +package scoreboardmenu; + +public class ScoreboardOutput { + + private ScoreboardOutput() { + } + + private static scoreboardmenu.ScoreboardOutput instance; + + public static scoreboardmenu.ScoreboardOutput getInstance() { + if (instance == null) + instance = new scoreboardmenu.ScoreboardOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My Part/src/scoreboardmenu/ScoreboardView.java b/My Part/src/scoreboardmenu/ScoreboardView.java new file mode 100644 index 0000000..fb3dd22 --- /dev/null +++ b/My Part/src/scoreboardmenu/ScoreboardView.java @@ -0,0 +1,42 @@ +package scoreboardmenu; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ScoreboardView { + public static Scanner scanner = new Scanner(System.in); + private static ScoreboardView instance; + private ScoreboardView() { + } + public static ScoreboardView getInstance() { + if (instance == null) + instance = new ScoreboardView(); + return instance; + } + + public void runScoreboard() { + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + switch (command) { + case "scoreboard show": + Scoreboard.getInstance().showScoreboard(); + break; + case "menu show-current": + ScoreboardOutput.getInstance().showMessage("Scoreboard Menu"); + break; + case "menu exit": + MainMenuView.mainMenuView; + default: + ScoreboardOutput.getInstance().showMessage("invalid command"); + } + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } +} diff --git a/My part 6/main/java/controller/AIClass.java b/My part 6/main/java/controller/AIClass.java new file mode 100644 index 0000000..5e41136 --- /dev/null +++ b/My part 6/main/java/controller/AIClass.java @@ -0,0 +1,60 @@ +package controller; + +import model.Board; +import model.cards.monstercard.MonsterCard; +import model.Player; + +public class AIClass { + +// public static String getOrder(Board machineBoard, Board playerBoard, Player AIPlayer, Player humanPlayer, Enum phaseOfGame) { +// if () {//TODO PUT A CONDITION THAT PHASE IS BATTLE PHASE +// int numberOfMonsterToAttack = -1; +// selectMachineMonsterCardToAttack(machineBoard, AIPlayer); +// if (canAttackToFaceUpMonster(machineBoard, playerBoard) != -1) { +// return "attack" + canAttackToFaceUpMonster(machineBoard, playerBoard); +// } else if (canAttackToFaceDownCard(playerBoard) != -1) { +// return "attack" + canAttackToFaceDownCard(playerBoard); +// } +// } +// } +// +// private static int canAttackToFaceDownCard(Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DH")) +// return i; +// } +// return -1; +// } +// +// private static void selectMachineMonsterCardToAttack(Board board, Player player) { +// MonsterCard[] monsterArray = board.getMonstersZone(); +// MonsterCard monsterCard = monsterArray[1]; +// for (int i = 2; i <= 5; i++) { +// if (monsterCard.getAttackLevel() < monsterArray[i].getAttackLevel()) +// monsterCard = monsterArray[i]; +// board.setMyCardSelected(true); +// board.setSelectedCard(monsterCard); +// } +// } +// +// private static int canAttackToFaceUpMonster(Board machineBoard, Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// MonsterCard monsterToAttack = (MonsterCard) machineBoard.getSelectedCard(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("OO") && monsterArray[i].getAttackLevel() < monsterToAttack.getAttackLevel()) +// return i; +// } +// +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DO") && monsterArray[i].getDefenseLevel() < monsterToAttack.getAttackLevel()) { +// } +// return i; +// } +// return -1; +// } +// +// public static String getRandomMove() { +// +// } +} diff --git a/My part 6/main/java/controller/Database.java b/My part 6/main/java/controller/Database.java new file mode 100644 index 0000000..e5d87af --- /dev/null +++ b/My part 6/main/java/controller/Database.java @@ -0,0 +1,120 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.magiccard.MagicCardStatuses; +import model.cards.monstercard.MonsterCard; +import model.cards.monstercard.MonsterCardAttributes; + +import java.io.*; +import java.util.ArrayList; + +public class Database { + public static void prepareGame() { + new File("src/main/resources/players").mkdirs(); + addCardsToGame(); + readPlayersDataFromDatabase(); + } + + private static void addCardsToGame() { + try { + FileReader monsterCardFileReader = new FileReader("src/main/resources/cards/Monster Upgraded.csv"); + CSVReader monsterCardCSVReader = new CSVReaderBuilder(monsterCardFileReader).withSkipLines(1).build(); + + String[] monsterCardData; + while ((monsterCardData = monsterCardCSVReader.readNext()) != null) { + createNewMonsterCard(monsterCardData); + } + + + FileReader magicCardFileReader = new FileReader("src/main/resources/cards/SpellTrap.csv"); + CSVReader magicCardCSVReader = new CSVReaderBuilder(magicCardFileReader).withSkipLines(1).build(); + + String[] magicCardData; + while ((magicCardData = magicCardCSVReader.readNext()) != null) { + createNewMagicCard(magicCardData); + } + + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + } + + private static void createNewMonsterCard(String[] data) { + String name = data[0]; + short level = Short.parseShort(data[1]); + MonsterCardAttributes monsterCardAttributes = MonsterCardAttributes.valueOf(data[2]); + String monsterType = data[3]; + CardTypes cardType = CardTypes.valueOf(data[4].toUpperCase()); + int attackPoints = Integer.parseInt(data[5]); + int defensePoints = Integer.parseInt(data[6]); + String description = data[7]; + int price = Integer.parseInt(data[8]); + + new MonsterCard(name, level, monsterCardAttributes, monsterType, cardType, attackPoints, defensePoints, description, price); + } + + private static void createNewMagicCard(String[] data) { + String name = data[0]; + CardTypes cardType = CardTypes.valueOf(data[1].toUpperCase()); + String icon = data[2]; + String description = data[3]; + MagicCardStatuses status = MagicCardStatuses.valueOf(data[4].toUpperCase()); + int price = Integer.parseInt(data[5]); + + new MagicCard(name, cardType, icon, description, status,price); + } + + public static void readPlayersDataFromDatabase() { +// TODO: complete it by Iman's code + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + File file = new File("src/main/resources/players"); + FilenameFilter filenameFilter = (direction, name) -> name.endsWith(".json"); + String[] filesName = file.list(filenameFilter); + + if (filesName == null) return; + for (String fileName : filesName) { + try { + FileReader fileReader = new FileReader("src/main/resources/players/" + fileName); + Player player = gson.fromJson(fileReader, Player.class); + fileReader.close(); + Player.addPlayerToAllPlayers(player); + addCardsToPlayer(player); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + private static void addCardsToPlayer(Player player) { + ArrayList boughtCards = player.getBoughtCards(); + for (int i = 0; i < boughtCards.size(); i++) { + Card fakeCard = boughtCards.get(0); + Card originalCard = Card.getCardByName(fakeCard.getName()); + boughtCards.remove(fakeCard); + player.addCardToBoughtCards(originalCard); + } + } + + public static void updatePlayerInformationInDatabase(Player player) { + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + try { + FileWriter fileWriter = new FileWriter("src/main/resources/players/" + player.getUsername() + ".json"); + fileWriter.write(gson.toJson(player)); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/My part 6/main/java/controller/Main.java b/My part 6/main/java/controller/Main.java new file mode 100644 index 0000000..274e490 --- /dev/null +++ b/My part 6/main/java/controller/Main.java @@ -0,0 +1,10 @@ +package controller; + +import view.LoginMenuView; + +public class Main { + public static void main(String[] args) { + Database.prepareGame(); + LoginMenuView.loginMenuView(); + } +} \ No newline at end of file diff --git a/My part 6/main/java/controller/SpellCardController.java b/My part 6/main/java/controller/SpellCardController.java new file mode 100644 index 0000000..6080ef6 --- /dev/null +++ b/My part 6/main/java/controller/SpellCardController.java @@ -0,0 +1,537 @@ +package controller; + +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.SpellCardView; + +import java.util.ArrayList; +import java.util.Collections; + +public class SpellCardController { +// this method doesn't handle field spell cards + public static boolean doSpellCardEffect(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { +// handle every kind of spell cards except field and equip + String cardName = spellCard.getName(); + switch (cardName) { + case "Monster Reborn": + return doMonsterRebornEffect(turnPlayer, notTurnPlayer); + case "Terraforming": + return doTerraformingEffect(turnPlayer); + case "Pot of Greed": + return doPotOfGreedEffect(turnPlayer); + case "Raigeki": + return doRaigekiEffect(notTurnPlayer); + case "Change of Heart": + return doChangeOfHeartEffect(); + case "Harpie's Feather Duster": + return doHarpieFeatherDusterEffect(notTurnPlayer); + case "Swords of Revealing Light": + return doSwordsOfRevealingLight(); + case "Dark Hole": + return doDarkHoleEffect(turnPlayer, notTurnPlayer); + case "Supply Squad": +// TODO: i should know how turn changes, then handle it --> it shouldn't handle here + break; + case "Spell Absorption": + return true; + case "Messenger of peace": +// TODO: handle it base on Parsa code + break; + case "Twin Twisters": + return doTwinTwistersEffect(turnPlayer, notTurnPlayer); + case "Mystical space typhoon": + return doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + case "Ring of defense": +// TODO: handle it base trap and monster code + break; +// it's the only ritual spell card + case "Advanced Ritual Art": + return doAdvancedRitualArtEffect(); + } + +// handle equip spell cards + return chooseMonsterToEquip(turnPlayer, notTurnPlayer, spellCard); +// any other kind of card doesn't enter to this method + } + + +// handle every kind of spell cards except field and equip + private static boolean doMonsterRebornEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showGraveyardsMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(turnPlayer.getBoard().getGraveyard()); + int notTurnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()); + if (turnPlayerGraveyardMonsterCardsSize + notTurnPlayerGraveyardMonsterCardsSize == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findMonsterRebornChosenCard(turnPlayer, notTurnPlayer, cardNumber); + if (chosenCard != null) break; + SpellCardView.invalidNumber(); + } + +// TODO: how to handle special summon + return true; + } + + private static int getCardNumber() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findCardNumber()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static MonsterCard findMonsterRebornChosenCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + ArrayList turnPlayerGraveyard = turnPlayer.getBoard().getGraveyard(); + ArrayList notTurnPlayerGraveyard = notTurnPlayer.getBoard().getGraveyard(); + + for (Card card : turnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + for (Card card : notTurnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + + return null; + } + + private static boolean doTerraformingEffect(Player player) { +// TODO: do Iman handle with main cards? + ArrayList cards = player.getBoard().getDeck().getMainCards(); + ArrayList fieldSpellCards = findFieldSpellCards(cards); + + SpellCardView.showFieldSpellCards(fieldSpellCards); + if (fieldSpellCards.size() == 0) return false; + + MagicCard chosenFieldSpellCard; + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= fieldSpellCards.size()) { + chosenFieldSpellCard = fieldSpellCards.get(cardNumber - 1); + player.getBoard().getCardsInHand().add(chosenFieldSpellCard); + cards.remove(chosenFieldSpellCard); + break; + } + SpellCardView.invalidNumber(); + } + + Collections.shuffle(cards); + return true; + } + + private static ArrayList findFieldSpellCards(ArrayList cards) { +// create array list of field spell cards + ArrayList fieldSpellCards = new ArrayList<>(); + for (Card card : cards) { + if (!Card.isMonsterCard(card)) { + MagicCard magicCard = (MagicCard) card; + if (magicCard.getIcon().equals("Field")) fieldSpellCards.add(magicCard); + } + } + return fieldSpellCards; + } + + private static boolean doPotOfGreedEffect(Player player) { + Board board = player.getBoard(); + ArrayList deckCards = board.getDeck().getMainCards(); + if (deckCards.size() < 2) return false; + + Card firstCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + Card secondCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + board.getCardsInHand().add(firstCard); + board.getCardsInHand().add(secondCard); + + return true; + } + + private static boolean doRaigekiEffect(Player player) { + MonsterCard[] monstersZone = player.getBoard().getMonstersZone(); + if (isCardArrayNull(monstersZone)) return false; + emptyAZone(player, monstersZone); + return true; + } + + private static boolean isCardArrayNull(Card[] cards) { + for (Card card : cards) { + if (card != null) return false; + } + return true; + } + + private static void emptyAZone(Player player, Card[] cards) { + for (int i = 0; i < cards.length; ++i) { + if (cards[i] != null) { + player.getBoard().getGraveyard().add(cards[i]); + cards[i] = null; + } + } + } + + private static boolean doChangeOfHeartEffect() { +// TODO: handle it! + return true; + } + + private static boolean doHarpieFeatherDusterEffect(Player player) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (isCardArrayNull(magicsZone)) return false; + emptyAZone(player, magicsZone); + return true; + } + + private static boolean doSwordsOfRevealingLight() { +// TODO: handle it! + return true; + } + + private static boolean doDarkHoleEffect(Player turnPlayer, Player notTurnPlayer) { + return doRaigekiEffect(turnPlayer) || doRaigekiEffect(notTurnPlayer); + } + + public static void doSpellAbsorptionEffect(Player player) { + if (player.getBoard().isCardFaceUp("Spell Absorption")) player.increaseLifePoint(500); + } + + private static boolean doTwinTwistersEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showCardsInHand(turnPlayer); + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= cardsInHand.size()) { + turnPlayer.getBoard().getGraveyard().add(cardsInHand.get(cardNumber - 1)); + cardsInHand.remove(cardNumber - 1); + break; + } + SpellCardView.invalidNumber(); + } + + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return true; + + int numberOfChosenCards; + while (true) { + numberOfChosenCards = getNumberOfCardsToChoose(); + if (0 <= numberOfChosenCards && numberOfChosenCards <= 2 && + numberOfChosenCards <= turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards) { + break; + } + SpellCardView.invalidNumber(); + } + + for (int i = 0; i < numberOfChosenCards; i++) { + doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + } + + return true; + } + + private static int getNumberOfCardsToChoose() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findNumberOfCardsToChoose()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static boolean destroyAMagicCardFromMagicZone(Player player, int cardNumber, int startNumber) { + MagicCard[] playerMagicsZone = player.getBoard().getMagicsZone(); + for (int i = 1; i < playerMagicsZone.length; i++) { + if (playerMagicsZone[i] != null) { + if (startNumber == cardNumber) { + player.getBoard().getGraveyard().add(playerMagicsZone[i]); + playerMagicsZone[i] = null; + return true; + } + ++startNumber; + } + } + + return false; + } + + private static boolean doMysticalSpaceTyphoonEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (destroyAMagicCardFromMagicZone(turnPlayer, cardNumber, 1) || + destroyAMagicCardFromMagicZone(notTurnPlayer, cardNumber, turnPlayerNumberOfMagicCards + 1)) + break; + SpellCardView.invalidNumber(); + } + + return true; + } + +// it's the only ritual spell card + private static boolean doAdvancedRitualArtEffect() { +// TODO: handle it based on Iman's code + return false; + } + + +// handle field spell cards + public static void handleFieldSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + MagicCard firstPlayerFieldZoneCard = firstPlayer.getBoard().getFieldZone(); + MagicCard secondPlayerFieldZoneCard = secondPlayer.getBoard().getFieldZone(); + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, firstPlayerFieldZoneCard, doEffect); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, secondPlayerFieldZoneCard, doEffect); + } + + private static Player findMonsterCardOwner(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard) { + if (firstPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return firstPlayer; + if (secondPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return secondPlayer; + +// this will never happen, just for assurance + return null; + } + + private static void handleEachFieldSpellCardEffect(Player monsterCardOwner, MonsterCard monsterCard, MagicCard fieldZoneCard, + boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + if (fieldZoneCard == null || !fieldZoneCard.getCardFaceUp()) return; + + switch (fieldZoneCard.getName()) { + case "Yami": + handleYamiEffect(monsterCard, doEffect); + break; + case "Forest": + handleForestEffect(monsterCard, doEffect); + break; + case "Closed Forest": + handleClosedForestEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Umiiruka": + handleUmiirukaEffect(monsterCard, doEffect); + break; + } + } + + private static void handleYamiEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } else if (monsterCard.getMonsterType().equals("Fairy")) { + if (doEffect) { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } + } + } + + private static void handleForestEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Insect") || monsterCardType.equals("Beast") || + monsterCardType.equals("Beast-Warrior")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } + } + + private static void handleClosedForestEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int graveyardMonsterCardsSize = Card.findNumberOfMonsterCards(monsterCardOwner.getBoard().getGraveyard()); + MonsterCard[] monstersZone = monsterCardOwner.getBoard().getMonstersZone(); + + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null && monstersZone[i].getMonsterType().equals("Beast-Type")) { + if (doEffect) monsterCard.increaseAttackPoints(100 * graveyardMonsterCardsSize); + else monsterCard.decreaseAttackPoints(100 * graveyardMonsterCardsSize); + } + } + + } + + private static void handleUmiirukaEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (monsterCard.getMonsterType().equals("Aqua")) { + if (doEffect) { + monsterCard.increaseAttackPoints(500); + monsterCard.decreaseDefencePoints(400); + } else { + monsterCard.decreaseAttackPoints(500); + monsterCard.increaseDefencePoints(400); + } + } + } + + +// handle equip spell cards + private static boolean chooseMonsterToEquip(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { + SpellCardView.showFaceUpMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerFaceUpMonsterCardsNumber = turnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + int notTurnPlayerFaceUpMonsterCardsNumber = notTurnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + Board turnPlayerBoard = turnPlayer.getBoard(); + if (turnPlayerFaceUpMonsterCardsNumber + notTurnPlayerFaceUpMonsterCardsNumber == 0 || + !turnPlayerBoard.isMagicsZoneFull()) return false; + if (spellCard.getName().equals("Magnum Shield") && turnPlayerBoard.getNumberOfWarriorMonsterCards() == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findFaceUpMonsterCard(turnPlayer, notTurnPlayer, cardNumber); +// second and third condition assure me that Magnum Shield just equipped Warrior Monster Cards + if (chosenCard != null && + (!spellCard.getName().equals("Magnum Shield") || chosenCard.getMonsterType().equals("Warrior"))) break; + SpellCardView.invalidNumber(); + } + + chosenCard.addToEquippedBy(spellCard); + turnPlayerBoard.addMagicCardToMagicsZone(spellCard); + return true; + } + + private static MonsterCard findFaceUpMonsterCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + MonsterCard[] turnPlayerFaceUpMonsterCards = turnPlayer.getBoard().getMonstersZone(); + MonsterCard[] notTurnPlayerFaceUpMonsterCards = notTurnPlayer.getBoard().getMonstersZone(); + + for (int i = 1; i < turnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = turnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + for (int i = 1; i < notTurnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = notTurnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + + return null; + } + + public static void handleEquipSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + for (MagicCard spellCard : monsterCard.getEquippedBy()) { + switch (spellCard.getName()) { + case "Sword of dark destruction": + handleSwordOfDarkDestructionEffect(monsterCard, doEffect); + break; + case "Black Pendant": + handleBlackPendantEffect(monsterCard, doEffect); + break; + case "United We Stand": + handleUnitedWeStandEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Magnum Shield": + handleMagnumShieldEffect(monsterCard, doEffect); + break; + } + } + } + + private static void handleSwordOfDarkDestructionEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(400); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(400); + monsterCard.increaseDefencePoints(200); + } + } + + } + + private static void handleBlackPendantEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (doEffect) monsterCard.increaseAttackPoints(500); + else monsterCard.decreaseAttackPoints(500); + } + + private static void handleUnitedWeStandEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int numberOfFaceUpMonsterCards = monsterCardOwner.getBoard().getNumberOfFaceUpMonsterCards(); + if (doEffect) { + monsterCard.increaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.increaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } else { + monsterCard.decreaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.decreaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } + } + + private static void handleMagnumShieldEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + +// I know that Magnum Shield just equipped Warrior monster cards + if (monsterCard.isDefensePosition()) { + if (doEffect) monsterCard.increaseDefencePoints(monsterCard.getAttackPoints()); + else monsterCard.decreaseDefencePoints(monsterCard.getAttackPoints()); + } else { + if (doEffect) monsterCard.increaseAttackPoints(monsterCard.getDefensePoints()); + else monsterCard.decreaseAttackPoints(monsterCard.getDefensePoints()); + } + } +} diff --git a/My part 6/main/java/controller/Utils.java b/My part 6/main/java/controller/Utils.java new file mode 100644 index 0000000..05df0d8 --- /dev/null +++ b/My part 6/main/java/controller/Utils.java @@ -0,0 +1,34 @@ +package controller; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Utils { + private static Scanner scanner; + + static { + scanner = new Scanner(System.in); + } + + public static Scanner getScanner() { + return scanner; + } + + public static void resetScanner(String input) { + scanner = new Scanner(new ByteArrayInputStream(input.getBytes())); + } + + public static ByteArrayOutputStream setByteArrayOutputStream() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + return outContent; + } + + public static Matcher getMatcher(String regex, String command) { + return Pattern.compile(regex).matcher(command); + } +} diff --git a/My part 6/main/java/controller/deckmenu/DeckMenuController.java b/My part 6/main/java/controller/deckmenu/DeckMenuController.java new file mode 100644 index 0000000..952b347 --- /dev/null +++ b/My part 6/main/java/controller/deckmenu/DeckMenuController.java @@ -0,0 +1,94 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +import java.util.Objects; + +public class DeckMenuController { + + private static DeckMenuController instance = null; + + private DeckMenuController() { + } + + public static DeckMenuController getInstance() { + return Objects.requireNonNullElseGet(instance, () -> (instance = new DeckMenuController())); + } + + public void createDeck(String name, Player owner) { + if (!DeckMenuTools.isDeckNameUnique(name)) + return; + + new Deck(name, owner , true , true); + DeckMenuOutput.getInstance().showMessage("deck created successfully!"); + } + + public void deleteDeck(String name) { + if (!DeckMenuTools.doesDeckExist(name)) {return;} + // if (DeckMenuTools.isDeckNameUnique(name)) return; + + DeckMenuDatabase.removeDeck(name); + DeckMenuOutput.getInstance().showMessage("deck deleted successfully!"); + + } + + + public void setActiveDeck(String name, Player player) { + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesDeckExist(name) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(name), player); + if (isPermitted) { + player.activateADeck(deck); + + DeckMenuOutput.getInstance().showMessage("deck activated successfully!"); + } + + } + + public void addCardToDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card = null; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player) + && ((isMain) ? DeckMenuTools.doesDeckHaveSpace(deck) : DeckMenuTools.doesSideDeckHaveSpace(deck)) + && DeckMenuTools.isNumberOfCardsInDeckLessThanFour(deck, card = DeckMenuDatabase.getInstance().getCardByName(cardName)) + && DeckMenuTools.doesPlayerHaveEnoughCards(card , player); + if (isPermitted) { + player.removeCardFromBoughtCards(card); + deck.addCard(card, isMain); + DeckMenuOutput.getInstance().showMessage("card added to deck successfully!"); + } + } + + public void removeCardFromDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player); + if (isPermitted) { + card = DeckMenuDatabase.getInstance().getCardByName(cardName); + player.addCardToBoughtCards(card); + deck.moveCardTo(player.getAllPlayerCard(),card, isMain , true); + DeckMenuOutput.getInstance().showMessage("card removed from deck successfully!"); + } + } + + public void showAllDecks(Player player) { + for (Deck deck : player.getAllDeck()) + DeckMenuOutput.getInstance().showMessage(deck.toString()); + + } + + public void showDeck(String name, Player player, boolean isMain) { + if (!DeckMenuTools.doesDeckExist(name)) + return; + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (!DeckMenuTools.doesDeckBelongToPlayer(deck, player)) + return; + DeckMenuOutput.getInstance().showMessage(deck.toString(isMain)); + + } +} diff --git a/My part 6/main/java/controller/deckmenu/DeckMenuDatabase.java b/My part 6/main/java/controller/deckmenu/DeckMenuDatabase.java new file mode 100644 index 0000000..d16b03f --- /dev/null +++ b/My part 6/main/java/controller/deckmenu/DeckMenuDatabase.java @@ -0,0 +1,50 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; +import java.util.ArrayList; + +public class DeckMenuDatabase { + + public static ArrayList allPlayers = new ArrayList<>(); + public static ArrayList allCards = new ArrayList<>(); + public static ArrayList allDecks = new ArrayList<>(); + + private DeckMenuDatabase() { + } + + private static DeckMenuDatabase instance; + + public static DeckMenuDatabase getInstance() { + if (instance == null) + instance = new DeckMenuDatabase(); + return instance; + } + + public static void removeDeck(String name) { + allDecks.removeIf(deck -> deck.getName().equals(name)); + } + + public Card getCardByName(String name) { + for (Card card : allCards) { + if (card.getName().equals(name)) + return card; + } + return null; + + } + + public Deck getDeckByName(String name) { + for (Deck deck : allDecks) { + if (deck.getName().equals(name)) + return deck; + } + return null; + + } + // setPlayers() {file v Jason} + // setDecks() {file v Jason} + // loadingDatabase() + // updatingDatabase() + +} diff --git a/My part 6/main/java/controller/deckmenu/DeckMenuOutput.java b/My part 6/main/java/controller/deckmenu/DeckMenuOutput.java new file mode 100644 index 0000000..92896b1 --- /dev/null +++ b/My part 6/main/java/controller/deckmenu/DeckMenuOutput.java @@ -0,0 +1,23 @@ +package controller.deckmenu; + +public class DeckMenuOutput { + + private DeckMenuOutput() { + } + + private static DeckMenuOutput instance; + + public static DeckMenuOutput getInstance() { + if (instance == null) + instance = new DeckMenuOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My part 6/main/java/controller/deckmenu/DeckMenuTools.java b/My part 6/main/java/controller/deckmenu/DeckMenuTools.java new file mode 100644 index 0000000..20266b2 --- /dev/null +++ b/My part 6/main/java/controller/deckmenu/DeckMenuTools.java @@ -0,0 +1,70 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +public class DeckMenuTools { + public static boolean isDeckNameUnique(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck == null) + return true; + + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " already exists"); + return false; + + } + public static boolean doesDeckExist(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck != null) + return true; + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " does not exist"); + return false; + + } + public static boolean doesDeckBelongToPlayer(Deck deck, Player player) { + if (deck.getOwner().getUsername().equals(player.getUsername())) + return true; + DeckMenuOutput.getInstance().showMessage("this deck doesn't belong to you!"); + return false; + } + public static boolean doesDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getMainCards().size() < 60) + return true; + DeckMenuOutput.getInstance().showMessage("main deck is full!"); + return false; + } + public static boolean doesSideDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getSideCards().size() < 15) + return true; + DeckMenuOutput.getInstance().showMessage("side deck is full!"); + return false; + } + public static boolean isNumberOfCardsInDeckLessThanFour(Deck deck, Card card) { + if (deck.getNumberOfCardsInDeck(card) < 3) + return true; + DeckMenuOutput.getInstance().showMessage("there are already three cards with name " + card.getName() + + " in deck " + deck.getName() + " !"); + return false; + } + public static boolean isDeckAllowed(Deck deck) { + int numberOfCardsInSideDeck = deck.getNumberOfCardsInSideDeck(); + int numberOfCardsInMainDeck = deck.getNumberOfCardsInMainDeck(); + return numberOfCardsInMainDeck <= 60 && numberOfCardsInMainDeck >= 40 && numberOfCardsInSideDeck <= 15; + } + public static boolean doesPlayerHaveEnoughCards(Card card, Player player) { + if (player.hasCard(card)) + return true; + DeckMenuOutput.getInstance().showMessage("you dont have this type of card anymore!"); + return false; + } + public static boolean doesCardExist(String cardName) { + Card card = Card.getCardByName(cardName); + if (card != null) + return true; + DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist"); + return false; + } + +} diff --git a/My part 6/main/java/controller/duelmenu/DuelMenuController.java b/My part 6/main/java/controller/duelmenu/DuelMenuController.java new file mode 100644 index 0000000..c4ca63b --- /dev/null +++ b/My part 6/main/java/controller/duelmenu/DuelMenuController.java @@ -0,0 +1,726 @@ +package controller.duelmenu; + +import controller.SpellCardController; +import controller.Utils; +import model.Board; +import model.Deck; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.DuelMenuView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.regex.Matcher; + +public class DuelMenuController { + private Player turnPlayer; + private Player notTurnPlayer; + private Player helpTurnPlayer; + private Phases phase; + private boolean isAITurn; + private int isSummoned = 0; //0 : is not summoned before, 1 : is summoned before + + public static String specifyTurnPlayer(Player firstPlayer, Player secondPlayer) { + String firstPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(firstPlayer); + if (!isMiniGameChoiceValid(firstPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices firstPlayerChoice = MiniGameChoices.valueOf(firstPlayerChoiceInString.toUpperCase()); + + String secondPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(secondPlayer); + if (!isMiniGameChoiceValid(secondPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices secondPlayerChoice = MiniGameChoices.valueOf(secondPlayerChoiceInString.toUpperCase()); + + if (firstPlayerChoice.equals(secondPlayerChoice)) return "draw"; + + return findMiniGameWinner(firstPlayer, secondPlayer, firstPlayerChoice, secondPlayerChoice); + } + + private static boolean isMiniGameChoiceValid(String choice) { + try { + MiniGameChoices.valueOf(choice.toUpperCase()); + return true; + } catch (Exception exception) { + return false; + } + } + + private static String findMiniGameWinner(Player firstPlayer, Player secondPlayer, + MiniGameChoices firstPlayerChoice, MiniGameChoices secondPlayerChoice) { + switch (firstPlayerChoice) { + case STONE: + if (secondPlayerChoice.equals(MiniGameChoices.PAPER)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case PAPER: + if (secondPlayerChoice.equals(MiniGameChoices.SCISSOR)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case SCISSOR: + if (secondPlayerChoice.equals(MiniGameChoices.STONE)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + } + +// this is never happen + return null; + } + + public DuelMenuMessages initialGame(Player firstPlayer, Player secondPlayer) { +// TODO: handle it for ai + String result = specifyTurnPlayer(firstPlayer, secondPlayer); + if (result.equals("invalid choice")) return DuelMenuMessages.MINI_GAME_INVALID_CHOICE; + else if (result.equals("draw")) return DuelMenuMessages.DRAW; + else turnPlayer = Player.getPlayerByUsername(result); + + if (turnPlayer.equals(firstPlayer)) notTurnPlayer = secondPlayer; + else notTurnPlayer = firstPlayer; + + turnPlayer.createBoard(); + notTurnPlayer.createBoard(); + + turnPlayer.getBoard().setDeck(turnPlayer.getActivatedDeck()); + notTurnPlayer.getBoard().setDeck(notTurnPlayer.getActivatedDeck()); + + Collections.shuffle(turnPlayer.getActivatedDeck().getMainCards()); + Collections.shuffle(notTurnPlayer.getActivatedDeck().getMainCards()); + + return DuelMenuMessages.SHOW_TURN_PLAYER; + } + + public DuelMenuMessages findCommand(String command) { +// TODO: handle menu commands --> menu exit and ... + if (command.startsWith("decrease ")) return cheatCodeDecreaseOpponentLifePont(command); + else if (command.startsWith("increase ")) return cheatCodeIncreaseLifePoint(command); + else if (command.startsWith("duel set-winner ")) return cheatCodeSetWinner(command); + else if (command.startsWith("select ")) return checkSelectCard(command); + else if (command.equals("select -d")) return deselectCard(); + else if (command.equals("summon")) ;//return checkSummonMonster(); + else if (command.equals("set")) return checkSetACard(); + else if (command.startsWith("set --position")) ;// return checkChangePosition(command); + else if (command.equals("flip-summon")) return flipSummon(); + else if (command.equals("attack direct")) return directAttack(); + else if (command.startsWith("attack")) return attack(command); + else if (command.equals("activate effect")) return checkActiveASpellCard(); + else if (command.equals("show graveyard")) { + DuelMenuView.showGraveyard(turnPlayer.getBoard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("back")) ;//checkBack(); + else if (command.equals("card show --selected")) { + DuelMenuView.printCard(1, turnPlayer.getBoard().getSelectedCard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("cancel")) ;//cancelCommand(); + else if (command.equals("surrender")) /*TODO*/ ; + +// TODO: handle cheat/debug commands + + return DuelMenuMessages.INVALID_COMMAND; + } + + private DuelMenuMessages cheatCodeDecreaseOpponentLifePont(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_DECREASE_OPPONENT_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + notTurnPlayer.decreaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + } + + private DuelMenuMessages cheatCodeIncreaseLifePoint(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_INCREASE_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + turnPlayer.increaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + } + + private DuelMenuMessages cheatCodeSetWinner(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_SET_WINNER.getRegex(), command); + if (matcher.find()) { + String nickname = matcher.group(1); + if (turnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/ ; + else if (notTurnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/ ; + else return DuelMenuMessages.WRONG_NICKNAME_CHEAT_CODE; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + return DuelMenuMessages.EMPTY; + } + + //Iman's Code + private void changePhase() { + phase = phase.next(); + DuelMenuMessages.changephase(phase); + if (phase == Phases.DRAW_PHASE){ + drawPhase(); + } + + } + + private void changeGameTurn(Player firstPlayer, Player secondPlayer) { + if (turnPlayer == firstPlayer) { + turnPlayer = secondPlayer; + notTurnPlayer = firstPlayer; + } + if (turnPlayer == secondPlayer) { + turnPlayer = firstPlayer; + notTurnPlayer = secondPlayer; + } + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void changeGameTurn() { + helpTurnPlayer = turnPlayer; + turnPlayer = notTurnPlayer; + notTurnPlayer = helpTurnPlayer; + isSummoned = 0; + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void drawPhase() { + changeGameTurn(); + DuelMenuMessages.playerTurn(turnPlayer); + cardDraw(); + } + + public void cardDraw() { + Deck deck = turnPlayer.getBoard().getDeck(); + if (deck.getNumberOfCardsInMainDeck() == 0) { + turnPlayer.setLifePoint(0); + return; + } + turnPlayer.getBoard().drawCard(); + } + + private void summonMonster() { + int position = 0; // TODO fix this + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + + if (selectedMonster.getLevel() == 5 || selectedMonster.getLevel() == 6) { + summonWithOneTribute(position); + } else if (selectedMonster.getLevel() == 7 || selectedMonster.getLevel() == 8) { + summonWithTwoTribute(position); + } else { + selectedCard.getCardFaceUp(); + selectedMonster.settoOO(selectedMonster); + turnPlayer.getBoard().addMonsterCardToMonsterZone(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + DuelMenuMessages.summonedSuccessfully(); + } + } + + private DuelMenuMessages checkSummonMonster() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard) || selectedCard.getCardType() == CardTypes.RITUAL) { + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + else if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + else if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + else if (isSummoned == 1) { + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + + else { + summonMonster(); + return DuelMenuMessages.EMPTY; + } + } + +// public void tributeCardFromMonsterZone(int position) { +// graveyardCards.add(monstesrZones.get(position).getCurrentMonster()); +// monsterZones.get(position).removeCard(); +// } + + private DuelMenuMessages summonWithOneTribute(int position) { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (!turnPlayer.getBoard().isThereOneMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + return DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE; + } + String addressString = Utils.getScanner().nextLine().trim(); + if (addressString.equals("")) return null; // TODO fix this + int address = setCardAddressInMyBoard(Integer.parseInt(addressString)); + if (address < 1 || address > 5) { + return DuelMenuMessages.NO_MONSTER_ON_ADDRESS; + } + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address)) { + return DuelMenuMessages.NO_MONSTER_ON_THIS_ADDRESS; + } + else { + monstersZone[address] = null; + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + cardsInHand.remove(selectedCard); + isSummoned = 1; + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + } + } + + private void summonWithTwoTribute(int position) { + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (!turnPlayer.getBoard().isThereTwoMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + DuelMenuMessages.NotEnoughCardForTribute(); + } + String addressString1 = Utils.getScanner().nextLine().trim(); + if (addressString1.equals("surrender")) return; + String addressString2 = Utils.getScanner().nextLine().trim(); + if (addressString2.equals("surrender")) return; + int address1 = setCardAddressInMyBoard(Integer.parseInt(addressString1)); + int address2 = setCardAddressInMyBoard(Integer.parseInt(addressString2)); + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address1)) return; + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address2)) return; + monstersZone[address1] = null; + monstersZone[address2] = null; + isSummoned = 1; + + } + + private int setCardAddressInMyBoard(int address) { + if (address == 5) return 5; + if (address == 3) return 3; + if (address == 1) return 2; + if (address == 2) return 2; + if (address == 4) return 4; + return -1; + } + + private DuelMenuMessages set() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + // int position = selectedCardIndex; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected()) { + return DuelMenuMessages.SET_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + if (isSummoned == 1){ + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + isSummoned = 1; + if (model.cards.Card.isMonsterCard(selectedCard)) { + MonsterCard selectedMonster = (MonsterCard) selectedCard; + setAMonsterCard(selectedMonster); + } + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + + + } + + private DuelMenuMessages checkSetACard() { + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (board.getSelectedCard() == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!board.isACardInHandSelected()) return DuelMenuMessages.CANT_SET; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.NOT_TRUE_PHASE; + else if (Card.isMonsterCard(selectedCard)) return setAMonsterCard(selectedCard); + + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + } + + + private DuelMenuMessages setAMonsterCard(Card selectedCard) { + MonsterCard monsterCard = (MonsterCard) selectedCard; + if (turnPlayer.getBoard().isMonsterZoneFull()) return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + else turnPlayer.getBoard().addMonsterCardToMonsterZone(monsterCard); + monsterCard.settoDH(monsterCard); + return DuelMenuMessages.SET_SUCCESSFULLY; + } + + private DuelMenuMessages setPositionAttack() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (!selectedMonster.isDefensePosition() || !selectedMonster.toString().equals("DO")) { + return DuelMenuMessages.ALREADY_IN_WANTED_POSITION; + } + if (isSummoned == 1){ //TODO Already changed position? + return DuelMenuMessages.ALREADY_CHANGED_POSITION; + } + selectedMonster.settoOO(selectedMonster); + return DuelMenuMessages.MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY; + } + + private DuelMenuMessages setPositionDefence() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (selectedMonster.isDefensePosition() || !selectedMonster.toString().equals("OO")) { + return DuelMenuMessages.ALREADY_IN_WANTED_POSITION; + } + if (isSummoned == 1){ //TODO Already changed position? + return DuelMenuMessages.ALREADY_CHANGED_POSITION; + } + selectedMonster.settoDO(selectedMonster); + return DuelMenuMessages.MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY; + } + + private DuelMenuMessages flipSummon() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard)) { // check type of monsters + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (selectedMonster.toString().equals("DH") || isSummoned != 0) { + return DuelMenuMessages.FLIP_SUMMON_NOT_POSSIBLE; + } + selectedMonster.settoDO(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + + } + + private DuelMenuMessages ritualSummon() { +// TODO: complete it! + return DuelMenuMessages.EMPTY; + } + + private DuelMenuMessages specialSummon() { +// TODO: complete it! + return DuelMenuMessages.EMPTY; + } + + private DuelMenuMessages checkSelectCard(String command) { +// TODO: handle --> if there isn't any card in main deck, he/she loses +// TODO: maybe clean it more + Matcher matcher; + if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MONSTER_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MAGIC_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_FIELD_ZONE.getRegex(), command).find()) { + if (turnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(true); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_CARDS_IN_HAND.getRegex(), command)).find() ) { + int number = Integer.parseInt(matcher.group(1)); + if (number > turnPlayer.getBoard().getCardsInHand().size()) { + return DuelMenuMessages.INVALID_SELECTION; + } + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getCardsInHand().get(number - 1)); + turnPlayer.getBoard().setMyCardSelected(true); + turnPlayer.getBoard().setACardInHandSelected(true); + + } else { + turnPlayer.getBoard().setSelectedCard(null); + turnPlayer.getBoard().setMyCardSelected(false); + return DuelMenuMessages.INVALID_SELECTION; + } + + return DuelMenuMessages.CARD_SELECTED; + } + + private boolean isSelectionValid(Matcher matcher) { + int number = Integer.parseInt(matcher.group(1)); + return number <= 5 && number >= 1; + } + + private boolean isCardAvailableInMonstersZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMonstersZone()[number] != null; + } + + private boolean isCardAvailableInMagicsZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMagicsZone()[number] != null; + } + + private void selectCardFromMonstersZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMonstersZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMonstersZone()[number]); + } + } + + private void selectCardFromMagicsZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMagicsZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMagicsZone()[number]); + } + } + + private void selectCardFromFieldZone(boolean isMyCardSelected) { + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getFieldZone()); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getSelectedCard()); + } + } + + private DuelMenuMessages deselectCard() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages result = checkDeselectCard(); + if (result == null) { + board.setSelectedCard(null); + return DuelMenuMessages.DESELECTED; + } else return result; + } + + private DuelMenuMessages checkDeselectCard() { + Board board = turnPlayer.getBoard(); + if (board.getSelectedCard() == null) + return DuelMenuMessages.NOT_SELECTED_CARD; + return null; + } +// +// +// private void victimize() { +//// TODO: handle it! +// } +// + +// +// private DuelMenuMessages checkChangePosition(String command) { +// +// } +// +// private DuelMenuMessages changePosition(String command) { +// +// } +// +// private void updateGraveyard() { +//// TODO: handle it! +// } +// + + private DuelMenuMessages attack(String command) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.ATTACK.getRegex(), command); + if (matcher.find()) { + int numberOfChosenCard = Integer.parseInt(matcher.group(1)); + + DuelMenuMessages result = checkAttack(numberOfChosenCard); + if (result == null) { + MonsterCard attackingMonster = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentMonster = opponentPlayerBoard.getMonstersZone()[numberOfChosenCard]; + + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + DuelMenuMessages tempResult = attackingMonster.attack(turnPlayer, notTurnPlayer, numberOfChosenCard); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + + return tempResult; + } + return result; + + } else return DuelMenuMessages.INVALID_CARD_SELECT; + } + + private DuelMenuMessages checkAttack(int numberOfChosenCard) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + if (attackingPlayerBoard.getSelectedCard() == null || !attackingPlayerBoard.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (attackingPlayerBoard.getSelectedCard() instanceof MonsterCard) + return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + //TODO check battle phase + MonsterCard card = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + if (card.isAttacked()) + return DuelMenuMessages.ATTACKED_BEFORE; + if (opponentPlayerBoard.getMonstersZone()[numberOfChosenCard] == null) + return DuelMenuMessages.NO_CARD_FOUND_IN_THE_POSITION; + return null; + } + + private DuelMenuMessages directAttack() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages messages = checkDirectAttack(); + if (messages != null) + return messages; + else { + MonsterCard card = (MonsterCard) board.getSelectedCard(); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + notTurnPlayer.decreaseLifePoint(card.getAttackPoints()); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + + DuelMenuMessages.setDamageAmount(card.getAttackPoints()); + return DuelMenuMessages.DIRECT_ATTACK_DONE; + } + } + + private DuelMenuMessages checkDirectAttack() { + Board board = turnPlayer.getBoard(); + + if (board.getSelectedCard() == null || !board.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (phase.equals(Phases.BATTLE_PHASE)) + return DuelMenuMessages.NOT_SUITABLE_PHASE; + if (board.getSelectedCard() instanceof MonsterCard) { + MonsterCard card = (MonsterCard) board.getSelectedCard();//TODO: handle cast exception!! + if (card.isAttacked()) return DuelMenuMessages.ATTACKED_BEFORE; + } else return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + + return null; + } + + private DuelMenuMessages checkActiveASpellCard() { +// TODO: clean it! + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (selectedCard == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!selectedCard.getCardType().equals(CardTypes.SPELL)) return DuelMenuMessages.NOT_SPELL_CARD; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.CANT_ACTIVATE_SPELL_EFFECT; + else if (selectedCard.isPowerUsed()) return DuelMenuMessages.CARD_ACTIVATED_BEFORE; + else if (!turnPlayer.getBoard().isMyCardSelected()) return DuelMenuMessages.NOT_OWNER; + + MagicCard spellCard = (MagicCard) selectedCard; + if (spellCard.getIcon().equals("Field")) { + turnPlayer.getBoard().addSpellCardToFieldZone(spellCard); + spellCard.setPowerUsed(true); + spellCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } else if (board.isMagicsZoneFull() && board.isACardInHandSelected()) return DuelMenuMessages.FULL_MAGICS_ZONE; + + if (!SpellCardController.doSpellCardEffect(turnPlayer, notTurnPlayer, spellCard)) return DuelMenuMessages.UNDONE_PREPARATIONS; + if (board.isACardInHandSelected()) board.addMagicCardToMagicsZone(spellCard); + selectedCard.setPowerUsed(true); + selectedCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } + + private DuelMenuMessages setAMagicCard(MagicCard magicCard) { + Board board = turnPlayer.getBoard(); + if (magicCard.getIcon().equals("Field")) board.addSpellCardToFieldZone(magicCard); + else if (board.isMagicsZoneFull()) return DuelMenuMessages.FULL_MAGICS_ZONE; + else board.addMagicCardToMagicsZone(magicCard); + magicCard.setPowerUsed(false); + magicCard.setCardFaceUp(false); + + return DuelMenuMessages.SET_SUCCESSFULLY; + } + +// private DuelMenuMessages checkBack() { +// +// } +// +// private void cancelCommand() { +// +// } +// +// private Player/*or Enum*/ checkWinner() { +// +// } +// +// TODO: ----------------------------------------------- + +} diff --git a/My part 6/main/java/controller/duelmenu/DuelMenuMessages.java b/My part 6/main/java/controller/duelmenu/DuelMenuMessages.java new file mode 100644 index 0000000..bf50377 --- /dev/null +++ b/My part 6/main/java/controller/duelmenu/DuelMenuMessages.java @@ -0,0 +1,112 @@ +package controller.duelmenu; + +import model.Player; + +public enum DuelMenuMessages { + MINI_GAME_INVALID_CHOICE("please enter a valid option\n"), + DRAW("draw\nplease try again:\n"), + SHOW_TURN_PLAYER(" should start first\n"), + INVALID_SELECTION("invalid selection\n"), + CARD_SELECTED("card selected\n"), + CARD_NOT_FOUND("no card found in the given position\n"), + UNAVAILABLE_SELECTED_CARD("no card is selected yet\n"), + NOT_SPELL_CARD("activate effect is only for spell cards.\n"), + CANT_ACTIVATE_SPELL_EFFECT("you can’t activate an effect on this turn\n"), + CARD_ACTIVATED_BEFORE("you have already activated this card\n"), + FULL_MAGICS_ZONE("spell card zone is full\n"), + UNDONE_PREPARATIONS("preparations of this spell are not done yet\n"), + SPELL_ACTIVATED("spell activated\n"), + NOT_OWNER("you aren't owner of selected card\n"), + CANT_SET("you can’t set this card\n"), + NOT_TRUE_PHASE("you can’t do this action in this phase\n"), + SET_SUCCESSFULLY("set successfully\n"), + NOT_SELECTED_CARD("no card is selected yet\n"), + ATTACKED_BEFORE("this card already attacked\n"), + NOT_SUITABLE_PHASE("you can’t do this action in this phase\n"), + INVALID_CARD_SELECT("invalid selection\n"), + NO_CARD_FOUND_IN_THE_POSITION("no card found in the given position\n"), + CANT_ATTACK_WITH_CARD("you can’t attack with this card\n"), + YOU_CANT_ATTACK_TO_THIS_CARD("you cant attack to this card\n"), + ATTACK_CANCELED("attack to this card was canceled\n"), + DIRECT_ATTACK_DONE("you opponent receives battle damage\n"), + DESELECTED("card deselected\n"), + INVALID_COMMAND_CHEAT_CODE("invalid command\n"), + OPPONENT_GOT_DAMAGE_IN_ATTACK("your opponent’s monster is destroyed and your opponent receives battle damage\n"), + ATTACKING_PLAYER_CARD_DESTROYED("Your monster card is destroyed and you received battle damage\n"), + DEFENSE_POSITION_MONSTER_DESTROYED("the defense position monster is destroyed\n"), + NO_CARD_DESTROYED("no card is destroyed\n"), + RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD("no card is destroyed and you received battle damage\n"), + BOTH_CARDS_GET_DESTROYED("both you and your opponent monster cards are destroyed and no one receives damage\n"), + WRONG_NICKNAME_CHEAT_CODE("your entered nickname is wrong\n"), + EMPTY(""), + NO_CARD_SELECTED("no card is selected yet\n"), + SUMMON_NOT_POSSIBLE("you can’t summon this card\n"), + FLIP_SUMMON_NOT_POSSIBLE("you can’t flip summon this card\n"), + SET_NOT_POSSIBLE("you can’t set this card\n"), + PLAYER_TURN("it's 's turn"), + PHASE_IS_CHANGED("phase: \n"), + ALREADY_SUMMONED_OR_SET("you already summoned/set on this turn\n"), + NOT_ENOUGH_CARD_FOR_TRIBUTE("there are not enough card for tribute\n"), + NO_MONSTER_ON_THIS_ADDRESS("there are no monster one this address\n"), + MONSTER_ZONE_IS_FULL("monster card zone is full\n"), + SUMMONED_SUCCESSFULLY("summoned successfully\n"), + NO_MONSTER_ON_ADDRESS("there no monsters on this address"), + MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY("monster card position changed successfully\n"), + ALREADY_CHANGED_POSITION("you already changed this card position in this turn\n"), + ALREADY_IN_WANTED_POSITION("this card is already in the wanted position\n"), + CHANG_POSITION_NOT_POSSIBLE("you can’t change this card position\n"), + INVALID_COMMAND("invalid command\n"); + private String message; + + DuelMenuMessages(String message) { + this.message = message; + } + + public static void setShowTurnPlayer(Player player) { + DuelMenuMessages.SHOW_TURN_PLAYER.message = player.getUsername() + " should start first\n"; + } + + public static void summonedSuccessfully() { + System.out.print("summoned successfully\n"); + } + + public static void NotEnoughCardForTribute(){ + DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE.message = "there are not enough card for tribute\n"; + System.out.print("there are not enough card for tribute\n"); + } + + public static void noCardSelected() { + DuelMenuMessages.NO_CARD_SELECTED.message = "no card is selected yet"; + } + + public static void playerTurn(Player player) { + DuelMenuMessages.PLAYER_TURN.message = "it's + player.getUsername() + 's turn"; + } + + public static void changephase(Phases phase) { + DuelMenuMessages.PHASE_IS_CHANGED.message = "phase: " + phase; + } + + public static void setDamageAmount(int damageAmount) { + DuelMenuMessages.DIRECT_ATTACK_DONE.message = "you opponent receives " + damageAmount + " battle damage\n"; + } + + public static void setOpponentGotDamageInAttack(int damage) { + DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK.message = + "your opponent’s monster is destroyed and your opponent receives" + damage + " battle damage\n"; + } + + public static void setAttackingPlayerCardDestroyed(int damage) { + DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED.message = + "Your monster card is destroyed and you received " + damage + " battle damage\n"; + } + + public static void setReceiveDamageByAttackingToDefenseCard(int damage) { + DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD.message = + "no card is destroyed and you received " + damage + " battle damage\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 6/main/java/controller/duelmenu/DuelMenuRegexes.java b/My part 6/main/java/controller/duelmenu/DuelMenuRegexes.java new file mode 100644 index 0000000..9450450 --- /dev/null +++ b/My part 6/main/java/controller/duelmenu/DuelMenuRegexes.java @@ -0,0 +1,28 @@ +package controller.duelmenu; + +public enum DuelMenuRegexes { + SELECT_MONSTER_ZONE("^select --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_MAGIC_ZONE("^select --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN("^select --(?:monster|M) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN("^select --(?:spell|S) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_FIELD_ZONE("^select --(?:field|F)$"), + SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN("^select --(?:field|F) --(?:opponent|O)$"), + SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:field|F)$"), + SELECT_CARDS_IN_HAND("^select --(?:hand|H) ((?:-|)\\d+)$"), + CHEAT_DECREASE_OPPONENT_LIFE_POINT("^decrease --opponentLP ([0-9]+)$"), + CHEAT_INCREASE_LIFE_POINT("^increase --LP ([0-9]+)$"), + CHEAT_SET_WINNER("^duel set-winner (\\S+)$"), + ATTACK("^attack ([0-9]+)$"); + + private final String regex; + + DuelMenuRegexes(String message) { + this.regex = message; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 6/main/java/controller/duelmenu/MiniGameChoices.java b/My part 6/main/java/controller/duelmenu/MiniGameChoices.java new file mode 100644 index 0000000..57881a4 --- /dev/null +++ b/My part 6/main/java/controller/duelmenu/MiniGameChoices.java @@ -0,0 +1,17 @@ +package controller.duelmenu; + +public enum MiniGameChoices { + STONE("stone"), + PAPER("paper"), + SCISSOR("scissor"); + + private final String choice; + + MiniGameChoices(String choice) { + this.choice = choice; + } + + public String getChoice() { + return choice; + } +} diff --git a/My part 6/main/java/controller/duelmenu/Phases.java b/My part 6/main/java/controller/duelmenu/Phases.java new file mode 100644 index 0000000..14000bb --- /dev/null +++ b/My part 6/main/java/controller/duelmenu/Phases.java @@ -0,0 +1,15 @@ +package controller.duelmenu; + +public enum Phases { + DRAW_PHASE, + STANDBY_PHASE, + MAIN_PHASE_1, + BATTLE_PHASE, + MAIN_PHASE_2, + END_PHASE; + private static Phases[] values = values(); + + public Phases next() { + return values[(this.ordinal() + 1) % values.length]; + } +} diff --git a/My part 6/main/java/controller/importexportmenu/ImportExportMenuController.java b/My part 6/main/java/controller/importexportmenu/ImportExportMenuController.java new file mode 100644 index 0000000..cde2f83 --- /dev/null +++ b/My part 6/main/java/controller/importexportmenu/ImportExportMenuController.java @@ -0,0 +1,100 @@ +package controller.importexportmenu; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Utils; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.regex.Matcher; + +public class ImportExportMenuController { + public static ImportExportMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU; + else if (command.equals("menu show-current")) return ImportExportMenuMessages.SHOW_MENU; + else if (command.startsWith("import card")) return importCard(command); + else if (command.startsWith("export card")) return exportCard(command); + + return ImportExportMenuMessages.INVALID_COMMAND; + } + + private static ImportExportMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + return ImportExportMenuMessages.INVALID_NAVIGATION; + } + + private static ImportExportMenuMessages importCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.IMPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + try { + FileReader fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + MonsterCard monsterCard = gson.fromJson(fileReader, MonsterCard.class); + + if (Card.getCardByName(cardName) != null) return ImportExportMenuMessages.AVAILABLE_CARD; + if (monsterCard.getAttribute() == null) { +// so we understand that the card is a magic card + fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + MagicCard magicCard = gson.fromJson(fileReader, MagicCard.class); + Card.addCardToAllCards(magicCard); + if (isCardIncomplete(magicCard) || isMagicCardIncomplete(magicCard)) + return ImportExportMenuMessages.INVALID_FILE; + } else { +// so we understand that the card is a monster card + monsterCard.createEquippedByArrayList(); + Card.addCardToAllCards(monsterCard); + if (isCardIncomplete(monsterCard) || isMonsterCardIncomplete(monsterCard)) + return ImportExportMenuMessages.INVALID_FILE; + } + fileReader.close(); + } catch (IOException ignore) { + return ImportExportMenuMessages.UNAVAILABLE_FILE; + } + + + return ImportExportMenuMessages.EMPTY; + } + + private static boolean isCardIncomplete(Card card) { + return card.getName() == null || card.getDescription() == null || card.getCardType() == null; + } + + private static boolean isMonsterCardIncomplete(MonsterCard monsterCard) { + return monsterCard.getAttribute() == null || monsterCard.getMonsterType() == null; + } + + private static boolean isMagicCardIncomplete(MagicCard magicCard) { + return magicCard.getIcon() == null || magicCard.getStatus() == null; + } + + private static ImportExportMenuMessages exportCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.EXPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card card = Card.getCardByName(cardName); + if (card == null) return ImportExportMenuMessages.UNAVAILABLE_CARD; + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(card)); + fileWriter.close(); + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + + + return ImportExportMenuMessages.EMPTY; + } +} diff --git a/My part 6/main/java/controller/importexportmenu/ImportExportMenuMessages.java b/My part 6/main/java/controller/importexportmenu/ImportExportMenuMessages.java new file mode 100644 index 0000000..8f83021 --- /dev/null +++ b/My part 6/main/java/controller/importexportmenu/ImportExportMenuMessages.java @@ -0,0 +1,23 @@ +package controller.importexportmenu; + +public enum ImportExportMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_IMPORT_EXPORT_MENU(""), + SHOW_MENU("Import/Export Menu\n"), + INVALID_COMMAND("invalid command\n"), + UNAVAILABLE_FILE("there isn't any file with your entered card name\n"), + INVALID_FILE("your card file is not valid to import\n"), + AVAILABLE_CARD("your entered card name is available\n"), + UNAVAILABLE_CARD("your entered card name is not available\n"), + EMPTY(""); + + private final String message; + + ImportExportMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 6/main/java/controller/importexportmenu/ImportExportMenuRegexes.java b/My part 6/main/java/controller/importexportmenu/ImportExportMenuRegexes.java new file mode 100644 index 0000000..65c74dc --- /dev/null +++ b/My part 6/main/java/controller/importexportmenu/ImportExportMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.importexportmenu; + +public enum ImportExportMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + IMPORT_CARD("^import card ([^\n]+)$"), + EXPORT_CARD("^export card ([^\n]+)$"); + + private final String regex; + + ImportExportMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 6/main/java/controller/loginmenu/LoginMenuController.java b/My part 6/main/java/controller/loginmenu/LoginMenuController.java new file mode 100644 index 0000000..178d000 --- /dev/null +++ b/My part 6/main/java/controller/loginmenu/LoginMenuController.java @@ -0,0 +1,120 @@ +package controller.loginmenu; + +import controller.Utils; +import model.Player; +import view.MainMenuView; + +import java.util.regex.Matcher; + +public class LoginMenuController { + public static LoginMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) System.exit(0); + else if (command.equals("menu show-current")) return LoginMenuMessages.SHOW_MENU; + else if (command.startsWith("user create")) { + return checkCreateUser(command); + } else if (command.startsWith("user login")) { + return checkLoginUser(command); + } + + return LoginMenuMessages.INVALID_COMMAND; + } + + private static LoginMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(LoginMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return LoginMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return LoginMenuMessages.INVALID_NAVIGATION; + } + + return LoginMenuMessages.FIRST_LOGIN; + } + + private static LoginMenuMessages checkCreateUser(String command) { + Matcher matcher; + String username, nickname, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIRST_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(2); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SECOND_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(3); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_THIRD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(1); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FOURTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIFTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(3); + password = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SIXTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (Player.getPlayerByUsername(username) != null) { + LoginMenuMessages.setUsername(username); + return LoginMenuMessages.USERNAME_EXISTS; + } + if (Player.isNicknameExist(nickname)) { + LoginMenuMessages.setNickname(nickname); + return LoginMenuMessages.NICKNAME_EXISTS; + } + +// TODO: handle to have "strong password" error + createUser(username, password, nickname); + return LoginMenuMessages.USER_CREATED; + } + + private static void createUser(String username, String password, String nickname) { + new Player(username, password, nickname); + } + + private static LoginMenuMessages checkLoginUser(String command) { + Matcher matcher; + String username, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (!Player.isPasswordCorrect(username, password)) { + return LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD; + } + + return LoginMenuMessages.USER_LOGGED_IN; + } + + public static void loginUser(String command) { + Matcher matcher; + String username = null; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + } + + + MainMenuView mainMenuView = new MainMenuView(Player.getPlayerByUsername(username)); + mainMenuView.mainMenuView(); + } +} diff --git a/My part 6/main/java/controller/loginmenu/LoginMenuMessages.java b/My part 6/main/java/controller/loginmenu/LoginMenuMessages.java new file mode 100644 index 0000000..167c111 --- /dev/null +++ b/My part 6/main/java/controller/loginmenu/LoginMenuMessages.java @@ -0,0 +1,31 @@ +package controller.loginmenu; + +public enum LoginMenuMessages { + FIRST_LOGIN("please login first"), + INVALID_NAVIGATION("menu navigation is not possible"), + SHOW_MENU("Login Menu"), + USER_CREATED("user created successfully!"), + USERNAME_EXISTS("user with username already exists"), + NICKNAME_EXISTS("user with nickname already exists"), + USER_LOGGED_IN("user logged in successfully!"), + UNMATCHED_USERNAME_AND_PASSWORD("Username and password didn’t match!"), + INVALID_COMMAND("invalid command"); + + private String message; + + LoginMenuMessages(String message) { + this.message = message; + } + + public static void setUsername(String username) { + USERNAME_EXISTS.message = "user with username " + username + " already exists"; + } + + public static void setNickname(String nickname) { + NICKNAME_EXISTS.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 6/main/java/controller/loginmenu/LoginMenuRegexes.java b/My part 6/main/java/controller/loginmenu/LoginMenuRegexes.java new file mode 100644 index 0000000..f518551 --- /dev/null +++ b/My part 6/main/java/controller/loginmenu/LoginMenuRegexes.java @@ -0,0 +1,23 @@ +package controller.loginmenu; + +public enum LoginMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + CREATE_USER_FIRST_PATTERN("^user create --(?:username|U) (\\S+) --(?:nickname|N) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_SECOND_PATTERN("^user create --(?:username|U) (\\S+) --(?:password|P) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_THIRD_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_FOURTH_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"), + CREATE_USER_FIFTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:username|U) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_SIXTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:nickname|N) (\\S+) --(?:username|U) (\\S+)$"), + LOGIN_USER_USERNAME_PATTERN("^user login --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + LOGIN_USER_PASSWORD_PATTERN("^user login --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"); + + private final String regex; + + LoginMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 6/main/java/controller/mainmenu/MainMenuController.java b/My part 6/main/java/controller/mainmenu/MainMenuController.java new file mode 100644 index 0000000..e6be9bd --- /dev/null +++ b/My part 6/main/java/controller/mainmenu/MainMenuController.java @@ -0,0 +1,114 @@ +package controller.mainmenu; + +import controller.Utils; +import model.Player; +import view.*; + +import java.util.regex.Matcher; + +public class MainMenuController { + private final Player loggedInPlayer; + + public MainMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public MainMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return MainMenuMessages.EXIT_MAIN_MENU; + else if (command.equals("menu show-current")) return MainMenuMessages.SHOW_MENU; + else if (command.equals("user logout")) return MainMenuMessages.USER_LOGGED_OUT; + else if (command.startsWith("duel")) return enterDuelMenu(command); + + return MainMenuMessages.INVALID_COMMAND; + } + + private MainMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(MainMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return MainMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Main")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Duel")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Deck")) { + DeckMenuView deckMenuView = new DeckMenuView(loggedInPlayer); + deckMenuView.runDeckMenu(); + } else if (menu.equalsIgnoreCase("Scoreboard")) { + ScoreboardMenuView scoreboardMenuView = new ScoreboardMenuView(); + scoreboardMenuView.runScoreboard(); + } else if (menu.equalsIgnoreCase("Profile")) { + ProfileMenuView profileMenuView = new ProfileMenuView(loggedInPlayer); + profileMenuView.profileMenuView(); + } else if (menu.equalsIgnoreCase("Shop")) { + ShopMenuView shopMenuView = new ShopMenuView(loggedInPlayer); + shopMenuView.shopMenuView(); + } else if (menu.equalsIgnoreCase("ImportExport")) { + ImportExportMenuView importExportMenuView = new ImportExportMenuView(); + importExportMenuView.ImportExportMenuView(); + } + + return MainMenuMessages.EMPTY; + } + + private MainMenuMessages enterDuelMenu(String command) { +// TODO: clean and optimise this code according to AI + Matcher matcher; + String opponentPlayerCommand, rounds; + if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIRST_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_THIRD_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FOURTH_PATTERN.getRegex(), command) ).find()) { + opponentPlayerCommand = matcher.group(1); + rounds = matcher.group(2); + } else if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SECOND_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIFTH_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SIXTH_PATTERN.getRegex(), command) ).find()) { + rounds = matcher.group(1); + opponentPlayerCommand = matcher.group(2); + } else { + return MainMenuMessages.INVALID_COMMAND; + } + + if (opponentPlayerCommand.startsWith("second-player")) { + String opponentPlayerUsername = opponentPlayerCommand.substring(14); + Player opponentPlayer = Player.getPlayerByUsername(opponentPlayerUsername); + if (opponentPlayer == null) { + return MainMenuMessages.UNAVAILABLE_USERNAME; + } + + if (opponentPlayer.equals(loggedInPlayer)) return MainMenuMessages.SAME_USERNAME; + + if (loggedInPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(loggedInPlayer.getUsername()); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } else if (opponentPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(opponentPlayerUsername); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } + +// TODO: handle MainMenuMessages.INVALID_DECK message +// TODO: MainMenuMessages.setInvalidDeck(opponentPlayerUsername or loggedInPlayer.getUsername()); +// TODO: return MainMenuMessages.INVALID_DECK; + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + +// TODO: handle 1 or 3 turn game + DuelMenuView duelMenuView = new DuelMenuView(loggedInPlayer, opponentPlayer); + duelMenuView.duelMenuView(); + } else { +// TODO: handle entering to enter duel menu by AI + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + } + + return MainMenuMessages.EMPTY; + } +} diff --git a/My part 6/main/java/controller/mainmenu/MainMenuMessages.java b/My part 6/main/java/controller/mainmenu/MainMenuMessages.java new file mode 100644 index 0000000..85fa672 --- /dev/null +++ b/My part 6/main/java/controller/mainmenu/MainMenuMessages.java @@ -0,0 +1,33 @@ +package controller.mainmenu; + +public enum MainMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_MAIN_MENU(""), + SHOW_MENU("Main Menu\n"), + USER_LOGGED_OUT("user logged out successfully!\n"), + UNAVAILABLE_USERNAME("there is no player with this username\n"), + SAME_USERNAME("please enter another username\n"), + UNAVAILABLE_ACTIVE_DECK(" has no active deck\n"), + INVALID_DECK("’s deck is invalid\n"), + INVALID_ROUNDS_NUMBER("number of rounds is not supported\n"), + INVALID_COMMAND("invalid command\n"), + EMPTY(""); + + private String message; + + MainMenuMessages(String message) { + this.message = message; + } + + public static void setUnavailableActiveDeck(String username) { + UNAVAILABLE_ACTIVE_DECK.message = username + " has no active deck\n"; + } + + public static void setInvalidDeck(String username) { + INVALID_DECK.message = username + "’s deck is invalid\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 6/main/java/controller/mainmenu/MainMenuRegexes.java b/My part 6/main/java/controller/mainmenu/MainMenuRegexes.java new file mode 100644 index 0000000..210780f --- /dev/null +++ b/My part 6/main/java/controller/mainmenu/MainMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.mainmenu; + +public enum MainMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + ENTER_DUEL_MENU_FIRST_PATTERN("^duel --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_SECOND_PATTERN("^duel --(?:new|N) --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_THIRD_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_FOURTH_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+) --(?:new|N)$"), + ENTER_DUEL_MENU_FIFTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_SIXTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N)$"); + + private final String regex; + + MainMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 6/main/java/controller/profilemenu/ProfileMenuController.java b/My part 6/main/java/controller/profilemenu/ProfileMenuController.java new file mode 100644 index 0000000..5384e86 --- /dev/null +++ b/My part 6/main/java/controller/profilemenu/ProfileMenuController.java @@ -0,0 +1,99 @@ +package controller.profilemenu; + +import controller.Database; +import controller.Utils; +import model.Player; + +import java.util.regex.Matcher; + +public class ProfileMenuController { + private final Player loggedInPlayer; + + public ProfileMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ProfileMenuMessages findCommand(String command) { + String[] split = command.split("\\s+"); + if (split.length < 2) { + return ProfileMenuMessages.INVALID_COMMAND; + } else if (split[1].equals("enter")) { + return ProfileMenuMessages.CANT_NAVIGATE_MENU; + } else if (split[1].equals("exit")) { + return ProfileMenuMessages.EXIT_MENU; + } else if (split[1].equals("show")) { + return ProfileMenuMessages.PROFILE_MENU; + } else if (split[2].equals("--nickname")) { + return changeNickname(command); + } else if (command.startsWith("profile change")) { + return changePassword(command); + } + + return ProfileMenuMessages.INVALID_COMMAND; + } + + public ProfileMenuMessages changeNickname(String command) { + Matcher matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_NICKNAME.getRegex(), command); + + ProfileMenuMessages holdEnum = checkChangeNickName(matcher); + + if (holdEnum == null) { + loggedInPlayer.setNickname(matcher.group(1)); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_NICKNAME_DONE; + } + return holdEnum; + } + + public ProfileMenuMessages checkChangeNickName(Matcher matcher) { + if (matcher.find()) { + String nickname = matcher.group(1); + if (Player.isNicknameExist(nickname)) { + ProfileMenuMessages.setNickname(nickname); + return ProfileMenuMessages.NOT_UNIQUE_NICKNAME; + } + return null; + } else return ProfileMenuMessages.INVALID_COMMAND; + + } + + public ProfileMenuMessages changePassword(String command) { + String currentPassword, newPassword; + Matcher matcher; + if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIRST_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SECOND_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_THIRD_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FOURTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIFTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SIXTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else return ProfileMenuMessages.INVALID_COMMAND; + + ProfileMenuMessages holdEnum = checkChangePassword(currentPassword, newPassword); + + if (holdEnum == null) { + loggedInPlayer.setPassword(newPassword); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_PASSWORD_DONE; + } + + return holdEnum; + } + + public ProfileMenuMessages checkChangePassword(String currentPassword, String newPassword) { + if (!loggedInPlayer.getPassword().equals(currentPassword)) return ProfileMenuMessages.WRONG_CURRENT_PASSWORD; + if (currentPassword.equals(newPassword)) return ProfileMenuMessages.SAME_PASSWORD; + return null; + } +} diff --git a/My part 6/main/java/controller/profilemenu/ProfileMenuMessages.java b/My part 6/main/java/controller/profilemenu/ProfileMenuMessages.java new file mode 100644 index 0000000..4c0895f --- /dev/null +++ b/My part 6/main/java/controller/profilemenu/ProfileMenuMessages.java @@ -0,0 +1,27 @@ +package controller.profilemenu; + +public enum ProfileMenuMessages { + NOT_UNIQUE_NICKNAME("user with nickname already exists"), + CHANGE_NICKNAME_DONE("nickname changed successfully!"), + CHANGE_PASSWORD_DONE("password changed successfully!"), + WRONG_CURRENT_PASSWORD("current password is invalid"), + INVALID_COMMAND("invalid command"), + PROFILE_MENU("profile menu"), + EXIT_MENU("exit"), + CANT_NAVIGATE_MENU("menu navigation is not possible"), + SAME_PASSWORD("please enter a new password"); + + private String message; + + ProfileMenuMessages(String message) { + this.message = message; + } + + public static void setNickname(String nickname) { + ProfileMenuMessages.NOT_UNIQUE_NICKNAME.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 6/main/java/controller/profilemenu/ProfileMenuRegexes.java b/My part 6/main/java/controller/profilemenu/ProfileMenuRegexes.java new file mode 100644 index 0000000..ba8630d --- /dev/null +++ b/My part 6/main/java/controller/profilemenu/ProfileMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.profilemenu; + +public enum ProfileMenuRegexes { + CHANGE_NICKNAME("^profile change --nickname (\\S+)$"), + CHANGE_PASSWORD_FIRST_PATTERN("^profile change --(?:password|P) --(?:current|C) (\\S+) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_SECOND_PATTERN("^profile change --(?:password|P) --(?:new|N) (\\S+) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_THIRD_PATTERN("^profile change --(?:current|C) (\\S+) --(?:password|P) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_FOURTH_PATTERN("^profile change --(?:current|C) (\\S+) --(?:new|N) (\\S+) --(?:password$|P)"), + CHANGE_PASSWORD_FIFTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:password|P) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_SIXTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:current|C) (\\S+) --(?:password$|P)"); + + private final String regex; + + ProfileMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 6/main/java/controller/scoreboardmenu/Scoreboard.java b/My part 6/main/java/controller/scoreboardmenu/Scoreboard.java new file mode 100644 index 0000000..cb725a7 --- /dev/null +++ b/My part 6/main/java/controller/scoreboardmenu/Scoreboard.java @@ -0,0 +1,40 @@ +package controller.scoreboardmenu; + +import java.util.ArrayList; +import model.*; + +public class Scoreboard { + + private Scoreboard() { + } + + private static Scoreboard instance; + + public static Scoreboard getInstance() { + if (instance == null) + instance = new Scoreboard(); + return instance; + } + + public void showScoreboard() { + int counter = 1; + int index = 0; + long previousScore = -1; + StringBuilder output = new StringBuilder(); + ArrayList allUsers = Player.getAllPlayers(); + allUsers.sort(Player::compareTo); + for (Player player : allUsers) { + + + if (player.getScore() != previousScore) { + index += counter; + counter = 1; + } else counter++; + output.append(index).append(". ").append(player.getNickname()).append(": ").append(player.getScore()).append("\n"); + previousScore = player.getScore(); + + } + ScoreboardOutput.getInstance().showMessage(output.toString()); + } + +} diff --git a/My part 6/main/java/controller/scoreboardmenu/ScoreboardOutput.java b/My part 6/main/java/controller/scoreboardmenu/ScoreboardOutput.java new file mode 100644 index 0000000..c77252d --- /dev/null +++ b/My part 6/main/java/controller/scoreboardmenu/ScoreboardOutput.java @@ -0,0 +1,23 @@ +package controller.scoreboardmenu; + +public class ScoreboardOutput { + + private ScoreboardOutput() { + } + + private static ScoreboardOutput instance; + + public static ScoreboardOutput getInstance() { + if (instance == null) + instance = new ScoreboardOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My part 6/main/java/controller/shopmenu/ShopMenuController.java b/My part 6/main/java/controller/shopmenu/ShopMenuController.java new file mode 100644 index 0000000..11dc61c --- /dev/null +++ b/My part 6/main/java/controller/shopmenu/ShopMenuController.java @@ -0,0 +1,63 @@ +package controller.shopmenu; + +import controller.Database; +import controller.Utils; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.DuelMenuRegexes; +import model.Player; +import model.cards.Card; + +import java.util.regex.Matcher; + +public class ShopMenuController { + private final Player loggedInPlayer; + + public ShopMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ShopMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ShopMenuMessages.EXIT_SHOP_MENU; + else if (command.equals("menu show-current")) return ShopMenuMessages.SHOW_MENU; + else if (command.startsWith("shop buy")) return buyACard(command); + else if (command.equals("shop show --all")) return ShopMenuMessages.SHOW_ALL_CARDS; + else if (command.startsWith("increase ")) return cheatCodeIncreaseMoney(command); + + return ShopMenuMessages.INVALID_COMMAND; + } + + private ShopMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + return ShopMenuMessages.INVALID_NAVIGATION; + } + + private ShopMenuMessages buyACard(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.BUY_CARD.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card boughtCard = Card.getCardByName(cardName); + if (boughtCard == null) return ShopMenuMessages.UNAVAILABLE_CARD; + + int boughtCardPrice = boughtCard.getPrice(); + if (boughtCardPrice > loggedInPlayer.getMoney()) return ShopMenuMessages.NOT_ENOUGH_MONEY; + + loggedInPlayer.decreaseMoney(boughtCardPrice); + loggedInPlayer.addCardToBoughtCards(boughtCard); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ShopMenuMessages.EMPTY; + } + + private ShopMenuMessages cheatCodeIncreaseMoney(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.CHEAT_INCREASE_MONEY.getRegex(), command); + if (matcher.find()) { + loggedInPlayer.increaseMoney(Integer.parseInt(matcher.group(1))); + return ShopMenuMessages.EMPTY; + } else return ShopMenuMessages.INVALID_COMMAND; + + } +} diff --git a/My part 6/main/java/controller/shopmenu/ShopMenuMessages.java b/My part 6/main/java/controller/shopmenu/ShopMenuMessages.java new file mode 100644 index 0000000..339bd0a --- /dev/null +++ b/My part 6/main/java/controller/shopmenu/ShopMenuMessages.java @@ -0,0 +1,22 @@ +package controller.shopmenu; + +public enum ShopMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_SHOP_MENU(""), + SHOW_MENU("Shop Menu\n"), + UNAVAILABLE_CARD("there is no card with this name\n"), + NOT_ENOUGH_MONEY("not enough money\n"), + EMPTY(""), + SHOW_ALL_CARDS(""), + INVALID_COMMAND("invalid command\n"); + + private final String message; + + ShopMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 6/main/java/controller/shopmenu/ShopMenuRegexes.java b/My part 6/main/java/controller/shopmenu/ShopMenuRegexes.java new file mode 100644 index 0000000..0f4dd79 --- /dev/null +++ b/My part 6/main/java/controller/shopmenu/ShopMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.shopmenu; + +public enum ShopMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + BUY_CARD("^shop buy ([^\n]+)$"), + CHEAT_INCREASE_MONEY("^increase --money ([0-9]+)$"); + + private final String regex; + + ShopMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 6/main/java/model/Board.java b/My part 6/main/java/model/Board.java new file mode 100644 index 0000000..17afcf9 --- /dev/null +++ b/My part 6/main/java/model/Board.java @@ -0,0 +1,210 @@ +package model; + +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Board { + private MonsterCard[] monstersZone; + private MagicCard[] magicsZone; + private ArrayList graveyard; + private ArrayList cardsInHand; + private Deck deck; + private MagicCard fieldZone;//TODO: maybe it should be from these classes --> Spell / fieldSpell + private Card selectedCard; +// if this boolean equals "false" so we can conclude that opponent card selected or nothing selected + private boolean isMyCardSelected; + private boolean isACardInHandSelected; + + { + monstersZone = new MonsterCard[6]; + magicsZone = new MagicCard[6]; + graveyard = new ArrayList<>(); + cardsInHand = new ArrayList<>(); + fieldZone = null; + isMyCardSelected = false; + isACardInHandSelected = false; + } + + public void setDeck(Deck deck) { + this.deck = deck;//TODO: maybe we should have a copy of deck in duel menu --> if all changes don't apply in main deck + } + + public MonsterCard[] getMonstersZone() { + return monstersZone; + } + + public MagicCard[] getMagicsZone() { + return magicsZone; + } + + public ArrayList getGraveyard() { + return graveyard; + } + + public ArrayList getCardsInHand() { + return cardsInHand; + } + + public MagicCard getFieldZone() { + return fieldZone; + } + + public Card getSelectedCard() { + return selectedCard; + } + + public Deck getDeck() { + return deck; + } + + public void setSelectedCard(Card selectedCard) { + this.selectedCard = selectedCard; + } + + public void setFieldZone(MagicCard fieldZone) { this.fieldZone = fieldZone; } + + public boolean isMyCardSelected() { + return isMyCardSelected; + } + + public void setMyCardSelected(boolean myCardSelected) { + isMyCardSelected = myCardSelected; + } + + public boolean isACardInHandSelected() { + return isACardInHandSelected; + } + + public void setACardInHandSelected(boolean ACardInHandSelected) { + isACardInHandSelected = ACardInHandSelected; + } + + public boolean isMagicsZoneFull() { + return getNumberOfFullPartsOfMagicsZone() == 5; + } + + public boolean isMonsterZoneFull() { + return getNumberOfFullPartsOfMonstersZone() == 5; + } + + public boolean isMagicsZoneEmpty() { + return getNumberOfFullPartsOfMagicsZone() == 0; + } + + public int getNumberOfFullPartsOfMagicsZone() { + int numberOfFullPartsOfMagicsZone = 0; + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) ++numberOfFullPartsOfMagicsZone; + } + return numberOfFullPartsOfMagicsZone; + } + + public int getNumberOfFullPartsOfMonstersZone() { + int getNumberOfFullPartsOfMonstersZone = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null) ++getNumberOfFullPartsOfMonstersZone; + } + return getNumberOfFullPartsOfMonstersZone; + } + + public boolean isCardFaceUp(String cardName) { +// if cardName isn't available, then this method returns false + boolean isCardFaceUp = false; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = monstersZone[i].getCardFaceUp(); + } + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = magicsZone[i].getCardFaceUp(); + } + return isCardFaceUp; + } + + public void addSpellCardToFieldZone(MagicCard spellCard) { + MagicCard previousFieldZone = fieldZone; + if (previousFieldZone != null) graveyard.add(previousFieldZone); + setFieldZone(spellCard); + cardsInHand.remove(spellCard); + } + + public boolean addMagicCardToMagicsZone(MagicCard magicCard) { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] == null) { + magicsZone[i] = magicCard; + cardsInHand.remove(magicCard); + return true; + } + } + return false; + } + + public boolean addMonsterCardToMonsterZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] == null) { + monstersZone[i] = monsterCard; + cardsInHand.remove(monsterCard); + return true; + } + } + return false; + } + + public boolean isCardAvailableInMonstersZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monsterCard)) return true; + } + return false; + } + + public int getNumberOfFaceUpMonsterCards() { + int numberOfFaceUpMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getCardFaceUp()) ++numberOfFaceUpMonsterCards; + } + + return numberOfFaceUpMonsterCards; + } + + public int getNumberOfWarriorMonsterCards() { + int numberOfWarriorMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getMonsterType().equals("Warrior")) ++numberOfWarriorMonsterCards; + } + + return numberOfWarriorMonsterCards; + } + + public boolean isThereCardInAddress(MonsterCard[] monsterZone, int address) { + if (monsterZone[address] != null) return true; + return false; + } + + public boolean isThereOneMonsterForTribute(MonsterCard[] monsterZone) { + for (Card card : monsterZone) { + if (card != null) return true; + } + return false; + } + + public boolean isThereTwoMonsterForTribute(MonsterCard[] monstersZone) { + int counter = 0; + for (Card card : monstersZone) { + if (card != null) counter++; + } + if (counter < 2) { + return false; + } + return true; + } + + public void drawCard() { + Card card = deck.mainCards.get(deck.mainCards.size() - 1); + cardsInHand.add(card); + deck.mainCards.remove(deck.mainCards.size() - 1); + System.out.println("new card added to the hand: " + card.getName()); + } + + +} diff --git a/My part 6/main/java/model/Deck.java b/My part 6/main/java/model/Deck.java new file mode 100644 index 0000000..de3aad2 --- /dev/null +++ b/My part 6/main/java/model/Deck.java @@ -0,0 +1,216 @@ +package model; + +import controller.deckmenu.DeckMenuDatabase; +import model.*; +import controller.deckmenu.*; +import model.cards.Card; + +import java.util.ArrayList; + +public class Deck { + public ArrayList mainCards = new ArrayList<>(); + public ArrayList sideCards = new ArrayList<>(); + Player owner; + String name; + DeckType type; + Boolean isActive = false; + Boolean IsValid; + + public Deck(String name, Player owner, boolean hasSideDeck, boolean shouldBeSaved) { + this.name = name; + if (shouldBeSaved) + DeckMenuDatabase.allDecks.add(this); + if (!hasSideDeck) + sideCards = null; + this.owner = owner; + } + + public Deck(String name, Player owner) { + this.name = name; + sideCards = null; + this.owner = owner; + } + + public Deck(String name) { + this.name = name; + sideCards = null; + } + public Deck() { + sideCards = null; + } + + public void updateOwnerDecks() { + String deckType = (name.length() > 16) ? name.substring(name.length() - 16) : ""; + if (deckType.equals(".purchased-cards")) + owner.setAllPlayerCard(this); + else { + owner.getAllDeck().add(this); + if (this.isActive) + owner.setActiveDeck(this); + } + } + + public ArrayList getMainCards() { + if (mainCards == null) + return (mainCards = new ArrayList<>()); + return mainCards; + } + + public void setMainCards(ArrayList mainCards) { + this.mainCards = mainCards; + } + + public ArrayList getSideCards() { + return sideCards; + } + + public void setSideCards(ArrayList sideCards) { + this.sideCards = sideCards; + } + + public Player getOwner() { + return owner; + } + + public void setOwner(Player owner) { + this.owner = owner; + } + + public void setActive(Boolean active) { + isActive = active; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setActivation(Boolean active) { + isActive = active; + } + + public void setValid(Boolean valid) { + IsValid = valid; + } + + public void setType(DeckType type) { + this.type = type; + } + + public void addCard(Card card, boolean shouldBeAddedToMain) { + if (shouldBeAddedToMain) + mainCards.add(card); + else + sideCards.add(card); + if (card != null) + card.setCurrentDeck(this); + } + + public void addCard(Card card) { + mainCards.add(card); + if (card != null && !name.equals("selected collected deck")) + card.setCurrentDeck(this); + } + + public void moveCardTo(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCard(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public void moveCardToForGame(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCardForGame(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public boolean hasCard(Card card, boolean isMain) { + if (isMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) + return true; + + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + return true; + } + return false; + } + + public void removeCard(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) { + mainCards.remove(cardInMain); + return; + } + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + sideCards.remove(cardInSide); + return; + } + } + + public void removeCardForGame(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) + mainCards.remove(card); + else + sideCards.remove(card); + } + + public int getNumberOfCardsInDeck(Card card) { + int count = 0; + for (Card cardInDeck : mainCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + for (Card cardInDeck : sideCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + return count; + } + + public int getNumberOfCardsInMainDeck() { + return mainCards.size(); + } + + public int getNumberOfCardsInSideDeck() { + return sideCards.size(); + } + + public void updateCurrentDeck() { + if (mainCards != null) + for (Card card : mainCards) + if (card != null) + card.setCurrentDeck(this); + if (sideCards != null) + for (Card card : sideCards) + if (card != null) + card.setCurrentDeck(this); + } + + public String toString(boolean isMain) { + StringBuilder output = new StringBuilder(); + int number = 1; + if (isMain) + for (Card card : mainCards) { + if (card == null) + continue; + output.append(number).append(". ").append(card.toString()); + number++; + } + else + for (Card card : sideCards) { + if (card == null) + continue; + output.append(number).append(". ").append(card.toString()); + number++; + } + return output.toString(); + } + +} \ No newline at end of file diff --git a/My part 6/main/java/model/DeckType.java b/My part 6/main/java/model/DeckType.java new file mode 100644 index 0000000..2d1643c --- /dev/null +++ b/My part 6/main/java/model/DeckType.java @@ -0,0 +1,8 @@ +package model; + +public enum DeckType { + regulardeck, + inactivedeck, + graveyarddeck, + selectedcarddeck +} diff --git a/My part 6/main/java/model/Player.java b/My part 6/main/java/model/Player.java new file mode 100644 index 0000000..28c2187 --- /dev/null +++ b/My part 6/main/java/model/Player.java @@ -0,0 +1,289 @@ +package model; + +import com.google.gson.annotations.Expose; +import controller.Database; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Player { + private static ArrayList allPlayers; + + static { + allPlayers = new ArrayList<>(); + } + + @Expose + private ArrayList boughtCards; + @Expose + private ArrayList allMainDecks; + private Board board; + @Expose + private Deck sideDeck; + @Expose + private Deck activatedDeck; + @Expose + private String username; + @Expose + private String password; + @Expose + private String nickname; + @Expose + private long score; + @Expose + private long money; + private int lifePoint; + private transient Deck allPlayerCard; + private transient ArrayList allDeck = new ArrayList<>(); + private transient ArrayList gameDecks = new ArrayList<>(); + + { + boughtCards = new ArrayList<>(); + allMainDecks = new ArrayList<>(); + board = null; + sideDeck = new Deck(); + activatedDeck = null; + score = 0; + money = 100000; + lifePoint = 8000; + } + + public Player(String username, String password, String nickname) { + setUsername(username); + setPassword(password); + setNickname(nickname); + addPlayerToAllPlayers(this); + allPlayers.add(this); + Database.updatePlayerInformationInDatabase(this); + } + + public static Boolean isNicknameExist(String nickname) { + for (Player player : allPlayers) { + if (player.nickname.equals(nickname)) return true; + } + return false; + } + + public static Boolean isPasswordCorrect(String username, String password) { + Player player = getPlayerByUsername(username); + if (player == null) return false; + + return player.password.equals(password); + } + + public static Player getPlayerByUsername(String username) { + for (Player player : allPlayers) { + if (player.username.equals(username)) return player; + } + return null; + } + + public void setBoughtCards(ArrayList boughtCards) { + this.boughtCards = boughtCards; + } + + public Deck getActiveDeck() { + return activatedDeck; + } + + public void setActiveDeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public ArrayList getAllDeck() { + if (allDeck == null) + return (allDeck = new ArrayList<>()); + return allDeck; + } + + public void setAllDeck(ArrayList allDeck) { + this.allDeck = allDeck; + } + + public Deck getAllPlayerCard() { + return allPlayerCard; + } + + public static ArrayList getAllPlayers() { + return allPlayers; + } + + public void addCardToAllPlayerCard(Card card) { + this.allPlayerCard.getMainCards().add(card); + } + + public void setAllPlayerCard(Deck allPlayerCard) { + this.allPlayerCard = allPlayerCard; + } + + public static void addPlayerToAllPlayers(Player player) { + allPlayers.add(player); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public long getScore() { + return score; + } + + public long getMoney() { + return money; + } + + public Deck getActivatedDeck() { + return activatedDeck; + } + + public ArrayList getBoughtCards() { + return boughtCards; + } + + public void increaseScore(long score) { + this.score += score; + } + + public void decreaseScore(long score) { + this.score -= score; + } + + public void increaseMoney(long money) { + this.money += money; + } + + public void decreaseMoney(long money) { + this.money -= money; + } + + public void addCardToBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.add(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.add(new MagicCard((MagicCard) card)); + } + } + + public void addMainDeck(String deckName) { + Deck mainDeck = new Deck(deckName); + this.allMainDecks.add(mainDeck); + } + + public Boolean isMainDeckExist(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return true; + } + return false; + } + + public void deleteMainDeck(String deckName) { + Deck mainDeck = getDeckByName(deckName); + if (mainDeck != null) { + boughtCards.addAll(mainDeck.getMainCards()); + allMainDecks.remove(mainDeck); + } + } + + public Deck getDeckByName(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return deck; + } + return null; + } + + public int compareTo(Player player) { + if (this.score > player.score) + return -1; + if (this.score < player.score) + return 1; + if (this.nickname.compareTo(player.getNickname()) > 0) + return -1; + if (this.nickname.compareTo(player.getNickname()) < 0) + return 1; + return 0; + } + + public void activateADeck(String deckName) { + Deck deck = getDeckByName(deckName); + if (deck != null) activatedDeck = deck; + } + public void activateADeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public void addCardToMainDeck() { +// TODO: ???? but remember to remove this card from boughtCards :) + } + + public void removeACard() { +// TODO: ???? but remember to add this card from boughtCards :) + } + + public void decreaseLifePoint(int amount) { + this.lifePoint -= amount; + } + + public void increaseLifePoint(int amount) { + this.lifePoint += amount; + } + + public void setLifePoint(int lifePoint) { + this.lifePoint = lifePoint; + } + + public int getLifePoint() { + return lifePoint; + } + + public void createBoard() { + board = new Board(); + } + + public Board getBoard() { + return board; + } + + public boolean hasCard(Card card){ + for (Card boughtCard : boughtCards) { + if (card.getName().equals(boughtCard.getName())) + return true; + } + return false; + } + + public void removeCardFromBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.remove(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.remove(new MagicCard((MagicCard) card)); + } + } +} \ No newline at end of file diff --git a/My part 6/main/java/model/cards/Card.java b/My part 6/main/java/model/cards/Card.java new file mode 100644 index 0000000..9ebd536 --- /dev/null +++ b/My part 6/main/java/model/cards/Card.java @@ -0,0 +1,115 @@ +package model.cards; + +import com.google.gson.annotations.Expose; +import model.Deck; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.TreeMap; + +public class Card { + protected static HashMap allCards; + + static { + allCards = new HashMap<>(); + } + + @Expose + protected final String name; + protected final String description; + protected final CardTypes cardType; + protected final int price; +// if this boolean equals "false" so we can conclude that card is "face down" + protected transient boolean isCardFaceUp; + protected transient boolean isPowerUsed; + protected transient Deck currentDeck; + + { + isCardFaceUp = false; + isPowerUsed = false; + } + + public Card(String name, String description, CardTypes cardType, int price) { + this.name = name; + this.description = description; + this.cardType = cardType; + this.price = price; + } + + public static Card getCardByName(String name) { + return allCards.get(name); + } + + public static TreeMap getListOfCards() { + TreeMap listOfCards = new TreeMap<>(); + for (String cardName : allCards.keySet()) { + Integer cardPrice = allCards.get(cardName).getPrice(); + listOfCards.put(cardName, cardPrice); + } + return listOfCards; + } + + public static boolean isMonsterCard(Card card) { + try { + MonsterCard monsterCard = (MonsterCard) card; + return true; + } catch (Exception exception) { + return false; + } + } + + public static int findNumberOfMonsterCards(ArrayList cards) { + int numberOfMonsterCards = 0; + for (Card card : cards) { + if (Card.isMonsterCard(card)) ++numberOfMonsterCards; + } + return numberOfMonsterCards; + } + + public static void addCardToAllCards(Card card) { + allCards.put(card.getName(), card); + } + + public static HashMap getAllCards() { + return allCards; + } + + public String getName() { + return name; + } + + public void setCurrentDeck(Deck currentDeck) { this.currentDeck = currentDeck; } + + public Deck getCurrentDeck() { + return currentDeck; + } + + public CardTypes getCardType() { + return cardType; + } + + public int getPrice() { + return price; + } + + public void setPowerUsed(boolean powerUsed) { + isPowerUsed = powerUsed; + } + + public boolean isPowerUsed() { + return isPowerUsed; + } + + public String getDescription() { + return description; + } + + public Boolean getCardFaceUp() { + return isCardFaceUp; + } + + public void setCardFaceUp(Boolean cardFaceUp) { + isCardFaceUp = cardFaceUp; + } +} diff --git a/My part 6/main/java/model/cards/CardTypes.java b/My part 6/main/java/model/cards/CardTypes.java new file mode 100644 index 0000000..520056f --- /dev/null +++ b/My part 6/main/java/model/cards/CardTypes.java @@ -0,0 +1,26 @@ +package model.cards; + +import com.google.gson.annotations.SerializedName; + +public enum CardTypes { + @SerializedName("Normal") + NORMAL("Normal"), + @SerializedName("Effect") + EFFECT("Effect"), + @SerializedName("Ritual") + RITUAL("Ritual"), + @SerializedName("Spell") + SPELL("Spell"), + @SerializedName("Trap") + TRAP("Trap"); + + private final String regex; + + CardTypes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 6/main/java/model/cards/magiccard/MagicCard.java b/My part 6/main/java/model/cards/magiccard/MagicCard.java new file mode 100644 index 0000000..396faf8 --- /dev/null +++ b/My part 6/main/java/model/cards/magiccard/MagicCard.java @@ -0,0 +1,39 @@ +package model.cards.magiccard; + +import model.cards.Card; +import model.cards.CardTypes; + +public class MagicCard extends Card { + protected final String icon; + protected final MagicCardStatuses status; + + public MagicCard(String name, CardTypes cardType, String icon, String description, MagicCardStatuses status, int price) { + super(name, description, cardType, price); + this.icon = icon; + this.status = status; + allCards.put(name, this); + } + + public MagicCard(MagicCard magicCard) { + super(magicCard.name, magicCard.description, magicCard.cardType, magicCard.price); + this.icon = magicCard.icon; + this.status = magicCard.status; + } + + public String getIcon() { + return icon; + } + + public MagicCardStatuses getStatus() { + return status; + } + + public void print() { +// TODO: handle it --> «this.equals(null)» have error and «System.out.print» should be in the view +// if (this.equals(null)) +// System.out.print("E "); +// else if (isCardFaceUp) +// System.out.print("O "); +// else System.out.print("H "); + } +} diff --git a/My part 6/main/java/model/cards/magiccard/MagicCardStatuses.java b/My part 6/main/java/model/cards/magiccard/MagicCardStatuses.java new file mode 100644 index 0000000..a2540c9 --- /dev/null +++ b/My part 6/main/java/model/cards/magiccard/MagicCardStatuses.java @@ -0,0 +1,20 @@ +package model.cards.magiccard; + +import com.google.gson.annotations.SerializedName; + +public enum MagicCardStatuses { + @SerializedName("Limited") + LIMITED("Limited"), + @SerializedName("Unlimited") + UNLIMITED("Unlimited"); + + private final String regex; + + MagicCardStatuses(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 6/main/java/model/cards/monstercard/MonsterCard.java b/My part 6/main/java/model/cards/monstercard/MonsterCard.java new file mode 100644 index 0000000..d72dedd --- /dev/null +++ b/My part 6/main/java/model/cards/monstercard/MonsterCard.java @@ -0,0 +1,139 @@ +package model.cards.monstercard; + +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; + +import java.util.ArrayList; + +public class MonsterCard extends Card implements SpecialMonstersFunction { + protected final short level; + protected final MonsterCardAttributes attribute; + protected final String monsterType; + protected int attackPoints; + protected int defensePoints; + protected transient ArrayList equippedBy; +// if this boolean equals "false" so we can conclude that card is in attack position + protected transient boolean isDefensePosition; + protected transient boolean isAttacked = false; + + { + equippedBy = new ArrayList<>(); + isDefensePosition = false; + } + + public MonsterCard(String name, short level, MonsterCardAttributes attribute, String monsterType, CardTypes cardType, + int attackPoints, int defensePoints, String description, int price) { + super(name, description, cardType, price); + this.level = level; + this.attribute = attribute; + this.monsterType = monsterType; + setAttackPoints(attackPoints); + setDefensePoints(defensePoints); + allCards.put(name, this); + } + + public MonsterCard(MonsterCard monsterCard) { + super(monsterCard.name, monsterCard.description, monsterCard.cardType, monsterCard.price); + this.level = monsterCard.level; + this.attribute = monsterCard.attribute; + this.monsterType = monsterCard.monsterType; + this.attackPoints = monsterCard.attackPoints; + this.defensePoints = monsterCard.defensePoints; + } + + public short getLevel() { + return level; + } + + public MonsterCardAttributes getAttribute() { + return attribute; + } + + public String getMonsterType() { + return monsterType; + } + + public int getAttackPoints() { + return attackPoints; + } + + public void setAttackPoints(int attackPoints) { + this.attackPoints = attackPoints; + } + + public int getDefensePoints() { + return defensePoints; + } + + public void setDefensePoints(int defensePoints) { + this.defensePoints = defensePoints; + } + + public boolean isAttacked() { + return isAttacked; + } + + public void setAttacked(boolean attacked) { + isAttacked = attacked; + } + + public boolean isDefensePosition() { + return isDefensePosition; + } + + public void setDefensePosition(boolean defensePosition) { + isDefensePosition = defensePosition; + } + + public ArrayList getEquippedBy() { + return equippedBy; + } + + public void addToEquippedBy(MagicCard equippedBy) { + this.equippedBy.add(equippedBy); + } + + public void increaseAttackPoints(int amount) { + attackPoints += amount; + } + + public void decreaseAttackPoints(int amount) { + attackPoints -= amount; + } + + public void increaseDefencePoints(int amount) { + defensePoints += amount; + } + + public void decreaseDefencePoints(int amount) { + defensePoints -= amount; + } + + public void createEquippedByArrayList() { + equippedBy = new ArrayList<>(); + } + + public void settoDO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoDH(MonsterCard selectedMonster) { + this.setCardFaceUp(!isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoOO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = false; + } + + @Override + public String toString() { + if (!this.getCardFaceUp() && this.isDefensePosition) return "DH"; + else if (this.getCardFaceUp() && this.isDefensePosition) return "DO"; + else if (this.getCardFaceUp() && !this.isDefensePosition) return "OO"; + return "E "; + } +} diff --git a/My part 6/main/java/model/cards/monstercard/MonsterCardAttributes.java b/My part 6/main/java/model/cards/monstercard/MonsterCardAttributes.java new file mode 100644 index 0000000..4677550 --- /dev/null +++ b/My part 6/main/java/model/cards/monstercard/MonsterCardAttributes.java @@ -0,0 +1,10 @@ +package model.cards.monstercard; + +public enum MonsterCardAttributes { + DARK, + EARTH, + FIRE, + LIGHT, + WATER, + WIND; +} diff --git a/My part 6/main/java/model/cards/monstercard/SpecialMonstersFunction.java b/My part 6/main/java/model/cards/monstercard/SpecialMonstersFunction.java new file mode 100644 index 0000000..0b73141 --- /dev/null +++ b/My part 6/main/java/model/cards/monstercard/SpecialMonstersFunction.java @@ -0,0 +1,157 @@ +package model.cards.monstercard; + +import controller.duelmenu.DuelMenuMessages; +import model.Board; +import model.Player; + +public interface SpecialMonstersFunction { + default DuelMenuMessages attack(Player attackingPlayer, Player opponentPlayer, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + MonsterCard attackingCard = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentCard = opponentPlayerBoard.getMonstersZone()[numberToAttack]; + + if (opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack) != null) { + + switch (opponentCard.toString()) { + case "OO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayer.decreaseLifePoint(attackingCard.attackPoints - opponentCard.attackPoints); + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + DuelMenuMessages.setOpponentGotDamageInAttack(attackingCard.attackPoints - opponentCard.attackPoints); + return DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setAttackingPlayerCardDestroyed(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED; + } + + case "DO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + return DuelMenuMessages.DEFENSE_POSITION_MONSTER_DESTROYED; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + return DuelMenuMessages.NO_CARD_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setReceiveDamageByAttackingToDefenseCard(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD; + } + case "DH": + break; + } + + return null; + + } else + return opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + + default DuelMenuMessages defense(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + switch (opponentCard.getName()) { + case "Command knight": + commandKnightFunction(opponentPlayerBoard); + break; + case "Yomi Ship": + return yomiShipFunction(attackingPlayerBoard, attackingCard, opponentCard); + case "Suijin": + return suijinFunction(attackingCard); + case "Marshmallon": + return marshmallonFunction(attackingPlayer); + case "Texchanger": + return texchangerFunction(opponentCard); + case "Exploder Dragon": + return exploderDragon(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + return null; + } + + default DuelMenuMessages texchangerFunction(MonsterCard opponentCard) { + if (!opponentCard.isPowerUsed()) { + opponentCard.setPowerUsed(true); + // choosing a card ehzar??????? + return DuelMenuMessages.ATTACK_CANCELED; + } + return null; + } + + default DuelMenuMessages commandKnightFunction(Board opponentPlayerBoard) { + for (int i = 1; i <= 5; i++) { + if (opponentPlayerBoard.getMonstersZone()[i] != null && !opponentPlayerBoard.getMonstersZone()[i].getName().equals("Command knight")) { + return DuelMenuMessages.YOU_CANT_ATTACK_TO_THIS_CARD; + } + } + return null; + } + + default DuelMenuMessages yomiShipFunction(Board attackingPlayerBoard, MonsterCard attackingCard, MonsterCard opponentCard) { + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + return null; + } + + default DuelMenuMessages suijinFunction(MonsterCard attackingCard) { +// attackingCard.setAttackLevel(0);//TODO: undo it!! + return null; + } + + default DuelMenuMessages marshmallonFunction(Player attackingPlayer) { + attackingPlayer.decreaseLifePoint(1000); + return null; + } + + default DuelMenuMessages exploderDragon(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int number) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + return null; + } + + default void deleteMonsterFromZone(MonsterCard monster, MonsterCard[] monstersZone) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monster)) { + monstersZone[i] = null; + break; + } + } + } +} diff --git a/My part 6/main/java/view/DeckMenuView.java b/My part 6/main/java/view/DeckMenuView.java new file mode 100644 index 0000000..5341692 --- /dev/null +++ b/My part 6/main/java/view/DeckMenuView.java @@ -0,0 +1,137 @@ +package view; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import controller.Utils; +import controller.deckmenu.DeckMenuController; +import controller.deckmenu.DeckMenuOutput; +import model.*; + +public class DeckMenuView { + public static Scanner scanner = Utils.getScanner(); + + private final Player loggedInPlayer; + + public DeckMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + private final String[] deckMenuRegexes = { + "^deck create (?\\w+)$", + "^deck delete (?\\w+)$", + "^deck set-activate (?\\w+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck add-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck show (?:--all|-a)$", + "^deck show (?:--deck-name|-d) (?.+) (?:--side|-s)$", + "^deck show (?:--side|-s) (?:--deck-name|-d) (?.+)$", + "^deck show (?:--deck-name|-d) (?.+)$", + "^menu show-current$", + "^menu exit$" + }; + + public void runDeckMenu() { + Matcher commandMatcher; + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + int whichCommand; + for (whichCommand = 0; whichCommand < deckMenuRegexes.length; whichCommand++) { + commandMatcher = findMatcher(command, deckMenuRegexes[whichCommand]); + if (commandMatcher.find()) { + executeDeckMenuCommands(commandMatcher, whichCommand); + break; + } else if (whichCommand == deckMenuRegexes.length - 1) + DeckMenuOutput.getInstance().showMessage("invalid command"); + } + + } + } + + private void executeDeckMenuCommands(Matcher commandMatcher, int whichCommand) { + DeckMenuController controller = DeckMenuController.getInstance(); + switch (whichCommand) { + case 0: + controller.createDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 1: + controller.deleteDeck(commandMatcher.group("name")); + break; + case 2: + controller.setActiveDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + String cardName = commandMatcher.group("cardName"), + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, false); + break; + case 9: + case 10: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, true); + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, false); + break; + case 17: + case 18: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, true); + break; + case 19: + controller.showAllDecks(loggedInPlayer); + break; + case 20: + case 21: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, false); + break; + case 22: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, true); + break; + case 23: + DeckMenuOutput.getInstance().showMessage("Deck Menu"); + break; + case 24: + MainMenuView mainMenuView = new MainMenuView(loggedInPlayer); + mainMenuView.mainMenuView(); + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } + + +} diff --git a/My part 6/main/java/view/DuelMenuView.java b/My part 6/main/java/view/DuelMenuView.java new file mode 100644 index 0000000..24661b5 --- /dev/null +++ b/My part 6/main/java/view/DuelMenuView.java @@ -0,0 +1,140 @@ +package view; + +import controller.Utils; +import controller.duelmenu.DuelMenuController; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.Phases; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +public class DuelMenuView { + private Player firstPlayer; + private Player secondPlayer; + private Phases phase; + + public DuelMenuView(Player firstPlayer, Player secondPlayer) { + this.firstPlayer = firstPlayer; + this.secondPlayer = secondPlayer; + } + + public static String findChooseOfPlayerInMiniGame(Player player) { + System.out.println(player.getUsername() + ", please choose between stone, paper and scissor:"); + return Utils.getScanner().nextLine().trim(); + } + + public static void showGraveyard(Board board) { + if (board.getGraveyard().size() != 0) { + for (int i = 1; i <= board.getGraveyard().size(); i++) { + printCard(i , board.getGraveyard().get(i)); + } + } else System.out.println("graveyard empty"); + while (true) { + String input = Utils.getScanner().nextLine(); + if (input.equals("back")) + break; + } + } + + public static void printCard(int number, Card card) { + System.out.println(number + ". " + card.getName() + ": " + card.getDescription()); + } + + private static void showBoard(Board playerBoard, Board opponentBoard) { + showCardsInHand(opponentBoard); +// showLeftCardDeck(opponentBoard);//?????????????????????? + showOpponentMagicsZone(opponentBoard); + showOpponentMonstersZone(opponentBoard); + showGraveyard(opponentBoard); + System.out.println("--------------------------"); + showCardsInHand(playerBoard); +// showLeftCardDeck(playerBoard);//???????? + showMagicsZone(playerBoard); + showMonstersZone(playerBoard); + showGraveyard(playerBoard); + } + + private static void showMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// monsters[5].print(); +// System.out.print(monsters[5].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[4].print() + " "); +// System.out.println(); + } + + private static void showMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[5].print(); + magicsZone[3].print(); + magicsZone[1].print(); + magicsZone[2].print(); + magicsZone[4].print(); + } + + private static void showOpponentMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// System.out.print(monsters[4].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[5].print() + " "); + } + + private static void showOpponentMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[4].print(); + magicsZone[2].print(); + magicsZone[1].print(); + magicsZone[3].print(); + magicsZone[5].print(); + } + + private static void showCardsInHand(Board board) { + for (int i = 0; i < board.getCardsInHand().size(); i++) { + System.out.print("C "); + } + System.out.println(); + } + + private static void showSelectedCard(Board board) { + if (showCardCheck(board)) { + System.out.println(board.getSelectedCard().getName() + " " + board.getSelectedCard().getDescription()); + + } + } + + private static boolean showCardCheck(Board board) { + if (board.getSelectedCard() == null) { + System.out.println("you have not selected card"); + return false; + } + if (!board.isMyCardSelected() && !board.getSelectedCard().getCardFaceUp()) { + System.out.println("you cant see this card!"); + return false; + } + return true; + } + + public void duelMenuView() { + DuelMenuController duelMenuController = new DuelMenuController(); + + DuelMenuMessages resultOfInitialGame = null; + while (resultOfInitialGame == null || !resultOfInitialGame.equals(DuelMenuMessages.SHOW_TURN_PLAYER)) { + resultOfInitialGame = duelMenuController.initialGame(firstPlayer, secondPlayer); + System.out.print(resultOfInitialGame.getMessage()); + } + + while (true) { + String command = Utils.getScanner().nextLine().trim(); + DuelMenuMessages result = duelMenuController.findCommand(command); + + System.out.print(result.getMessage()); + } + } + +} diff --git a/My part 6/main/java/view/ImportExportMenuView.java b/My part 6/main/java/view/ImportExportMenuView.java new file mode 100644 index 0000000..ee91f94 --- /dev/null +++ b/My part 6/main/java/view/ImportExportMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; + +public class ImportExportMenuView { + public void ImportExportMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ImportExportMenuMessages result = ImportExportMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU)) break; + } + } +} diff --git a/My part 6/main/java/view/LoginMenuView.java b/My part 6/main/java/view/LoginMenuView.java new file mode 100644 index 0000000..f094c8b --- /dev/null +++ b/My part 6/main/java/view/LoginMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; + +public class LoginMenuView { + public static void loginMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + LoginMenuMessages result = LoginMenuController.findCommand(command); + + System.out.println(result.getMessage()); + + if (result.equals(LoginMenuMessages.USER_LOGGED_IN)) LoginMenuController.loginUser(command); + } + } +} diff --git a/My part 6/main/java/view/MainMenuView.java b/My part 6/main/java/view/MainMenuView.java new file mode 100644 index 0000000..7dde978 --- /dev/null +++ b/My part 6/main/java/view/MainMenuView.java @@ -0,0 +1,31 @@ +package view; + +import controller.Utils; +import controller.mainmenu.MainMenuController; +import controller.mainmenu.MainMenuMessages; +import model.Player; + +public class MainMenuView { + private Player loggedInPlayer; + + public MainMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void mainMenuView() { + MainMenuController mainMenuController = new MainMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + MainMenuMessages result = mainMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(MainMenuMessages.EXIT_MAIN_MENU) || + result.equals(MainMenuMessages.USER_LOGGED_OUT)) break; + } + } +} diff --git a/My part 6/main/java/view/ProfileMenuView.java b/My part 6/main/java/view/ProfileMenuView.java new file mode 100644 index 0000000..1e1b091 --- /dev/null +++ b/My part 6/main/java/view/ProfileMenuView.java @@ -0,0 +1,25 @@ +package view; + +import controller.profilemenu.ProfileMenuController; +import controller.profilemenu.ProfileMenuMessages; +import controller.Utils; +import model.Player; + +public class ProfileMenuView { + private final Player loggedInPlayer; + + public ProfileMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void profileMenuView() { + ProfileMenuController profileMenuController = new ProfileMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ProfileMenuMessages result = profileMenuController.findCommand(command); + + if (result.equals(ProfileMenuMessages.EXIT_MENU)) break; + else System.out.print(result.getMessage()); + } + } +} diff --git a/My part 6/main/java/view/ScoreboardMenuView.java b/My part 6/main/java/view/ScoreboardMenuView.java new file mode 100644 index 0000000..57e679c --- /dev/null +++ b/My part 6/main/java/view/ScoreboardMenuView.java @@ -0,0 +1,40 @@ +package view; + +import controller.Utils; +import controller.scoreboardmenu.Scoreboard; +import controller.scoreboardmenu.ScoreboardOutput; +import model.Player; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ScoreboardMenuView { + public static Scanner scanner = Utils.getScanner(); + + public void runScoreboard() { + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + switch (command) { + case "scoreboard show": + Scoreboard.getInstance().showScoreboard(); + break; + case "menu show-current": + ScoreboardOutput.getInstance().showMessage("Scoreboard Menu"); + break; + case "menu exit": +// MainMenuView mainMenuView = new MainMenuView(); +// mainMenuView.mainMenuView(); + default: + ScoreboardOutput.getInstance().showMessage("invalid command"); + } + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } +} diff --git a/My part 6/main/java/view/ShopMenuView.java b/My part 6/main/java/view/ShopMenuView.java new file mode 100644 index 0000000..0ed2331 --- /dev/null +++ b/My part 6/main/java/view/ShopMenuView.java @@ -0,0 +1,41 @@ +package view; + +import controller.Utils; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import model.cards.Card; + +import java.util.TreeMap; + +public class ShopMenuView { + private Player loggedInPlayer; + + public ShopMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + private static void showListOfCards() { + TreeMap listOfCards = Card.getListOfCards(); + for (String cardName : listOfCards.keySet()) { + System.out.println(cardName + ": " + listOfCards.get(cardName)); + } + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void shopMenuView() { + ShopMenuController shopMenuController = new ShopMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ShopMenuMessages result = shopMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ShopMenuMessages.EXIT_SHOP_MENU)) break; + else if (result.equals(ShopMenuMessages.SHOW_ALL_CARDS)) showListOfCards(); + } + } +} diff --git a/My part 6/main/java/view/SpellCardView.java b/My part 6/main/java/view/SpellCardView.java new file mode 100644 index 0000000..69bf703 --- /dev/null +++ b/My part 6/main/java/view/SpellCardView.java @@ -0,0 +1,118 @@ +package view; + +import controller.Utils; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class SpellCardView extends DuelMenuView { + private SpellCardView(Player firstPlayer, Player secondPlayer) { + super(firstPlayer, secondPlayer); + } + + public static void showGraveyardsMonsterCards(Player turnPlayer, Player notTurnPlayer) { +// it used for Monster Reborn spell card + System.out.println("your graveyard monster cards:"); + showGraveyardMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent graveyard monster cards:"); + showGraveyardMonsterCards(notTurnPlayer.getBoard(), Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()) + 1); + } + + private static void showGraveyardMonsterCards(Board board, int startNumber) { +// it used for Monster Reborn spell card + int count = startNumber; + for (int i = 0; i < board.getGraveyard().size(); i++) { + if (Card.isMonsterCard(board.getGraveyard().get(i))) { + printCard(count, board.getGraveyard().get(i)); + ++count; + } + } + if (count == startNumber) System.out.println("There isn't any monster card."); + } + + public static String findCardNumber() { + System.out.println("choose a number:"); + return Utils.getScanner().nextLine(); + } + + public static void invalidNumber() { + System.out.println("invalid number"); + } + + public static void showFieldSpellCards(ArrayList magicCards) { + System.out.println("your field spell cards:"); + if (magicCards.size() == 0) System.out.println("There isn't any field spell card."); + else { + for (int i = 1; i <= magicCards.size(); i++) { + printCard(i, magicCards.get(i - 1)); + } + } + } + + public static void showCardsInHand(Player player) { + System.out.println("you have these cards in hand:"); + ArrayList cardsInHand = player.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) System.out.println("There isn't any card in your hand."); + else { + for (int i = 1; i <= cardsInHand.size(); i++) { + printCard(i, cardsInHand.get(i - 1)); + } + } + } + + public static void showMagicsZonesCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your spell and trap zone cards:"); + int endNumber = showMagicsZoneCards(turnPlayer, 1); + System.out.println("opponent spell and trap zone cards:"); + showMagicsZoneCards(notTurnPlayer, endNumber); + } + + private static int showMagicsZoneCards(Player player, int startNumber) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (player.getBoard().isMagicsZoneEmpty()) System.out.println("There isn't any spell and trap card."); + else { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) { + printCard(startNumber, magicsZone[i]); + ++startNumber; + } + } + } + + return startNumber; + } + + public static String findNumberOfCardsToChoose() { + System.out.println("How many cards do you want to choose to destroy?"); + return Utils.getScanner().nextLine(); + } + + public static void showFaceUpMonsterCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your face up monster cards:"); + int endNumber = showEachPlayerFaceUpMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent face up monster cards:"); + showEachPlayerFaceUpMonsterCards(notTurnPlayer.getBoard(), endNumber); + } + + private static int showEachPlayerFaceUpMonsterCards(Board board, int startNumber) { + if (board.getNumberOfFaceUpMonsterCards() == 0) { + System.out.println("There isn't any face up monster card."); + return startNumber; + } + + MonsterCard[] monstersZone = board.getMonstersZone(); + for (int i = 1; i < monstersZone.length; i++) { + MonsterCard monsterCard = monstersZone[i]; + if (monsterCard.getCardFaceUp()) { + printCard(startNumber, monsterCard); + ++startNumber; + } + } + + return startNumber; + } +} diff --git a/My part 6/main/main.iml b/My part 6/main/main.iml new file mode 100644 index 0000000..2185ddd --- /dev/null +++ b/My part 6/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/My part 6/main/resources/cards/Monster Upgraded.csv b/My part 6/main/resources/cards/Monster Upgraded.csv new file mode 100644 index 0000000..eae794e --- /dev/null +++ b/My part 6/main/resources/cards/Monster Upgraded.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARTH,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARTH,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,FIRE,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My part 6/main/resources/cards/Monster.csv b/My part 6/main/resources/cards/Monster.csv new file mode 100644 index 0000000..8c45a5c --- /dev/null +++ b/My part 6/main/resources/cards/Monster.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARHT,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARHT,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron ,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,Fire,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My part 6/main/resources/cards/SpellTrap.csv b/My part 6/main/resources/cards/SpellTrap.csv new file mode 100644 index 0000000..e536e99 --- /dev/null +++ b/My part 6/main/resources/cards/SpellTrap.csv @@ -0,0 +1,38 @@ +Name,Type ,Icon (Property),Description,Status,Price +Trap Hole,Trap,Normal,When your opponent Normal or Flip Summons 1 monster with 1000 or more ATK: Target that monster; destroy that target.,Unlimited,2000 +Mirror Force,Trap,Normal,When an opponent's monster declares an attack: Destroy all your opponent's Attack Position monsters.,Unlimited,2000 +Magic Cylinder,Trap,Normal,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, and if you do, inflict damage to your opponent equal to its ATK.",Unlimited,2000 +Mind Crush,Trap,Normal,"Declare 1 card name; if that card is in your opponent's hand, they must discard all copies of it, otherwise you discard 1 random card.",Unlimited,2000 +Torrential Tribute,Trap,Normal,When a monster(s) is Summoned: Destroy all monsters on the field.,Unlimited,2000 +Time Seal,Trap,Normal,Skip the Draw Phase of your opponent's next turn.,Limited,2000 +Negate Attack,Trap,Counter,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, then end the Battle Phase.",Unlimited,3000 +Solemn Warning,Trap,Counter,"When a monster(s) would be Summoned, OR when a Spell/Trap Card, or monster effect, is activated that includes an effect that Special Summons a monster(s): Pay 2000 LP; negate the Summon or activation, and if you do, destroy it.",Unlimited,3000 +Magic Jamamer,Trap,Counter,"When a Spell Card is activated: Discard 1 card; negate the activation, and if you do, destroy it.",Unlimited,3000 +Call of The Haunted,Trap,Continuous,"Activate this card by targeting 1 monster in your GY; Special Summon that target in Attack Position. When this card leaves the field, destroy that monster. When that monster is destroyed, destroy this card.",Unlimited,3500 +Vanity's Emptiness,Trap,Continuous,Neither player can Special Summon monsters. If a card is sent from the Deck or the field to your Graveyard: Destroy this card.,Limited,3500 +Wall of Revealing Light,Trap,Continuous,Activate by paying any multiple of 1000 Life Points. Monsters your opponent controls cannot attack if their ATK is less than or equal to the amount you paid.,Limited,3500 +Monster Reborn,Spell,Normal,Target 1 monster in either GY; Special Summon it.,Limited,2500 +Terraforming,Spell,Normal,Add 1 Field Spell from your Deck to your hand.,Limited,2500 +Pot of Greed,Spell,Normal,Draw 2 cards.,Limited,2500 +Raigeki,Spell,Normal,Destroy all monsters your opponent controls.,Limited,2500 +Change of Heart,Spell,Normal,Target 1 monster your opponent controls; take control of it until the End Phase.,Limited,2500 +Swords of Revealing Light,Spell,Normal,"After this card's activation, it remains on the field, but destroy it during the End Phase of your opponent's 3rd turn. When this card is activated: If your opponent controls a face-down monster, flip all monsters they control face-up. While this card is face-up on the field, your opponent's monsters cannot declare an attack.",Unlimited,2500 +Harpie's Feather Duster,Spell,Normal,Destroy all Spells and Traps your opponent controls.,Limited,2500 +Dark Hole,Spell,Normal,Destroy all monsters on the field.,Unlimited,2500 +Supply Squad,Spell,Continuous,"Once per turn, if a monster(s) you control is destroyed by battle or card effect: Draw 1 card.",Unlimited,4000 +Spell Absorption,Spell,Continuous,"Each time a Spell Card is activated, gain 500 Life Points immediately after it resolves.",Unlimited,4000 +Messenger of peace,Spell,Continuous,"Monsters with 1500 or more ATK cannot declare an attack. Once per turn, during your Standby Phase, pay 100 LP or destroy this card.",Unlimited,4000 +Twin Twisters,Spell,Quick-play,"Discard 1 card, then target up to 2 Spells/Traps on the field; destroy them.",Unlimited,3500 +Mystical space typhoon,Spell,Quick-play,Target 1 Spell/Trap on the field; destroy that target.,Unlimited,3500 +Ring of defense,Spell,Quick-play,When a Trap effect that inflicts damage is activated: Make that effect damage 0.,Unlimited,3500 +Yami,Spell,Field,"All Fiend and Spellcaster monsters on the field gain 200 ATK/DEF, also all Fairy monsters on the field lose 200 ATK/DEF.",Unlimited,4300 +Forest,Spell,Field,"All Insect, Beast, Plant, and Beast-Warrior monsters on the field gain 200 ATK/DEF.",Unlimited,4300 +Closed Forest,Spell,Field,All Beast-Type monsters you control gain 100 ATK for each monster in your Graveyard. Field Spell Cards cannot be activated. Field Spell Cards cannot be activated during the turn this card is destroyed.,Unlimited,4300 +Umiiruka,Spell,Field,Increase the ATK of all WATER monsters by 500 points and decrease their DEF by 400 points.,Unlimited,4300 +Sword of dark destruction,Spell,Equip,A DARK monster equipped with this card increases its ATK by 400 points and decreases its DEF by 200 points.,Unlimited,4300 +Black Pendant,Spell,Equip,The equipped monster gains 500 ATK. When this card is sent from the field to the Graveyard: Inflict 500 damage to your opponent.,Unlimited,4300 +United We Stand,Spell,Equip,The equipped monster gains 800 ATK/DEF for each face-up monster you control.,Unlimited,4300 +Magnum Shield,Spell,Equip,"Equip only to a Warrior-Type monster. Apply this effect, depending on its battle position. +● Attack Position: It gains ATK equal to its original DEF. +● Defense Position: It gains DEF equal to its original ATK.",Unlimited,4300 +Advanced Ritual Art,Spell,Ritual,This card can be used to Ritual Summon any 1 Ritual Monster. You must also send Normal Monsters from your Deck to the Graveyard whose total Levels equal the Level of that Ritual Monster.,Unlimited,3000 \ No newline at end of file diff --git a/My part 6/main/resources/players/amir.json b/My part 6/main/resources/players/amir.json new file mode 100644 index 0000000..867f62c --- /dev/null +++ b/My part 6/main/resources/players/amir.json @@ -0,0 +1,17 @@ +{ + "boughtCards": [ + { + "name": "Battle OX" + }, + { + "name": "Suijin" + } + ], + "allMainDecks": [], + "sideDeck": {}, + "username": "amir", + "password": "12345", + "nickname": "amir", + "score": 0, + "money": 88400 +} \ No newline at end of file diff --git a/My part 6/main/resources/players/parsa.json b/My part 6/main/resources/players/parsa.json new file mode 100644 index 0000000..2825eb1 --- /dev/null +++ b/My part 6/main/resources/players/parsa.json @@ -0,0 +1,10 @@ +{ + "boughtCards": [], + "allMainDecks": [], + "sideDeck": {}, + "username": "parsa", + "password": "newPass", + "nickname": "P", + "score": 0, + "money": 100000 +} \ No newline at end of file diff --git a/My part 6/test/java/controller/ImportExportMenuControllerTest.java b/My part 6/test/java/controller/ImportExportMenuControllerTest.java new file mode 100644 index 0000000..aea2298 --- /dev/null +++ b/My part 6/test/java/controller/ImportExportMenuControllerTest.java @@ -0,0 +1,140 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Database; +import controller.MenuTest; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; +import model.cards.Card; +import org.apache.commons.io.FileUtils; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +class ImportExportMenuControllerTest extends MenuTest { + + @Test + void findCommandEnterAMenuMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu exit"); + Assertions.assertEquals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU, result); + + result = ImportExportMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ImportExportMenuMessages.SHOW_MENU, result); + + result = ImportExportMenuController.findCommand("menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandImportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("import cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_FILE, result); + + createCardJsonFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.AVAILABLE_CARD, result); + + Card.getAllCards().remove("Battle OX"); + removeNameValueFromJsonCardFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Battle OX"); + Card.getAllCards().remove("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Battle OX.json")); + + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + removeNameValueFromJsonCardFile("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Trap Hole.json")); + } + + void createCardJsonFile(String cardName) { + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(Card.getCardByName(cardName))); + fileWriter.close(); + } catch (IOException ignored) { + } + } + + void removeNameValueFromJsonCardFile(String cardName) { + JSONParser parser = new JSONParser(); + try { + Object object = parser.parse(new FileReader("src/database/cards/" + cardName + ".json")); + JSONObject jsonObject = (JSONObject) object; + jsonObject.remove("name"); + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(jsonObject)); + fileWriter.close(); + } catch (Exception ignored) { + } + } + + @Test + void findCommandExportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("export cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("export card A"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_CARD, result); + + result = ImportExportMenuController.findCommand("export card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My part 6/test/java/controller/LoginMenuControllerTest.java b/My part 6/test/java/controller/LoginMenuControllerTest.java new file mode 100644 index 0000000..b095e9e --- /dev/null +++ b/My part 6/test/java/controller/LoginMenuControllerTest.java @@ -0,0 +1,87 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; + +class LoginMenuControllerTest extends MenuTest { + @Test + void findCommandEnterAMenuMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_NAVIGATION, result); + + result = LoginMenuController.findCommand("menu enter MaIn MenU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + + result = LoginMenuController.findCommand("menu enter DUEL MENU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + } + + @Test + void findCommandCheckCreateUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user create --username John 1 --nickname Johny --password 12345"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user create --U John1 --nickname Johny1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --username John2 --P 12345 --nickname Johny2"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny3 --username John3 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny4 --password 12345 --U John4"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --username John5 --nickname Johny5"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --nickname Johny6 --username John6"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John6 --N Johny6"); + Assertions.assertEquals(LoginMenuMessages.USERNAME_EXISTS, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John7 --nickname Johny6"); + Assertions.assertEquals(LoginMenuMessages.NICKNAME_EXISTS, result); + } + + @Test + void findCommandCheckLoginUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user login --username John 12 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user login --username John12 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + + result = LoginMenuController.findCommand("user login --username John2 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + result = LoginMenuController.findCommand("user login --username John1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + + result = LoginMenuController.findCommand("user login --password 12345 --username John1"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + } + + @Test + void loginUser() { + Utils.resetScanner("user logout\n"); + ByteArrayOutputStream outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --password 12345 --username John1"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + + Utils.resetScanner("user logout\n"); + outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --username John1 --password 12345"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + } +} \ No newline at end of file diff --git a/My part 6/test/java/controller/MenuTest.java b/My part 6/test/java/controller/MenuTest.java new file mode 100644 index 0000000..5df1b3c --- /dev/null +++ b/My part 6/test/java/controller/MenuTest.java @@ -0,0 +1,20 @@ +package controller; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +import java.io.File; +import java.io.IOException; + +public class MenuTest { + @BeforeAll + static void prepareGame() { + Database.prepareGame(); + } + + @AfterAll + static void deletePlayersDirectory() throws IOException { + FileUtils.deleteDirectory(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/main/resources/players")); + } +} \ No newline at end of file diff --git a/My part 6/test/java/controller/ProfileMenuTest.java b/My part 6/test/java/controller/ProfileMenuTest.java new file mode 100644 index 0000000..ddad54d --- /dev/null +++ b/My part 6/test/java/controller/ProfileMenuTest.java @@ -0,0 +1,57 @@ +package controller; + +import controller.profilemenu.ProfileMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import controller.profilemenu.ProfileMenuController; + +public class ProfileMenuTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + String userName = "parsa"; + String password = "123"; + String nickname = "P"; + new Player(userName, password, nickname); + } + + @Test + public void changeName() { + Player player = Player.getPlayerByUsername("parsa"); + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --nickname newname"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + Assertions.assertEquals("newname", player.getNickname()); + result = profileMenuController.findCommand("profile change --nickname P"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + } + + @Test + public void changePassword() { + Player player = Player.getPlayerByUsername("parsa"); + + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --password --current 12 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.WRONG_CURRENT_PASSWORD, result); + Assertions.assertEquals("123", player.getPassword()); + + result = profileMenuController.findCommand("profile change --password --current 123 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_PASSWORD_DONE, result); + Assertions.assertEquals("newPass", player.getPassword()); + } + + @Test + public void allError() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.INVALID_COMMAND, profileMenuController.findCommand("profile")); + Assertions.assertEquals(ProfileMenuMessages.CANT_NAVIGATE_MENU, profileMenuController.findCommand("loginmenu enter")); + } + + @Test + public void checkExit() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.EXIT_MENU , profileMenuController.findCommand("menu exit")); + } +} diff --git a/My part 6/test/java/controller/ShopMenuControllerTest.java b/My part 6/test/java/controller/ShopMenuControllerTest.java new file mode 100644 index 0000000..58d998d --- /dev/null +++ b/My part 6/test/java/controller/ShopMenuControllerTest.java @@ -0,0 +1,77 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ShopMenuControllerTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + LoginMenuController.findCommand("user create --username John --P 12345 --nickname Johny"); + } + + @Test + void findCommandEnterAMenuMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu exit"); + Assertions.assertEquals(ShopMenuMessages.EXIT_SHOP_MENU, result); + + result = shopMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ShopMenuMessages.SHOW_MENU, result); + + result = shopMenuController.findCommand("menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandBuyACardMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("shop buy:)"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("shop buy A"); + Assertions.assertEquals(ShopMenuMessages.UNAVAILABLE_CARD, result); + + result = shopMenuController.findCommand("shop buy Battle OX"); + Assertions.assertEquals(ShopMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My part 6/test/test.iml b/My part 6/test/test.iml new file mode 100644 index 0000000..c2315e9 --- /dev/null +++ b/My part 6/test/test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/My part 7/main/java/controller/AIClass.java b/My part 7/main/java/controller/AIClass.java new file mode 100644 index 0000000..5e41136 --- /dev/null +++ b/My part 7/main/java/controller/AIClass.java @@ -0,0 +1,60 @@ +package controller; + +import model.Board; +import model.cards.monstercard.MonsterCard; +import model.Player; + +public class AIClass { + +// public static String getOrder(Board machineBoard, Board playerBoard, Player AIPlayer, Player humanPlayer, Enum phaseOfGame) { +// if () {//TODO PUT A CONDITION THAT PHASE IS BATTLE PHASE +// int numberOfMonsterToAttack = -1; +// selectMachineMonsterCardToAttack(machineBoard, AIPlayer); +// if (canAttackToFaceUpMonster(machineBoard, playerBoard) != -1) { +// return "attack" + canAttackToFaceUpMonster(machineBoard, playerBoard); +// } else if (canAttackToFaceDownCard(playerBoard) != -1) { +// return "attack" + canAttackToFaceDownCard(playerBoard); +// } +// } +// } +// +// private static int canAttackToFaceDownCard(Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DH")) +// return i; +// } +// return -1; +// } +// +// private static void selectMachineMonsterCardToAttack(Board board, Player player) { +// MonsterCard[] monsterArray = board.getMonstersZone(); +// MonsterCard monsterCard = monsterArray[1]; +// for (int i = 2; i <= 5; i++) { +// if (monsterCard.getAttackLevel() < monsterArray[i].getAttackLevel()) +// monsterCard = monsterArray[i]; +// board.setMyCardSelected(true); +// board.setSelectedCard(monsterCard); +// } +// } +// +// private static int canAttackToFaceUpMonster(Board machineBoard, Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// MonsterCard monsterToAttack = (MonsterCard) machineBoard.getSelectedCard(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("OO") && monsterArray[i].getAttackLevel() < monsterToAttack.getAttackLevel()) +// return i; +// } +// +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DO") && monsterArray[i].getDefenseLevel() < monsterToAttack.getAttackLevel()) { +// } +// return i; +// } +// return -1; +// } +// +// public static String getRandomMove() { +// +// } +} diff --git a/My part 7/main/java/controller/Database.java b/My part 7/main/java/controller/Database.java new file mode 100644 index 0000000..e5d87af --- /dev/null +++ b/My part 7/main/java/controller/Database.java @@ -0,0 +1,120 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.magiccard.MagicCardStatuses; +import model.cards.monstercard.MonsterCard; +import model.cards.monstercard.MonsterCardAttributes; + +import java.io.*; +import java.util.ArrayList; + +public class Database { + public static void prepareGame() { + new File("src/main/resources/players").mkdirs(); + addCardsToGame(); + readPlayersDataFromDatabase(); + } + + private static void addCardsToGame() { + try { + FileReader monsterCardFileReader = new FileReader("src/main/resources/cards/Monster Upgraded.csv"); + CSVReader monsterCardCSVReader = new CSVReaderBuilder(monsterCardFileReader).withSkipLines(1).build(); + + String[] monsterCardData; + while ((monsterCardData = monsterCardCSVReader.readNext()) != null) { + createNewMonsterCard(monsterCardData); + } + + + FileReader magicCardFileReader = new FileReader("src/main/resources/cards/SpellTrap.csv"); + CSVReader magicCardCSVReader = new CSVReaderBuilder(magicCardFileReader).withSkipLines(1).build(); + + String[] magicCardData; + while ((magicCardData = magicCardCSVReader.readNext()) != null) { + createNewMagicCard(magicCardData); + } + + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + } + + private static void createNewMonsterCard(String[] data) { + String name = data[0]; + short level = Short.parseShort(data[1]); + MonsterCardAttributes monsterCardAttributes = MonsterCardAttributes.valueOf(data[2]); + String monsterType = data[3]; + CardTypes cardType = CardTypes.valueOf(data[4].toUpperCase()); + int attackPoints = Integer.parseInt(data[5]); + int defensePoints = Integer.parseInt(data[6]); + String description = data[7]; + int price = Integer.parseInt(data[8]); + + new MonsterCard(name, level, monsterCardAttributes, monsterType, cardType, attackPoints, defensePoints, description, price); + } + + private static void createNewMagicCard(String[] data) { + String name = data[0]; + CardTypes cardType = CardTypes.valueOf(data[1].toUpperCase()); + String icon = data[2]; + String description = data[3]; + MagicCardStatuses status = MagicCardStatuses.valueOf(data[4].toUpperCase()); + int price = Integer.parseInt(data[5]); + + new MagicCard(name, cardType, icon, description, status,price); + } + + public static void readPlayersDataFromDatabase() { +// TODO: complete it by Iman's code + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + File file = new File("src/main/resources/players"); + FilenameFilter filenameFilter = (direction, name) -> name.endsWith(".json"); + String[] filesName = file.list(filenameFilter); + + if (filesName == null) return; + for (String fileName : filesName) { + try { + FileReader fileReader = new FileReader("src/main/resources/players/" + fileName); + Player player = gson.fromJson(fileReader, Player.class); + fileReader.close(); + Player.addPlayerToAllPlayers(player); + addCardsToPlayer(player); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + private static void addCardsToPlayer(Player player) { + ArrayList boughtCards = player.getBoughtCards(); + for (int i = 0; i < boughtCards.size(); i++) { + Card fakeCard = boughtCards.get(0); + Card originalCard = Card.getCardByName(fakeCard.getName()); + boughtCards.remove(fakeCard); + player.addCardToBoughtCards(originalCard); + } + } + + public static void updatePlayerInformationInDatabase(Player player) { + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + try { + FileWriter fileWriter = new FileWriter("src/main/resources/players/" + player.getUsername() + ".json"); + fileWriter.write(gson.toJson(player)); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/My part 7/main/java/controller/Main.java b/My part 7/main/java/controller/Main.java new file mode 100644 index 0000000..274e490 --- /dev/null +++ b/My part 7/main/java/controller/Main.java @@ -0,0 +1,10 @@ +package controller; + +import view.LoginMenuView; + +public class Main { + public static void main(String[] args) { + Database.prepareGame(); + LoginMenuView.loginMenuView(); + } +} \ No newline at end of file diff --git a/My part 7/main/java/controller/SpellCardController.java b/My part 7/main/java/controller/SpellCardController.java new file mode 100644 index 0000000..6080ef6 --- /dev/null +++ b/My part 7/main/java/controller/SpellCardController.java @@ -0,0 +1,537 @@ +package controller; + +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.SpellCardView; + +import java.util.ArrayList; +import java.util.Collections; + +public class SpellCardController { +// this method doesn't handle field spell cards + public static boolean doSpellCardEffect(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { +// handle every kind of spell cards except field and equip + String cardName = spellCard.getName(); + switch (cardName) { + case "Monster Reborn": + return doMonsterRebornEffect(turnPlayer, notTurnPlayer); + case "Terraforming": + return doTerraformingEffect(turnPlayer); + case "Pot of Greed": + return doPotOfGreedEffect(turnPlayer); + case "Raigeki": + return doRaigekiEffect(notTurnPlayer); + case "Change of Heart": + return doChangeOfHeartEffect(); + case "Harpie's Feather Duster": + return doHarpieFeatherDusterEffect(notTurnPlayer); + case "Swords of Revealing Light": + return doSwordsOfRevealingLight(); + case "Dark Hole": + return doDarkHoleEffect(turnPlayer, notTurnPlayer); + case "Supply Squad": +// TODO: i should know how turn changes, then handle it --> it shouldn't handle here + break; + case "Spell Absorption": + return true; + case "Messenger of peace": +// TODO: handle it base on Parsa code + break; + case "Twin Twisters": + return doTwinTwistersEffect(turnPlayer, notTurnPlayer); + case "Mystical space typhoon": + return doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + case "Ring of defense": +// TODO: handle it base trap and monster code + break; +// it's the only ritual spell card + case "Advanced Ritual Art": + return doAdvancedRitualArtEffect(); + } + +// handle equip spell cards + return chooseMonsterToEquip(turnPlayer, notTurnPlayer, spellCard); +// any other kind of card doesn't enter to this method + } + + +// handle every kind of spell cards except field and equip + private static boolean doMonsterRebornEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showGraveyardsMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(turnPlayer.getBoard().getGraveyard()); + int notTurnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()); + if (turnPlayerGraveyardMonsterCardsSize + notTurnPlayerGraveyardMonsterCardsSize == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findMonsterRebornChosenCard(turnPlayer, notTurnPlayer, cardNumber); + if (chosenCard != null) break; + SpellCardView.invalidNumber(); + } + +// TODO: how to handle special summon + return true; + } + + private static int getCardNumber() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findCardNumber()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static MonsterCard findMonsterRebornChosenCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + ArrayList turnPlayerGraveyard = turnPlayer.getBoard().getGraveyard(); + ArrayList notTurnPlayerGraveyard = notTurnPlayer.getBoard().getGraveyard(); + + for (Card card : turnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + for (Card card : notTurnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + + return null; + } + + private static boolean doTerraformingEffect(Player player) { +// TODO: do Iman handle with main cards? + ArrayList cards = player.getBoard().getDeck().getMainCards(); + ArrayList fieldSpellCards = findFieldSpellCards(cards); + + SpellCardView.showFieldSpellCards(fieldSpellCards); + if (fieldSpellCards.size() == 0) return false; + + MagicCard chosenFieldSpellCard; + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= fieldSpellCards.size()) { + chosenFieldSpellCard = fieldSpellCards.get(cardNumber - 1); + player.getBoard().getCardsInHand().add(chosenFieldSpellCard); + cards.remove(chosenFieldSpellCard); + break; + } + SpellCardView.invalidNumber(); + } + + Collections.shuffle(cards); + return true; + } + + private static ArrayList findFieldSpellCards(ArrayList cards) { +// create array list of field spell cards + ArrayList fieldSpellCards = new ArrayList<>(); + for (Card card : cards) { + if (!Card.isMonsterCard(card)) { + MagicCard magicCard = (MagicCard) card; + if (magicCard.getIcon().equals("Field")) fieldSpellCards.add(magicCard); + } + } + return fieldSpellCards; + } + + private static boolean doPotOfGreedEffect(Player player) { + Board board = player.getBoard(); + ArrayList deckCards = board.getDeck().getMainCards(); + if (deckCards.size() < 2) return false; + + Card firstCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + Card secondCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + board.getCardsInHand().add(firstCard); + board.getCardsInHand().add(secondCard); + + return true; + } + + private static boolean doRaigekiEffect(Player player) { + MonsterCard[] monstersZone = player.getBoard().getMonstersZone(); + if (isCardArrayNull(monstersZone)) return false; + emptyAZone(player, monstersZone); + return true; + } + + private static boolean isCardArrayNull(Card[] cards) { + for (Card card : cards) { + if (card != null) return false; + } + return true; + } + + private static void emptyAZone(Player player, Card[] cards) { + for (int i = 0; i < cards.length; ++i) { + if (cards[i] != null) { + player.getBoard().getGraveyard().add(cards[i]); + cards[i] = null; + } + } + } + + private static boolean doChangeOfHeartEffect() { +// TODO: handle it! + return true; + } + + private static boolean doHarpieFeatherDusterEffect(Player player) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (isCardArrayNull(magicsZone)) return false; + emptyAZone(player, magicsZone); + return true; + } + + private static boolean doSwordsOfRevealingLight() { +// TODO: handle it! + return true; + } + + private static boolean doDarkHoleEffect(Player turnPlayer, Player notTurnPlayer) { + return doRaigekiEffect(turnPlayer) || doRaigekiEffect(notTurnPlayer); + } + + public static void doSpellAbsorptionEffect(Player player) { + if (player.getBoard().isCardFaceUp("Spell Absorption")) player.increaseLifePoint(500); + } + + private static boolean doTwinTwistersEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showCardsInHand(turnPlayer); + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= cardsInHand.size()) { + turnPlayer.getBoard().getGraveyard().add(cardsInHand.get(cardNumber - 1)); + cardsInHand.remove(cardNumber - 1); + break; + } + SpellCardView.invalidNumber(); + } + + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return true; + + int numberOfChosenCards; + while (true) { + numberOfChosenCards = getNumberOfCardsToChoose(); + if (0 <= numberOfChosenCards && numberOfChosenCards <= 2 && + numberOfChosenCards <= turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards) { + break; + } + SpellCardView.invalidNumber(); + } + + for (int i = 0; i < numberOfChosenCards; i++) { + doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + } + + return true; + } + + private static int getNumberOfCardsToChoose() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findNumberOfCardsToChoose()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static boolean destroyAMagicCardFromMagicZone(Player player, int cardNumber, int startNumber) { + MagicCard[] playerMagicsZone = player.getBoard().getMagicsZone(); + for (int i = 1; i < playerMagicsZone.length; i++) { + if (playerMagicsZone[i] != null) { + if (startNumber == cardNumber) { + player.getBoard().getGraveyard().add(playerMagicsZone[i]); + playerMagicsZone[i] = null; + return true; + } + ++startNumber; + } + } + + return false; + } + + private static boolean doMysticalSpaceTyphoonEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (destroyAMagicCardFromMagicZone(turnPlayer, cardNumber, 1) || + destroyAMagicCardFromMagicZone(notTurnPlayer, cardNumber, turnPlayerNumberOfMagicCards + 1)) + break; + SpellCardView.invalidNumber(); + } + + return true; + } + +// it's the only ritual spell card + private static boolean doAdvancedRitualArtEffect() { +// TODO: handle it based on Iman's code + return false; + } + + +// handle field spell cards + public static void handleFieldSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + MagicCard firstPlayerFieldZoneCard = firstPlayer.getBoard().getFieldZone(); + MagicCard secondPlayerFieldZoneCard = secondPlayer.getBoard().getFieldZone(); + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, firstPlayerFieldZoneCard, doEffect); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, secondPlayerFieldZoneCard, doEffect); + } + + private static Player findMonsterCardOwner(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard) { + if (firstPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return firstPlayer; + if (secondPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return secondPlayer; + +// this will never happen, just for assurance + return null; + } + + private static void handleEachFieldSpellCardEffect(Player monsterCardOwner, MonsterCard monsterCard, MagicCard fieldZoneCard, + boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + if (fieldZoneCard == null || !fieldZoneCard.getCardFaceUp()) return; + + switch (fieldZoneCard.getName()) { + case "Yami": + handleYamiEffect(monsterCard, doEffect); + break; + case "Forest": + handleForestEffect(monsterCard, doEffect); + break; + case "Closed Forest": + handleClosedForestEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Umiiruka": + handleUmiirukaEffect(monsterCard, doEffect); + break; + } + } + + private static void handleYamiEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } else if (monsterCard.getMonsterType().equals("Fairy")) { + if (doEffect) { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } + } + } + + private static void handleForestEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Insect") || monsterCardType.equals("Beast") || + monsterCardType.equals("Beast-Warrior")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } + } + + private static void handleClosedForestEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int graveyardMonsterCardsSize = Card.findNumberOfMonsterCards(monsterCardOwner.getBoard().getGraveyard()); + MonsterCard[] monstersZone = monsterCardOwner.getBoard().getMonstersZone(); + + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null && monstersZone[i].getMonsterType().equals("Beast-Type")) { + if (doEffect) monsterCard.increaseAttackPoints(100 * graveyardMonsterCardsSize); + else monsterCard.decreaseAttackPoints(100 * graveyardMonsterCardsSize); + } + } + + } + + private static void handleUmiirukaEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (monsterCard.getMonsterType().equals("Aqua")) { + if (doEffect) { + monsterCard.increaseAttackPoints(500); + monsterCard.decreaseDefencePoints(400); + } else { + monsterCard.decreaseAttackPoints(500); + monsterCard.increaseDefencePoints(400); + } + } + } + + +// handle equip spell cards + private static boolean chooseMonsterToEquip(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { + SpellCardView.showFaceUpMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerFaceUpMonsterCardsNumber = turnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + int notTurnPlayerFaceUpMonsterCardsNumber = notTurnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + Board turnPlayerBoard = turnPlayer.getBoard(); + if (turnPlayerFaceUpMonsterCardsNumber + notTurnPlayerFaceUpMonsterCardsNumber == 0 || + !turnPlayerBoard.isMagicsZoneFull()) return false; + if (spellCard.getName().equals("Magnum Shield") && turnPlayerBoard.getNumberOfWarriorMonsterCards() == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findFaceUpMonsterCard(turnPlayer, notTurnPlayer, cardNumber); +// second and third condition assure me that Magnum Shield just equipped Warrior Monster Cards + if (chosenCard != null && + (!spellCard.getName().equals("Magnum Shield") || chosenCard.getMonsterType().equals("Warrior"))) break; + SpellCardView.invalidNumber(); + } + + chosenCard.addToEquippedBy(spellCard); + turnPlayerBoard.addMagicCardToMagicsZone(spellCard); + return true; + } + + private static MonsterCard findFaceUpMonsterCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + MonsterCard[] turnPlayerFaceUpMonsterCards = turnPlayer.getBoard().getMonstersZone(); + MonsterCard[] notTurnPlayerFaceUpMonsterCards = notTurnPlayer.getBoard().getMonstersZone(); + + for (int i = 1; i < turnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = turnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + for (int i = 1; i < notTurnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = notTurnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + + return null; + } + + public static void handleEquipSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + for (MagicCard spellCard : monsterCard.getEquippedBy()) { + switch (spellCard.getName()) { + case "Sword of dark destruction": + handleSwordOfDarkDestructionEffect(monsterCard, doEffect); + break; + case "Black Pendant": + handleBlackPendantEffect(monsterCard, doEffect); + break; + case "United We Stand": + handleUnitedWeStandEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Magnum Shield": + handleMagnumShieldEffect(monsterCard, doEffect); + break; + } + } + } + + private static void handleSwordOfDarkDestructionEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(400); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(400); + monsterCard.increaseDefencePoints(200); + } + } + + } + + private static void handleBlackPendantEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (doEffect) monsterCard.increaseAttackPoints(500); + else monsterCard.decreaseAttackPoints(500); + } + + private static void handleUnitedWeStandEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int numberOfFaceUpMonsterCards = monsterCardOwner.getBoard().getNumberOfFaceUpMonsterCards(); + if (doEffect) { + monsterCard.increaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.increaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } else { + monsterCard.decreaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.decreaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } + } + + private static void handleMagnumShieldEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + +// I know that Magnum Shield just equipped Warrior monster cards + if (monsterCard.isDefensePosition()) { + if (doEffect) monsterCard.increaseDefencePoints(monsterCard.getAttackPoints()); + else monsterCard.decreaseDefencePoints(monsterCard.getAttackPoints()); + } else { + if (doEffect) monsterCard.increaseAttackPoints(monsterCard.getDefensePoints()); + else monsterCard.decreaseAttackPoints(monsterCard.getDefensePoints()); + } + } +} diff --git a/My part 7/main/java/controller/Utils.java b/My part 7/main/java/controller/Utils.java new file mode 100644 index 0000000..05df0d8 --- /dev/null +++ b/My part 7/main/java/controller/Utils.java @@ -0,0 +1,34 @@ +package controller; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Utils { + private static Scanner scanner; + + static { + scanner = new Scanner(System.in); + } + + public static Scanner getScanner() { + return scanner; + } + + public static void resetScanner(String input) { + scanner = new Scanner(new ByteArrayInputStream(input.getBytes())); + } + + public static ByteArrayOutputStream setByteArrayOutputStream() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + return outContent; + } + + public static Matcher getMatcher(String regex, String command) { + return Pattern.compile(regex).matcher(command); + } +} diff --git a/My part 7/main/java/controller/deckmenu/DeckMenuController.java b/My part 7/main/java/controller/deckmenu/DeckMenuController.java new file mode 100644 index 0000000..597a002 --- /dev/null +++ b/My part 7/main/java/controller/deckmenu/DeckMenuController.java @@ -0,0 +1,103 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +import java.util.Objects; + +public class DeckMenuController { + + private static DeckMenuController instance = null; + + private DeckMenuController() { + } + + public static DeckMenuController getInstance() { + return Objects.requireNonNullElseGet(instance, () -> (instance = new DeckMenuController())); + } + + public void createDeck(String name, Player owner) { + if (!DeckMenuTools.isDeckNameUnique(name)) + return; + + new Deck(name, owner , true , true); + DeckMenuOutput.getInstance().showMessage("deck created successfully!"); + } + + public void deleteDeck(String name) { + if (!DeckMenuTools.doesDeckExist(name)) {return;} + // if (DeckMenuTools.isDeckNameUnique(name)) return; + + DeckMenuDatabase.removeDeck(name); + DeckMenuOutput.getInstance().showMessage("deck deleted successfully!"); + + } + + + public void setActiveDeck(String name, Player player) { + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesDeckExist(name) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(name), player); + if (isPermitted) { + player.activateADeck(deck); + + DeckMenuOutput.getInstance().showMessage("deck activated successfully!"); + } + + } + + public void addCardToDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card = null; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player) + && ((isMain) ? DeckMenuTools.doesDeckHaveSpace(deck) : DeckMenuTools.doesSideDeckHaveSpace(deck)); + if ((card = DeckMenuDatabase.getInstance().getCardByName(cardName, player)) == null) DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist"); + else { + isPermitted = isPermitted + && DeckMenuTools.isNumberOfCardsInDeckLessThanFour(deck, card) + && DeckMenuTools.doesPlayerHaveEnoughCards(card , player); + if (isPermitted) { + player.removeCardFromBoughtCards(card); + deck.addCard(card, isMain); + DeckMenuOutput.getInstance().showMessage("card added to deck successfully!"); + } + } + } + + public void removeCardFromDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player); + if (isPermitted) { + card = DeckMenuDatabase.getInstance().getCardByName(cardName, player); + if (card == null) { + if (isMain) DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist in main deck"); + else DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist in side deck"); + } else { + player.addCardToBoughtCards(card); + deck.moveCardTo(player.getAllPlayerCard(),card, isMain , true); + DeckMenuOutput.getInstance().showMessage("card removed from deck successfully!"); + } + } + } + + public void showAllDecks(Player player) { + for (Deck deck : player.getAllDeck()) + DeckMenuOutput.getInstance().showMessage(deck.toString()); + + } + + public void showDeck(String name, Player player, boolean isMain) { + if (!DeckMenuTools.doesDeckExist(name)) + return; + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (!DeckMenuTools.doesDeckBelongToPlayer(deck, player)) + return; + DeckMenuOutput.getInstance().showMessage(deck.toString(isMain)); + + } +} diff --git a/My part 7/main/java/controller/deckmenu/DeckMenuDatabase.java b/My part 7/main/java/controller/deckmenu/DeckMenuDatabase.java new file mode 100644 index 0000000..22f7f4b --- /dev/null +++ b/My part 7/main/java/controller/deckmenu/DeckMenuDatabase.java @@ -0,0 +1,50 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; +import java.util.ArrayList; + +public class DeckMenuDatabase { + + public static ArrayList allPlayers = new ArrayList<>(); + public static ArrayList allCards = new ArrayList<>(); + public static ArrayList allDecks = new ArrayList<>(); + + private DeckMenuDatabase() { + } + + private static DeckMenuDatabase instance; + + public static DeckMenuDatabase getInstance() { + if (instance == null) + instance = new DeckMenuDatabase(); + return instance; + } + + public static void removeDeck(String name) { + allDecks.removeIf(deck -> deck.getName().equals(name)); + } + + public Card getCardByName(String name, Player player) { + for (Card card : player.getBoughtCards()) { + if (card.getName().equals(name)) + return card; + } + return null; + + } + + public Deck getDeckByName(String name) { + for (Deck deck : allDecks) { + if (deck.getName().equals(name)) + return deck; + } + return null; + + } + // setPlayers() {file v Jason} + // setDecks() {file v Jason} + // loadingDatabase() + // updatingDatabase() + +} diff --git a/My part 7/main/java/controller/deckmenu/DeckMenuOutput.java b/My part 7/main/java/controller/deckmenu/DeckMenuOutput.java new file mode 100644 index 0000000..92896b1 --- /dev/null +++ b/My part 7/main/java/controller/deckmenu/DeckMenuOutput.java @@ -0,0 +1,23 @@ +package controller.deckmenu; + +public class DeckMenuOutput { + + private DeckMenuOutput() { + } + + private static DeckMenuOutput instance; + + public static DeckMenuOutput getInstance() { + if (instance == null) + instance = new DeckMenuOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My part 7/main/java/controller/deckmenu/DeckMenuTools.java b/My part 7/main/java/controller/deckmenu/DeckMenuTools.java new file mode 100644 index 0000000..20266b2 --- /dev/null +++ b/My part 7/main/java/controller/deckmenu/DeckMenuTools.java @@ -0,0 +1,70 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +public class DeckMenuTools { + public static boolean isDeckNameUnique(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck == null) + return true; + + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " already exists"); + return false; + + } + public static boolean doesDeckExist(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck != null) + return true; + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " does not exist"); + return false; + + } + public static boolean doesDeckBelongToPlayer(Deck deck, Player player) { + if (deck.getOwner().getUsername().equals(player.getUsername())) + return true; + DeckMenuOutput.getInstance().showMessage("this deck doesn't belong to you!"); + return false; + } + public static boolean doesDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getMainCards().size() < 60) + return true; + DeckMenuOutput.getInstance().showMessage("main deck is full!"); + return false; + } + public static boolean doesSideDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getSideCards().size() < 15) + return true; + DeckMenuOutput.getInstance().showMessage("side deck is full!"); + return false; + } + public static boolean isNumberOfCardsInDeckLessThanFour(Deck deck, Card card) { + if (deck.getNumberOfCardsInDeck(card) < 3) + return true; + DeckMenuOutput.getInstance().showMessage("there are already three cards with name " + card.getName() + + " in deck " + deck.getName() + " !"); + return false; + } + public static boolean isDeckAllowed(Deck deck) { + int numberOfCardsInSideDeck = deck.getNumberOfCardsInSideDeck(); + int numberOfCardsInMainDeck = deck.getNumberOfCardsInMainDeck(); + return numberOfCardsInMainDeck <= 60 && numberOfCardsInMainDeck >= 40 && numberOfCardsInSideDeck <= 15; + } + public static boolean doesPlayerHaveEnoughCards(Card card, Player player) { + if (player.hasCard(card)) + return true; + DeckMenuOutput.getInstance().showMessage("you dont have this type of card anymore!"); + return false; + } + public static boolean doesCardExist(String cardName) { + Card card = Card.getCardByName(cardName); + if (card != null) + return true; + DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist"); + return false; + } + +} diff --git a/My part 7/main/java/controller/duelmenu/DuelMenuController.java b/My part 7/main/java/controller/duelmenu/DuelMenuController.java new file mode 100644 index 0000000..1614bf3 --- /dev/null +++ b/My part 7/main/java/controller/duelmenu/DuelMenuController.java @@ -0,0 +1,726 @@ +package controller.duelmenu; + +import controller.SpellCardController; +import controller.Utils; +import model.Board; +import model.Deck; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.DuelMenuView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.regex.Matcher; + +public class DuelMenuController { + private Player turnPlayer; + private Player notTurnPlayer; + private Player helpTurnPlayer; + private Phases phase; + private boolean isAITurn; + private int isSummoned = 0; //0 : is not summoned before, 1 : is summoned before + + public static String specifyTurnPlayer(Player firstPlayer, Player secondPlayer) { + String firstPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(firstPlayer); + if (!isMiniGameChoiceValid(firstPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices firstPlayerChoice = MiniGameChoices.valueOf(firstPlayerChoiceInString.toUpperCase()); + + String secondPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(secondPlayer); + if (!isMiniGameChoiceValid(secondPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices secondPlayerChoice = MiniGameChoices.valueOf(secondPlayerChoiceInString.toUpperCase()); + + if (firstPlayerChoice.equals(secondPlayerChoice)) return "draw"; + + return findMiniGameWinner(firstPlayer, secondPlayer, firstPlayerChoice, secondPlayerChoice); + } + + private static boolean isMiniGameChoiceValid(String choice) { + try { + MiniGameChoices.valueOf(choice.toUpperCase()); + return true; + } catch (Exception exception) { + return false; + } + } + + private static String findMiniGameWinner(Player firstPlayer, Player secondPlayer, + MiniGameChoices firstPlayerChoice, MiniGameChoices secondPlayerChoice) { + switch (firstPlayerChoice) { + case STONE: + if (secondPlayerChoice.equals(MiniGameChoices.PAPER)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case PAPER: + if (secondPlayerChoice.equals(MiniGameChoices.SCISSOR)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case SCISSOR: + if (secondPlayerChoice.equals(MiniGameChoices.STONE)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + } + +// this is never happen + return null; + } + + public DuelMenuMessages initialGame(Player firstPlayer, Player secondPlayer) { +// TODO: handle it for ai + String result = specifyTurnPlayer(firstPlayer, secondPlayer); + if (result.equals("invalid choice")) return DuelMenuMessages.MINI_GAME_INVALID_CHOICE; + else if (result.equals("draw")) return DuelMenuMessages.DRAW; + else turnPlayer = Player.getPlayerByUsername(result); + + if (turnPlayer.equals(firstPlayer)) notTurnPlayer = secondPlayer; + else notTurnPlayer = firstPlayer; + + turnPlayer.createBoard(); + notTurnPlayer.createBoard(); + + turnPlayer.getBoard().setDeck(turnPlayer.getActivatedDeck()); + notTurnPlayer.getBoard().setDeck(notTurnPlayer.getActivatedDeck()); + + Collections.shuffle(turnPlayer.getActivatedDeck().getMainCards()); + Collections.shuffle(notTurnPlayer.getActivatedDeck().getMainCards()); + + return DuelMenuMessages.SHOW_TURN_PLAYER; + } + + public DuelMenuMessages findCommand(String command) { +// TODO: handle menu commands --> menu exit and ... + if (command.startsWith("decrease ")) return cheatCodeDecreaseOpponentLifePont(command); + else if (command.startsWith("increase ")) return cheatCodeIncreaseLifePoint(command); + else if (command.startsWith("duel set-winner ")) return cheatCodeSetWinner(command); + else if (command.startsWith("select ")) return checkSelectCard(command); + else if (command.equals("select -d")) return deselectCard(); + else if (command.equals("summon")) ;//return checkSummonMonster(); + else if (command.equals("set")) return checkSetACard(); + else if (command.startsWith("set --position")) ;// return checkChangePosition(command); + else if (command.equals("flip-summon")) return flipSummon(); + else if (command.equals("attack direct")) return directAttack(); + else if (command.startsWith("attack")) return attack(command); + else if (command.equals("activate effect")) return checkActiveASpellCard(); + else if (command.equals("show graveyard")) { + DuelMenuView.showGraveyard(turnPlayer.getBoard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("back")) ;//checkBack(); + else if (command.equals("card show --selected")) { + DuelMenuView.printCard(1, turnPlayer.getBoard().getSelectedCard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("cancel")) ;//cancelCommand(); + else if (command.equals("surrender")) /*TODO*/ ; + +// TODO: handle cheat/debug commands + + return DuelMenuMessages.INVALID_COMMAND; + } + + private DuelMenuMessages cheatCodeDecreaseOpponentLifePont(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_DECREASE_OPPONENT_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + notTurnPlayer.decreaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + } + + private DuelMenuMessages cheatCodeIncreaseLifePoint(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_INCREASE_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + turnPlayer.increaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + } + + private DuelMenuMessages cheatCodeSetWinner(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_SET_WINNER.getRegex(), command); + if (matcher.find()) { + String nickname = matcher.group(1); + if (turnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/ ; + else if (notTurnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/ ; + else return DuelMenuMessages.WRONG_NICKNAME_CHEAT_CODE; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + return DuelMenuMessages.EMPTY; + } + + //Iman's Code + private void changePhase() { + phase = phase.next(); + DuelMenuMessages.changephase(phase); + if (phase == Phases.DRAW_PHASE){ + drawPhase(); + } + + } + + private void changeGameTurn(Player firstPlayer, Player secondPlayer) { + if (turnPlayer == firstPlayer) { + turnPlayer = secondPlayer; + notTurnPlayer = firstPlayer; + } + if (turnPlayer == secondPlayer) { + turnPlayer = firstPlayer; + notTurnPlayer = secondPlayer; + } + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void changeGameTurn() { + helpTurnPlayer = turnPlayer; + turnPlayer = notTurnPlayer; + notTurnPlayer = helpTurnPlayer; + isSummoned = 0; + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void drawPhase() { + changeGameTurn(); + DuelMenuMessages.playerTurn(turnPlayer); + cardDraw(); + } + + public void cardDraw() { + Deck deck = turnPlayer.getBoard().getDeck(); + if (deck.getNumberOfCardsInMainDeck() == 0) { + turnPlayer.setLifePoint(0); + return; + } +// turnPlayer.getBoard().drawCard(); + } + + private void summonMonster() { + int position = 0; // TODO fix this + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + + if (selectedMonster.getLevel() == 5 || selectedMonster.getLevel() == 6) { + summonWithOneTribute(position); + } else if (selectedMonster.getLevel() == 7 || selectedMonster.getLevel() == 8) { + summonWithTwoTribute(position); + } else { + selectedCard.getCardFaceUp(); + selectedMonster.settoOO(selectedMonster); + turnPlayer.getBoard().addMonsterCardToMonsterZone(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + DuelMenuMessages.summonedSuccessfully(); + } + } + + private DuelMenuMessages checkSummonMonster() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard) || selectedCard.getCardType() == CardTypes.RITUAL) { + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + else if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + else if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + else if (isSummoned == 1) { + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + + else { + summonMonster(); + return DuelMenuMessages.EMPTY; + } + } + +// public void tributeCardFromMonsterZone(int position) { +// graveyardCards.add(monstesrZones.get(position).getCurrentMonster()); +// monsterZones.get(position).removeCard(); +// } + + private DuelMenuMessages summonWithOneTribute(int position) { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (!turnPlayer.getBoard().isThereOneMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + return DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE; + } + String addressString = Utils.getScanner().nextLine().trim(); + if (addressString.equals("")) return null; // TODO fix this + int address = setCardAddressInMyBoard(Integer.parseInt(addressString)); + if (address < 1 || address > 5) { + return DuelMenuMessages.NO_MONSTER_ON_ADDRESS; + } + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address)) { + return DuelMenuMessages.NO_MONSTER_ON_THIS_ADDRESS; + } + else { + monstersZone[address] = null; + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + cardsInHand.remove(selectedCard); + isSummoned = 1; + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + } + } + + private void summonWithTwoTribute(int position) { + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (!turnPlayer.getBoard().isThereTwoMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + DuelMenuMessages.NotEnoughCardForTribute(); + } + String addressString1 = Utils.getScanner().nextLine().trim(); + if (addressString1.equals("surrender")) return; + String addressString2 = Utils.getScanner().nextLine().trim(); + if (addressString2.equals("surrender")) return; + int address1 = setCardAddressInMyBoard(Integer.parseInt(addressString1)); + int address2 = setCardAddressInMyBoard(Integer.parseInt(addressString2)); + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address1)) return; + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address2)) return; + monstersZone[address1] = null; + monstersZone[address2] = null; + isSummoned = 1; + + } + + private int setCardAddressInMyBoard(int address) { + if (address == 5) return 5; + if (address == 3) return 3; + if (address == 1) return 2; + if (address == 2) return 2; + if (address == 4) return 4; + return -1; + } + + private DuelMenuMessages set() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + // int position = selectedCardIndex; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected()) { + return DuelMenuMessages.SET_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + if (isSummoned == 1){ + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + isSummoned = 1; + if (model.cards.Card.isMonsterCard(selectedCard)) { + MonsterCard selectedMonster = (MonsterCard) selectedCard; + setAMonsterCard(selectedMonster); + } + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + + + } + + private DuelMenuMessages checkSetACard() { + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (board.getSelectedCard() == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!board.isACardInHandSelected()) return DuelMenuMessages.CANT_SET; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.NOT_TRUE_PHASE; + else if (Card.isMonsterCard(selectedCard)) return setAMonsterCard(selectedCard); + + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + } + + + private DuelMenuMessages setAMonsterCard(Card selectedCard) { + MonsterCard monsterCard = (MonsterCard) selectedCard; + if (turnPlayer.getBoard().isMonsterZoneFull()) return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + else turnPlayer.getBoard().addMonsterCardToMonsterZone(monsterCard); + monsterCard.settoDH(monsterCard); + return DuelMenuMessages.SET_SUCCESSFULLY; + } + + private DuelMenuMessages setPositionAttack() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (!selectedMonster.isDefensePosition() || !selectedMonster.toString().equals("DO")) { + return DuelMenuMessages.ALREADY_IN_WANTED_POSITION; + } + if (isSummoned == 1){ //TODO Already changed position? + return DuelMenuMessages.ALREADY_CHANGED_POSITION; + } + selectedMonster.settoOO(selectedMonster); + return DuelMenuMessages.MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY; + } + + private DuelMenuMessages setPositionDefence() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (selectedMonster.isDefensePosition() || !selectedMonster.toString().equals("OO")) { + return DuelMenuMessages.ALREADY_IN_WANTED_POSITION; + } + if (isSummoned == 1){ //TODO Already changed position? + return DuelMenuMessages.ALREADY_CHANGED_POSITION; + } + selectedMonster.settoDO(selectedMonster); + return DuelMenuMessages.MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY; + } + + private DuelMenuMessages flipSummon() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard)) { // check type of monsters + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (selectedMonster.toString().equals("DH") || isSummoned != 0) { + return DuelMenuMessages.FLIP_SUMMON_NOT_POSSIBLE; + } + selectedMonster.settoDO(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + + } + + private DuelMenuMessages ritualSummon() { +// TODO: complete it! + return DuelMenuMessages.EMPTY; + } + + private DuelMenuMessages specialSummon() { +// TODO: complete it! + return DuelMenuMessages.EMPTY; + } + + private DuelMenuMessages checkSelectCard(String command) { +// TODO: handle --> if there isn't any card in main deck, he/she loses +// TODO: maybe clean it more + Matcher matcher; + if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MONSTER_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MAGIC_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_FIELD_ZONE.getRegex(), command).find()) { + if (turnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(true); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_CARDS_IN_HAND.getRegex(), command)).find() ) { + int number = Integer.parseInt(matcher.group(1)); + if (number > turnPlayer.getBoard().getCardsInHand().size()) { + return DuelMenuMessages.INVALID_SELECTION; + } + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getCardsInHand().get(number - 1)); + turnPlayer.getBoard().setMyCardSelected(true); + turnPlayer.getBoard().setACardInHandSelected(true); + + } else { + turnPlayer.getBoard().setSelectedCard(null); + turnPlayer.getBoard().setMyCardSelected(false); + return DuelMenuMessages.INVALID_SELECTION; + } + + return DuelMenuMessages.CARD_SELECTED; + } + + private boolean isSelectionValid(Matcher matcher) { + int number = Integer.parseInt(matcher.group(1)); + return number <= 5 && number >= 1; + } + + private boolean isCardAvailableInMonstersZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMonstersZone()[number] != null; + } + + private boolean isCardAvailableInMagicsZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMagicsZone()[number] != null; + } + + private void selectCardFromMonstersZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMonstersZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMonstersZone()[number]); + } + } + + private void selectCardFromMagicsZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMagicsZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMagicsZone()[number]); + } + } + + private void selectCardFromFieldZone(boolean isMyCardSelected) { + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getFieldZone()); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getSelectedCard()); + } + } + + private DuelMenuMessages deselectCard() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages result = checkDeselectCard(); + if (result == null) { + board.setSelectedCard(null); + return DuelMenuMessages.DESELECTED; + } else return result; + } + + private DuelMenuMessages checkDeselectCard() { + Board board = turnPlayer.getBoard(); + if (board.getSelectedCard() == null) + return DuelMenuMessages.NOT_SELECTED_CARD; + return null; + } +// +// +// private void victimize() { +//// TODO: handle it! +// } +// + +// +// private DuelMenuMessages checkChangePosition(String command) { +// +// } +// +// private DuelMenuMessages changePosition(String command) { +// +// } +// +// private void updateGraveyard() { +//// TODO: handle it! +// } +// + + private DuelMenuMessages attack(String command) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.ATTACK.getRegex(), command); + if (matcher.find()) { + int numberOfChosenCard = Integer.parseInt(matcher.group(1)); + + DuelMenuMessages result = checkAttack(numberOfChosenCard); + if (result == null) { + MonsterCard attackingMonster = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentMonster = opponentPlayerBoard.getMonstersZone()[numberOfChosenCard]; + + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + DuelMenuMessages tempResult = attackingMonster.attack(turnPlayer, notTurnPlayer, numberOfChosenCard); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + + return tempResult; + } + return result; + + } else return DuelMenuMessages.INVALID_CARD_SELECT; + } + + private DuelMenuMessages checkAttack(int numberOfChosenCard) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + if (attackingPlayerBoard.getSelectedCard() == null || !attackingPlayerBoard.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (attackingPlayerBoard.getSelectedCard() instanceof MonsterCard) + return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + //TODO check battle phase + MonsterCard card = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + if (card.isAttacked()) + return DuelMenuMessages.ATTACKED_BEFORE; + if (opponentPlayerBoard.getMonstersZone()[numberOfChosenCard] == null) + return DuelMenuMessages.NO_CARD_FOUND_IN_THE_POSITION; + return null; + } + + private DuelMenuMessages directAttack() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages messages = checkDirectAttack(); + if (messages != null) + return messages; + else { + MonsterCard card = (MonsterCard) board.getSelectedCard(); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + notTurnPlayer.decreaseLifePoint(card.getAttackPoints()); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + + DuelMenuMessages.setDamageAmount(card.getAttackPoints()); + return DuelMenuMessages.DIRECT_ATTACK_DONE; + } + } + + private DuelMenuMessages checkDirectAttack() { + Board board = turnPlayer.getBoard(); + + if (board.getSelectedCard() == null || !board.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (phase.equals(Phases.BATTLE_PHASE)) + return DuelMenuMessages.NOT_SUITABLE_PHASE; + if (board.getSelectedCard() instanceof MonsterCard) { + MonsterCard card = (MonsterCard) board.getSelectedCard();//TODO: handle cast exception!! + if (card.isAttacked()) return DuelMenuMessages.ATTACKED_BEFORE; + } else return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + + return null; + } + + private DuelMenuMessages checkActiveASpellCard() { +// TODO: clean it! + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (selectedCard == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!selectedCard.getCardType().equals(CardTypes.SPELL)) return DuelMenuMessages.NOT_SPELL_CARD; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.CANT_ACTIVATE_SPELL_EFFECT; + else if (selectedCard.isPowerUsed()) return DuelMenuMessages.CARD_ACTIVATED_BEFORE; + else if (!turnPlayer.getBoard().isMyCardSelected()) return DuelMenuMessages.NOT_OWNER; + + MagicCard spellCard = (MagicCard) selectedCard; + if (spellCard.getIcon().equals("Field")) { + turnPlayer.getBoard().addSpellCardToFieldZone(spellCard); + spellCard.setPowerUsed(true); + spellCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } else if (board.isMagicsZoneFull() && board.isACardInHandSelected()) return DuelMenuMessages.FULL_MAGICS_ZONE; + + if (!SpellCardController.doSpellCardEffect(turnPlayer, notTurnPlayer, spellCard)) return DuelMenuMessages.UNDONE_PREPARATIONS; + if (board.isACardInHandSelected()) board.addMagicCardToMagicsZone(spellCard); + selectedCard.setPowerUsed(true); + selectedCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } + + private DuelMenuMessages setAMagicCard(MagicCard magicCard) { + Board board = turnPlayer.getBoard(); + if (magicCard.getIcon().equals("Field")) board.addSpellCardToFieldZone(magicCard); + else if (board.isMagicsZoneFull()) return DuelMenuMessages.FULL_MAGICS_ZONE; + else board.addMagicCardToMagicsZone(magicCard); + magicCard.setPowerUsed(false); + magicCard.setCardFaceUp(false); + + return DuelMenuMessages.SET_SUCCESSFULLY; + } + +// private DuelMenuMessages checkBack() { +// +// } +// +// private void cancelCommand() { +// +// } +// +// private Player/*or Enum*/ checkWinner() { +// +// } +// +// TODO: ----------------------------------------------- + +} diff --git a/My part 7/main/java/controller/duelmenu/DuelMenuMessages.java b/My part 7/main/java/controller/duelmenu/DuelMenuMessages.java new file mode 100644 index 0000000..bf50377 --- /dev/null +++ b/My part 7/main/java/controller/duelmenu/DuelMenuMessages.java @@ -0,0 +1,112 @@ +package controller.duelmenu; + +import model.Player; + +public enum DuelMenuMessages { + MINI_GAME_INVALID_CHOICE("please enter a valid option\n"), + DRAW("draw\nplease try again:\n"), + SHOW_TURN_PLAYER(" should start first\n"), + INVALID_SELECTION("invalid selection\n"), + CARD_SELECTED("card selected\n"), + CARD_NOT_FOUND("no card found in the given position\n"), + UNAVAILABLE_SELECTED_CARD("no card is selected yet\n"), + NOT_SPELL_CARD("activate effect is only for spell cards.\n"), + CANT_ACTIVATE_SPELL_EFFECT("you can’t activate an effect on this turn\n"), + CARD_ACTIVATED_BEFORE("you have already activated this card\n"), + FULL_MAGICS_ZONE("spell card zone is full\n"), + UNDONE_PREPARATIONS("preparations of this spell are not done yet\n"), + SPELL_ACTIVATED("spell activated\n"), + NOT_OWNER("you aren't owner of selected card\n"), + CANT_SET("you can’t set this card\n"), + NOT_TRUE_PHASE("you can’t do this action in this phase\n"), + SET_SUCCESSFULLY("set successfully\n"), + NOT_SELECTED_CARD("no card is selected yet\n"), + ATTACKED_BEFORE("this card already attacked\n"), + NOT_SUITABLE_PHASE("you can’t do this action in this phase\n"), + INVALID_CARD_SELECT("invalid selection\n"), + NO_CARD_FOUND_IN_THE_POSITION("no card found in the given position\n"), + CANT_ATTACK_WITH_CARD("you can’t attack with this card\n"), + YOU_CANT_ATTACK_TO_THIS_CARD("you cant attack to this card\n"), + ATTACK_CANCELED("attack to this card was canceled\n"), + DIRECT_ATTACK_DONE("you opponent receives battle damage\n"), + DESELECTED("card deselected\n"), + INVALID_COMMAND_CHEAT_CODE("invalid command\n"), + OPPONENT_GOT_DAMAGE_IN_ATTACK("your opponent’s monster is destroyed and your opponent receives battle damage\n"), + ATTACKING_PLAYER_CARD_DESTROYED("Your monster card is destroyed and you received battle damage\n"), + DEFENSE_POSITION_MONSTER_DESTROYED("the defense position monster is destroyed\n"), + NO_CARD_DESTROYED("no card is destroyed\n"), + RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD("no card is destroyed and you received battle damage\n"), + BOTH_CARDS_GET_DESTROYED("both you and your opponent monster cards are destroyed and no one receives damage\n"), + WRONG_NICKNAME_CHEAT_CODE("your entered nickname is wrong\n"), + EMPTY(""), + NO_CARD_SELECTED("no card is selected yet\n"), + SUMMON_NOT_POSSIBLE("you can’t summon this card\n"), + FLIP_SUMMON_NOT_POSSIBLE("you can’t flip summon this card\n"), + SET_NOT_POSSIBLE("you can’t set this card\n"), + PLAYER_TURN("it's 's turn"), + PHASE_IS_CHANGED("phase: \n"), + ALREADY_SUMMONED_OR_SET("you already summoned/set on this turn\n"), + NOT_ENOUGH_CARD_FOR_TRIBUTE("there are not enough card for tribute\n"), + NO_MONSTER_ON_THIS_ADDRESS("there are no monster one this address\n"), + MONSTER_ZONE_IS_FULL("monster card zone is full\n"), + SUMMONED_SUCCESSFULLY("summoned successfully\n"), + NO_MONSTER_ON_ADDRESS("there no monsters on this address"), + MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY("monster card position changed successfully\n"), + ALREADY_CHANGED_POSITION("you already changed this card position in this turn\n"), + ALREADY_IN_WANTED_POSITION("this card is already in the wanted position\n"), + CHANG_POSITION_NOT_POSSIBLE("you can’t change this card position\n"), + INVALID_COMMAND("invalid command\n"); + private String message; + + DuelMenuMessages(String message) { + this.message = message; + } + + public static void setShowTurnPlayer(Player player) { + DuelMenuMessages.SHOW_TURN_PLAYER.message = player.getUsername() + " should start first\n"; + } + + public static void summonedSuccessfully() { + System.out.print("summoned successfully\n"); + } + + public static void NotEnoughCardForTribute(){ + DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE.message = "there are not enough card for tribute\n"; + System.out.print("there are not enough card for tribute\n"); + } + + public static void noCardSelected() { + DuelMenuMessages.NO_CARD_SELECTED.message = "no card is selected yet"; + } + + public static void playerTurn(Player player) { + DuelMenuMessages.PLAYER_TURN.message = "it's + player.getUsername() + 's turn"; + } + + public static void changephase(Phases phase) { + DuelMenuMessages.PHASE_IS_CHANGED.message = "phase: " + phase; + } + + public static void setDamageAmount(int damageAmount) { + DuelMenuMessages.DIRECT_ATTACK_DONE.message = "you opponent receives " + damageAmount + " battle damage\n"; + } + + public static void setOpponentGotDamageInAttack(int damage) { + DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK.message = + "your opponent’s monster is destroyed and your opponent receives" + damage + " battle damage\n"; + } + + public static void setAttackingPlayerCardDestroyed(int damage) { + DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED.message = + "Your monster card is destroyed and you received " + damage + " battle damage\n"; + } + + public static void setReceiveDamageByAttackingToDefenseCard(int damage) { + DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD.message = + "no card is destroyed and you received " + damage + " battle damage\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 7/main/java/controller/duelmenu/DuelMenuRegexes.java b/My part 7/main/java/controller/duelmenu/DuelMenuRegexes.java new file mode 100644 index 0000000..9450450 --- /dev/null +++ b/My part 7/main/java/controller/duelmenu/DuelMenuRegexes.java @@ -0,0 +1,28 @@ +package controller.duelmenu; + +public enum DuelMenuRegexes { + SELECT_MONSTER_ZONE("^select --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_MAGIC_ZONE("^select --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN("^select --(?:monster|M) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN("^select --(?:spell|S) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_FIELD_ZONE("^select --(?:field|F)$"), + SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN("^select --(?:field|F) --(?:opponent|O)$"), + SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:field|F)$"), + SELECT_CARDS_IN_HAND("^select --(?:hand|H) ((?:-|)\\d+)$"), + CHEAT_DECREASE_OPPONENT_LIFE_POINT("^decrease --opponentLP ([0-9]+)$"), + CHEAT_INCREASE_LIFE_POINT("^increase --LP ([0-9]+)$"), + CHEAT_SET_WINNER("^duel set-winner (\\S+)$"), + ATTACK("^attack ([0-9]+)$"); + + private final String regex; + + DuelMenuRegexes(String message) { + this.regex = message; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 7/main/java/controller/duelmenu/MiniGameChoices.java b/My part 7/main/java/controller/duelmenu/MiniGameChoices.java new file mode 100644 index 0000000..57881a4 --- /dev/null +++ b/My part 7/main/java/controller/duelmenu/MiniGameChoices.java @@ -0,0 +1,17 @@ +package controller.duelmenu; + +public enum MiniGameChoices { + STONE("stone"), + PAPER("paper"), + SCISSOR("scissor"); + + private final String choice; + + MiniGameChoices(String choice) { + this.choice = choice; + } + + public String getChoice() { + return choice; + } +} diff --git a/My part 7/main/java/controller/duelmenu/Phases.java b/My part 7/main/java/controller/duelmenu/Phases.java new file mode 100644 index 0000000..14000bb --- /dev/null +++ b/My part 7/main/java/controller/duelmenu/Phases.java @@ -0,0 +1,15 @@ +package controller.duelmenu; + +public enum Phases { + DRAW_PHASE, + STANDBY_PHASE, + MAIN_PHASE_1, + BATTLE_PHASE, + MAIN_PHASE_2, + END_PHASE; + private static Phases[] values = values(); + + public Phases next() { + return values[(this.ordinal() + 1) % values.length]; + } +} diff --git a/My part 7/main/java/controller/importexportmenu/ImportExportMenuController.java b/My part 7/main/java/controller/importexportmenu/ImportExportMenuController.java new file mode 100644 index 0000000..cde2f83 --- /dev/null +++ b/My part 7/main/java/controller/importexportmenu/ImportExportMenuController.java @@ -0,0 +1,100 @@ +package controller.importexportmenu; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Utils; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.regex.Matcher; + +public class ImportExportMenuController { + public static ImportExportMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU; + else if (command.equals("menu show-current")) return ImportExportMenuMessages.SHOW_MENU; + else if (command.startsWith("import card")) return importCard(command); + else if (command.startsWith("export card")) return exportCard(command); + + return ImportExportMenuMessages.INVALID_COMMAND; + } + + private static ImportExportMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + return ImportExportMenuMessages.INVALID_NAVIGATION; + } + + private static ImportExportMenuMessages importCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.IMPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + try { + FileReader fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + MonsterCard monsterCard = gson.fromJson(fileReader, MonsterCard.class); + + if (Card.getCardByName(cardName) != null) return ImportExportMenuMessages.AVAILABLE_CARD; + if (monsterCard.getAttribute() == null) { +// so we understand that the card is a magic card + fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + MagicCard magicCard = gson.fromJson(fileReader, MagicCard.class); + Card.addCardToAllCards(magicCard); + if (isCardIncomplete(magicCard) || isMagicCardIncomplete(magicCard)) + return ImportExportMenuMessages.INVALID_FILE; + } else { +// so we understand that the card is a monster card + monsterCard.createEquippedByArrayList(); + Card.addCardToAllCards(monsterCard); + if (isCardIncomplete(monsterCard) || isMonsterCardIncomplete(monsterCard)) + return ImportExportMenuMessages.INVALID_FILE; + } + fileReader.close(); + } catch (IOException ignore) { + return ImportExportMenuMessages.UNAVAILABLE_FILE; + } + + + return ImportExportMenuMessages.EMPTY; + } + + private static boolean isCardIncomplete(Card card) { + return card.getName() == null || card.getDescription() == null || card.getCardType() == null; + } + + private static boolean isMonsterCardIncomplete(MonsterCard monsterCard) { + return monsterCard.getAttribute() == null || monsterCard.getMonsterType() == null; + } + + private static boolean isMagicCardIncomplete(MagicCard magicCard) { + return magicCard.getIcon() == null || magicCard.getStatus() == null; + } + + private static ImportExportMenuMessages exportCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.EXPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card card = Card.getCardByName(cardName); + if (card == null) return ImportExportMenuMessages.UNAVAILABLE_CARD; + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(card)); + fileWriter.close(); + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + + + return ImportExportMenuMessages.EMPTY; + } +} diff --git a/My part 7/main/java/controller/importexportmenu/ImportExportMenuMessages.java b/My part 7/main/java/controller/importexportmenu/ImportExportMenuMessages.java new file mode 100644 index 0000000..8f83021 --- /dev/null +++ b/My part 7/main/java/controller/importexportmenu/ImportExportMenuMessages.java @@ -0,0 +1,23 @@ +package controller.importexportmenu; + +public enum ImportExportMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_IMPORT_EXPORT_MENU(""), + SHOW_MENU("Import/Export Menu\n"), + INVALID_COMMAND("invalid command\n"), + UNAVAILABLE_FILE("there isn't any file with your entered card name\n"), + INVALID_FILE("your card file is not valid to import\n"), + AVAILABLE_CARD("your entered card name is available\n"), + UNAVAILABLE_CARD("your entered card name is not available\n"), + EMPTY(""); + + private final String message; + + ImportExportMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 7/main/java/controller/importexportmenu/ImportExportMenuRegexes.java b/My part 7/main/java/controller/importexportmenu/ImportExportMenuRegexes.java new file mode 100644 index 0000000..65c74dc --- /dev/null +++ b/My part 7/main/java/controller/importexportmenu/ImportExportMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.importexportmenu; + +public enum ImportExportMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + IMPORT_CARD("^import card ([^\n]+)$"), + EXPORT_CARD("^export card ([^\n]+)$"); + + private final String regex; + + ImportExportMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 7/main/java/controller/loginmenu/LoginMenuController.java b/My part 7/main/java/controller/loginmenu/LoginMenuController.java new file mode 100644 index 0000000..178d000 --- /dev/null +++ b/My part 7/main/java/controller/loginmenu/LoginMenuController.java @@ -0,0 +1,120 @@ +package controller.loginmenu; + +import controller.Utils; +import model.Player; +import view.MainMenuView; + +import java.util.regex.Matcher; + +public class LoginMenuController { + public static LoginMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) System.exit(0); + else if (command.equals("menu show-current")) return LoginMenuMessages.SHOW_MENU; + else if (command.startsWith("user create")) { + return checkCreateUser(command); + } else if (command.startsWith("user login")) { + return checkLoginUser(command); + } + + return LoginMenuMessages.INVALID_COMMAND; + } + + private static LoginMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(LoginMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return LoginMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return LoginMenuMessages.INVALID_NAVIGATION; + } + + return LoginMenuMessages.FIRST_LOGIN; + } + + private static LoginMenuMessages checkCreateUser(String command) { + Matcher matcher; + String username, nickname, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIRST_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(2); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SECOND_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(3); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_THIRD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(1); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FOURTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIFTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(3); + password = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SIXTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (Player.getPlayerByUsername(username) != null) { + LoginMenuMessages.setUsername(username); + return LoginMenuMessages.USERNAME_EXISTS; + } + if (Player.isNicknameExist(nickname)) { + LoginMenuMessages.setNickname(nickname); + return LoginMenuMessages.NICKNAME_EXISTS; + } + +// TODO: handle to have "strong password" error + createUser(username, password, nickname); + return LoginMenuMessages.USER_CREATED; + } + + private static void createUser(String username, String password, String nickname) { + new Player(username, password, nickname); + } + + private static LoginMenuMessages checkLoginUser(String command) { + Matcher matcher; + String username, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (!Player.isPasswordCorrect(username, password)) { + return LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD; + } + + return LoginMenuMessages.USER_LOGGED_IN; + } + + public static void loginUser(String command) { + Matcher matcher; + String username = null; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + } + + + MainMenuView mainMenuView = new MainMenuView(Player.getPlayerByUsername(username)); + mainMenuView.mainMenuView(); + } +} diff --git a/My part 7/main/java/controller/loginmenu/LoginMenuMessages.java b/My part 7/main/java/controller/loginmenu/LoginMenuMessages.java new file mode 100644 index 0000000..167c111 --- /dev/null +++ b/My part 7/main/java/controller/loginmenu/LoginMenuMessages.java @@ -0,0 +1,31 @@ +package controller.loginmenu; + +public enum LoginMenuMessages { + FIRST_LOGIN("please login first"), + INVALID_NAVIGATION("menu navigation is not possible"), + SHOW_MENU("Login Menu"), + USER_CREATED("user created successfully!"), + USERNAME_EXISTS("user with username already exists"), + NICKNAME_EXISTS("user with nickname already exists"), + USER_LOGGED_IN("user logged in successfully!"), + UNMATCHED_USERNAME_AND_PASSWORD("Username and password didn’t match!"), + INVALID_COMMAND("invalid command"); + + private String message; + + LoginMenuMessages(String message) { + this.message = message; + } + + public static void setUsername(String username) { + USERNAME_EXISTS.message = "user with username " + username + " already exists"; + } + + public static void setNickname(String nickname) { + NICKNAME_EXISTS.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 7/main/java/controller/loginmenu/LoginMenuRegexes.java b/My part 7/main/java/controller/loginmenu/LoginMenuRegexes.java new file mode 100644 index 0000000..f518551 --- /dev/null +++ b/My part 7/main/java/controller/loginmenu/LoginMenuRegexes.java @@ -0,0 +1,23 @@ +package controller.loginmenu; + +public enum LoginMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + CREATE_USER_FIRST_PATTERN("^user create --(?:username|U) (\\S+) --(?:nickname|N) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_SECOND_PATTERN("^user create --(?:username|U) (\\S+) --(?:password|P) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_THIRD_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_FOURTH_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"), + CREATE_USER_FIFTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:username|U) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_SIXTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:nickname|N) (\\S+) --(?:username|U) (\\S+)$"), + LOGIN_USER_USERNAME_PATTERN("^user login --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + LOGIN_USER_PASSWORD_PATTERN("^user login --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"); + + private final String regex; + + LoginMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 7/main/java/controller/mainmenu/MainMenuController.java b/My part 7/main/java/controller/mainmenu/MainMenuController.java new file mode 100644 index 0000000..e6be9bd --- /dev/null +++ b/My part 7/main/java/controller/mainmenu/MainMenuController.java @@ -0,0 +1,114 @@ +package controller.mainmenu; + +import controller.Utils; +import model.Player; +import view.*; + +import java.util.regex.Matcher; + +public class MainMenuController { + private final Player loggedInPlayer; + + public MainMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public MainMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return MainMenuMessages.EXIT_MAIN_MENU; + else if (command.equals("menu show-current")) return MainMenuMessages.SHOW_MENU; + else if (command.equals("user logout")) return MainMenuMessages.USER_LOGGED_OUT; + else if (command.startsWith("duel")) return enterDuelMenu(command); + + return MainMenuMessages.INVALID_COMMAND; + } + + private MainMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(MainMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return MainMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Main")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Duel")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Deck")) { + DeckMenuView deckMenuView = new DeckMenuView(loggedInPlayer); + deckMenuView.runDeckMenu(); + } else if (menu.equalsIgnoreCase("Scoreboard")) { + ScoreboardMenuView scoreboardMenuView = new ScoreboardMenuView(); + scoreboardMenuView.runScoreboard(); + } else if (menu.equalsIgnoreCase("Profile")) { + ProfileMenuView profileMenuView = new ProfileMenuView(loggedInPlayer); + profileMenuView.profileMenuView(); + } else if (menu.equalsIgnoreCase("Shop")) { + ShopMenuView shopMenuView = new ShopMenuView(loggedInPlayer); + shopMenuView.shopMenuView(); + } else if (menu.equalsIgnoreCase("ImportExport")) { + ImportExportMenuView importExportMenuView = new ImportExportMenuView(); + importExportMenuView.ImportExportMenuView(); + } + + return MainMenuMessages.EMPTY; + } + + private MainMenuMessages enterDuelMenu(String command) { +// TODO: clean and optimise this code according to AI + Matcher matcher; + String opponentPlayerCommand, rounds; + if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIRST_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_THIRD_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FOURTH_PATTERN.getRegex(), command) ).find()) { + opponentPlayerCommand = matcher.group(1); + rounds = matcher.group(2); + } else if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SECOND_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIFTH_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SIXTH_PATTERN.getRegex(), command) ).find()) { + rounds = matcher.group(1); + opponentPlayerCommand = matcher.group(2); + } else { + return MainMenuMessages.INVALID_COMMAND; + } + + if (opponentPlayerCommand.startsWith("second-player")) { + String opponentPlayerUsername = opponentPlayerCommand.substring(14); + Player opponentPlayer = Player.getPlayerByUsername(opponentPlayerUsername); + if (opponentPlayer == null) { + return MainMenuMessages.UNAVAILABLE_USERNAME; + } + + if (opponentPlayer.equals(loggedInPlayer)) return MainMenuMessages.SAME_USERNAME; + + if (loggedInPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(loggedInPlayer.getUsername()); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } else if (opponentPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(opponentPlayerUsername); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } + +// TODO: handle MainMenuMessages.INVALID_DECK message +// TODO: MainMenuMessages.setInvalidDeck(opponentPlayerUsername or loggedInPlayer.getUsername()); +// TODO: return MainMenuMessages.INVALID_DECK; + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + +// TODO: handle 1 or 3 turn game + DuelMenuView duelMenuView = new DuelMenuView(loggedInPlayer, opponentPlayer); + duelMenuView.duelMenuView(); + } else { +// TODO: handle entering to enter duel menu by AI + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + } + + return MainMenuMessages.EMPTY; + } +} diff --git a/My part 7/main/java/controller/mainmenu/MainMenuMessages.java b/My part 7/main/java/controller/mainmenu/MainMenuMessages.java new file mode 100644 index 0000000..85fa672 --- /dev/null +++ b/My part 7/main/java/controller/mainmenu/MainMenuMessages.java @@ -0,0 +1,33 @@ +package controller.mainmenu; + +public enum MainMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_MAIN_MENU(""), + SHOW_MENU("Main Menu\n"), + USER_LOGGED_OUT("user logged out successfully!\n"), + UNAVAILABLE_USERNAME("there is no player with this username\n"), + SAME_USERNAME("please enter another username\n"), + UNAVAILABLE_ACTIVE_DECK(" has no active deck\n"), + INVALID_DECK("’s deck is invalid\n"), + INVALID_ROUNDS_NUMBER("number of rounds is not supported\n"), + INVALID_COMMAND("invalid command\n"), + EMPTY(""); + + private String message; + + MainMenuMessages(String message) { + this.message = message; + } + + public static void setUnavailableActiveDeck(String username) { + UNAVAILABLE_ACTIVE_DECK.message = username + " has no active deck\n"; + } + + public static void setInvalidDeck(String username) { + INVALID_DECK.message = username + "’s deck is invalid\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 7/main/java/controller/mainmenu/MainMenuRegexes.java b/My part 7/main/java/controller/mainmenu/MainMenuRegexes.java new file mode 100644 index 0000000..210780f --- /dev/null +++ b/My part 7/main/java/controller/mainmenu/MainMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.mainmenu; + +public enum MainMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + ENTER_DUEL_MENU_FIRST_PATTERN("^duel --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_SECOND_PATTERN("^duel --(?:new|N) --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_THIRD_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_FOURTH_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+) --(?:new|N)$"), + ENTER_DUEL_MENU_FIFTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_SIXTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N)$"); + + private final String regex; + + MainMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 7/main/java/controller/profilemenu/ProfileMenuController.java b/My part 7/main/java/controller/profilemenu/ProfileMenuController.java new file mode 100644 index 0000000..5384e86 --- /dev/null +++ b/My part 7/main/java/controller/profilemenu/ProfileMenuController.java @@ -0,0 +1,99 @@ +package controller.profilemenu; + +import controller.Database; +import controller.Utils; +import model.Player; + +import java.util.regex.Matcher; + +public class ProfileMenuController { + private final Player loggedInPlayer; + + public ProfileMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ProfileMenuMessages findCommand(String command) { + String[] split = command.split("\\s+"); + if (split.length < 2) { + return ProfileMenuMessages.INVALID_COMMAND; + } else if (split[1].equals("enter")) { + return ProfileMenuMessages.CANT_NAVIGATE_MENU; + } else if (split[1].equals("exit")) { + return ProfileMenuMessages.EXIT_MENU; + } else if (split[1].equals("show")) { + return ProfileMenuMessages.PROFILE_MENU; + } else if (split[2].equals("--nickname")) { + return changeNickname(command); + } else if (command.startsWith("profile change")) { + return changePassword(command); + } + + return ProfileMenuMessages.INVALID_COMMAND; + } + + public ProfileMenuMessages changeNickname(String command) { + Matcher matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_NICKNAME.getRegex(), command); + + ProfileMenuMessages holdEnum = checkChangeNickName(matcher); + + if (holdEnum == null) { + loggedInPlayer.setNickname(matcher.group(1)); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_NICKNAME_DONE; + } + return holdEnum; + } + + public ProfileMenuMessages checkChangeNickName(Matcher matcher) { + if (matcher.find()) { + String nickname = matcher.group(1); + if (Player.isNicknameExist(nickname)) { + ProfileMenuMessages.setNickname(nickname); + return ProfileMenuMessages.NOT_UNIQUE_NICKNAME; + } + return null; + } else return ProfileMenuMessages.INVALID_COMMAND; + + } + + public ProfileMenuMessages changePassword(String command) { + String currentPassword, newPassword; + Matcher matcher; + if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIRST_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SECOND_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_THIRD_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FOURTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIFTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SIXTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else return ProfileMenuMessages.INVALID_COMMAND; + + ProfileMenuMessages holdEnum = checkChangePassword(currentPassword, newPassword); + + if (holdEnum == null) { + loggedInPlayer.setPassword(newPassword); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_PASSWORD_DONE; + } + + return holdEnum; + } + + public ProfileMenuMessages checkChangePassword(String currentPassword, String newPassword) { + if (!loggedInPlayer.getPassword().equals(currentPassword)) return ProfileMenuMessages.WRONG_CURRENT_PASSWORD; + if (currentPassword.equals(newPassword)) return ProfileMenuMessages.SAME_PASSWORD; + return null; + } +} diff --git a/My part 7/main/java/controller/profilemenu/ProfileMenuMessages.java b/My part 7/main/java/controller/profilemenu/ProfileMenuMessages.java new file mode 100644 index 0000000..4c0895f --- /dev/null +++ b/My part 7/main/java/controller/profilemenu/ProfileMenuMessages.java @@ -0,0 +1,27 @@ +package controller.profilemenu; + +public enum ProfileMenuMessages { + NOT_UNIQUE_NICKNAME("user with nickname already exists"), + CHANGE_NICKNAME_DONE("nickname changed successfully!"), + CHANGE_PASSWORD_DONE("password changed successfully!"), + WRONG_CURRENT_PASSWORD("current password is invalid"), + INVALID_COMMAND("invalid command"), + PROFILE_MENU("profile menu"), + EXIT_MENU("exit"), + CANT_NAVIGATE_MENU("menu navigation is not possible"), + SAME_PASSWORD("please enter a new password"); + + private String message; + + ProfileMenuMessages(String message) { + this.message = message; + } + + public static void setNickname(String nickname) { + ProfileMenuMessages.NOT_UNIQUE_NICKNAME.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 7/main/java/controller/profilemenu/ProfileMenuRegexes.java b/My part 7/main/java/controller/profilemenu/ProfileMenuRegexes.java new file mode 100644 index 0000000..ba8630d --- /dev/null +++ b/My part 7/main/java/controller/profilemenu/ProfileMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.profilemenu; + +public enum ProfileMenuRegexes { + CHANGE_NICKNAME("^profile change --nickname (\\S+)$"), + CHANGE_PASSWORD_FIRST_PATTERN("^profile change --(?:password|P) --(?:current|C) (\\S+) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_SECOND_PATTERN("^profile change --(?:password|P) --(?:new|N) (\\S+) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_THIRD_PATTERN("^profile change --(?:current|C) (\\S+) --(?:password|P) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_FOURTH_PATTERN("^profile change --(?:current|C) (\\S+) --(?:new|N) (\\S+) --(?:password$|P)"), + CHANGE_PASSWORD_FIFTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:password|P) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_SIXTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:current|C) (\\S+) --(?:password$|P)"); + + private final String regex; + + ProfileMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 7/main/java/controller/scoreboardmenu/Scoreboard.java b/My part 7/main/java/controller/scoreboardmenu/Scoreboard.java new file mode 100644 index 0000000..cb725a7 --- /dev/null +++ b/My part 7/main/java/controller/scoreboardmenu/Scoreboard.java @@ -0,0 +1,40 @@ +package controller.scoreboardmenu; + +import java.util.ArrayList; +import model.*; + +public class Scoreboard { + + private Scoreboard() { + } + + private static Scoreboard instance; + + public static Scoreboard getInstance() { + if (instance == null) + instance = new Scoreboard(); + return instance; + } + + public void showScoreboard() { + int counter = 1; + int index = 0; + long previousScore = -1; + StringBuilder output = new StringBuilder(); + ArrayList allUsers = Player.getAllPlayers(); + allUsers.sort(Player::compareTo); + for (Player player : allUsers) { + + + if (player.getScore() != previousScore) { + index += counter; + counter = 1; + } else counter++; + output.append(index).append(". ").append(player.getNickname()).append(": ").append(player.getScore()).append("\n"); + previousScore = player.getScore(); + + } + ScoreboardOutput.getInstance().showMessage(output.toString()); + } + +} diff --git a/My part 7/main/java/controller/scoreboardmenu/ScoreboardOutput.java b/My part 7/main/java/controller/scoreboardmenu/ScoreboardOutput.java new file mode 100644 index 0000000..c77252d --- /dev/null +++ b/My part 7/main/java/controller/scoreboardmenu/ScoreboardOutput.java @@ -0,0 +1,23 @@ +package controller.scoreboardmenu; + +public class ScoreboardOutput { + + private ScoreboardOutput() { + } + + private static ScoreboardOutput instance; + + public static ScoreboardOutput getInstance() { + if (instance == null) + instance = new ScoreboardOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/My part 7/main/java/controller/shopmenu/ShopMenuController.java b/My part 7/main/java/controller/shopmenu/ShopMenuController.java new file mode 100644 index 0000000..11dc61c --- /dev/null +++ b/My part 7/main/java/controller/shopmenu/ShopMenuController.java @@ -0,0 +1,63 @@ +package controller.shopmenu; + +import controller.Database; +import controller.Utils; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.DuelMenuRegexes; +import model.Player; +import model.cards.Card; + +import java.util.regex.Matcher; + +public class ShopMenuController { + private final Player loggedInPlayer; + + public ShopMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ShopMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ShopMenuMessages.EXIT_SHOP_MENU; + else if (command.equals("menu show-current")) return ShopMenuMessages.SHOW_MENU; + else if (command.startsWith("shop buy")) return buyACard(command); + else if (command.equals("shop show --all")) return ShopMenuMessages.SHOW_ALL_CARDS; + else if (command.startsWith("increase ")) return cheatCodeIncreaseMoney(command); + + return ShopMenuMessages.INVALID_COMMAND; + } + + private ShopMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + return ShopMenuMessages.INVALID_NAVIGATION; + } + + private ShopMenuMessages buyACard(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.BUY_CARD.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card boughtCard = Card.getCardByName(cardName); + if (boughtCard == null) return ShopMenuMessages.UNAVAILABLE_CARD; + + int boughtCardPrice = boughtCard.getPrice(); + if (boughtCardPrice > loggedInPlayer.getMoney()) return ShopMenuMessages.NOT_ENOUGH_MONEY; + + loggedInPlayer.decreaseMoney(boughtCardPrice); + loggedInPlayer.addCardToBoughtCards(boughtCard); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ShopMenuMessages.EMPTY; + } + + private ShopMenuMessages cheatCodeIncreaseMoney(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.CHEAT_INCREASE_MONEY.getRegex(), command); + if (matcher.find()) { + loggedInPlayer.increaseMoney(Integer.parseInt(matcher.group(1))); + return ShopMenuMessages.EMPTY; + } else return ShopMenuMessages.INVALID_COMMAND; + + } +} diff --git a/My part 7/main/java/controller/shopmenu/ShopMenuMessages.java b/My part 7/main/java/controller/shopmenu/ShopMenuMessages.java new file mode 100644 index 0000000..339bd0a --- /dev/null +++ b/My part 7/main/java/controller/shopmenu/ShopMenuMessages.java @@ -0,0 +1,22 @@ +package controller.shopmenu; + +public enum ShopMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_SHOP_MENU(""), + SHOW_MENU("Shop Menu\n"), + UNAVAILABLE_CARD("there is no card with this name\n"), + NOT_ENOUGH_MONEY("not enough money\n"), + EMPTY(""), + SHOW_ALL_CARDS(""), + INVALID_COMMAND("invalid command\n"); + + private final String message; + + ShopMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/My part 7/main/java/controller/shopmenu/ShopMenuRegexes.java b/My part 7/main/java/controller/shopmenu/ShopMenuRegexes.java new file mode 100644 index 0000000..0f4dd79 --- /dev/null +++ b/My part 7/main/java/controller/shopmenu/ShopMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.shopmenu; + +public enum ShopMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + BUY_CARD("^shop buy ([^\n]+)$"), + CHEAT_INCREASE_MONEY("^increase --money ([0-9]+)$"); + + private final String regex; + + ShopMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 7/main/java/model/Board.java b/My part 7/main/java/model/Board.java new file mode 100644 index 0000000..e15bc3d --- /dev/null +++ b/My part 7/main/java/model/Board.java @@ -0,0 +1,211 @@ +package model; + +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Board { + private MonsterCard[] monstersZone; + private MagicCard[] magicsZone; + private ArrayList graveyard; + private ArrayList cardsInHand; + private Deck deck; + private MagicCard fieldZone;//TODO: maybe it should be from these classes --> Spell / fieldSpell + private Card selectedCard; +// if this boolean equals "false" so we can conclude that opponent card selected or nothing selected + private boolean isMyCardSelected; + private boolean isACardInHandSelected; + + { + monstersZone = new MonsterCard[6]; + magicsZone = new MagicCard[6]; + graveyard = new ArrayList<>(); + cardsInHand = new ArrayList<>(); + fieldZone = null; + isMyCardSelected = false; + isACardInHandSelected = false; + } + + public void setDeck(Deck deck) { + this.deck = deck;//TODO: maybe we should have a copy of deck in duel menu --> if all changes don't apply in main deck + } + + public MonsterCard[] getMonstersZone() { + return monstersZone; + } + + public MagicCard[] getMagicsZone() { + return magicsZone; + } + + public ArrayList getGraveyard() { + return graveyard; + } + + public ArrayList getCardsInHand() { + return cardsInHand; + } + + public MagicCard getFieldZone() { + return fieldZone; + } + + public Card getSelectedCard() { + return selectedCard; + } + + public Deck getDeck() { + return deck; + } + + public void setSelectedCard(Card selectedCard) { + this.selectedCard = selectedCard; + } + + public void setFieldZone(MagicCard fieldZone) { this.fieldZone = fieldZone; } + + public boolean isMyCardSelected() { + return isMyCardSelected; + } + + public void setMyCardSelected(boolean myCardSelected) { + isMyCardSelected = myCardSelected; + } + + public boolean isACardInHandSelected() { + return isACardInHandSelected; + } + + public void setACardInHandSelected(boolean ACardInHandSelected) { + isACardInHandSelected = ACardInHandSelected; + } + + public boolean isMagicsZoneFull() { + return getNumberOfFullPartsOfMagicsZone() == 5; + } + + public boolean isMonsterZoneFull() { + return getNumberOfFullPartsOfMonstersZone() == 5; + } + + public boolean isMagicsZoneEmpty() { + return getNumberOfFullPartsOfMagicsZone() == 0; + } + + public int getNumberOfFullPartsOfMagicsZone() { + int numberOfFullPartsOfMagicsZone = 0; + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) ++numberOfFullPartsOfMagicsZone; + } + return numberOfFullPartsOfMagicsZone; + } + + public int getNumberOfFullPartsOfMonstersZone() { + int getNumberOfFullPartsOfMonstersZone = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null) ++getNumberOfFullPartsOfMonstersZone; + } + return getNumberOfFullPartsOfMonstersZone; + } + + public boolean isCardFaceUp(String cardName) { +// if cardName isn't available, then this method returns false + boolean isCardFaceUp = false; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = monstersZone[i].getCardFaceUp(); + } + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = magicsZone[i].getCardFaceUp(); + } + return isCardFaceUp; + } + + public void addSpellCardToFieldZone(MagicCard spellCard) { + MagicCard previousFieldZone = fieldZone; + if (previousFieldZone != null) graveyard.add(previousFieldZone); + setFieldZone(spellCard); + cardsInHand.remove(spellCard); + } + + public boolean addMagicCardToMagicsZone(MagicCard magicCard) { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] == null) { + magicsZone[i] = magicCard; + cardsInHand.remove(magicCard); + return true; + } + } + return false; + } + + public boolean addMonsterCardToMonsterZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] == null) { + monstersZone[i] = monsterCard; + cardsInHand.remove(monsterCard); + return true; + } + } + return false; + } + + public boolean isCardAvailableInMonstersZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monsterCard)) return true; + } + return false; + } + + public int getNumberOfFaceUpMonsterCards() { + int numberOfFaceUpMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getCardFaceUp()) ++numberOfFaceUpMonsterCards; + } + + return numberOfFaceUpMonsterCards; + } + + public int getNumberOfWarriorMonsterCards() { + int numberOfWarriorMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getMonsterType().equals("Warrior")) ++numberOfWarriorMonsterCards; + } + + return numberOfWarriorMonsterCards; + } + + public boolean isThereCardInAddress(MonsterCard[] monsterZone, int address) { + if (monsterZone[address] != null) return true; + return false; + } + + public boolean isThereOneMonsterForTribute(MonsterCard[] monsterZone) { + for (Card card : monsterZone) { + if (card != null) return true; + } + return false; + } + + public boolean isThereTwoMonsterForTribute(MonsterCard[] monstersZone) { + int counter = 0; + for (Card card : monstersZone) { + if (card != null) counter++; + } + if (counter < 2) { + return false; + } + return true; + } + + +// public void drawCard() { +// Card card = deck.getNumberOfCardsInDeck(deck.getNumberOfCardsInDeck() - 1); +// cardsInHand.add(card); +// deck.remove(deck.size() - 1); +// System.out.println("new card added to the hand: " + card.getName()); +// } + + +} diff --git a/My part 7/main/java/model/Deck.java b/My part 7/main/java/model/Deck.java new file mode 100644 index 0000000..42b0c88 --- /dev/null +++ b/My part 7/main/java/model/Deck.java @@ -0,0 +1,214 @@ +package model; + +import controller.deckmenu.DeckMenuDatabase; +import model.*; +import controller.deckmenu.*; +import model.cards.Card; + +import java.util.ArrayList; + +public class Deck { + public ArrayList mainCards = new ArrayList<>(); + public ArrayList sideCards = new ArrayList<>(); + Player owner; + String name; + DeckType type; + Boolean isActive = false; + Boolean IsValid; + + public Deck(String name, Player owner, boolean hasSideDeck, boolean shouldBeSaved) { + this.name = name; + if (shouldBeSaved) + DeckMenuDatabase.allDecks.add(this); + if (!hasSideDeck) + sideCards = null; + this.owner = owner; + } + + public Deck(String name, Player owner) { + this.name = name; + sideCards = null; + this.owner = owner; + } + + public Deck(String name) { + this.name = name; + sideCards = null; + } + public Deck() { + sideCards = null; + } + + public void updateOwnerDecks() { + String deckType = (name.length() > 16) ? name.substring(name.length() - 16) : ""; + if (deckType.equals(".purchased-cards")) + owner.setAllPlayerCard(this); + else { + owner.getAllDeck().add(this); + if (this.isActive) + owner.setActiveDeck(this); + } + } + + public ArrayList getMainCards() { + if (mainCards == null) + return (mainCards = new ArrayList<>()); + return mainCards; + } + + public void setMainCards(ArrayList mainCards) { + this.mainCards = mainCards; + } + + public ArrayList getSideCards() { + return sideCards; + } + + public void setSideCards(ArrayList sideCards) { + this.sideCards = sideCards; + } + + public Player getOwner() { + return owner; + } + + public void setOwner(Player owner) { + this.owner = owner; + } + + public void setActive(Boolean active) { + isActive = active; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setActivation(Boolean active) { + isActive = active; + } + + public void setValid(Boolean valid) { + IsValid = valid; + } + + public void setType(DeckType type) { + this.type = type; + } + + public void addCard(Card card, boolean shouldBeAddedToMain) { + if (shouldBeAddedToMain) + mainCards.add(card); + else + sideCards.add(card); + if (card != null) + card.setCurrentDeck(this); + } + + public void addCard(Card card) { + mainCards.add(card); + if (card != null && !name.equals("selected collected deck")) + card.setCurrentDeck(this); + } + + public void moveCardTo(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCard(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public void moveCardToForGame(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCardForGame(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public boolean hasCard(Card card, boolean isMain) { + if (isMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) + return true; + + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + return true; + } + return false; + } + + public void removeCard(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) { + mainCards.remove(cardInMain); + return; + } + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + sideCards.remove(cardInSide); + return; + } + } + + public void removeCardForGame(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) + mainCards.remove(card); + else + sideCards.remove(card); + } + + public int getNumberOfCardsInDeck(Card card) { + int count = 0; + for (Card cardInDeck : mainCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + for (Card cardInDeck : sideCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + return count; + } + + public int getNumberOfCardsInMainDeck() { + return mainCards.size(); + } + + public int getNumberOfCardsInSideDeck() { + return sideCards.size(); + } + + public void updateCurrentDeck() { + if (mainCards != null) + for (Card card : mainCards) + if (card != null) + card.setCurrentDeck(this); + if (sideCards != null) + for (Card card : sideCards) + if (card != null) + card.setCurrentDeck(this); + } + public String toString(boolean isMain) { + StringBuilder output = new StringBuilder(); + int number = 1; + if (isMain) + for (Card card : mainCards) { + if (card == null) + continue; + output.append(number).append(". ").append(card.toString()); + number++; + } + else + for (Card card : sideCards) { + if (card == null) + continue; + output.append(number).append(". ").append(card.toString()); + number++; + } + return output.toString(); + } +} \ No newline at end of file diff --git a/My part 7/main/java/model/DeckType.java b/My part 7/main/java/model/DeckType.java new file mode 100644 index 0000000..2d1643c --- /dev/null +++ b/My part 7/main/java/model/DeckType.java @@ -0,0 +1,8 @@ +package model; + +public enum DeckType { + regulardeck, + inactivedeck, + graveyarddeck, + selectedcarddeck +} diff --git a/My part 7/main/java/model/Player.java b/My part 7/main/java/model/Player.java new file mode 100644 index 0000000..fb21fe0 --- /dev/null +++ b/My part 7/main/java/model/Player.java @@ -0,0 +1,288 @@ +package model; + +import com.google.gson.annotations.Expose; +import controller.Database; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class Player { + private static ArrayList allPlayers; + + static { + allPlayers = new ArrayList<>(); + } + + @Expose + private ArrayList boughtCards; + @Expose + private ArrayList allMainDecks; + private Board board; + @Expose + private Deck sideDeck; + @Expose + private Deck activatedDeck; + @Expose + private String username; + @Expose + private String password; + @Expose + private String nickname; + @Expose + private long score; + @Expose + private long money; + private int lifePoint; + private transient Deck allPlayerCard; + private transient ArrayList allDeck = new ArrayList<>(); + private transient ArrayList gameDecks = new ArrayList<>(); + + { + boughtCards = new ArrayList<>(); + allMainDecks = new ArrayList<>(); + board = null; + sideDeck = new Deck(); + activatedDeck = null; + score = 0; + money = 100000; + lifePoint = 8000; + } + + public Player(String username, String password, String nickname) { + setUsername(username); + setPassword(password); + setNickname(nickname); + addPlayerToAllPlayers(this); + Database.updatePlayerInformationInDatabase(this); + } + + public static Boolean isNicknameExist(String nickname) { + for (Player player : allPlayers) { + if (player.nickname.equals(nickname)) return true; + } + return false; + } + + public static Boolean isPasswordCorrect(String username, String password) { + Player player = getPlayerByUsername(username); + if (player == null) return false; + + return player.password.equals(password); + } + + public static Player getPlayerByUsername(String username) { + for (Player player : allPlayers) { + if (player.username.equals(username)) return player; + } + return null; + } + + public void setBoughtCards(ArrayList boughtCards) { + this.boughtCards = boughtCards; + } + + public Deck getActiveDeck() { + return activatedDeck; + } + + public void setActiveDeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public ArrayList getAllDeck() { + if (allDeck == null) + return (allDeck = new ArrayList<>()); + return allDeck; + } + + public void setAllDeck(ArrayList allDeck) { + this.allDeck = allDeck; + } + + public Deck getAllPlayerCard() { + return allPlayerCard; + } + + public static ArrayList getAllPlayers() { + return allPlayers; + } + + public void addCardToAllPlayerCard(Card card) { + this.allPlayerCard.getMainCards().add(card); + } + + public void setAllPlayerCard(Deck allPlayerCard) { + this.allPlayerCard = allPlayerCard; + } + + public static void addPlayerToAllPlayers(Player player) { + allPlayers.add(player); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public long getScore() { + return score; + } + + public long getMoney() { + return money; + } + + public Deck getActivatedDeck() { + return activatedDeck; + } + + public ArrayList getBoughtCards() { + return boughtCards; + } + + public void increaseScore(long score) { + this.score += score; + } + + public void decreaseScore(long score) { + this.score -= score; + } + + public void increaseMoney(long money) { + this.money += money; + } + + public void decreaseMoney(long money) { + this.money -= money; + } + + public void addCardToBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.add(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.add(new MagicCard((MagicCard) card)); + } + } + + public void addMainDeck(String deckName) { + Deck mainDeck = new Deck(deckName); + this.allMainDecks.add(mainDeck); + } + + public Boolean isMainDeckExist(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return true; + } + return false; + } + + public void deleteMainDeck(String deckName) { + Deck mainDeck = getDeckByName(deckName); + if (mainDeck != null) { + boughtCards.addAll(mainDeck.getMainCards()); + allMainDecks.remove(mainDeck); + } + } + + public Deck getDeckByName(String deckName) { + for (Deck deck : allMainDecks) { + if (deck.getName().equals(deckName)) return deck; + } + return null; + } + + public int compareTo(Player player) { + if (this.score > player.score) + return -1; + if (this.score < player.score) + return 1; + if (this.nickname.compareTo(player.getNickname()) > 0) + return -1; + if (this.nickname.compareTo(player.getNickname()) < 0) + return 1; + return 0; + } + + public void activateADeck(String deckName) { + Deck deck = getDeckByName(deckName); + if (deck != null) activatedDeck = deck; + } + public void activateADeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public void addCardToMainDeck() { +// TODO: ???? but remember to remove this card from boughtCards :) + } + + public void removeACard() { +// TODO: ???? but remember to add this card from boughtCards :) + } + + public void decreaseLifePoint(int amount) { + this.lifePoint -= amount; + } + + public void increaseLifePoint(int amount) { + this.lifePoint += amount; + } + + public void setLifePoint(int lifePoint) { + this.lifePoint = lifePoint; + } + + public int getLifePoint() { + return lifePoint; + } + + public void createBoard() { + board = new Board(); + } + + public Board getBoard() { + return board; + } + + public boolean hasCard(Card card){ + for (Card boughtCard : boughtCards) { + if (card.getName().equals(boughtCard.getName())) + return true; + } + return false; + } + + public void removeCardFromBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.remove(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.remove(new MagicCard((MagicCard) card)); + } + } +} \ No newline at end of file diff --git a/My part 7/main/java/model/cards/Card.java b/My part 7/main/java/model/cards/Card.java new file mode 100644 index 0000000..9ebd536 --- /dev/null +++ b/My part 7/main/java/model/cards/Card.java @@ -0,0 +1,115 @@ +package model.cards; + +import com.google.gson.annotations.Expose; +import model.Deck; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.TreeMap; + +public class Card { + protected static HashMap allCards; + + static { + allCards = new HashMap<>(); + } + + @Expose + protected final String name; + protected final String description; + protected final CardTypes cardType; + protected final int price; +// if this boolean equals "false" so we can conclude that card is "face down" + protected transient boolean isCardFaceUp; + protected transient boolean isPowerUsed; + protected transient Deck currentDeck; + + { + isCardFaceUp = false; + isPowerUsed = false; + } + + public Card(String name, String description, CardTypes cardType, int price) { + this.name = name; + this.description = description; + this.cardType = cardType; + this.price = price; + } + + public static Card getCardByName(String name) { + return allCards.get(name); + } + + public static TreeMap getListOfCards() { + TreeMap listOfCards = new TreeMap<>(); + for (String cardName : allCards.keySet()) { + Integer cardPrice = allCards.get(cardName).getPrice(); + listOfCards.put(cardName, cardPrice); + } + return listOfCards; + } + + public static boolean isMonsterCard(Card card) { + try { + MonsterCard monsterCard = (MonsterCard) card; + return true; + } catch (Exception exception) { + return false; + } + } + + public static int findNumberOfMonsterCards(ArrayList cards) { + int numberOfMonsterCards = 0; + for (Card card : cards) { + if (Card.isMonsterCard(card)) ++numberOfMonsterCards; + } + return numberOfMonsterCards; + } + + public static void addCardToAllCards(Card card) { + allCards.put(card.getName(), card); + } + + public static HashMap getAllCards() { + return allCards; + } + + public String getName() { + return name; + } + + public void setCurrentDeck(Deck currentDeck) { this.currentDeck = currentDeck; } + + public Deck getCurrentDeck() { + return currentDeck; + } + + public CardTypes getCardType() { + return cardType; + } + + public int getPrice() { + return price; + } + + public void setPowerUsed(boolean powerUsed) { + isPowerUsed = powerUsed; + } + + public boolean isPowerUsed() { + return isPowerUsed; + } + + public String getDescription() { + return description; + } + + public Boolean getCardFaceUp() { + return isCardFaceUp; + } + + public void setCardFaceUp(Boolean cardFaceUp) { + isCardFaceUp = cardFaceUp; + } +} diff --git a/My part 7/main/java/model/cards/CardTypes.java b/My part 7/main/java/model/cards/CardTypes.java new file mode 100644 index 0000000..520056f --- /dev/null +++ b/My part 7/main/java/model/cards/CardTypes.java @@ -0,0 +1,26 @@ +package model.cards; + +import com.google.gson.annotations.SerializedName; + +public enum CardTypes { + @SerializedName("Normal") + NORMAL("Normal"), + @SerializedName("Effect") + EFFECT("Effect"), + @SerializedName("Ritual") + RITUAL("Ritual"), + @SerializedName("Spell") + SPELL("Spell"), + @SerializedName("Trap") + TRAP("Trap"); + + private final String regex; + + CardTypes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 7/main/java/model/cards/magiccard/MagicCard.java b/My part 7/main/java/model/cards/magiccard/MagicCard.java new file mode 100644 index 0000000..396faf8 --- /dev/null +++ b/My part 7/main/java/model/cards/magiccard/MagicCard.java @@ -0,0 +1,39 @@ +package model.cards.magiccard; + +import model.cards.Card; +import model.cards.CardTypes; + +public class MagicCard extends Card { + protected final String icon; + protected final MagicCardStatuses status; + + public MagicCard(String name, CardTypes cardType, String icon, String description, MagicCardStatuses status, int price) { + super(name, description, cardType, price); + this.icon = icon; + this.status = status; + allCards.put(name, this); + } + + public MagicCard(MagicCard magicCard) { + super(magicCard.name, magicCard.description, magicCard.cardType, magicCard.price); + this.icon = magicCard.icon; + this.status = magicCard.status; + } + + public String getIcon() { + return icon; + } + + public MagicCardStatuses getStatus() { + return status; + } + + public void print() { +// TODO: handle it --> «this.equals(null)» have error and «System.out.print» should be in the view +// if (this.equals(null)) +// System.out.print("E "); +// else if (isCardFaceUp) +// System.out.print("O "); +// else System.out.print("H "); + } +} diff --git a/My part 7/main/java/model/cards/magiccard/MagicCardStatuses.java b/My part 7/main/java/model/cards/magiccard/MagicCardStatuses.java new file mode 100644 index 0000000..a2540c9 --- /dev/null +++ b/My part 7/main/java/model/cards/magiccard/MagicCardStatuses.java @@ -0,0 +1,20 @@ +package model.cards.magiccard; + +import com.google.gson.annotations.SerializedName; + +public enum MagicCardStatuses { + @SerializedName("Limited") + LIMITED("Limited"), + @SerializedName("Unlimited") + UNLIMITED("Unlimited"); + + private final String regex; + + MagicCardStatuses(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/My part 7/main/java/model/cards/monstercard/MonsterCard.java b/My part 7/main/java/model/cards/monstercard/MonsterCard.java new file mode 100644 index 0000000..d72dedd --- /dev/null +++ b/My part 7/main/java/model/cards/monstercard/MonsterCard.java @@ -0,0 +1,139 @@ +package model.cards.monstercard; + +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; + +import java.util.ArrayList; + +public class MonsterCard extends Card implements SpecialMonstersFunction { + protected final short level; + protected final MonsterCardAttributes attribute; + protected final String monsterType; + protected int attackPoints; + protected int defensePoints; + protected transient ArrayList equippedBy; +// if this boolean equals "false" so we can conclude that card is in attack position + protected transient boolean isDefensePosition; + protected transient boolean isAttacked = false; + + { + equippedBy = new ArrayList<>(); + isDefensePosition = false; + } + + public MonsterCard(String name, short level, MonsterCardAttributes attribute, String monsterType, CardTypes cardType, + int attackPoints, int defensePoints, String description, int price) { + super(name, description, cardType, price); + this.level = level; + this.attribute = attribute; + this.monsterType = monsterType; + setAttackPoints(attackPoints); + setDefensePoints(defensePoints); + allCards.put(name, this); + } + + public MonsterCard(MonsterCard monsterCard) { + super(monsterCard.name, monsterCard.description, monsterCard.cardType, monsterCard.price); + this.level = monsterCard.level; + this.attribute = monsterCard.attribute; + this.monsterType = monsterCard.monsterType; + this.attackPoints = monsterCard.attackPoints; + this.defensePoints = monsterCard.defensePoints; + } + + public short getLevel() { + return level; + } + + public MonsterCardAttributes getAttribute() { + return attribute; + } + + public String getMonsterType() { + return monsterType; + } + + public int getAttackPoints() { + return attackPoints; + } + + public void setAttackPoints(int attackPoints) { + this.attackPoints = attackPoints; + } + + public int getDefensePoints() { + return defensePoints; + } + + public void setDefensePoints(int defensePoints) { + this.defensePoints = defensePoints; + } + + public boolean isAttacked() { + return isAttacked; + } + + public void setAttacked(boolean attacked) { + isAttacked = attacked; + } + + public boolean isDefensePosition() { + return isDefensePosition; + } + + public void setDefensePosition(boolean defensePosition) { + isDefensePosition = defensePosition; + } + + public ArrayList getEquippedBy() { + return equippedBy; + } + + public void addToEquippedBy(MagicCard equippedBy) { + this.equippedBy.add(equippedBy); + } + + public void increaseAttackPoints(int amount) { + attackPoints += amount; + } + + public void decreaseAttackPoints(int amount) { + attackPoints -= amount; + } + + public void increaseDefencePoints(int amount) { + defensePoints += amount; + } + + public void decreaseDefencePoints(int amount) { + defensePoints -= amount; + } + + public void createEquippedByArrayList() { + equippedBy = new ArrayList<>(); + } + + public void settoDO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoDH(MonsterCard selectedMonster) { + this.setCardFaceUp(!isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoOO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = false; + } + + @Override + public String toString() { + if (!this.getCardFaceUp() && this.isDefensePosition) return "DH"; + else if (this.getCardFaceUp() && this.isDefensePosition) return "DO"; + else if (this.getCardFaceUp() && !this.isDefensePosition) return "OO"; + return "E "; + } +} diff --git a/My part 7/main/java/model/cards/monstercard/MonsterCardAttributes.java b/My part 7/main/java/model/cards/monstercard/MonsterCardAttributes.java new file mode 100644 index 0000000..4677550 --- /dev/null +++ b/My part 7/main/java/model/cards/monstercard/MonsterCardAttributes.java @@ -0,0 +1,10 @@ +package model.cards.monstercard; + +public enum MonsterCardAttributes { + DARK, + EARTH, + FIRE, + LIGHT, + WATER, + WIND; +} diff --git a/My part 7/main/java/model/cards/monstercard/SpecialMonstersFunction.java b/My part 7/main/java/model/cards/monstercard/SpecialMonstersFunction.java new file mode 100644 index 0000000..0b73141 --- /dev/null +++ b/My part 7/main/java/model/cards/monstercard/SpecialMonstersFunction.java @@ -0,0 +1,157 @@ +package model.cards.monstercard; + +import controller.duelmenu.DuelMenuMessages; +import model.Board; +import model.Player; + +public interface SpecialMonstersFunction { + default DuelMenuMessages attack(Player attackingPlayer, Player opponentPlayer, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + MonsterCard attackingCard = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentCard = opponentPlayerBoard.getMonstersZone()[numberToAttack]; + + if (opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack) != null) { + + switch (opponentCard.toString()) { + case "OO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayer.decreaseLifePoint(attackingCard.attackPoints - opponentCard.attackPoints); + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + DuelMenuMessages.setOpponentGotDamageInAttack(attackingCard.attackPoints - opponentCard.attackPoints); + return DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setAttackingPlayerCardDestroyed(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED; + } + + case "DO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + return DuelMenuMessages.DEFENSE_POSITION_MONSTER_DESTROYED; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + return DuelMenuMessages.NO_CARD_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setReceiveDamageByAttackingToDefenseCard(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD; + } + case "DH": + break; + } + + return null; + + } else + return opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + + default DuelMenuMessages defense(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + switch (opponentCard.getName()) { + case "Command knight": + commandKnightFunction(opponentPlayerBoard); + break; + case "Yomi Ship": + return yomiShipFunction(attackingPlayerBoard, attackingCard, opponentCard); + case "Suijin": + return suijinFunction(attackingCard); + case "Marshmallon": + return marshmallonFunction(attackingPlayer); + case "Texchanger": + return texchangerFunction(opponentCard); + case "Exploder Dragon": + return exploderDragon(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + return null; + } + + default DuelMenuMessages texchangerFunction(MonsterCard opponentCard) { + if (!opponentCard.isPowerUsed()) { + opponentCard.setPowerUsed(true); + // choosing a card ehzar??????? + return DuelMenuMessages.ATTACK_CANCELED; + } + return null; + } + + default DuelMenuMessages commandKnightFunction(Board opponentPlayerBoard) { + for (int i = 1; i <= 5; i++) { + if (opponentPlayerBoard.getMonstersZone()[i] != null && !opponentPlayerBoard.getMonstersZone()[i].getName().equals("Command knight")) { + return DuelMenuMessages.YOU_CANT_ATTACK_TO_THIS_CARD; + } + } + return null; + } + + default DuelMenuMessages yomiShipFunction(Board attackingPlayerBoard, MonsterCard attackingCard, MonsterCard opponentCard) { + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + return null; + } + + default DuelMenuMessages suijinFunction(MonsterCard attackingCard) { +// attackingCard.setAttackLevel(0);//TODO: undo it!! + return null; + } + + default DuelMenuMessages marshmallonFunction(Player attackingPlayer) { + attackingPlayer.decreaseLifePoint(1000); + return null; + } + + default DuelMenuMessages exploderDragon(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int number) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + return null; + } + + default void deleteMonsterFromZone(MonsterCard monster, MonsterCard[] monstersZone) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monster)) { + monstersZone[i] = null; + break; + } + } + } +} diff --git a/My part 7/main/java/view/DeckMenuView.java b/My part 7/main/java/view/DeckMenuView.java new file mode 100644 index 0000000..5341692 --- /dev/null +++ b/My part 7/main/java/view/DeckMenuView.java @@ -0,0 +1,137 @@ +package view; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import controller.Utils; +import controller.deckmenu.DeckMenuController; +import controller.deckmenu.DeckMenuOutput; +import model.*; + +public class DeckMenuView { + public static Scanner scanner = Utils.getScanner(); + + private final Player loggedInPlayer; + + public DeckMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + private final String[] deckMenuRegexes = { + "^deck create (?\\w+)$", + "^deck delete (?\\w+)$", + "^deck set-activate (?\\w+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck add-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck show (?:--all|-a)$", + "^deck show (?:--deck-name|-d) (?.+) (?:--side|-s)$", + "^deck show (?:--side|-s) (?:--deck-name|-d) (?.+)$", + "^deck show (?:--deck-name|-d) (?.+)$", + "^menu show-current$", + "^menu exit$" + }; + + public void runDeckMenu() { + Matcher commandMatcher; + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + int whichCommand; + for (whichCommand = 0; whichCommand < deckMenuRegexes.length; whichCommand++) { + commandMatcher = findMatcher(command, deckMenuRegexes[whichCommand]); + if (commandMatcher.find()) { + executeDeckMenuCommands(commandMatcher, whichCommand); + break; + } else if (whichCommand == deckMenuRegexes.length - 1) + DeckMenuOutput.getInstance().showMessage("invalid command"); + } + + } + } + + private void executeDeckMenuCommands(Matcher commandMatcher, int whichCommand) { + DeckMenuController controller = DeckMenuController.getInstance(); + switch (whichCommand) { + case 0: + controller.createDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 1: + controller.deleteDeck(commandMatcher.group("name")); + break; + case 2: + controller.setActiveDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + String cardName = commandMatcher.group("cardName"), + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, false); + break; + case 9: + case 10: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, true); + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, false); + break; + case 17: + case 18: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, true); + break; + case 19: + controller.showAllDecks(loggedInPlayer); + break; + case 20: + case 21: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, false); + break; + case 22: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, true); + break; + case 23: + DeckMenuOutput.getInstance().showMessage("Deck Menu"); + break; + case 24: + MainMenuView mainMenuView = new MainMenuView(loggedInPlayer); + mainMenuView.mainMenuView(); + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } + + +} diff --git a/My part 7/main/java/view/DuelMenuView.java b/My part 7/main/java/view/DuelMenuView.java new file mode 100644 index 0000000..24661b5 --- /dev/null +++ b/My part 7/main/java/view/DuelMenuView.java @@ -0,0 +1,140 @@ +package view; + +import controller.Utils; +import controller.duelmenu.DuelMenuController; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.Phases; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +public class DuelMenuView { + private Player firstPlayer; + private Player secondPlayer; + private Phases phase; + + public DuelMenuView(Player firstPlayer, Player secondPlayer) { + this.firstPlayer = firstPlayer; + this.secondPlayer = secondPlayer; + } + + public static String findChooseOfPlayerInMiniGame(Player player) { + System.out.println(player.getUsername() + ", please choose between stone, paper and scissor:"); + return Utils.getScanner().nextLine().trim(); + } + + public static void showGraveyard(Board board) { + if (board.getGraveyard().size() != 0) { + for (int i = 1; i <= board.getGraveyard().size(); i++) { + printCard(i , board.getGraveyard().get(i)); + } + } else System.out.println("graveyard empty"); + while (true) { + String input = Utils.getScanner().nextLine(); + if (input.equals("back")) + break; + } + } + + public static void printCard(int number, Card card) { + System.out.println(number + ". " + card.getName() + ": " + card.getDescription()); + } + + private static void showBoard(Board playerBoard, Board opponentBoard) { + showCardsInHand(opponentBoard); +// showLeftCardDeck(opponentBoard);//?????????????????????? + showOpponentMagicsZone(opponentBoard); + showOpponentMonstersZone(opponentBoard); + showGraveyard(opponentBoard); + System.out.println("--------------------------"); + showCardsInHand(playerBoard); +// showLeftCardDeck(playerBoard);//???????? + showMagicsZone(playerBoard); + showMonstersZone(playerBoard); + showGraveyard(playerBoard); + } + + private static void showMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// monsters[5].print(); +// System.out.print(monsters[5].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[4].print() + " "); +// System.out.println(); + } + + private static void showMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[5].print(); + magicsZone[3].print(); + magicsZone[1].print(); + magicsZone[2].print(); + magicsZone[4].print(); + } + + private static void showOpponentMonstersZone(Board board) { + MonsterCard[] monsters = board.getMonstersZone(); +// System.out.print(monsters[4].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[5].print() + " "); + } + + private static void showOpponentMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[4].print(); + magicsZone[2].print(); + magicsZone[1].print(); + magicsZone[3].print(); + magicsZone[5].print(); + } + + private static void showCardsInHand(Board board) { + for (int i = 0; i < board.getCardsInHand().size(); i++) { + System.out.print("C "); + } + System.out.println(); + } + + private static void showSelectedCard(Board board) { + if (showCardCheck(board)) { + System.out.println(board.getSelectedCard().getName() + " " + board.getSelectedCard().getDescription()); + + } + } + + private static boolean showCardCheck(Board board) { + if (board.getSelectedCard() == null) { + System.out.println("you have not selected card"); + return false; + } + if (!board.isMyCardSelected() && !board.getSelectedCard().getCardFaceUp()) { + System.out.println("you cant see this card!"); + return false; + } + return true; + } + + public void duelMenuView() { + DuelMenuController duelMenuController = new DuelMenuController(); + + DuelMenuMessages resultOfInitialGame = null; + while (resultOfInitialGame == null || !resultOfInitialGame.equals(DuelMenuMessages.SHOW_TURN_PLAYER)) { + resultOfInitialGame = duelMenuController.initialGame(firstPlayer, secondPlayer); + System.out.print(resultOfInitialGame.getMessage()); + } + + while (true) { + String command = Utils.getScanner().nextLine().trim(); + DuelMenuMessages result = duelMenuController.findCommand(command); + + System.out.print(result.getMessage()); + } + } + +} diff --git a/My part 7/main/java/view/ImportExportMenuView.java b/My part 7/main/java/view/ImportExportMenuView.java new file mode 100644 index 0000000..ee91f94 --- /dev/null +++ b/My part 7/main/java/view/ImportExportMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; + +public class ImportExportMenuView { + public void ImportExportMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ImportExportMenuMessages result = ImportExportMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU)) break; + } + } +} diff --git a/My part 7/main/java/view/LoginMenuView.java b/My part 7/main/java/view/LoginMenuView.java new file mode 100644 index 0000000..f094c8b --- /dev/null +++ b/My part 7/main/java/view/LoginMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; + +public class LoginMenuView { + public static void loginMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + LoginMenuMessages result = LoginMenuController.findCommand(command); + + System.out.println(result.getMessage()); + + if (result.equals(LoginMenuMessages.USER_LOGGED_IN)) LoginMenuController.loginUser(command); + } + } +} diff --git a/My part 7/main/java/view/MainMenuView.java b/My part 7/main/java/view/MainMenuView.java new file mode 100644 index 0000000..7dde978 --- /dev/null +++ b/My part 7/main/java/view/MainMenuView.java @@ -0,0 +1,31 @@ +package view; + +import controller.Utils; +import controller.mainmenu.MainMenuController; +import controller.mainmenu.MainMenuMessages; +import model.Player; + +public class MainMenuView { + private Player loggedInPlayer; + + public MainMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void mainMenuView() { + MainMenuController mainMenuController = new MainMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + MainMenuMessages result = mainMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(MainMenuMessages.EXIT_MAIN_MENU) || + result.equals(MainMenuMessages.USER_LOGGED_OUT)) break; + } + } +} diff --git a/My part 7/main/java/view/ProfileMenuView.java b/My part 7/main/java/view/ProfileMenuView.java new file mode 100644 index 0000000..1e1b091 --- /dev/null +++ b/My part 7/main/java/view/ProfileMenuView.java @@ -0,0 +1,25 @@ +package view; + +import controller.profilemenu.ProfileMenuController; +import controller.profilemenu.ProfileMenuMessages; +import controller.Utils; +import model.Player; + +public class ProfileMenuView { + private final Player loggedInPlayer; + + public ProfileMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void profileMenuView() { + ProfileMenuController profileMenuController = new ProfileMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ProfileMenuMessages result = profileMenuController.findCommand(command); + + if (result.equals(ProfileMenuMessages.EXIT_MENU)) break; + else System.out.print(result.getMessage()); + } + } +} diff --git a/My part 7/main/java/view/ScoreboardMenuView.java b/My part 7/main/java/view/ScoreboardMenuView.java new file mode 100644 index 0000000..c1255b1 --- /dev/null +++ b/My part 7/main/java/view/ScoreboardMenuView.java @@ -0,0 +1,38 @@ +package view; + +import controller.Utils; +import controller.scoreboardmenu.Scoreboard; +import controller.scoreboardmenu.ScoreboardOutput; +import model.Player; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ScoreboardMenuView { + public static Scanner scanner = Utils.getScanner(); + + public void runScoreboard() { + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + if (command.equals("menu exit")) break; + switch (command) { + case "scoreboard show": + Scoreboard.getInstance().showScoreboard(); + break; + case "menu show-current": + ScoreboardOutput.getInstance().showMessage("Scoreboard Menu"); + break; + default: + ScoreboardOutput.getInstance().showMessage("invalid command"); + } + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } +} diff --git a/My part 7/main/java/view/ShopMenuView.java b/My part 7/main/java/view/ShopMenuView.java new file mode 100644 index 0000000..0ed2331 --- /dev/null +++ b/My part 7/main/java/view/ShopMenuView.java @@ -0,0 +1,41 @@ +package view; + +import controller.Utils; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import model.cards.Card; + +import java.util.TreeMap; + +public class ShopMenuView { + private Player loggedInPlayer; + + public ShopMenuView(Player loggedInPlayer) { + setLoggedInPlayer(loggedInPlayer); + } + + private static void showListOfCards() { + TreeMap listOfCards = Card.getListOfCards(); + for (String cardName : listOfCards.keySet()) { + System.out.println(cardName + ": " + listOfCards.get(cardName)); + } + } + + public void setLoggedInPlayer(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public void shopMenuView() { + ShopMenuController shopMenuController = new ShopMenuController(loggedInPlayer); + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ShopMenuMessages result = shopMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ShopMenuMessages.EXIT_SHOP_MENU)) break; + else if (result.equals(ShopMenuMessages.SHOW_ALL_CARDS)) showListOfCards(); + } + } +} diff --git a/My part 7/main/java/view/SpellCardView.java b/My part 7/main/java/view/SpellCardView.java new file mode 100644 index 0000000..69bf703 --- /dev/null +++ b/My part 7/main/java/view/SpellCardView.java @@ -0,0 +1,118 @@ +package view; + +import controller.Utils; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class SpellCardView extends DuelMenuView { + private SpellCardView(Player firstPlayer, Player secondPlayer) { + super(firstPlayer, secondPlayer); + } + + public static void showGraveyardsMonsterCards(Player turnPlayer, Player notTurnPlayer) { +// it used for Monster Reborn spell card + System.out.println("your graveyard monster cards:"); + showGraveyardMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent graveyard monster cards:"); + showGraveyardMonsterCards(notTurnPlayer.getBoard(), Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()) + 1); + } + + private static void showGraveyardMonsterCards(Board board, int startNumber) { +// it used for Monster Reborn spell card + int count = startNumber; + for (int i = 0; i < board.getGraveyard().size(); i++) { + if (Card.isMonsterCard(board.getGraveyard().get(i))) { + printCard(count, board.getGraveyard().get(i)); + ++count; + } + } + if (count == startNumber) System.out.println("There isn't any monster card."); + } + + public static String findCardNumber() { + System.out.println("choose a number:"); + return Utils.getScanner().nextLine(); + } + + public static void invalidNumber() { + System.out.println("invalid number"); + } + + public static void showFieldSpellCards(ArrayList magicCards) { + System.out.println("your field spell cards:"); + if (magicCards.size() == 0) System.out.println("There isn't any field spell card."); + else { + for (int i = 1; i <= magicCards.size(); i++) { + printCard(i, magicCards.get(i - 1)); + } + } + } + + public static void showCardsInHand(Player player) { + System.out.println("you have these cards in hand:"); + ArrayList cardsInHand = player.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) System.out.println("There isn't any card in your hand."); + else { + for (int i = 1; i <= cardsInHand.size(); i++) { + printCard(i, cardsInHand.get(i - 1)); + } + } + } + + public static void showMagicsZonesCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your spell and trap zone cards:"); + int endNumber = showMagicsZoneCards(turnPlayer, 1); + System.out.println("opponent spell and trap zone cards:"); + showMagicsZoneCards(notTurnPlayer, endNumber); + } + + private static int showMagicsZoneCards(Player player, int startNumber) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (player.getBoard().isMagicsZoneEmpty()) System.out.println("There isn't any spell and trap card."); + else { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) { + printCard(startNumber, magicsZone[i]); + ++startNumber; + } + } + } + + return startNumber; + } + + public static String findNumberOfCardsToChoose() { + System.out.println("How many cards do you want to choose to destroy?"); + return Utils.getScanner().nextLine(); + } + + public static void showFaceUpMonsterCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your face up monster cards:"); + int endNumber = showEachPlayerFaceUpMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent face up monster cards:"); + showEachPlayerFaceUpMonsterCards(notTurnPlayer.getBoard(), endNumber); + } + + private static int showEachPlayerFaceUpMonsterCards(Board board, int startNumber) { + if (board.getNumberOfFaceUpMonsterCards() == 0) { + System.out.println("There isn't any face up monster card."); + return startNumber; + } + + MonsterCard[] monstersZone = board.getMonstersZone(); + for (int i = 1; i < monstersZone.length; i++) { + MonsterCard monsterCard = monstersZone[i]; + if (monsterCard.getCardFaceUp()) { + printCard(startNumber, monsterCard); + ++startNumber; + } + } + + return startNumber; + } +} diff --git a/My part 7/main/main.iml b/My part 7/main/main.iml new file mode 100644 index 0000000..2185ddd --- /dev/null +++ b/My part 7/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/My part 7/main/resources/cards/Monster Upgraded.csv b/My part 7/main/resources/cards/Monster Upgraded.csv new file mode 100644 index 0000000..eae794e --- /dev/null +++ b/My part 7/main/resources/cards/Monster Upgraded.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARTH,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARTH,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,FIRE,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My part 7/main/resources/cards/Monster.csv b/My part 7/main/resources/cards/Monster.csv new file mode 100644 index 0000000..8c45a5c --- /dev/null +++ b/My part 7/main/resources/cards/Monster.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARHT,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARHT,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron ,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,Fire,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/My part 7/main/resources/cards/SpellTrap.csv b/My part 7/main/resources/cards/SpellTrap.csv new file mode 100644 index 0000000..e536e99 --- /dev/null +++ b/My part 7/main/resources/cards/SpellTrap.csv @@ -0,0 +1,38 @@ +Name,Type ,Icon (Property),Description,Status,Price +Trap Hole,Trap,Normal,When your opponent Normal or Flip Summons 1 monster with 1000 or more ATK: Target that monster; destroy that target.,Unlimited,2000 +Mirror Force,Trap,Normal,When an opponent's monster declares an attack: Destroy all your opponent's Attack Position monsters.,Unlimited,2000 +Magic Cylinder,Trap,Normal,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, and if you do, inflict damage to your opponent equal to its ATK.",Unlimited,2000 +Mind Crush,Trap,Normal,"Declare 1 card name; if that card is in your opponent's hand, they must discard all copies of it, otherwise you discard 1 random card.",Unlimited,2000 +Torrential Tribute,Trap,Normal,When a monster(s) is Summoned: Destroy all monsters on the field.,Unlimited,2000 +Time Seal,Trap,Normal,Skip the Draw Phase of your opponent's next turn.,Limited,2000 +Negate Attack,Trap,Counter,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, then end the Battle Phase.",Unlimited,3000 +Solemn Warning,Trap,Counter,"When a monster(s) would be Summoned, OR when a Spell/Trap Card, or monster effect, is activated that includes an effect that Special Summons a monster(s): Pay 2000 LP; negate the Summon or activation, and if you do, destroy it.",Unlimited,3000 +Magic Jamamer,Trap,Counter,"When a Spell Card is activated: Discard 1 card; negate the activation, and if you do, destroy it.",Unlimited,3000 +Call of The Haunted,Trap,Continuous,"Activate this card by targeting 1 monster in your GY; Special Summon that target in Attack Position. When this card leaves the field, destroy that monster. When that monster is destroyed, destroy this card.",Unlimited,3500 +Vanity's Emptiness,Trap,Continuous,Neither player can Special Summon monsters. If a card is sent from the Deck or the field to your Graveyard: Destroy this card.,Limited,3500 +Wall of Revealing Light,Trap,Continuous,Activate by paying any multiple of 1000 Life Points. Monsters your opponent controls cannot attack if their ATK is less than or equal to the amount you paid.,Limited,3500 +Monster Reborn,Spell,Normal,Target 1 monster in either GY; Special Summon it.,Limited,2500 +Terraforming,Spell,Normal,Add 1 Field Spell from your Deck to your hand.,Limited,2500 +Pot of Greed,Spell,Normal,Draw 2 cards.,Limited,2500 +Raigeki,Spell,Normal,Destroy all monsters your opponent controls.,Limited,2500 +Change of Heart,Spell,Normal,Target 1 monster your opponent controls; take control of it until the End Phase.,Limited,2500 +Swords of Revealing Light,Spell,Normal,"After this card's activation, it remains on the field, but destroy it during the End Phase of your opponent's 3rd turn. When this card is activated: If your opponent controls a face-down monster, flip all monsters they control face-up. While this card is face-up on the field, your opponent's monsters cannot declare an attack.",Unlimited,2500 +Harpie's Feather Duster,Spell,Normal,Destroy all Spells and Traps your opponent controls.,Limited,2500 +Dark Hole,Spell,Normal,Destroy all monsters on the field.,Unlimited,2500 +Supply Squad,Spell,Continuous,"Once per turn, if a monster(s) you control is destroyed by battle or card effect: Draw 1 card.",Unlimited,4000 +Spell Absorption,Spell,Continuous,"Each time a Spell Card is activated, gain 500 Life Points immediately after it resolves.",Unlimited,4000 +Messenger of peace,Spell,Continuous,"Monsters with 1500 or more ATK cannot declare an attack. Once per turn, during your Standby Phase, pay 100 LP or destroy this card.",Unlimited,4000 +Twin Twisters,Spell,Quick-play,"Discard 1 card, then target up to 2 Spells/Traps on the field; destroy them.",Unlimited,3500 +Mystical space typhoon,Spell,Quick-play,Target 1 Spell/Trap on the field; destroy that target.,Unlimited,3500 +Ring of defense,Spell,Quick-play,When a Trap effect that inflicts damage is activated: Make that effect damage 0.,Unlimited,3500 +Yami,Spell,Field,"All Fiend and Spellcaster monsters on the field gain 200 ATK/DEF, also all Fairy monsters on the field lose 200 ATK/DEF.",Unlimited,4300 +Forest,Spell,Field,"All Insect, Beast, Plant, and Beast-Warrior monsters on the field gain 200 ATK/DEF.",Unlimited,4300 +Closed Forest,Spell,Field,All Beast-Type monsters you control gain 100 ATK for each monster in your Graveyard. Field Spell Cards cannot be activated. Field Spell Cards cannot be activated during the turn this card is destroyed.,Unlimited,4300 +Umiiruka,Spell,Field,Increase the ATK of all WATER monsters by 500 points and decrease their DEF by 400 points.,Unlimited,4300 +Sword of dark destruction,Spell,Equip,A DARK monster equipped with this card increases its ATK by 400 points and decreases its DEF by 200 points.,Unlimited,4300 +Black Pendant,Spell,Equip,The equipped monster gains 500 ATK. When this card is sent from the field to the Graveyard: Inflict 500 damage to your opponent.,Unlimited,4300 +United We Stand,Spell,Equip,The equipped monster gains 800 ATK/DEF for each face-up monster you control.,Unlimited,4300 +Magnum Shield,Spell,Equip,"Equip only to a Warrior-Type monster. Apply this effect, depending on its battle position. +● Attack Position: It gains ATK equal to its original DEF. +● Defense Position: It gains DEF equal to its original ATK.",Unlimited,4300 +Advanced Ritual Art,Spell,Ritual,This card can be used to Ritual Summon any 1 Ritual Monster. You must also send Normal Monsters from your Deck to the Graveyard whose total Levels equal the Level of that Ritual Monster.,Unlimited,3000 \ No newline at end of file diff --git a/My part 7/main/resources/players/amir.json b/My part 7/main/resources/players/amir.json new file mode 100644 index 0000000..867f62c --- /dev/null +++ b/My part 7/main/resources/players/amir.json @@ -0,0 +1,17 @@ +{ + "boughtCards": [ + { + "name": "Battle OX" + }, + { + "name": "Suijin" + } + ], + "allMainDecks": [], + "sideDeck": {}, + "username": "amir", + "password": "12345", + "nickname": "amir", + "score": 0, + "money": 88400 +} \ No newline at end of file diff --git a/My part 7/main/resources/players/iman.json b/My part 7/main/resources/players/iman.json new file mode 100644 index 0000000..cc28fbd --- /dev/null +++ b/My part 7/main/resources/players/iman.json @@ -0,0 +1,10 @@ +{ + "boughtCards": [], + "allMainDecks": [], + "sideDeck": {}, + "username": "iman", + "password": "12345", + "nickname": "imannick", + "score": 0, + "money": 100000 +} \ No newline at end of file diff --git a/My part 7/main/resources/players/iman1.json b/My part 7/main/resources/players/iman1.json new file mode 100644 index 0000000..d207867 --- /dev/null +++ b/My part 7/main/resources/players/iman1.json @@ -0,0 +1,10 @@ +{ + "boughtCards": [], + "allMainDecks": [], + "sideDeck": {}, + "username": "iman1", + "password": "12345", + "nickname": "iman1nick", + "score": 0, + "money": 100000 +} \ No newline at end of file diff --git a/My part 7/main/resources/players/parsa.json b/My part 7/main/resources/players/parsa.json new file mode 100644 index 0000000..2825eb1 --- /dev/null +++ b/My part 7/main/resources/players/parsa.json @@ -0,0 +1,10 @@ +{ + "boughtCards": [], + "allMainDecks": [], + "sideDeck": {}, + "username": "parsa", + "password": "newPass", + "nickname": "P", + "score": 0, + "money": 100000 +} \ No newline at end of file diff --git a/My part 7/test/java/controller/ImportExportMenuControllerTest.java b/My part 7/test/java/controller/ImportExportMenuControllerTest.java new file mode 100644 index 0000000..aea2298 --- /dev/null +++ b/My part 7/test/java/controller/ImportExportMenuControllerTest.java @@ -0,0 +1,140 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Database; +import controller.MenuTest; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; +import model.cards.Card; +import org.apache.commons.io.FileUtils; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +class ImportExportMenuControllerTest extends MenuTest { + + @Test + void findCommandEnterAMenuMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu exit"); + Assertions.assertEquals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU, result); + + result = ImportExportMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ImportExportMenuMessages.SHOW_MENU, result); + + result = ImportExportMenuController.findCommand("menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandImportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("import cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_FILE, result); + + createCardJsonFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.AVAILABLE_CARD, result); + + Card.getAllCards().remove("Battle OX"); + removeNameValueFromJsonCardFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Battle OX"); + Card.getAllCards().remove("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Battle OX.json")); + + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + removeNameValueFromJsonCardFile("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Trap Hole.json")); + } + + void createCardJsonFile(String cardName) { + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(Card.getCardByName(cardName))); + fileWriter.close(); + } catch (IOException ignored) { + } + } + + void removeNameValueFromJsonCardFile(String cardName) { + JSONParser parser = new JSONParser(); + try { + Object object = parser.parse(new FileReader("src/database/cards/" + cardName + ".json")); + JSONObject jsonObject = (JSONObject) object; + jsonObject.remove("name"); + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(jsonObject)); + fileWriter.close(); + } catch (Exception ignored) { + } + } + + @Test + void findCommandExportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("export cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("export card A"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_CARD, result); + + result = ImportExportMenuController.findCommand("export card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My part 7/test/java/controller/LoginMenuControllerTest.java b/My part 7/test/java/controller/LoginMenuControllerTest.java new file mode 100644 index 0000000..b095e9e --- /dev/null +++ b/My part 7/test/java/controller/LoginMenuControllerTest.java @@ -0,0 +1,87 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; + +class LoginMenuControllerTest extends MenuTest { + @Test + void findCommandEnterAMenuMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_NAVIGATION, result); + + result = LoginMenuController.findCommand("menu enter MaIn MenU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + + result = LoginMenuController.findCommand("menu enter DUEL MENU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + } + + @Test + void findCommandCheckCreateUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user create --username John 1 --nickname Johny --password 12345"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user create --U John1 --nickname Johny1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --username John2 --P 12345 --nickname Johny2"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny3 --username John3 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny4 --password 12345 --U John4"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --username John5 --nickname Johny5"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --nickname Johny6 --username John6"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John6 --N Johny6"); + Assertions.assertEquals(LoginMenuMessages.USERNAME_EXISTS, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John7 --nickname Johny6"); + Assertions.assertEquals(LoginMenuMessages.NICKNAME_EXISTS, result); + } + + @Test + void findCommandCheckLoginUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user login --username John 12 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user login --username John12 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + + result = LoginMenuController.findCommand("user login --username John2 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + result = LoginMenuController.findCommand("user login --username John1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + + result = LoginMenuController.findCommand("user login --password 12345 --username John1"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + } + + @Test + void loginUser() { + Utils.resetScanner("user logout\n"); + ByteArrayOutputStream outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --password 12345 --username John1"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + + Utils.resetScanner("user logout\n"); + outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --username John1 --password 12345"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + } +} \ No newline at end of file diff --git a/My part 7/test/java/controller/MenuTest.java b/My part 7/test/java/controller/MenuTest.java new file mode 100644 index 0000000..5df1b3c --- /dev/null +++ b/My part 7/test/java/controller/MenuTest.java @@ -0,0 +1,20 @@ +package controller; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +import java.io.File; +import java.io.IOException; + +public class MenuTest { + @BeforeAll + static void prepareGame() { + Database.prepareGame(); + } + + @AfterAll + static void deletePlayersDirectory() throws IOException { + FileUtils.deleteDirectory(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/main/resources/players")); + } +} \ No newline at end of file diff --git a/My part 7/test/java/controller/ProfileMenuTest.java b/My part 7/test/java/controller/ProfileMenuTest.java new file mode 100644 index 0000000..ddad54d --- /dev/null +++ b/My part 7/test/java/controller/ProfileMenuTest.java @@ -0,0 +1,57 @@ +package controller; + +import controller.profilemenu.ProfileMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import controller.profilemenu.ProfileMenuController; + +public class ProfileMenuTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + String userName = "parsa"; + String password = "123"; + String nickname = "P"; + new Player(userName, password, nickname); + } + + @Test + public void changeName() { + Player player = Player.getPlayerByUsername("parsa"); + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --nickname newname"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + Assertions.assertEquals("newname", player.getNickname()); + result = profileMenuController.findCommand("profile change --nickname P"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + } + + @Test + public void changePassword() { + Player player = Player.getPlayerByUsername("parsa"); + + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --password --current 12 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.WRONG_CURRENT_PASSWORD, result); + Assertions.assertEquals("123", player.getPassword()); + + result = profileMenuController.findCommand("profile change --password --current 123 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_PASSWORD_DONE, result); + Assertions.assertEquals("newPass", player.getPassword()); + } + + @Test + public void allError() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.INVALID_COMMAND, profileMenuController.findCommand("profile")); + Assertions.assertEquals(ProfileMenuMessages.CANT_NAVIGATE_MENU, profileMenuController.findCommand("loginmenu enter")); + } + + @Test + public void checkExit() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.EXIT_MENU , profileMenuController.findCommand("menu exit")); + } +} diff --git a/My part 7/test/java/controller/ShopMenuControllerTest.java b/My part 7/test/java/controller/ShopMenuControllerTest.java new file mode 100644 index 0000000..58d998d --- /dev/null +++ b/My part 7/test/java/controller/ShopMenuControllerTest.java @@ -0,0 +1,77 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ShopMenuControllerTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + LoginMenuController.findCommand("user create --username John --P 12345 --nickname Johny"); + } + + @Test + void findCommandEnterAMenuMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu exit"); + Assertions.assertEquals(ShopMenuMessages.EXIT_SHOP_MENU, result); + + result = shopMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ShopMenuMessages.SHOW_MENU, result); + + result = shopMenuController.findCommand("menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandBuyACardMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("shop buy:)"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("shop buy A"); + Assertions.assertEquals(ShopMenuMessages.UNAVAILABLE_CARD, result); + + result = shopMenuController.findCommand("shop buy Battle OX"); + Assertions.assertEquals(ShopMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/My part 7/test/test.iml b/My part 7/test/test.iml new file mode 100644 index 0000000..c2315e9 --- /dev/null +++ b/My part 7/test/test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/My Part.iml b/src/My Part.iml new file mode 100644 index 0000000..1de981c --- /dev/null +++ b/src/My Part.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/deckmenu/DeckMenuView.java b/src/deckmenu/DeckMenuView.java new file mode 100644 index 0000000..66c3c8b --- /dev/null +++ b/src/deckmenu/DeckMenuView.java @@ -0,0 +1,140 @@ +package deckmenu; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import model.*; + +public class DeckMenuView { + public static Scanner scanner = new Scanner(System.in); + + private static DeckMenuView instance; + + private DeckMenuView() { + } + + public static DeckMenuView getInstance() { + if (instance == null) + instance = new DeckMenuView(); + return instance; + } + + private final String[] deckMenuRegexes = { + "^deck create (?\\w+)$", + "^deck delete (?\\w+)$", + "^deck set-activate (?\\w+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck add-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck show (?:--all|-a)$", + "^deck show (?:--deck-name|-d) (?.+) (?:--side|-s)$", + "^deck show (?:--side|-s) (?:--deck-name|-d) (?.+)$", + "^deck show (?:--deck-name|-d) (?.+)$", + "^menu show-current$", + "^menu exit$" + }; + + public void runDeckMenu() { + Matcher commandMatcher; + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + int whichCommand; + for (whichCommand = 0; whichCommand < deckMenuRegexes.length; whichCommand++) { + commandMatcher = findMatcher(command, deckMenuRegexes[whichCommand]); + if (commandMatcher.find()) { + executeDeckMenuCommands(commandMatcher, whichCommand); + break; + } else if (whichCommand == deckMenuRegexes.length - 1) + DeckMenuOutput.getInstance().showMessage("invalid command"); + } + + } + } + + private void executeDeckMenuCommands(Matcher commandMatcher, int whichCommand) { + DeckMenuController controller = DeckMenuController.getInstance(); + Player loggedInPlayer = MainMenu.getInstance().getPlayerLoggedIn(); + switch (whichCommand) { + case 0: + controller.createDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 1: + controller.deleteDeck(commandMatcher.group("name")); + break; + case 2: + controller.setActiveDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + String cardName = commandMatcher.group("cardName"), + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, false); + break; + case 9: + case 10: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, true); + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, false); + break; + case 17: + case 18: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, true); + break; + case 19: + controller.showAllDecks(loggedInPlayer); + break; + case 20: + case 21: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, false); + break; + case 22: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, true); + break; + case 23: + DeckMenuOutput.getInstance().showMessage("Deck Menu"); + break; + case 24: + MainMenuView.mainMenuView; +// go to main menu; + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } + + +} diff --git a/src/main/java/controller/AIClass.java b/src/main/java/controller/AIClass.java index 54d7935..5e41136 100644 --- a/src/main/java/controller/AIClass.java +++ b/src/main/java/controller/AIClass.java @@ -1,60 +1,60 @@ package controller; import model.Board; -import model.MonsterCard; +import model.cards.monstercard.MonsterCard; import model.Player; public class AIClass { - public static String getOrder(Board machineBoard, Board playerBoard, Player AIPlayer, Player humanPlayer, Enum phaseOfGame) { - if () {//TODO PUT A CONDITION THAT PHASE IS BATTLE PHASE - int numberOfMonsterToAttack = -1; - selectMachineMonsterCardToAttack(machineBoard, AIPlayer); - if (canAttackToFaceUpMonster(machineBoard, playerBoard) != -1) { - return "attack" + canAttackToFaceUpMonster(machineBoard, playerBoard); - } else if (canAttackToFaceDownCard(playerBoard) != -1) { - return "attack" + canAttackToFaceDownCard(playerBoard); - } - } - } - - private static int canAttackToFaceDownCard(Board playerBoard) { - MonsterCard[] monsterArray = playerBoard.getMonstersZone(); - for (int i = 1; i <= 5; i++) { - if (monsterArray[i].print().equals("DH")) - return i; - } - return -1; - } - - private static void selectMachineMonsterCardToAttack(Board board, Player player) { - MonsterCard[] monsterArray = board.getMonstersZone(); - MonsterCard monsterCard = monsterArray[1]; - for (int i = 2; i <= 5; i++) { - if (monsterCard.getAttackLevel() < monsterArray[i].getAttackLevel()) - monsterCard = monsterArray[i]; - board.setMyCardSelected(true); - board.setSelectedCard(monsterCard); - } - } - - private static int canAttackToFaceUpMonster(Board machineBoard, Board playerBoard) { - MonsterCard[] monsterArray = playerBoard.getMonstersZone(); - MonsterCard monsterToAttack = (MonsterCard) machineBoard.getSelectedCard(); - for (int i = 1; i <= 5; i++) { - if (monsterArray[i].print().equals("OO") && monsterArray[i].getAttackLevel() < monsterToAttack.getAttackLevel()) - return i; - } - - for (int i = 1; i <= 5; i++) { - if (monsterArray[i].print().equals("DO") && monsterArray[i].getDefenseLevel() < monsterToAttack.getAttackLevel()) { - } - return i; - } - return -1; - } - - public static String getRandomMove() { - - } +// public static String getOrder(Board machineBoard, Board playerBoard, Player AIPlayer, Player humanPlayer, Enum phaseOfGame) { +// if () {//TODO PUT A CONDITION THAT PHASE IS BATTLE PHASE +// int numberOfMonsterToAttack = -1; +// selectMachineMonsterCardToAttack(machineBoard, AIPlayer); +// if (canAttackToFaceUpMonster(machineBoard, playerBoard) != -1) { +// return "attack" + canAttackToFaceUpMonster(machineBoard, playerBoard); +// } else if (canAttackToFaceDownCard(playerBoard) != -1) { +// return "attack" + canAttackToFaceDownCard(playerBoard); +// } +// } +// } +// +// private static int canAttackToFaceDownCard(Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DH")) +// return i; +// } +// return -1; +// } +// +// private static void selectMachineMonsterCardToAttack(Board board, Player player) { +// MonsterCard[] monsterArray = board.getMonstersZone(); +// MonsterCard monsterCard = monsterArray[1]; +// for (int i = 2; i <= 5; i++) { +// if (monsterCard.getAttackLevel() < monsterArray[i].getAttackLevel()) +// monsterCard = monsterArray[i]; +// board.setMyCardSelected(true); +// board.setSelectedCard(monsterCard); +// } +// } +// +// private static int canAttackToFaceUpMonster(Board machineBoard, Board playerBoard) { +// MonsterCard[] monsterArray = playerBoard.getMonstersZone(); +// MonsterCard monsterToAttack = (MonsterCard) machineBoard.getSelectedCard(); +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("OO") && monsterArray[i].getAttackLevel() < monsterToAttack.getAttackLevel()) +// return i; +// } +// +// for (int i = 1; i <= 5; i++) { +// if (monsterArray[i].print().equals("DO") && monsterArray[i].getDefenseLevel() < monsterToAttack.getAttackLevel()) { +// } +// return i; +// } +// return -1; +// } +// +// public static String getRandomMove() { +// +// } } diff --git a/src/main/java/controller/Database.java b/src/main/java/controller/Database.java new file mode 100644 index 0000000..e5d87af --- /dev/null +++ b/src/main/java/controller/Database.java @@ -0,0 +1,120 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.magiccard.MagicCardStatuses; +import model.cards.monstercard.MonsterCard; +import model.cards.monstercard.MonsterCardAttributes; + +import java.io.*; +import java.util.ArrayList; + +public class Database { + public static void prepareGame() { + new File("src/main/resources/players").mkdirs(); + addCardsToGame(); + readPlayersDataFromDatabase(); + } + + private static void addCardsToGame() { + try { + FileReader monsterCardFileReader = new FileReader("src/main/resources/cards/Monster Upgraded.csv"); + CSVReader monsterCardCSVReader = new CSVReaderBuilder(monsterCardFileReader).withSkipLines(1).build(); + + String[] monsterCardData; + while ((monsterCardData = monsterCardCSVReader.readNext()) != null) { + createNewMonsterCard(monsterCardData); + } + + + FileReader magicCardFileReader = new FileReader("src/main/resources/cards/SpellTrap.csv"); + CSVReader magicCardCSVReader = new CSVReaderBuilder(magicCardFileReader).withSkipLines(1).build(); + + String[] magicCardData; + while ((magicCardData = magicCardCSVReader.readNext()) != null) { + createNewMagicCard(magicCardData); + } + + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + } + + private static void createNewMonsterCard(String[] data) { + String name = data[0]; + short level = Short.parseShort(data[1]); + MonsterCardAttributes monsterCardAttributes = MonsterCardAttributes.valueOf(data[2]); + String monsterType = data[3]; + CardTypes cardType = CardTypes.valueOf(data[4].toUpperCase()); + int attackPoints = Integer.parseInt(data[5]); + int defensePoints = Integer.parseInt(data[6]); + String description = data[7]; + int price = Integer.parseInt(data[8]); + + new MonsterCard(name, level, monsterCardAttributes, monsterType, cardType, attackPoints, defensePoints, description, price); + } + + private static void createNewMagicCard(String[] data) { + String name = data[0]; + CardTypes cardType = CardTypes.valueOf(data[1].toUpperCase()); + String icon = data[2]; + String description = data[3]; + MagicCardStatuses status = MagicCardStatuses.valueOf(data[4].toUpperCase()); + int price = Integer.parseInt(data[5]); + + new MagicCard(name, cardType, icon, description, status,price); + } + + public static void readPlayersDataFromDatabase() { +// TODO: complete it by Iman's code + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + File file = new File("src/main/resources/players"); + FilenameFilter filenameFilter = (direction, name) -> name.endsWith(".json"); + String[] filesName = file.list(filenameFilter); + + if (filesName == null) return; + for (String fileName : filesName) { + try { + FileReader fileReader = new FileReader("src/main/resources/players/" + fileName); + Player player = gson.fromJson(fileReader, Player.class); + fileReader.close(); + Player.addPlayerToAllPlayers(player); + addCardsToPlayer(player); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + private static void addCardsToPlayer(Player player) { + ArrayList boughtCards = player.getBoughtCards(); + for (int i = 0; i < boughtCards.size(); i++) { + Card fakeCard = boughtCards.get(0); + Card originalCard = Card.getCardByName(fakeCard.getName()); + boughtCards.remove(fakeCard); + player.addCardToBoughtCards(originalCard); + } + } + + public static void updatePlayerInformationInDatabase(Player player) { + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); + + try { + FileWriter fileWriter = new FileWriter("src/main/resources/players/" + player.getUsername() + ".json"); + fileWriter.write(gson.toJson(player)); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } + } +} diff --git a/src/main/java/controller/Main.java b/src/main/java/controller/Main.java index bdfd14d..274e490 100644 --- a/src/main/java/controller/Main.java +++ b/src/main/java/controller/Main.java @@ -4,6 +4,7 @@ public class Main { public static void main(String[] args) { + Database.prepareGame(); LoginMenuView.loginMenuView(); } -} +} \ No newline at end of file diff --git a/src/main/java/controller/SpellCardController.java b/src/main/java/controller/SpellCardController.java new file mode 100644 index 0000000..6080ef6 --- /dev/null +++ b/src/main/java/controller/SpellCardController.java @@ -0,0 +1,537 @@ +package controller; + +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.SpellCardView; + +import java.util.ArrayList; +import java.util.Collections; + +public class SpellCardController { +// this method doesn't handle field spell cards + public static boolean doSpellCardEffect(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { +// handle every kind of spell cards except field and equip + String cardName = spellCard.getName(); + switch (cardName) { + case "Monster Reborn": + return doMonsterRebornEffect(turnPlayer, notTurnPlayer); + case "Terraforming": + return doTerraformingEffect(turnPlayer); + case "Pot of Greed": + return doPotOfGreedEffect(turnPlayer); + case "Raigeki": + return doRaigekiEffect(notTurnPlayer); + case "Change of Heart": + return doChangeOfHeartEffect(); + case "Harpie's Feather Duster": + return doHarpieFeatherDusterEffect(notTurnPlayer); + case "Swords of Revealing Light": + return doSwordsOfRevealingLight(); + case "Dark Hole": + return doDarkHoleEffect(turnPlayer, notTurnPlayer); + case "Supply Squad": +// TODO: i should know how turn changes, then handle it --> it shouldn't handle here + break; + case "Spell Absorption": + return true; + case "Messenger of peace": +// TODO: handle it base on Parsa code + break; + case "Twin Twisters": + return doTwinTwistersEffect(turnPlayer, notTurnPlayer); + case "Mystical space typhoon": + return doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + case "Ring of defense": +// TODO: handle it base trap and monster code + break; +// it's the only ritual spell card + case "Advanced Ritual Art": + return doAdvancedRitualArtEffect(); + } + +// handle equip spell cards + return chooseMonsterToEquip(turnPlayer, notTurnPlayer, spellCard); +// any other kind of card doesn't enter to this method + } + + +// handle every kind of spell cards except field and equip + private static boolean doMonsterRebornEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showGraveyardsMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(turnPlayer.getBoard().getGraveyard()); + int notTurnPlayerGraveyardMonsterCardsSize = Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()); + if (turnPlayerGraveyardMonsterCardsSize + notTurnPlayerGraveyardMonsterCardsSize == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findMonsterRebornChosenCard(turnPlayer, notTurnPlayer, cardNumber); + if (chosenCard != null) break; + SpellCardView.invalidNumber(); + } + +// TODO: how to handle special summon + return true; + } + + private static int getCardNumber() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findCardNumber()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static MonsterCard findMonsterRebornChosenCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + ArrayList turnPlayerGraveyard = turnPlayer.getBoard().getGraveyard(); + ArrayList notTurnPlayerGraveyard = notTurnPlayer.getBoard().getGraveyard(); + + for (Card card : turnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + for (Card card : notTurnPlayerGraveyard) { + if (Card.isMonsterCard(card)) { + if (count == cardNumber) return (MonsterCard) card; + ++count; + } + } + + return null; + } + + private static boolean doTerraformingEffect(Player player) { +// TODO: do Iman handle with main cards? + ArrayList cards = player.getBoard().getDeck().getMainCards(); + ArrayList fieldSpellCards = findFieldSpellCards(cards); + + SpellCardView.showFieldSpellCards(fieldSpellCards); + if (fieldSpellCards.size() == 0) return false; + + MagicCard chosenFieldSpellCard; + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= fieldSpellCards.size()) { + chosenFieldSpellCard = fieldSpellCards.get(cardNumber - 1); + player.getBoard().getCardsInHand().add(chosenFieldSpellCard); + cards.remove(chosenFieldSpellCard); + break; + } + SpellCardView.invalidNumber(); + } + + Collections.shuffle(cards); + return true; + } + + private static ArrayList findFieldSpellCards(ArrayList cards) { +// create array list of field spell cards + ArrayList fieldSpellCards = new ArrayList<>(); + for (Card card : cards) { + if (!Card.isMonsterCard(card)) { + MagicCard magicCard = (MagicCard) card; + if (magicCard.getIcon().equals("Field")) fieldSpellCards.add(magicCard); + } + } + return fieldSpellCards; + } + + private static boolean doPotOfGreedEffect(Player player) { + Board board = player.getBoard(); + ArrayList deckCards = board.getDeck().getMainCards(); + if (deckCards.size() < 2) return false; + + Card firstCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + Card secondCard = deckCards.get(deckCards.size() - 1); + deckCards.remove(deckCards.size() - 1); + board.getCardsInHand().add(firstCard); + board.getCardsInHand().add(secondCard); + + return true; + } + + private static boolean doRaigekiEffect(Player player) { + MonsterCard[] monstersZone = player.getBoard().getMonstersZone(); + if (isCardArrayNull(monstersZone)) return false; + emptyAZone(player, monstersZone); + return true; + } + + private static boolean isCardArrayNull(Card[] cards) { + for (Card card : cards) { + if (card != null) return false; + } + return true; + } + + private static void emptyAZone(Player player, Card[] cards) { + for (int i = 0; i < cards.length; ++i) { + if (cards[i] != null) { + player.getBoard().getGraveyard().add(cards[i]); + cards[i] = null; + } + } + } + + private static boolean doChangeOfHeartEffect() { +// TODO: handle it! + return true; + } + + private static boolean doHarpieFeatherDusterEffect(Player player) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (isCardArrayNull(magicsZone)) return false; + emptyAZone(player, magicsZone); + return true; + } + + private static boolean doSwordsOfRevealingLight() { +// TODO: handle it! + return true; + } + + private static boolean doDarkHoleEffect(Player turnPlayer, Player notTurnPlayer) { + return doRaigekiEffect(turnPlayer) || doRaigekiEffect(notTurnPlayer); + } + + public static void doSpellAbsorptionEffect(Player player) { + if (player.getBoard().isCardFaceUp("Spell Absorption")) player.increaseLifePoint(500); + } + + private static boolean doTwinTwistersEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showCardsInHand(turnPlayer); + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (1 <= cardNumber && cardNumber <= cardsInHand.size()) { + turnPlayer.getBoard().getGraveyard().add(cardsInHand.get(cardNumber - 1)); + cardsInHand.remove(cardNumber - 1); + break; + } + SpellCardView.invalidNumber(); + } + + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return true; + + int numberOfChosenCards; + while (true) { + numberOfChosenCards = getNumberOfCardsToChoose(); + if (0 <= numberOfChosenCards && numberOfChosenCards <= 2 && + numberOfChosenCards <= turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards) { + break; + } + SpellCardView.invalidNumber(); + } + + for (int i = 0; i < numberOfChosenCards; i++) { + doMysticalSpaceTyphoonEffect(turnPlayer, notTurnPlayer); + } + + return true; + } + + private static int getNumberOfCardsToChoose() { + while (true) { + try { + return Integer.parseInt(SpellCardView.findNumberOfCardsToChoose()); + } catch (Exception exception) { + SpellCardView.invalidNumber(); + } + } + } + + private static boolean destroyAMagicCardFromMagicZone(Player player, int cardNumber, int startNumber) { + MagicCard[] playerMagicsZone = player.getBoard().getMagicsZone(); + for (int i = 1; i < playerMagicsZone.length; i++) { + if (playerMagicsZone[i] != null) { + if (startNumber == cardNumber) { + player.getBoard().getGraveyard().add(playerMagicsZone[i]); + playerMagicsZone[i] = null; + return true; + } + ++startNumber; + } + } + + return false; + } + + private static boolean doMysticalSpaceTyphoonEffect(Player turnPlayer, Player notTurnPlayer) { + SpellCardView.showMagicsZonesCards(turnPlayer, notTurnPlayer); + int turnPlayerNumberOfMagicCards = turnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + int notTurnPlayerNumberOfMagicCards = notTurnPlayer.getBoard().getNumberOfFullPartsOfMagicsZone(); + if (turnPlayerNumberOfMagicCards + notTurnPlayerNumberOfMagicCards == 0) return false; + + while (true) { + int cardNumber = getCardNumber(); + if (destroyAMagicCardFromMagicZone(turnPlayer, cardNumber, 1) || + destroyAMagicCardFromMagicZone(notTurnPlayer, cardNumber, turnPlayerNumberOfMagicCards + 1)) + break; + SpellCardView.invalidNumber(); + } + + return true; + } + +// it's the only ritual spell card + private static boolean doAdvancedRitualArtEffect() { +// TODO: handle it based on Iman's code + return false; + } + + +// handle field spell cards + public static void handleFieldSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + MagicCard firstPlayerFieldZoneCard = firstPlayer.getBoard().getFieldZone(); + MagicCard secondPlayerFieldZoneCard = secondPlayer.getBoard().getFieldZone(); + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, firstPlayerFieldZoneCard, doEffect); + handleEachFieldSpellCardEffect(monsterCardOwner, monsterCard, secondPlayerFieldZoneCard, doEffect); + } + + private static Player findMonsterCardOwner(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard) { + if (firstPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return firstPlayer; + if (secondPlayer.getBoard().isCardAvailableInMonstersZone(monsterCard)) return secondPlayer; + +// this will never happen, just for assurance + return null; + } + + private static void handleEachFieldSpellCardEffect(Player monsterCardOwner, MonsterCard monsterCard, MagicCard fieldZoneCard, + boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + if (fieldZoneCard == null || !fieldZoneCard.getCardFaceUp()) return; + + switch (fieldZoneCard.getName()) { + case "Yami": + handleYamiEffect(monsterCard, doEffect); + break; + case "Forest": + handleForestEffect(monsterCard, doEffect); + break; + case "Closed Forest": + handleClosedForestEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Umiiruka": + handleUmiirukaEffect(monsterCard, doEffect); + break; + } + } + + private static void handleYamiEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } else if (monsterCard.getMonsterType().equals("Fairy")) { + if (doEffect) { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } + } + } + + private static void handleForestEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Insect") || monsterCardType.equals("Beast") || + monsterCardType.equals("Beast-Warrior")) { + if (doEffect) { + monsterCard.increaseAttackPoints(200); + monsterCard.increaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(200); + monsterCard.decreaseDefencePoints(200); + } + } + } + + private static void handleClosedForestEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int graveyardMonsterCardsSize = Card.findNumberOfMonsterCards(monsterCardOwner.getBoard().getGraveyard()); + MonsterCard[] monstersZone = monsterCardOwner.getBoard().getMonstersZone(); + + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null && monstersZone[i].getMonsterType().equals("Beast-Type")) { + if (doEffect) monsterCard.increaseAttackPoints(100 * graveyardMonsterCardsSize); + else monsterCard.decreaseAttackPoints(100 * graveyardMonsterCardsSize); + } + } + + } + + private static void handleUmiirukaEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (monsterCard.getMonsterType().equals("Aqua")) { + if (doEffect) { + monsterCard.increaseAttackPoints(500); + monsterCard.decreaseDefencePoints(400); + } else { + monsterCard.decreaseAttackPoints(500); + monsterCard.increaseDefencePoints(400); + } + } + } + + +// handle equip spell cards + private static boolean chooseMonsterToEquip(Player turnPlayer, Player notTurnPlayer, MagicCard spellCard) { + SpellCardView.showFaceUpMonsterCards(turnPlayer, notTurnPlayer); + + int turnPlayerFaceUpMonsterCardsNumber = turnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + int notTurnPlayerFaceUpMonsterCardsNumber = notTurnPlayer.getBoard().getNumberOfFaceUpMonsterCards(); + Board turnPlayerBoard = turnPlayer.getBoard(); + if (turnPlayerFaceUpMonsterCardsNumber + notTurnPlayerFaceUpMonsterCardsNumber == 0 || + !turnPlayerBoard.isMagicsZoneFull()) return false; + if (spellCard.getName().equals("Magnum Shield") && turnPlayerBoard.getNumberOfWarriorMonsterCards() == 0) return false; + + MonsterCard chosenCard; + while (true) { + int cardNumber = getCardNumber(); + chosenCard = findFaceUpMonsterCard(turnPlayer, notTurnPlayer, cardNumber); +// second and third condition assure me that Magnum Shield just equipped Warrior Monster Cards + if (chosenCard != null && + (!spellCard.getName().equals("Magnum Shield") || chosenCard.getMonsterType().equals("Warrior"))) break; + SpellCardView.invalidNumber(); + } + + chosenCard.addToEquippedBy(spellCard); + turnPlayerBoard.addMagicCardToMagicsZone(spellCard); + return true; + } + + private static MonsterCard findFaceUpMonsterCard(Player turnPlayer, Player notTurnPlayer, int cardNumber) { + int count = 1; + MonsterCard[] turnPlayerFaceUpMonsterCards = turnPlayer.getBoard().getMonstersZone(); + MonsterCard[] notTurnPlayerFaceUpMonsterCards = notTurnPlayer.getBoard().getMonstersZone(); + + for (int i = 1; i < turnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = turnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + for (int i = 1; i < notTurnPlayerFaceUpMonsterCards.length; i++) { + MonsterCard monsterCard = notTurnPlayerFaceUpMonsterCards[i]; + if (monsterCard.getCardFaceUp()) { + if (count == cardNumber) return monsterCard; + ++count; + } + } + + return null; + } + + public static void handleEquipSpellCardsEffect(Player firstPlayer, Player secondPlayer, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + Player monsterCardOwner = findMonsterCardOwner(firstPlayer, secondPlayer, monsterCard); + for (MagicCard spellCard : monsterCard.getEquippedBy()) { + switch (spellCard.getName()) { + case "Sword of dark destruction": + handleSwordOfDarkDestructionEffect(monsterCard, doEffect); + break; + case "Black Pendant": + handleBlackPendantEffect(monsterCard, doEffect); + break; + case "United We Stand": + handleUnitedWeStandEffect(monsterCardOwner, monsterCard, doEffect); + break; + case "Magnum Shield": + handleMagnumShieldEffect(monsterCard, doEffect); + break; + } + } + } + + private static void handleSwordOfDarkDestructionEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + String monsterCardType = monsterCard.getMonsterType(); + if (monsterCardType.equals("Fiend") || monsterCardType.equals("Spellcaster")) { + if (doEffect) { + monsterCard.increaseAttackPoints(400); + monsterCard.decreaseDefencePoints(200); + } else { + monsterCard.decreaseAttackPoints(400); + monsterCard.increaseDefencePoints(200); + } + } + + } + + private static void handleBlackPendantEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + if (doEffect) monsterCard.increaseAttackPoints(500); + else monsterCard.decreaseAttackPoints(500); + } + + private static void handleUnitedWeStandEffect(Player monsterCardOwner, MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + + int numberOfFaceUpMonsterCards = monsterCardOwner.getBoard().getNumberOfFaceUpMonsterCards(); + if (doEffect) { + monsterCard.increaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.increaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } else { + monsterCard.decreaseAttackPoints(800 * numberOfFaceUpMonsterCards); + monsterCard.decreaseDefencePoints(800 * numberOfFaceUpMonsterCards); + } + } + + private static void handleMagnumShieldEffect(MonsterCard monsterCard, boolean doEffect) { +// doEffect is true --> do the card effect +// doEffect is false --> undo the card effect + +// I know that Magnum Shield just equipped Warrior monster cards + if (monsterCard.isDefensePosition()) { + if (doEffect) monsterCard.increaseDefencePoints(monsterCard.getAttackPoints()); + else monsterCard.decreaseDefencePoints(monsterCard.getAttackPoints()); + } else { + if (doEffect) monsterCard.increaseAttackPoints(monsterCard.getDefensePoints()); + else monsterCard.decreaseAttackPoints(monsterCard.getDefensePoints()); + } + } +} diff --git a/src/main/java/controller/Utils.java b/src/main/java/controller/Utils.java index 1c4aef1..05df0d8 100644 --- a/src/main/java/controller/Utils.java +++ b/src/main/java/controller/Utils.java @@ -1,5 +1,8 @@ package controller; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -15,6 +18,16 @@ public static Scanner getScanner() { return scanner; } + public static void resetScanner(String input) { + scanner = new Scanner(new ByteArrayInputStream(input.getBytes())); + } + + public static ByteArrayOutputStream setByteArrayOutputStream() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + return outContent; + } + public static Matcher getMatcher(String regex, String command) { return Pattern.compile(regex).matcher(command); } diff --git a/src/main/java/controller/deckmenu/DeckMenuController.java b/src/main/java/controller/deckmenu/DeckMenuController.java new file mode 100644 index 0000000..184bf48 --- /dev/null +++ b/src/main/java/controller/deckmenu/DeckMenuController.java @@ -0,0 +1,100 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +import java.util.Objects; + +public class DeckMenuController { + + private static DeckMenuController instance = null; + + private DeckMenuController() { + } + + public static DeckMenuController getInstance() { + return Objects.requireNonNullElseGet(instance, () -> (instance = new DeckMenuController())); + } + + public void createDeck(String name, Player owner) { + if (!DeckMenuTools.isDeckNameUnique(name)) + return; + + new Deck(name, owner , true , true); + DeckMenuOutput.getInstance().showMessage("deck created successfully!"); + } + + public void deleteDeck(String name) { + if (!DeckMenuTools.doesDeckExist(name)) {return;} + // if (DeckMenuTools.isDeckNameUnique(name)) return; + + DeckMenuDatabase.removeDeck(name); + DeckMenuOutput.getInstance().showMessage("deck deleted successfully!"); + + } + + + public void setActiveDeck(String name, Player player) { + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesDeckExist(name) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(name), player); + if (isPermitted) { + player.activateADeck(deck); + + DeckMenuOutput.getInstance().showMessage("deck activated successfully!"); + } + + } + + public void addCardToDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card = null; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player) + && ((isMain) ? DeckMenuTools.doesDeckHaveSpace(deck) : DeckMenuTools.doesSideDeckHaveSpace(deck)) + && DeckMenuTools.isNumberOfCardsInDeckLessThanFour(deck, card = DeckMenuDatabase.getInstance().getCardByName(cardName)) + && DeckMenuTools.doesPlayerHaveEnoughCards(card , player); + if (isPermitted) { + player.removeCardFromBoughtCards(card); + deck.addCard(card, isMain); + DeckMenuOutput.getInstance().showMessage("card added to deck successfully!"); + } + } + + public void removeCardFromDeck(String cardName, String deckName, Player player, boolean isMain) { + Card card; + Deck deck = null; + boolean isPermitted = DeckMenuTools.doesCardExist(cardName) + && DeckMenuTools.doesDeckExist(deckName) + && DeckMenuTools.doesDeckBelongToPlayer(deck = DeckMenuDatabase.getInstance().getDeckByName(deckName), player); + if (isPermitted) { + card = DeckMenuDatabase.getInstance().getCardByName(cardName); + player.addCardToBoughtCards(card); + deck.moveCardTo(player.getAllPlayerCard(),card, isMain , true); + DeckMenuOutput.getInstance().showMessage("card removed from deck successfully!"); + } + } + + public void showAllDecks(Player player) { + for (Deck deck : player.getAllDeck()) + DeckMenuOutput.getInstance().showMessage(deck.toString()); + + } + + public void showDeck(String name, Player player, boolean isMain) { + if (!DeckMenuTools.doesDeckExist(name)) + return; + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (!DeckMenuTools.doesDeckBelongToPlayer(deck, player)) + return; + String message; + if (isMain) + message = "true"; + else + message = "false"; + DeckMenuOutput.getInstance().showMessage(message); + + + } +} diff --git a/src/main/java/controller/deckmenu/DeckMenuDatabase.java b/src/main/java/controller/deckmenu/DeckMenuDatabase.java new file mode 100644 index 0000000..d16b03f --- /dev/null +++ b/src/main/java/controller/deckmenu/DeckMenuDatabase.java @@ -0,0 +1,50 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; +import java.util.ArrayList; + +public class DeckMenuDatabase { + + public static ArrayList allPlayers = new ArrayList<>(); + public static ArrayList allCards = new ArrayList<>(); + public static ArrayList allDecks = new ArrayList<>(); + + private DeckMenuDatabase() { + } + + private static DeckMenuDatabase instance; + + public static DeckMenuDatabase getInstance() { + if (instance == null) + instance = new DeckMenuDatabase(); + return instance; + } + + public static void removeDeck(String name) { + allDecks.removeIf(deck -> deck.getName().equals(name)); + } + + public Card getCardByName(String name) { + for (Card card : allCards) { + if (card.getName().equals(name)) + return card; + } + return null; + + } + + public Deck getDeckByName(String name) { + for (Deck deck : allDecks) { + if (deck.getName().equals(name)) + return deck; + } + return null; + + } + // setPlayers() {file v Jason} + // setDecks() {file v Jason} + // loadingDatabase() + // updatingDatabase() + +} diff --git a/src/main/java/controller/deckmenu/DeckMenuOutput.java b/src/main/java/controller/deckmenu/DeckMenuOutput.java new file mode 100644 index 0000000..92896b1 --- /dev/null +++ b/src/main/java/controller/deckmenu/DeckMenuOutput.java @@ -0,0 +1,23 @@ +package controller.deckmenu; + +public class DeckMenuOutput { + + private DeckMenuOutput() { + } + + private static DeckMenuOutput instance; + + public static DeckMenuOutput getInstance() { + if (instance == null) + instance = new DeckMenuOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/src/main/java/controller/deckmenu/DeckMenuTools.java b/src/main/java/controller/deckmenu/DeckMenuTools.java new file mode 100644 index 0000000..20266b2 --- /dev/null +++ b/src/main/java/controller/deckmenu/DeckMenuTools.java @@ -0,0 +1,70 @@ +package controller.deckmenu; + +import model.*; +import model.cards.Card; + +public class DeckMenuTools { + public static boolean isDeckNameUnique(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck == null) + return true; + + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " already exists"); + return false; + + } + public static boolean doesDeckExist(String name) { + Deck deck = DeckMenuDatabase.getInstance().getDeckByName(name); + if (deck != null) + return true; + DeckMenuOutput.getInstance().showMessage("deck with name " + name + " does not exist"); + return false; + + } + public static boolean doesDeckBelongToPlayer(Deck deck, Player player) { + if (deck.getOwner().getUsername().equals(player.getUsername())) + return true; + DeckMenuOutput.getInstance().showMessage("this deck doesn't belong to you!"); + return false; + } + public static boolean doesDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getMainCards().size() < 60) + return true; + DeckMenuOutput.getInstance().showMessage("main deck is full!"); + return false; + } + public static boolean doesSideDeckHaveSpace(Deck deck) { + if (deck == null) return false; + if (deck.getSideCards().size() < 15) + return true; + DeckMenuOutput.getInstance().showMessage("side deck is full!"); + return false; + } + public static boolean isNumberOfCardsInDeckLessThanFour(Deck deck, Card card) { + if (deck.getNumberOfCardsInDeck(card) < 3) + return true; + DeckMenuOutput.getInstance().showMessage("there are already three cards with name " + card.getName() + + " in deck " + deck.getName() + " !"); + return false; + } + public static boolean isDeckAllowed(Deck deck) { + int numberOfCardsInSideDeck = deck.getNumberOfCardsInSideDeck(); + int numberOfCardsInMainDeck = deck.getNumberOfCardsInMainDeck(); + return numberOfCardsInMainDeck <= 60 && numberOfCardsInMainDeck >= 40 && numberOfCardsInSideDeck <= 15; + } + public static boolean doesPlayerHaveEnoughCards(Card card, Player player) { + if (player.hasCard(card)) + return true; + DeckMenuOutput.getInstance().showMessage("you dont have this type of card anymore!"); + return false; + } + public static boolean doesCardExist(String cardName) { + Card card = Card.getCardByName(cardName); + if (card != null) + return true; + DeckMenuOutput.getInstance().showMessage("card with name " + cardName + " does not exist"); + return false; + } + +} diff --git a/src/main/java/controller/duelmenu/DuelMenuController.java b/src/main/java/controller/duelmenu/DuelMenuController.java new file mode 100644 index 0000000..c4ca63b --- /dev/null +++ b/src/main/java/controller/duelmenu/DuelMenuController.java @@ -0,0 +1,726 @@ +package controller.duelmenu; + +import controller.SpellCardController; +import controller.Utils; +import model.Board; +import model.Deck; +import model.Player; +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; +import view.DuelMenuView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.regex.Matcher; + +public class DuelMenuController { + private Player turnPlayer; + private Player notTurnPlayer; + private Player helpTurnPlayer; + private Phases phase; + private boolean isAITurn; + private int isSummoned = 0; //0 : is not summoned before, 1 : is summoned before + + public static String specifyTurnPlayer(Player firstPlayer, Player secondPlayer) { + String firstPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(firstPlayer); + if (!isMiniGameChoiceValid(firstPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices firstPlayerChoice = MiniGameChoices.valueOf(firstPlayerChoiceInString.toUpperCase()); + + String secondPlayerChoiceInString = DuelMenuView.findChooseOfPlayerInMiniGame(secondPlayer); + if (!isMiniGameChoiceValid(secondPlayerChoiceInString)) return "invalid choice"; + MiniGameChoices secondPlayerChoice = MiniGameChoices.valueOf(secondPlayerChoiceInString.toUpperCase()); + + if (firstPlayerChoice.equals(secondPlayerChoice)) return "draw"; + + return findMiniGameWinner(firstPlayer, secondPlayer, firstPlayerChoice, secondPlayerChoice); + } + + private static boolean isMiniGameChoiceValid(String choice) { + try { + MiniGameChoices.valueOf(choice.toUpperCase()); + return true; + } catch (Exception exception) { + return false; + } + } + + private static String findMiniGameWinner(Player firstPlayer, Player secondPlayer, + MiniGameChoices firstPlayerChoice, MiniGameChoices secondPlayerChoice) { + switch (firstPlayerChoice) { + case STONE: + if (secondPlayerChoice.equals(MiniGameChoices.PAPER)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case PAPER: + if (secondPlayerChoice.equals(MiniGameChoices.SCISSOR)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + case SCISSOR: + if (secondPlayerChoice.equals(MiniGameChoices.STONE)) { + DuelMenuMessages.setShowTurnPlayer(secondPlayer); + return secondPlayer.getUsername(); + } else { + DuelMenuMessages.setShowTurnPlayer(firstPlayer); + return firstPlayer.getUsername(); + } + } + +// this is never happen + return null; + } + + public DuelMenuMessages initialGame(Player firstPlayer, Player secondPlayer) { +// TODO: handle it for ai + String result = specifyTurnPlayer(firstPlayer, secondPlayer); + if (result.equals("invalid choice")) return DuelMenuMessages.MINI_GAME_INVALID_CHOICE; + else if (result.equals("draw")) return DuelMenuMessages.DRAW; + else turnPlayer = Player.getPlayerByUsername(result); + + if (turnPlayer.equals(firstPlayer)) notTurnPlayer = secondPlayer; + else notTurnPlayer = firstPlayer; + + turnPlayer.createBoard(); + notTurnPlayer.createBoard(); + + turnPlayer.getBoard().setDeck(turnPlayer.getActivatedDeck()); + notTurnPlayer.getBoard().setDeck(notTurnPlayer.getActivatedDeck()); + + Collections.shuffle(turnPlayer.getActivatedDeck().getMainCards()); + Collections.shuffle(notTurnPlayer.getActivatedDeck().getMainCards()); + + return DuelMenuMessages.SHOW_TURN_PLAYER; + } + + public DuelMenuMessages findCommand(String command) { +// TODO: handle menu commands --> menu exit and ... + if (command.startsWith("decrease ")) return cheatCodeDecreaseOpponentLifePont(command); + else if (command.startsWith("increase ")) return cheatCodeIncreaseLifePoint(command); + else if (command.startsWith("duel set-winner ")) return cheatCodeSetWinner(command); + else if (command.startsWith("select ")) return checkSelectCard(command); + else if (command.equals("select -d")) return deselectCard(); + else if (command.equals("summon")) ;//return checkSummonMonster(); + else if (command.equals("set")) return checkSetACard(); + else if (command.startsWith("set --position")) ;// return checkChangePosition(command); + else if (command.equals("flip-summon")) return flipSummon(); + else if (command.equals("attack direct")) return directAttack(); + else if (command.startsWith("attack")) return attack(command); + else if (command.equals("activate effect")) return checkActiveASpellCard(); + else if (command.equals("show graveyard")) { + DuelMenuView.showGraveyard(turnPlayer.getBoard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("back")) ;//checkBack(); + else if (command.equals("card show --selected")) { + DuelMenuView.printCard(1, turnPlayer.getBoard().getSelectedCard()); + return DuelMenuMessages.EMPTY; + } else if (command.equals("cancel")) ;//cancelCommand(); + else if (command.equals("surrender")) /*TODO*/ ; + +// TODO: handle cheat/debug commands + + return DuelMenuMessages.INVALID_COMMAND; + } + + private DuelMenuMessages cheatCodeDecreaseOpponentLifePont(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_DECREASE_OPPONENT_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + notTurnPlayer.decreaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + } + + private DuelMenuMessages cheatCodeIncreaseLifePoint(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_INCREASE_LIFE_POINT.getRegex(), command); + if (matcher.find()) { + turnPlayer.increaseLifePoint(Integer.parseInt(matcher.group(1))); + return DuelMenuMessages.EMPTY; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + } + + private DuelMenuMessages cheatCodeSetWinner(String command) { + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.CHEAT_SET_WINNER.getRegex(), command); + if (matcher.find()) { + String nickname = matcher.group(1); + if (turnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/ ; + else if (notTurnPlayer.getNickname().equals(nickname)) /*TODO: handle win the player*/ ; + else return DuelMenuMessages.WRONG_NICKNAME_CHEAT_CODE; + } else return DuelMenuMessages.INVALID_COMMAND_CHEAT_CODE; + + return DuelMenuMessages.EMPTY; + } + + //Iman's Code + private void changePhase() { + phase = phase.next(); + DuelMenuMessages.changephase(phase); + if (phase == Phases.DRAW_PHASE){ + drawPhase(); + } + + } + + private void changeGameTurn(Player firstPlayer, Player secondPlayer) { + if (turnPlayer == firstPlayer) { + turnPlayer = secondPlayer; + notTurnPlayer = firstPlayer; + } + if (turnPlayer == secondPlayer) { + turnPlayer = firstPlayer; + notTurnPlayer = secondPlayer; + } + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void changeGameTurn() { + helpTurnPlayer = turnPlayer; + turnPlayer = notTurnPlayer; + notTurnPlayer = helpTurnPlayer; + isSummoned = 0; + DuelMenuMessages.playerTurn(turnPlayer); + + } + + private void drawPhase() { + changeGameTurn(); + DuelMenuMessages.playerTurn(turnPlayer); + cardDraw(); + } + + public void cardDraw() { + Deck deck = turnPlayer.getBoard().getDeck(); + if (deck.getNumberOfCardsInMainDeck() == 0) { + turnPlayer.setLifePoint(0); + return; + } + turnPlayer.getBoard().drawCard(); + } + + private void summonMonster() { + int position = 0; // TODO fix this + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + + if (selectedMonster.getLevel() == 5 || selectedMonster.getLevel() == 6) { + summonWithOneTribute(position); + } else if (selectedMonster.getLevel() == 7 || selectedMonster.getLevel() == 8) { + summonWithTwoTribute(position); + } else { + selectedCard.getCardFaceUp(); + selectedMonster.settoOO(selectedMonster); + turnPlayer.getBoard().addMonsterCardToMonsterZone(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + DuelMenuMessages.summonedSuccessfully(); + } + } + + private DuelMenuMessages checkSummonMonster() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard) || selectedCard.getCardType() == CardTypes.RITUAL) { + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + else if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + else if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + else if (isSummoned == 1) { + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + + else { + summonMonster(); + return DuelMenuMessages.EMPTY; + } + } + +// public void tributeCardFromMonsterZone(int position) { +// graveyardCards.add(monstesrZones.get(position).getCurrentMonster()); +// monsterZones.get(position).removeCard(); +// } + + private DuelMenuMessages summonWithOneTribute(int position) { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (!turnPlayer.getBoard().isThereOneMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + return DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE; + } + String addressString = Utils.getScanner().nextLine().trim(); + if (addressString.equals("")) return null; // TODO fix this + int address = setCardAddressInMyBoard(Integer.parseInt(addressString)); + if (address < 1 || address > 5) { + return DuelMenuMessages.NO_MONSTER_ON_ADDRESS; + } + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address)) { + return DuelMenuMessages.NO_MONSTER_ON_THIS_ADDRESS; + } + else { + monstersZone[address] = null; + ArrayList cardsInHand = turnPlayer.getBoard().getCardsInHand(); + cardsInHand.remove(selectedCard); + isSummoned = 1; + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + } + } + + private void summonWithTwoTribute(int position) { + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + if (!turnPlayer.getBoard().isThereTwoMonsterForTribute(turnPlayer.getBoard().getMonstersZone())) { + DuelMenuMessages.NotEnoughCardForTribute(); + } + String addressString1 = Utils.getScanner().nextLine().trim(); + if (addressString1.equals("surrender")) return; + String addressString2 = Utils.getScanner().nextLine().trim(); + if (addressString2.equals("surrender")) return; + int address1 = setCardAddressInMyBoard(Integer.parseInt(addressString1)); + int address2 = setCardAddressInMyBoard(Integer.parseInt(addressString2)); + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address1)) return; + if (!turnPlayer.getBoard().isThereCardInAddress(turnPlayer.getBoard().getMonstersZone(), address2)) return; + monstersZone[address1] = null; + monstersZone[address2] = null; + isSummoned = 1; + + } + + private int setCardAddressInMyBoard(int address) { + if (address == 5) return 5; + if (address == 3) return 3; + if (address == 1) return 2; + if (address == 2) return 2; + if (address == 4) return 4; + return -1; + } + + private DuelMenuMessages set() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + // int position = selectedCardIndex; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected()) { + return DuelMenuMessages.SET_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (turnPlayer.getBoard().isMonsterZoneFull()) { + return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + } + if (isSummoned == 1){ + return DuelMenuMessages.ALREADY_SUMMONED_OR_SET; + } + isSummoned = 1; + if (model.cards.Card.isMonsterCard(selectedCard)) { + MonsterCard selectedMonster = (MonsterCard) selectedCard; + setAMonsterCard(selectedMonster); + } + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + + + } + + private DuelMenuMessages checkSetACard() { + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (board.getSelectedCard() == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!board.isACardInHandSelected()) return DuelMenuMessages.CANT_SET; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.NOT_TRUE_PHASE; + else if (Card.isMonsterCard(selectedCard)) return setAMonsterCard(selectedCard); + + MagicCard magicCard = (MagicCard) selectedCard; + return setAMagicCard(magicCard); + } + + + private DuelMenuMessages setAMonsterCard(Card selectedCard) { + MonsterCard monsterCard = (MonsterCard) selectedCard; + if (turnPlayer.getBoard().isMonsterZoneFull()) return DuelMenuMessages.MONSTER_ZONE_IS_FULL; + else turnPlayer.getBoard().addMonsterCardToMonsterZone(monsterCard); + monsterCard.settoDH(monsterCard); + return DuelMenuMessages.SET_SUCCESSFULLY; + } + + private DuelMenuMessages setPositionAttack() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (!selectedMonster.isDefensePosition() || !selectedMonster.toString().equals("DO")) { + return DuelMenuMessages.ALREADY_IN_WANTED_POSITION; + } + if (isSummoned == 1){ //TODO Already changed position? + return DuelMenuMessages.ALREADY_CHANGED_POSITION; + } + selectedMonster.settoOO(selectedMonster); + return DuelMenuMessages.MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY; + } + + private DuelMenuMessages setPositionDefence() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (selectedMonster.isDefensePosition() || !selectedMonster.toString().equals("OO")) { + return DuelMenuMessages.ALREADY_IN_WANTED_POSITION; + } + if (isSummoned == 1){ //TODO Already changed position? + return DuelMenuMessages.ALREADY_CHANGED_POSITION; + } + selectedMonster.settoDO(selectedMonster); + return DuelMenuMessages.MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY; + } + + private DuelMenuMessages flipSummon() { + Card selectedCard = turnPlayer.getBoard().getSelectedCard(); + MonsterCard[] monstersZone = turnPlayer.getBoard().getMonstersZone(); + MonsterCard selectedMonster = (MonsterCard) selectedCard; + if (!turnPlayer.getBoard().isMyCardSelected()) { + DuelMenuMessages.noCardSelected(); + } + if (turnPlayer.getBoard().isACardInHandSelected() || !model.cards.Card.isMonsterCard(selectedCard)) { // check type of monsters + return DuelMenuMessages.SUMMON_NOT_POSSIBLE; + } + if (phase != Phases.MAIN_PHASE_1 && phase != Phases.MAIN_PHASE_2) { + return DuelMenuMessages.NOT_TRUE_PHASE; + } + if (!turnPlayer.getBoard().isCardAvailableInMonstersZone(selectedMonster)) { + return DuelMenuMessages.CHANG_POSITION_NOT_POSSIBLE; + } + if (selectedMonster.toString().equals("DH") || isSummoned != 0) { + return DuelMenuMessages.FLIP_SUMMON_NOT_POSSIBLE; + } + selectedMonster.settoDO(selectedMonster); + isSummoned = 1; + turnPlayer.getBoard().setSelectedCard(null); + return DuelMenuMessages.SUMMONED_SUCCESSFULLY; + + } + + private DuelMenuMessages ritualSummon() { +// TODO: complete it! + return DuelMenuMessages.EMPTY; + } + + private DuelMenuMessages specialSummon() { +// TODO: complete it! + return DuelMenuMessages.EMPTY; + } + + private DuelMenuMessages checkSelectCard(String command) { +// TODO: handle --> if there isn't any card in main deck, he/she loses +// TODO: maybe clean it more + Matcher matcher; + if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MONSTER_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_MAGIC_ZONE.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, true); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMonstersZone(matcher, notTurnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMonstersZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN.getRegex(), command)).find() ) { + if (!isSelectionValid(matcher)) return DuelMenuMessages.INVALID_SELECTION; + else if (!isCardAvailableInMagicsZone(matcher, turnPlayer)) return DuelMenuMessages.CARD_NOT_FOUND; + selectCardFromMagicsZone(matcher, false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_FIELD_ZONE.getRegex(), command).find()) { + if (turnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(true); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if (Utils.getMatcher(DuelMenuRegexes.SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN.getRegex(), command).find()) { + if (notTurnPlayer.getBoard().getFieldZone() == null) { + return DuelMenuMessages.CARD_NOT_FOUND; + } + selectCardFromFieldZone(false); + + } else if ( (matcher = Utils.getMatcher(DuelMenuRegexes.SELECT_CARDS_IN_HAND.getRegex(), command)).find() ) { + int number = Integer.parseInt(matcher.group(1)); + if (number > turnPlayer.getBoard().getCardsInHand().size()) { + return DuelMenuMessages.INVALID_SELECTION; + } + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getCardsInHand().get(number - 1)); + turnPlayer.getBoard().setMyCardSelected(true); + turnPlayer.getBoard().setACardInHandSelected(true); + + } else { + turnPlayer.getBoard().setSelectedCard(null); + turnPlayer.getBoard().setMyCardSelected(false); + return DuelMenuMessages.INVALID_SELECTION; + } + + return DuelMenuMessages.CARD_SELECTED; + } + + private boolean isSelectionValid(Matcher matcher) { + int number = Integer.parseInt(matcher.group(1)); + return number <= 5 && number >= 1; + } + + private boolean isCardAvailableInMonstersZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMonstersZone()[number] != null; + } + + private boolean isCardAvailableInMagicsZone(Matcher matcher, Player player) { + int number = Integer.parseInt(matcher.group(1)); + return player.getBoard().getMagicsZone()[number] != null; + } + + private void selectCardFromMonstersZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMonstersZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMonstersZone()[number]); + } + } + + private void selectCardFromMagicsZone(Matcher matcher, boolean isMyCardSelected) { + int number = Integer.parseInt(matcher.group(1)); + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getMagicsZone()[number]); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getMagicsZone()[number]); + } + } + + private void selectCardFromFieldZone(boolean isMyCardSelected) { + if (isMyCardSelected) { + turnPlayer.getBoard().setSelectedCard(turnPlayer.getBoard().getFieldZone()); + turnPlayer.getBoard().setMyCardSelected(true); + } else { + turnPlayer.getBoard().setSelectedCard(notTurnPlayer.getBoard().getSelectedCard()); + } + } + + private DuelMenuMessages deselectCard() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages result = checkDeselectCard(); + if (result == null) { + board.setSelectedCard(null); + return DuelMenuMessages.DESELECTED; + } else return result; + } + + private DuelMenuMessages checkDeselectCard() { + Board board = turnPlayer.getBoard(); + if (board.getSelectedCard() == null) + return DuelMenuMessages.NOT_SELECTED_CARD; + return null; + } +// +// +// private void victimize() { +//// TODO: handle it! +// } +// + +// +// private DuelMenuMessages checkChangePosition(String command) { +// +// } +// +// private DuelMenuMessages changePosition(String command) { +// +// } +// +// private void updateGraveyard() { +//// TODO: handle it! +// } +// + + private DuelMenuMessages attack(String command) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + Matcher matcher = Utils.getMatcher(DuelMenuRegexes.ATTACK.getRegex(), command); + if (matcher.find()) { + int numberOfChosenCard = Integer.parseInt(matcher.group(1)); + + DuelMenuMessages result = checkAttack(numberOfChosenCard); + if (result == null) { + MonsterCard attackingMonster = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentMonster = opponentPlayerBoard.getMonstersZone()[numberOfChosenCard]; + + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, true); + DuelMenuMessages tempResult = attackingMonster.attack(turnPlayer, notTurnPlayer, numberOfChosenCard); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, attackingMonster, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, opponentMonster, false); + + return tempResult; + } + return result; + + } else return DuelMenuMessages.INVALID_CARD_SELECT; + } + + private DuelMenuMessages checkAttack(int numberOfChosenCard) { + Board attackingPlayerBoard = turnPlayer.getBoard(); + Board opponentPlayerBoard = notTurnPlayer.getBoard(); + + if (attackingPlayerBoard.getSelectedCard() == null || !attackingPlayerBoard.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (attackingPlayerBoard.getSelectedCard() instanceof MonsterCard) + return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + //TODO check battle phase + MonsterCard card = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + if (card.isAttacked()) + return DuelMenuMessages.ATTACKED_BEFORE; + if (opponentPlayerBoard.getMonstersZone()[numberOfChosenCard] == null) + return DuelMenuMessages.NO_CARD_FOUND_IN_THE_POSITION; + return null; + } + + private DuelMenuMessages directAttack() { + Board board = turnPlayer.getBoard(); + DuelMenuMessages messages = checkDirectAttack(); + if (messages != null) + return messages; + else { + MonsterCard card = (MonsterCard) board.getSelectedCard(); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, true); + notTurnPlayer.decreaseLifePoint(card.getAttackPoints()); + SpellCardController.handleFieldSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + SpellCardController.handleEquipSpellCardsEffect(turnPlayer, notTurnPlayer, card, false); + + DuelMenuMessages.setDamageAmount(card.getAttackPoints()); + return DuelMenuMessages.DIRECT_ATTACK_DONE; + } + } + + private DuelMenuMessages checkDirectAttack() { + Board board = turnPlayer.getBoard(); + + if (board.getSelectedCard() == null || !board.isMyCardSelected()) + return DuelMenuMessages.NOT_SELECTED_CARD; + if (phase.equals(Phases.BATTLE_PHASE)) + return DuelMenuMessages.NOT_SUITABLE_PHASE; + if (board.getSelectedCard() instanceof MonsterCard) { + MonsterCard card = (MonsterCard) board.getSelectedCard();//TODO: handle cast exception!! + if (card.isAttacked()) return DuelMenuMessages.ATTACKED_BEFORE; + } else return DuelMenuMessages.CANT_ATTACK_WITH_CARD; + + return null; + } + + private DuelMenuMessages checkActiveASpellCard() { +// TODO: clean it! + Board board = turnPlayer.getBoard(); + Card selectedCard = board.getSelectedCard(); + if (selectedCard == null) return DuelMenuMessages.UNAVAILABLE_SELECTED_CARD; + else if (!selectedCard.getCardType().equals(CardTypes.SPELL)) return DuelMenuMessages.NOT_SPELL_CARD; + else if (!phase.equals(Phases.MAIN_PHASE_1) && !phase.equals(Phases.MAIN_PHASE_2)) return DuelMenuMessages.CANT_ACTIVATE_SPELL_EFFECT; + else if (selectedCard.isPowerUsed()) return DuelMenuMessages.CARD_ACTIVATED_BEFORE; + else if (!turnPlayer.getBoard().isMyCardSelected()) return DuelMenuMessages.NOT_OWNER; + + MagicCard spellCard = (MagicCard) selectedCard; + if (spellCard.getIcon().equals("Field")) { + turnPlayer.getBoard().addSpellCardToFieldZone(spellCard); + spellCard.setPowerUsed(true); + spellCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } else if (board.isMagicsZoneFull() && board.isACardInHandSelected()) return DuelMenuMessages.FULL_MAGICS_ZONE; + + if (!SpellCardController.doSpellCardEffect(turnPlayer, notTurnPlayer, spellCard)) return DuelMenuMessages.UNDONE_PREPARATIONS; + if (board.isACardInHandSelected()) board.addMagicCardToMagicsZone(spellCard); + selectedCard.setPowerUsed(true); + selectedCard.setCardFaceUp(true); + SpellCardController.doSpellAbsorptionEffect(turnPlayer); + SpellCardController.doSpellAbsorptionEffect(notTurnPlayer); + return DuelMenuMessages.SPELL_ACTIVATED; + } + + private DuelMenuMessages setAMagicCard(MagicCard magicCard) { + Board board = turnPlayer.getBoard(); + if (magicCard.getIcon().equals("Field")) board.addSpellCardToFieldZone(magicCard); + else if (board.isMagicsZoneFull()) return DuelMenuMessages.FULL_MAGICS_ZONE; + else board.addMagicCardToMagicsZone(magicCard); + magicCard.setPowerUsed(false); + magicCard.setCardFaceUp(false); + + return DuelMenuMessages.SET_SUCCESSFULLY; + } + +// private DuelMenuMessages checkBack() { +// +// } +// +// private void cancelCommand() { +// +// } +// +// private Player/*or Enum*/ checkWinner() { +// +// } +// +// TODO: ----------------------------------------------- + +} diff --git a/src/main/java/controller/duelmenu/DuelMenuMessages.java b/src/main/java/controller/duelmenu/DuelMenuMessages.java new file mode 100644 index 0000000..bf50377 --- /dev/null +++ b/src/main/java/controller/duelmenu/DuelMenuMessages.java @@ -0,0 +1,112 @@ +package controller.duelmenu; + +import model.Player; + +public enum DuelMenuMessages { + MINI_GAME_INVALID_CHOICE("please enter a valid option\n"), + DRAW("draw\nplease try again:\n"), + SHOW_TURN_PLAYER(" should start first\n"), + INVALID_SELECTION("invalid selection\n"), + CARD_SELECTED("card selected\n"), + CARD_NOT_FOUND("no card found in the given position\n"), + UNAVAILABLE_SELECTED_CARD("no card is selected yet\n"), + NOT_SPELL_CARD("activate effect is only for spell cards.\n"), + CANT_ACTIVATE_SPELL_EFFECT("you can’t activate an effect on this turn\n"), + CARD_ACTIVATED_BEFORE("you have already activated this card\n"), + FULL_MAGICS_ZONE("spell card zone is full\n"), + UNDONE_PREPARATIONS("preparations of this spell are not done yet\n"), + SPELL_ACTIVATED("spell activated\n"), + NOT_OWNER("you aren't owner of selected card\n"), + CANT_SET("you can’t set this card\n"), + NOT_TRUE_PHASE("you can’t do this action in this phase\n"), + SET_SUCCESSFULLY("set successfully\n"), + NOT_SELECTED_CARD("no card is selected yet\n"), + ATTACKED_BEFORE("this card already attacked\n"), + NOT_SUITABLE_PHASE("you can’t do this action in this phase\n"), + INVALID_CARD_SELECT("invalid selection\n"), + NO_CARD_FOUND_IN_THE_POSITION("no card found in the given position\n"), + CANT_ATTACK_WITH_CARD("you can’t attack with this card\n"), + YOU_CANT_ATTACK_TO_THIS_CARD("you cant attack to this card\n"), + ATTACK_CANCELED("attack to this card was canceled\n"), + DIRECT_ATTACK_DONE("you opponent receives battle damage\n"), + DESELECTED("card deselected\n"), + INVALID_COMMAND_CHEAT_CODE("invalid command\n"), + OPPONENT_GOT_DAMAGE_IN_ATTACK("your opponent’s monster is destroyed and your opponent receives battle damage\n"), + ATTACKING_PLAYER_CARD_DESTROYED("Your monster card is destroyed and you received battle damage\n"), + DEFENSE_POSITION_MONSTER_DESTROYED("the defense position monster is destroyed\n"), + NO_CARD_DESTROYED("no card is destroyed\n"), + RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD("no card is destroyed and you received battle damage\n"), + BOTH_CARDS_GET_DESTROYED("both you and your opponent monster cards are destroyed and no one receives damage\n"), + WRONG_NICKNAME_CHEAT_CODE("your entered nickname is wrong\n"), + EMPTY(""), + NO_CARD_SELECTED("no card is selected yet\n"), + SUMMON_NOT_POSSIBLE("you can’t summon this card\n"), + FLIP_SUMMON_NOT_POSSIBLE("you can’t flip summon this card\n"), + SET_NOT_POSSIBLE("you can’t set this card\n"), + PLAYER_TURN("it's 's turn"), + PHASE_IS_CHANGED("phase: \n"), + ALREADY_SUMMONED_OR_SET("you already summoned/set on this turn\n"), + NOT_ENOUGH_CARD_FOR_TRIBUTE("there are not enough card for tribute\n"), + NO_MONSTER_ON_THIS_ADDRESS("there are no monster one this address\n"), + MONSTER_ZONE_IS_FULL("monster card zone is full\n"), + SUMMONED_SUCCESSFULLY("summoned successfully\n"), + NO_MONSTER_ON_ADDRESS("there no monsters on this address"), + MONSTERCARD_POSITION_CHANGED_SUCCESSFULLY("monster card position changed successfully\n"), + ALREADY_CHANGED_POSITION("you already changed this card position in this turn\n"), + ALREADY_IN_WANTED_POSITION("this card is already in the wanted position\n"), + CHANG_POSITION_NOT_POSSIBLE("you can’t change this card position\n"), + INVALID_COMMAND("invalid command\n"); + private String message; + + DuelMenuMessages(String message) { + this.message = message; + } + + public static void setShowTurnPlayer(Player player) { + DuelMenuMessages.SHOW_TURN_PLAYER.message = player.getUsername() + " should start first\n"; + } + + public static void summonedSuccessfully() { + System.out.print("summoned successfully\n"); + } + + public static void NotEnoughCardForTribute(){ + DuelMenuMessages.NOT_ENOUGH_CARD_FOR_TRIBUTE.message = "there are not enough card for tribute\n"; + System.out.print("there are not enough card for tribute\n"); + } + + public static void noCardSelected() { + DuelMenuMessages.NO_CARD_SELECTED.message = "no card is selected yet"; + } + + public static void playerTurn(Player player) { + DuelMenuMessages.PLAYER_TURN.message = "it's + player.getUsername() + 's turn"; + } + + public static void changephase(Phases phase) { + DuelMenuMessages.PHASE_IS_CHANGED.message = "phase: " + phase; + } + + public static void setDamageAmount(int damageAmount) { + DuelMenuMessages.DIRECT_ATTACK_DONE.message = "you opponent receives " + damageAmount + " battle damage\n"; + } + + public static void setOpponentGotDamageInAttack(int damage) { + DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK.message = + "your opponent’s monster is destroyed and your opponent receives" + damage + " battle damage\n"; + } + + public static void setAttackingPlayerCardDestroyed(int damage) { + DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED.message = + "Your monster card is destroyed and you received " + damage + " battle damage\n"; + } + + public static void setReceiveDamageByAttackingToDefenseCard(int damage) { + DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD.message = + "no card is destroyed and you received " + damage + " battle damage\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/controller/duelmenu/DuelMenuRegexes.java b/src/main/java/controller/duelmenu/DuelMenuRegexes.java new file mode 100644 index 0000000..9450450 --- /dev/null +++ b/src/main/java/controller/duelmenu/DuelMenuRegexes.java @@ -0,0 +1,28 @@ +package controller.duelmenu; + +public enum DuelMenuRegexes { + SELECT_MONSTER_ZONE("^select --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_MAGIC_ZONE("^select --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MONSTER_ZONE_MONSTER_PATTERN("^select --(?:monster|M) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MONSTER_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:monster|M) ((?:-|)\\d+)$"), + SELECT_OPPONENT_MAGIC_ZONE_SPELL_PATTERN("^select --(?:spell|S) ((?:-|)\\d+) --(?:opponent|O)$"), + SELECT_OPPONENT_MAGIC_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:spell|S) ((?:-|)\\d+)$"), + SELECT_FIELD_ZONE("^select --(?:field|F)$"), + SELECT_OPPONENT_FIELD_ZONE_FIELD_PATTERN("^select --(?:field|F) --(?:opponent|O)$"), + SELECT_OPPONENT_FIELD_ZONE_OPPONENT_PATTERN("^select --(?:opponent|O) --(?:field|F)$"), + SELECT_CARDS_IN_HAND("^select --(?:hand|H) ((?:-|)\\d+)$"), + CHEAT_DECREASE_OPPONENT_LIFE_POINT("^decrease --opponentLP ([0-9]+)$"), + CHEAT_INCREASE_LIFE_POINT("^increase --LP ([0-9]+)$"), + CHEAT_SET_WINNER("^duel set-winner (\\S+)$"), + ATTACK("^attack ([0-9]+)$"); + + private final String regex; + + DuelMenuRegexes(String message) { + this.regex = message; + } + + public String getRegex() { + return regex; + } +} diff --git a/src/main/java/controller/duelmenu/MiniGameChoices.java b/src/main/java/controller/duelmenu/MiniGameChoices.java new file mode 100644 index 0000000..57881a4 --- /dev/null +++ b/src/main/java/controller/duelmenu/MiniGameChoices.java @@ -0,0 +1,17 @@ +package controller.duelmenu; + +public enum MiniGameChoices { + STONE("stone"), + PAPER("paper"), + SCISSOR("scissor"); + + private final String choice; + + MiniGameChoices(String choice) { + this.choice = choice; + } + + public String getChoice() { + return choice; + } +} diff --git a/src/main/java/controller/duelmenu/Phases.java b/src/main/java/controller/duelmenu/Phases.java new file mode 100644 index 0000000..14000bb --- /dev/null +++ b/src/main/java/controller/duelmenu/Phases.java @@ -0,0 +1,15 @@ +package controller.duelmenu; + +public enum Phases { + DRAW_PHASE, + STANDBY_PHASE, + MAIN_PHASE_1, + BATTLE_PHASE, + MAIN_PHASE_2, + END_PHASE; + private static Phases[] values = values(); + + public Phases next() { + return values[(this.ordinal() + 1) % values.length]; + } +} diff --git a/src/main/java/controller/importexportmenu/ImportExportMenuController.java b/src/main/java/controller/importexportmenu/ImportExportMenuController.java new file mode 100644 index 0000000..cde2f83 --- /dev/null +++ b/src/main/java/controller/importexportmenu/ImportExportMenuController.java @@ -0,0 +1,100 @@ +package controller.importexportmenu; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Utils; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.regex.Matcher; + +public class ImportExportMenuController { + public static ImportExportMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU; + else if (command.equals("menu show-current")) return ImportExportMenuMessages.SHOW_MENU; + else if (command.startsWith("import card")) return importCard(command); + else if (command.startsWith("export card")) return exportCard(command); + + return ImportExportMenuMessages.INVALID_COMMAND; + } + + private static ImportExportMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + return ImportExportMenuMessages.INVALID_NAVIGATION; + } + + private static ImportExportMenuMessages importCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.IMPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + try { + FileReader fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + MonsterCard monsterCard = gson.fromJson(fileReader, MonsterCard.class); + + if (Card.getCardByName(cardName) != null) return ImportExportMenuMessages.AVAILABLE_CARD; + if (monsterCard.getAttribute() == null) { +// so we understand that the card is a magic card + fileReader = new FileReader("src/database/cards/" + cardName + ".json"); + MagicCard magicCard = gson.fromJson(fileReader, MagicCard.class); + Card.addCardToAllCards(magicCard); + if (isCardIncomplete(magicCard) || isMagicCardIncomplete(magicCard)) + return ImportExportMenuMessages.INVALID_FILE; + } else { +// so we understand that the card is a monster card + monsterCard.createEquippedByArrayList(); + Card.addCardToAllCards(monsterCard); + if (isCardIncomplete(monsterCard) || isMonsterCardIncomplete(monsterCard)) + return ImportExportMenuMessages.INVALID_FILE; + } + fileReader.close(); + } catch (IOException ignore) { + return ImportExportMenuMessages.UNAVAILABLE_FILE; + } + + + return ImportExportMenuMessages.EMPTY; + } + + private static boolean isCardIncomplete(Card card) { + return card.getName() == null || card.getDescription() == null || card.getCardType() == null; + } + + private static boolean isMonsterCardIncomplete(MonsterCard monsterCard) { + return monsterCard.getAttribute() == null || monsterCard.getMonsterType() == null; + } + + private static boolean isMagicCardIncomplete(MagicCard magicCard) { + return magicCard.getIcon() == null || magicCard.getStatus() == null; + } + + private static ImportExportMenuMessages exportCard(String command) { + Matcher matcher = Utils.getMatcher(ImportExportMenuRegexes.EXPORT_CARD.getRegex(), command); + if (!matcher.find()) return ImportExportMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card card = Card.getCardByName(cardName); + if (card == null) return ImportExportMenuMessages.UNAVAILABLE_CARD; + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(card)); + fileWriter.close(); + } catch (IOException ioException) { + ioException.printStackTrace(); + System.exit(0); + } + + + return ImportExportMenuMessages.EMPTY; + } +} diff --git a/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java b/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java new file mode 100644 index 0000000..8f83021 --- /dev/null +++ b/src/main/java/controller/importexportmenu/ImportExportMenuMessages.java @@ -0,0 +1,23 @@ +package controller.importexportmenu; + +public enum ImportExportMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_IMPORT_EXPORT_MENU(""), + SHOW_MENU("Import/Export Menu\n"), + INVALID_COMMAND("invalid command\n"), + UNAVAILABLE_FILE("there isn't any file with your entered card name\n"), + INVALID_FILE("your card file is not valid to import\n"), + AVAILABLE_CARD("your entered card name is available\n"), + UNAVAILABLE_CARD("your entered card name is not available\n"), + EMPTY(""); + + private final String message; + + ImportExportMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java b/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java new file mode 100644 index 0000000..65c74dc --- /dev/null +++ b/src/main/java/controller/importexportmenu/ImportExportMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.importexportmenu; + +public enum ImportExportMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + IMPORT_CARD("^import card ([^\n]+)$"), + EXPORT_CARD("^export card ([^\n]+)$"); + + private final String regex; + + ImportExportMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/src/main/java/controller/loginmenu/LoginMenuController.java b/src/main/java/controller/loginmenu/LoginMenuController.java new file mode 100644 index 0000000..178d000 --- /dev/null +++ b/src/main/java/controller/loginmenu/LoginMenuController.java @@ -0,0 +1,120 @@ +package controller.loginmenu; + +import controller.Utils; +import model.Player; +import view.MainMenuView; + +import java.util.regex.Matcher; + +public class LoginMenuController { + public static LoginMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) System.exit(0); + else if (command.equals("menu show-current")) return LoginMenuMessages.SHOW_MENU; + else if (command.startsWith("user create")) { + return checkCreateUser(command); + } else if (command.startsWith("user login")) { + return checkLoginUser(command); + } + + return LoginMenuMessages.INVALID_COMMAND; + } + + private static LoginMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(LoginMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return LoginMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return LoginMenuMessages.INVALID_NAVIGATION; + } + + return LoginMenuMessages.FIRST_LOGIN; + } + + private static LoginMenuMessages checkCreateUser(String command) { + Matcher matcher; + String username, nickname, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIRST_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(2); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SECOND_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + nickname = matcher.group(3); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_THIRD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(1); + password = matcher.group(3); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FOURTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_FIFTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + nickname = matcher.group(3); + password = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.CREATE_USER_SIXTH_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(3); + nickname = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (Player.getPlayerByUsername(username) != null) { + LoginMenuMessages.setUsername(username); + return LoginMenuMessages.USERNAME_EXISTS; + } + if (Player.isNicknameExist(nickname)) { + LoginMenuMessages.setNickname(nickname); + return LoginMenuMessages.NICKNAME_EXISTS; + } + +// TODO: handle to have "strong password" error + createUser(username, password, nickname); + return LoginMenuMessages.USER_CREATED; + } + + private static void createUser(String username, String password, String nickname) { + new Player(username, password, nickname); + } + + private static LoginMenuMessages checkLoginUser(String command) { + Matcher matcher; + String username, password; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + password = matcher.group(2); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + password = matcher.group(1); + } else { + return LoginMenuMessages.INVALID_COMMAND; + } + + + if (!Player.isPasswordCorrect(username, password)) { + return LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD; + } + + return LoginMenuMessages.USER_LOGGED_IN; + } + + public static void loginUser(String command) { + Matcher matcher; + String username = null; + if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_USERNAME_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(1); + } else if (( matcher = Utils.getMatcher(LoginMenuRegexes.LOGIN_USER_PASSWORD_PATTERN.getRegex(), command) ).find()) { + username = matcher.group(2); + } + + + MainMenuView mainMenuView = new MainMenuView(Player.getPlayerByUsername(username)); + mainMenuView.mainMenuView(); + } +} diff --git a/src/main/java/controller/loginmenu/LoginMenuMessages.java b/src/main/java/controller/loginmenu/LoginMenuMessages.java new file mode 100644 index 0000000..167c111 --- /dev/null +++ b/src/main/java/controller/loginmenu/LoginMenuMessages.java @@ -0,0 +1,31 @@ +package controller.loginmenu; + +public enum LoginMenuMessages { + FIRST_LOGIN("please login first"), + INVALID_NAVIGATION("menu navigation is not possible"), + SHOW_MENU("Login Menu"), + USER_CREATED("user created successfully!"), + USERNAME_EXISTS("user with username already exists"), + NICKNAME_EXISTS("user with nickname already exists"), + USER_LOGGED_IN("user logged in successfully!"), + UNMATCHED_USERNAME_AND_PASSWORD("Username and password didn’t match!"), + INVALID_COMMAND("invalid command"); + + private String message; + + LoginMenuMessages(String message) { + this.message = message; + } + + public static void setUsername(String username) { + USERNAME_EXISTS.message = "user with username " + username + " already exists"; + } + + public static void setNickname(String nickname) { + NICKNAME_EXISTS.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/controller/loginmenu/LoginMenuRegexes.java b/src/main/java/controller/loginmenu/LoginMenuRegexes.java new file mode 100644 index 0000000..f518551 --- /dev/null +++ b/src/main/java/controller/loginmenu/LoginMenuRegexes.java @@ -0,0 +1,23 @@ +package controller.loginmenu; + +public enum LoginMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + CREATE_USER_FIRST_PATTERN("^user create --(?:username|U) (\\S+) --(?:nickname|N) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_SECOND_PATTERN("^user create --(?:username|U) (\\S+) --(?:password|P) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_THIRD_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + CREATE_USER_FOURTH_PATTERN("^user create --(?:nickname|N) (\\S+) --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"), + CREATE_USER_FIFTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:username|U) (\\S+) --(?:nickname|N) (\\S+)$"), + CREATE_USER_SIXTH_PATTERN("^user create --(?:password|P) (\\S+) --(?:nickname|N) (\\S+) --(?:username|U) (\\S+)$"), + LOGIN_USER_USERNAME_PATTERN("^user login --(?:username|U) (\\S+) --(?:password|P) (\\S+)$"), + LOGIN_USER_PASSWORD_PATTERN("^user login --(?:password|P) (\\S+) --(?:username|U) (\\S+)$"); + + private final String regex; + + LoginMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/src/main/java/controller/mainmenu/MainMenuController.java b/src/main/java/controller/mainmenu/MainMenuController.java new file mode 100644 index 0000000..e6be9bd --- /dev/null +++ b/src/main/java/controller/mainmenu/MainMenuController.java @@ -0,0 +1,114 @@ +package controller.mainmenu; + +import controller.Utils; +import model.Player; +import view.*; + +import java.util.regex.Matcher; + +public class MainMenuController { + private final Player loggedInPlayer; + + public MainMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public MainMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return MainMenuMessages.EXIT_MAIN_MENU; + else if (command.equals("menu show-current")) return MainMenuMessages.SHOW_MENU; + else if (command.equals("user logout")) return MainMenuMessages.USER_LOGGED_OUT; + else if (command.startsWith("duel")) return enterDuelMenu(command); + + return MainMenuMessages.INVALID_COMMAND; + } + + private MainMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(MainMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return MainMenuMessages.INVALID_COMMAND; + + String menu = matcher.group(1); + if (menu.equalsIgnoreCase("Login")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Main")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Duel")) { + return MainMenuMessages.INVALID_NAVIGATION; + } else if (menu.equalsIgnoreCase("Deck")) { + DeckMenuView deckMenuView = new DeckMenuView(loggedInPlayer); + deckMenuView.runDeckMenu(); + } else if (menu.equalsIgnoreCase("Scoreboard")) { + ScoreboardMenuView scoreboardMenuView = new ScoreboardMenuView(); + scoreboardMenuView.runScoreboard(); + } else if (menu.equalsIgnoreCase("Profile")) { + ProfileMenuView profileMenuView = new ProfileMenuView(loggedInPlayer); + profileMenuView.profileMenuView(); + } else if (menu.equalsIgnoreCase("Shop")) { + ShopMenuView shopMenuView = new ShopMenuView(loggedInPlayer); + shopMenuView.shopMenuView(); + } else if (menu.equalsIgnoreCase("ImportExport")) { + ImportExportMenuView importExportMenuView = new ImportExportMenuView(); + importExportMenuView.ImportExportMenuView(); + } + + return MainMenuMessages.EMPTY; + } + + private MainMenuMessages enterDuelMenu(String command) { +// TODO: clean and optimise this code according to AI + Matcher matcher; + String opponentPlayerCommand, rounds; + if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIRST_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_THIRD_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FOURTH_PATTERN.getRegex(), command) ).find()) { + opponentPlayerCommand = matcher.group(1); + rounds = matcher.group(2); + } else if (( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SECOND_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_FIFTH_PATTERN.getRegex(), command) ).find() || + ( matcher = Utils.getMatcher(MainMenuRegexes.ENTER_DUEL_MENU_SIXTH_PATTERN.getRegex(), command) ).find()) { + rounds = matcher.group(1); + opponentPlayerCommand = matcher.group(2); + } else { + return MainMenuMessages.INVALID_COMMAND; + } + + if (opponentPlayerCommand.startsWith("second-player")) { + String opponentPlayerUsername = opponentPlayerCommand.substring(14); + Player opponentPlayer = Player.getPlayerByUsername(opponentPlayerUsername); + if (opponentPlayer == null) { + return MainMenuMessages.UNAVAILABLE_USERNAME; + } + + if (opponentPlayer.equals(loggedInPlayer)) return MainMenuMessages.SAME_USERNAME; + + if (loggedInPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(loggedInPlayer.getUsername()); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } else if (opponentPlayer.getActivatedDeck() == null) { + MainMenuMessages.setUnavailableActiveDeck(opponentPlayerUsername); + return MainMenuMessages.UNAVAILABLE_ACTIVE_DECK; + } + +// TODO: handle MainMenuMessages.INVALID_DECK message +// TODO: MainMenuMessages.setInvalidDeck(opponentPlayerUsername or loggedInPlayer.getUsername()); +// TODO: return MainMenuMessages.INVALID_DECK; + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + +// TODO: handle 1 or 3 turn game + DuelMenuView duelMenuView = new DuelMenuView(loggedInPlayer, opponentPlayer); + duelMenuView.duelMenuView(); + } else { +// TODO: handle entering to enter duel menu by AI + + if (!rounds.equals("1") && !rounds.equals("3")) { + return MainMenuMessages.INVALID_ROUNDS_NUMBER; + } + } + + return MainMenuMessages.EMPTY; + } +} diff --git a/src/main/java/controller/mainmenu/MainMenuMessages.java b/src/main/java/controller/mainmenu/MainMenuMessages.java new file mode 100644 index 0000000..85fa672 --- /dev/null +++ b/src/main/java/controller/mainmenu/MainMenuMessages.java @@ -0,0 +1,33 @@ +package controller.mainmenu; + +public enum MainMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_MAIN_MENU(""), + SHOW_MENU("Main Menu\n"), + USER_LOGGED_OUT("user logged out successfully!\n"), + UNAVAILABLE_USERNAME("there is no player with this username\n"), + SAME_USERNAME("please enter another username\n"), + UNAVAILABLE_ACTIVE_DECK(" has no active deck\n"), + INVALID_DECK("’s deck is invalid\n"), + INVALID_ROUNDS_NUMBER("number of rounds is not supported\n"), + INVALID_COMMAND("invalid command\n"), + EMPTY(""); + + private String message; + + MainMenuMessages(String message) { + this.message = message; + } + + public static void setUnavailableActiveDeck(String username) { + UNAVAILABLE_ACTIVE_DECK.message = username + " has no active deck\n"; + } + + public static void setInvalidDeck(String username) { + INVALID_DECK.message = username + "’s deck is invalid\n"; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/controller/mainmenu/MainMenuRegexes.java b/src/main/java/controller/mainmenu/MainMenuRegexes.java new file mode 100644 index 0000000..210780f --- /dev/null +++ b/src/main/java/controller/mainmenu/MainMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.mainmenu; + +public enum MainMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + ENTER_DUEL_MENU_FIRST_PATTERN("^duel --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_SECOND_PATTERN("^duel --(?:new|N) --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_THIRD_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N) --(?:rounds|R) ((?:-|)\\d+)$"), + ENTER_DUEL_MENU_FOURTH_PATTERN("^duel --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:rounds|R) ((?:-|)\\d+) --(?:new|N)$"), + ENTER_DUEL_MENU_FIFTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:new|N) --(?:((?:second-player|S) \\S+)|(?:ai|A))$"), + ENTER_DUEL_MENU_SIXTH_PATTERN("^duel --(?:rounds|R) ((?:-|)\\d+) --(?:((?:second-player|S) \\S+)|(?:ai|A)) --(?:new|N)$"); + + private final String regex; + + MainMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/src/main/java/controller/profilemenu/ProfileMenuController.java b/src/main/java/controller/profilemenu/ProfileMenuController.java new file mode 100644 index 0000000..5384e86 --- /dev/null +++ b/src/main/java/controller/profilemenu/ProfileMenuController.java @@ -0,0 +1,99 @@ +package controller.profilemenu; + +import controller.Database; +import controller.Utils; +import model.Player; + +import java.util.regex.Matcher; + +public class ProfileMenuController { + private final Player loggedInPlayer; + + public ProfileMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ProfileMenuMessages findCommand(String command) { + String[] split = command.split("\\s+"); + if (split.length < 2) { + return ProfileMenuMessages.INVALID_COMMAND; + } else if (split[1].equals("enter")) { + return ProfileMenuMessages.CANT_NAVIGATE_MENU; + } else if (split[1].equals("exit")) { + return ProfileMenuMessages.EXIT_MENU; + } else if (split[1].equals("show")) { + return ProfileMenuMessages.PROFILE_MENU; + } else if (split[2].equals("--nickname")) { + return changeNickname(command); + } else if (command.startsWith("profile change")) { + return changePassword(command); + } + + return ProfileMenuMessages.INVALID_COMMAND; + } + + public ProfileMenuMessages changeNickname(String command) { + Matcher matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_NICKNAME.getRegex(), command); + + ProfileMenuMessages holdEnum = checkChangeNickName(matcher); + + if (holdEnum == null) { + loggedInPlayer.setNickname(matcher.group(1)); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_NICKNAME_DONE; + } + return holdEnum; + } + + public ProfileMenuMessages checkChangeNickName(Matcher matcher) { + if (matcher.find()) { + String nickname = matcher.group(1); + if (Player.isNicknameExist(nickname)) { + ProfileMenuMessages.setNickname(nickname); + return ProfileMenuMessages.NOT_UNIQUE_NICKNAME; + } + return null; + } else return ProfileMenuMessages.INVALID_COMMAND; + + } + + public ProfileMenuMessages changePassword(String command) { + String currentPassword, newPassword; + Matcher matcher; + if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIRST_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SECOND_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_THIRD_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FOURTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(1); + newPassword = matcher.group(2); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_FIFTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else if ((matcher = Utils.getMatcher(ProfileMenuRegexes.CHANGE_PASSWORD_SIXTH_PATTERN.getRegex(), command)).find()) { + currentPassword = matcher.group(2); + newPassword = matcher.group(1); + } else return ProfileMenuMessages.INVALID_COMMAND; + + ProfileMenuMessages holdEnum = checkChangePassword(currentPassword, newPassword); + + if (holdEnum == null) { + loggedInPlayer.setPassword(newPassword); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ProfileMenuMessages.CHANGE_PASSWORD_DONE; + } + + return holdEnum; + } + + public ProfileMenuMessages checkChangePassword(String currentPassword, String newPassword) { + if (!loggedInPlayer.getPassword().equals(currentPassword)) return ProfileMenuMessages.WRONG_CURRENT_PASSWORD; + if (currentPassword.equals(newPassword)) return ProfileMenuMessages.SAME_PASSWORD; + return null; + } +} diff --git a/src/main/java/controller/profilemenu/ProfileMenuMessages.java b/src/main/java/controller/profilemenu/ProfileMenuMessages.java new file mode 100644 index 0000000..4c0895f --- /dev/null +++ b/src/main/java/controller/profilemenu/ProfileMenuMessages.java @@ -0,0 +1,27 @@ +package controller.profilemenu; + +public enum ProfileMenuMessages { + NOT_UNIQUE_NICKNAME("user with nickname already exists"), + CHANGE_NICKNAME_DONE("nickname changed successfully!"), + CHANGE_PASSWORD_DONE("password changed successfully!"), + WRONG_CURRENT_PASSWORD("current password is invalid"), + INVALID_COMMAND("invalid command"), + PROFILE_MENU("profile menu"), + EXIT_MENU("exit"), + CANT_NAVIGATE_MENU("menu navigation is not possible"), + SAME_PASSWORD("please enter a new password"); + + private String message; + + ProfileMenuMessages(String message) { + this.message = message; + } + + public static void setNickname(String nickname) { + ProfileMenuMessages.NOT_UNIQUE_NICKNAME.message = "user with nickname " + nickname + " already exists"; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/controller/profilemenu/ProfileMenuRegexes.java b/src/main/java/controller/profilemenu/ProfileMenuRegexes.java new file mode 100644 index 0000000..ba8630d --- /dev/null +++ b/src/main/java/controller/profilemenu/ProfileMenuRegexes.java @@ -0,0 +1,21 @@ +package controller.profilemenu; + +public enum ProfileMenuRegexes { + CHANGE_NICKNAME("^profile change --nickname (\\S+)$"), + CHANGE_PASSWORD_FIRST_PATTERN("^profile change --(?:password|P) --(?:current|C) (\\S+) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_SECOND_PATTERN("^profile change --(?:password|P) --(?:new|N) (\\S+) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_THIRD_PATTERN("^profile change --(?:current|C) (\\S+) --(?:password|P) --(?:new|N) (\\S+)$"), + CHANGE_PASSWORD_FOURTH_PATTERN("^profile change --(?:current|C) (\\S+) --(?:new|N) (\\S+) --(?:password$|P)"), + CHANGE_PASSWORD_FIFTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:password|P) --(?:current|C) (\\S+)$"), + CHANGE_PASSWORD_SIXTH_PATTERN("^profile change --(?:new|N) (\\S+) --(?:current|C) (\\S+) --(?:password$|P)"); + + private final String regex; + + ProfileMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/src/main/java/controller/scoreboardmenu/Scoreboard.java b/src/main/java/controller/scoreboardmenu/Scoreboard.java new file mode 100644 index 0000000..cb725a7 --- /dev/null +++ b/src/main/java/controller/scoreboardmenu/Scoreboard.java @@ -0,0 +1,40 @@ +package controller.scoreboardmenu; + +import java.util.ArrayList; +import model.*; + +public class Scoreboard { + + private Scoreboard() { + } + + private static Scoreboard instance; + + public static Scoreboard getInstance() { + if (instance == null) + instance = new Scoreboard(); + return instance; + } + + public void showScoreboard() { + int counter = 1; + int index = 0; + long previousScore = -1; + StringBuilder output = new StringBuilder(); + ArrayList allUsers = Player.getAllPlayers(); + allUsers.sort(Player::compareTo); + for (Player player : allUsers) { + + + if (player.getScore() != previousScore) { + index += counter; + counter = 1; + } else counter++; + output.append(index).append(". ").append(player.getNickname()).append(": ").append(player.getScore()).append("\n"); + previousScore = player.getScore(); + + } + ScoreboardOutput.getInstance().showMessage(output.toString()); + } + +} diff --git a/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java b/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java new file mode 100644 index 0000000..c77252d --- /dev/null +++ b/src/main/java/controller/scoreboardmenu/ScoreboardOutput.java @@ -0,0 +1,23 @@ +package controller.scoreboardmenu; + +public class ScoreboardOutput { + + private ScoreboardOutput() { + } + + private static ScoreboardOutput instance; + + public static ScoreboardOutput getInstance() { + if (instance == null) + instance = new ScoreboardOutput(); + return instance; + } + + public void showMessage(String message) { + + System.out.print(message + "\n"); + + } + + +} diff --git a/src/main/java/controller/shopmenu/ShopMenuController.java b/src/main/java/controller/shopmenu/ShopMenuController.java new file mode 100644 index 0000000..11dc61c --- /dev/null +++ b/src/main/java/controller/shopmenu/ShopMenuController.java @@ -0,0 +1,63 @@ +package controller.shopmenu; + +import controller.Database; +import controller.Utils; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.DuelMenuRegexes; +import model.Player; +import model.cards.Card; + +import java.util.regex.Matcher; + +public class ShopMenuController { + private final Player loggedInPlayer; + + public ShopMenuController(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + public ShopMenuMessages findCommand(String command) { + + if (command.startsWith("menu enter")) return enterAMenu(command); + else if (command.equals("menu exit")) return ShopMenuMessages.EXIT_SHOP_MENU; + else if (command.equals("menu show-current")) return ShopMenuMessages.SHOW_MENU; + else if (command.startsWith("shop buy")) return buyACard(command); + else if (command.equals("shop show --all")) return ShopMenuMessages.SHOW_ALL_CARDS; + else if (command.startsWith("increase ")) return cheatCodeIncreaseMoney(command); + + return ShopMenuMessages.INVALID_COMMAND; + } + + private ShopMenuMessages enterAMenu(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.ENTER_A_MENU.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + return ShopMenuMessages.INVALID_NAVIGATION; + } + + private ShopMenuMessages buyACard(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.BUY_CARD.getRegex(), command); + if (!matcher.find()) return ShopMenuMessages.INVALID_COMMAND; + + String cardName = matcher.group(1); + Card boughtCard = Card.getCardByName(cardName); + if (boughtCard == null) return ShopMenuMessages.UNAVAILABLE_CARD; + + int boughtCardPrice = boughtCard.getPrice(); + if (boughtCardPrice > loggedInPlayer.getMoney()) return ShopMenuMessages.NOT_ENOUGH_MONEY; + + loggedInPlayer.decreaseMoney(boughtCardPrice); + loggedInPlayer.addCardToBoughtCards(boughtCard); + Database.updatePlayerInformationInDatabase(loggedInPlayer); + return ShopMenuMessages.EMPTY; + } + + private ShopMenuMessages cheatCodeIncreaseMoney(String command) { + Matcher matcher = Utils.getMatcher(ShopMenuRegexes.CHEAT_INCREASE_MONEY.getRegex(), command); + if (matcher.find()) { + loggedInPlayer.increaseMoney(Integer.parseInt(matcher.group(1))); + return ShopMenuMessages.EMPTY; + } else return ShopMenuMessages.INVALID_COMMAND; + + } +} diff --git a/src/main/java/controller/shopmenu/ShopMenuMessages.java b/src/main/java/controller/shopmenu/ShopMenuMessages.java new file mode 100644 index 0000000..339bd0a --- /dev/null +++ b/src/main/java/controller/shopmenu/ShopMenuMessages.java @@ -0,0 +1,22 @@ +package controller.shopmenu; + +public enum ShopMenuMessages { + INVALID_NAVIGATION("menu navigation is not possible\n"), + EXIT_SHOP_MENU(""), + SHOW_MENU("Shop Menu\n"), + UNAVAILABLE_CARD("there is no card with this name\n"), + NOT_ENOUGH_MONEY("not enough money\n"), + EMPTY(""), + SHOW_ALL_CARDS(""), + INVALID_COMMAND("invalid command\n"); + + private final String message; + + ShopMenuMessages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/controller/shopmenu/ShopMenuRegexes.java b/src/main/java/controller/shopmenu/ShopMenuRegexes.java new file mode 100644 index 0000000..0f4dd79 --- /dev/null +++ b/src/main/java/controller/shopmenu/ShopMenuRegexes.java @@ -0,0 +1,17 @@ +package controller.shopmenu; + +public enum ShopMenuRegexes { + ENTER_A_MENU("^menu enter (?i)(Login|Main|Duel|Deck|Scoreboard|Profile|Shop|ImportExport) Menu$"), + BUY_CARD("^shop buy ([^\n]+)$"), + CHEAT_INCREASE_MONEY("^increase --money ([0-9]+)$"); + + private final String regex; + + ShopMenuRegexes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java index 4dd056e..e083cda 100644 --- a/src/main/java/model/Board.java +++ b/src/main/java/model/Board.java @@ -1,67 +1,211 @@ package model; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + import java.util.ArrayList; public class Board { - - private MonsterCard[] monstersZone; - private TraoAndSpell[] spellsAndTrapsZone; + private MagicCard[] magicsZone; private ArrayList graveyard; + private ArrayList cardsInHand; private Deck deck; - // private MagicCard fieldZone;//TODO: maybe it should be from these classes --> Spell / fieldSpell + private MagicCard fieldZone;//TODO: maybe it should be from these classes --> Spell / fieldSpell private Card selectedCard; - protected boolean isMyCardSelected; - - // private Card selectedOpponentCard; - +// if this boolean equals "false" so we can conclude that opponent card selected or nothing selected + private boolean isMyCardSelected; + private boolean isACardInHandSelected; { monstersZone = new MonsterCard[6]; - spellsAndTrapsZone = new TraoAndSpell[6]; + magicsZone = new MagicCard[6]; graveyard = new ArrayList<>(); - // selectedOpponentCard = null; - selectedCard = null; + cardsInHand = new ArrayList<>(); + fieldZone = null; + isMyCardSelected = false; + isACardInHandSelected = false; } - /* public void setSelectedOpponentCard(Card selectedOpponentCard) { - this.selectedOpponentCard = selectedOpponentCard; - }*/ + public void setDeck(Deck deck) { + this.deck = deck;//TODO: maybe we should have a copy of deck in duel menu --> if all changes don't apply in main deck + } - public void setMyCardSelected(boolean myCardSelected) { - isMyCardSelected = myCardSelected; + public MonsterCard[] getMonstersZone() { + return monstersZone; } - public boolean getIsMyCardSelected() { - return isMyCardSelected; + public MagicCard[] getMagicsZone() { + return magicsZone; + } + + public ArrayList getGraveyard() { + return graveyard; } - public void setSelectedCard(Card selectedOwnCard) { - this.selectedCard = selectedOwnCard; + public ArrayList getCardsInHand() { + return cardsInHand; } - /*public Card getSelectedOpponentCard() { - return selectedOpponentCard; - }*/ + public MagicCard getFieldZone() { + return fieldZone; + } public Card getSelectedCard() { return selectedCard; } - public ArrayList getGraveyard() { - return graveyard; + public Deck getDeck() { + return deck; } - public TraoAndSpell[] getSpellsAndTrapsZone() { - return spellsAndTrapsZone; + public void setSelectedCard(Card selectedCard) { + this.selectedCard = selectedCard; } - public MonsterCard[] getMonstersZone() { - return monstersZone; + public void setFieldZone(MagicCard fieldZone) { this.fieldZone = fieldZone; } + + public boolean isMyCardSelected() { + return isMyCardSelected; } - public void setDeck(Deck deck) { - this.deck = deck;//TODO: maybe we should have a copy of deck in duel menu --> if all changes don't apply in main deck + public void setMyCardSelected(boolean myCardSelected) { + isMyCardSelected = myCardSelected; + } + + public boolean isACardInHandSelected() { + return isACardInHandSelected; + } + + public void setACardInHandSelected(boolean ACardInHandSelected) { + isACardInHandSelected = ACardInHandSelected; + } + + public boolean isMagicsZoneFull() { + return getNumberOfFullPartsOfMagicsZone() == 5; } + public boolean isMonsterZoneFull() { + return getNumberOfFullPartsOfMonstersZone() == 5; + } + + public boolean isMagicsZoneEmpty() { + return getNumberOfFullPartsOfMagicsZone() == 0; + } + + public int getNumberOfFullPartsOfMagicsZone() { + int numberOfFullPartsOfMagicsZone = 0; + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) ++numberOfFullPartsOfMagicsZone; + } + return numberOfFullPartsOfMagicsZone; + } + + public int getNumberOfFullPartsOfMonstersZone() { + int getNumberOfFullPartsOfMonstersZone = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] != null) ++getNumberOfFullPartsOfMonstersZone; + } + return getNumberOfFullPartsOfMonstersZone; + } + + public boolean isCardFaceUp(String cardName) { +// if cardName isn't available, then this method returns false + boolean isCardFaceUp = false; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = monstersZone[i].getCardFaceUp(); + } + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i].getName().equals(cardName) && !isCardFaceUp) isCardFaceUp = magicsZone[i].getCardFaceUp(); + } + return isCardFaceUp; + } + + public void addSpellCardToFieldZone(MagicCard spellCard) { + MagicCard previousFieldZone = fieldZone; + if (previousFieldZone != null) graveyard.add(previousFieldZone); + setFieldZone(spellCard); + cardsInHand.remove(spellCard); + } + + public boolean addMagicCardToMagicsZone(MagicCard magicCard) { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] == null) { + magicsZone[i] = magicCard; + cardsInHand.remove(magicCard); + return true; + } + } + return false; + } + + public boolean addMonsterCardToMonsterZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i] == null) { + monstersZone[i] = monsterCard; + cardsInHand.remove(monsterCard); + return true; + } + } + return false; + } + + public boolean isCardAvailableInMonstersZone(MonsterCard monsterCard) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monsterCard)) return true; + } + return false; + } + + public int getNumberOfFaceUpMonsterCards() { + int numberOfFaceUpMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getCardFaceUp()) ++numberOfFaceUpMonsterCards; + } + + return numberOfFaceUpMonsterCards; + } + + public int getNumberOfWarriorMonsterCards() { + int numberOfWarriorMonsterCards = 0; + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].getMonsterType().equals("Warrior")) ++numberOfWarriorMonsterCards; + } + + return numberOfWarriorMonsterCards; + } + + public boolean isThereCardInAddress(MonsterCard[] monsterZone, int address) { + if (monsterZone[address] != null) return true; + return false; + } + + public boolean isThereOneMonsterForTribute(MonsterCard[] monsterZone) { + for (Card card : monsterZone) { + if (card != null) return true; + } + return false; + } + + public boolean isThereTwoMonsterForTribute(MonsterCard[] monstersZone) { + int counter = 0; + for (Card card : monstersZone) { + if (card != null) counter++; + } + if (counter < 2) { + return false; + } + return true; + } + + + public void drawCard() { + Card card = deck.getNumberOfCardsInDeck(deck.getNumberOfCardsInDeck() - 1); + cardsInHand.add(card); + deck.remove(deck.size() - 1); + System.out.println("new card added to the hand: " + card.getName()); + } + + } diff --git a/src/main/java/model/Deck.java b/src/main/java/model/Deck.java index ec9f7ab..217f43b 100644 --- a/src/main/java/model/Deck.java +++ b/src/main/java/model/Deck.java @@ -1,23 +1,83 @@ package model; +import controller.deckmenu.DeckMenuDatabase; +import model.*; +import controller.deckmenu.*; +import model.cards.Card; + import java.util.ArrayList; public class Deck { - private String name; - private ArrayList cards; + public ArrayList mainCards = new ArrayList<>(); + public ArrayList sideCards = new ArrayList<>(); + Player owner; + String name; + DeckType type; + Boolean isActive = false; + Boolean IsValid; - { - cards = new ArrayList<>(); + public Deck(String name, Player owner, boolean hasSideDeck, boolean shouldBeSaved) { + this.name = name; + if (shouldBeSaved) + DeckMenuDatabase.allDecks.add(this); + if (!hasSideDeck) + sideCards = null; + this.owner = owner; } -// for creating main deck - public Deck(String name) { - setName(name); + public Deck(String name, Player owner) { + this.name = name; + sideCards = null; + this.owner = owner; } -// for creating side deck + public Deck(String name) { + this.name = name; + sideCards = null; + } public Deck() { - setName(null); + sideCards = null; + } + + public void updateOwnerDecks() { + String deckType = (name.length() > 16) ? name.substring(name.length() - 16) : ""; + if (deckType.equals(".purchased-cards")) + owner.setAllPlayerCard(this); + else { + owner.getAllDeck().add(this); + if (this.isActive) + owner.setActiveDeck(this); + } + } + + public ArrayList getMainCards() { + if (mainCards == null) + return (mainCards = new ArrayList<>()); + return mainCards; + } + + public void setMainCards(ArrayList mainCards) { + this.mainCards = mainCards; + } + + public ArrayList getSideCards() { + return sideCards; + } + + public void setSideCards(ArrayList sideCards) { + this.sideCards = sideCards; + } + + public Player getOwner() { + return owner; + } + + public void setOwner(Player owner) { + this.owner = owner; + } + + public void setActive(Boolean active) { + isActive = active; } public String getName() { @@ -28,15 +88,108 @@ public void setName(String name) { this.name = name; } - public ArrayList getCards() { - return cards; + public void setActivation(Boolean active) { + isActive = active; + } + + public void setValid(Boolean valid) { + IsValid = valid; + } + + public void setType(DeckType type) { + this.type = type; + } + + public void addCard(Card card, boolean shouldBeAddedToMain) { + if (shouldBeAddedToMain) + mainCards.add(card); + else + sideCards.add(card); + if (card != null) + card.setCurrentDeck(this); } public void addCard(Card card) { - cards.add(card); + mainCards.add(card); + if (card != null && !name.equals("selected collected deck")) + card.setCurrentDeck(this); + } + + public void moveCardTo(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCard(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public void moveCardToForGame(Deck destination, Card card, boolean isMainForOrigin, boolean isMainForDestination) { + removeCardForGame(card, isMainForOrigin); + destination.addCard(card, isMainForDestination); + } + + public boolean hasCard(Card card, boolean isMain) { + if (isMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) + return true; + + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + return true; + } + return false; + } + + public void removeCard(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) { + for (Card cardInMain : mainCards) + if (cardInMain.getName().equals(card.getName())) { + mainCards.remove(cardInMain); + return; + } + } else + for (Card cardInSide : sideCards) + if (cardInSide.getName().equals(card.getName())) { + sideCards.remove(cardInSide); + return; + } + } + + public void removeCardForGame(Card card, boolean shouldBeRemovedFromMain) { + if (shouldBeRemovedFromMain) + mainCards.remove(card); + else + sideCards.remove(card); + } + + public int getNumberOfCardsInDeck(Card card) { + int count = 0; + for (Card cardInDeck : mainCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + for (Card cardInDeck : sideCards) { + if (cardInDeck.getName().equals(card.getName())) + count++; + } + return count; + } + + public int getNumberOfCardsInMainDeck() { + return mainCards.size(); + } + + public int getNumberOfCardsInSideDeck() { + return sideCards.size(); } - public Integer getNumberOfCards() { - return cards.size(); + public void updateCurrentDeck() { + if (mainCards != null) + for (Card card : mainCards) + if (card != null) + card.setCurrentDeck(this); + if (sideCards != null) + for (Card card : sideCards) + if (card != null) + card.setCurrentDeck(this); } -} +} \ No newline at end of file diff --git a/src/main/java/model/DeckType.java b/src/main/java/model/DeckType.java new file mode 100644 index 0000000..2d1643c --- /dev/null +++ b/src/main/java/model/DeckType.java @@ -0,0 +1,8 @@ +package model; + +public enum DeckType { + regulardeck, + inactivedeck, + graveyarddeck, + selectedcarddeck +} diff --git a/src/main/java/model/Player.java b/src/main/java/model/Player.java index 64679d6..28c2187 100644 --- a/src/main/java/model/Player.java +++ b/src/main/java/model/Player.java @@ -1,5 +1,11 @@ package model; +import com.google.gson.annotations.Expose; +import controller.Database; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + import java.util.ArrayList; public class Player { @@ -9,44 +15,48 @@ public class Player { allPlayers = new ArrayList<>(); } + @Expose private ArrayList boughtCards; + @Expose private ArrayList allMainDecks; + private Board board; + @Expose private Deck sideDeck; + @Expose private Deck activatedDeck; + @Expose private String username; + @Expose private String password; + @Expose private String nickname; + @Expose private long score; + @Expose private long money; private int lifePoint; + private transient Deck allPlayerCard; + private transient ArrayList allDeck = new ArrayList<>(); + private transient ArrayList gameDecks = new ArrayList<>(); { boughtCards = new ArrayList<>(); allMainDecks = new ArrayList<>(); + board = null; sideDeck = new Deck(); activatedDeck = null; score = 0; - money = 0; + money = 100000; + lifePoint = 8000; } public Player(String username, String password, String nickname) { setUsername(username); setPassword(password); setNickname(nickname); + addPlayerToAllPlayers(this); allPlayers.add(this); - addPlayerToDataBase(this); - } - - private static void addPlayerToDataBase(Player player) { - - } - - public void setLifePoint(int lifePoint) { - this.lifePoint = lifePoint; - } - - public int getLifePoint() { - return lifePoint; + Database.updatePlayerInformationInDatabase(this); } public static Boolean isNicknameExist(String nickname) { @@ -70,7 +80,50 @@ public static Player getPlayerByUsername(String username) { return null; } + public void setBoughtCards(ArrayList boughtCards) { + this.boughtCards = boughtCards; + } + + public Deck getActiveDeck() { + return activatedDeck; + } + + public void setActiveDeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } + + public ArrayList getAllDeck() { + if (allDeck == null) + return (allDeck = new ArrayList<>()); + return allDeck; + } + + public void setAllDeck(ArrayList allDeck) { + this.allDeck = allDeck; + } + + public Deck getAllPlayerCard() { + return allPlayerCard; + } + + public static ArrayList getAllPlayers() { + return allPlayers; + } + + public void addCardToAllPlayerCard(Card card) { + this.allPlayerCard.getMainCards().add(card); + } + + public void setAllPlayerCard(Deck allPlayerCard) { + this.allPlayerCard = allPlayerCard; + } + public static void addPlayerToAllPlayers(Player player) { + allPlayers.add(player); + } public String getUsername() { return username; @@ -104,6 +157,14 @@ public long getMoney() { return money; } + public Deck getActivatedDeck() { + return activatedDeck; + } + + public ArrayList getBoughtCards() { + return boughtCards; + } + public void increaseScore(long score) { this.score += score; } @@ -121,11 +182,11 @@ public void decreaseMoney(long money) { } public void addCardToBoughtCards(Card card) { - this.boughtCards.add(card); - } - - public void addAmountToLifePoint(int amount){ - this.lifePoint+=amount; + if (Card.isMonsterCard(card)) { + this.boughtCards.add(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.add(new MagicCard((MagicCard) card)); + } } public void addMainDeck(String deckName) { @@ -143,7 +204,7 @@ public Boolean isMainDeckExist(String deckName) { public void deleteMainDeck(String deckName) { Deck mainDeck = getDeckByName(deckName); if (mainDeck != null) { - boughtCards.addAll(mainDeck.getCards()); + boughtCards.addAll(mainDeck.getMainCards()); allMainDecks.remove(mainDeck); } } @@ -155,10 +216,28 @@ public Deck getDeckByName(String deckName) { return null; } + public int compareTo(Player player) { + if (this.score > player.score) + return -1; + if (this.score < player.score) + return 1; + if (this.nickname.compareTo(player.getNickname()) > 0) + return -1; + if (this.nickname.compareTo(player.getNickname()) < 0) + return 1; + return 0; + } + public void activateADeck(String deckName) { Deck deck = getDeckByName(deckName); if (deck != null) activatedDeck = deck; } + public void activateADeck(Deck activatedDeck) { + if (this.activatedDeck != null) + this.activatedDeck.setActive(false); + this.activatedDeck = activatedDeck; + activatedDeck.setActive(true); + } public void addCardToMainDeck() { // TODO: ???? but remember to remove this card from boughtCards :) @@ -167,4 +246,44 @@ public void addCardToMainDeck() { public void removeACard() { // TODO: ???? but remember to add this card from boughtCards :) } -} + + public void decreaseLifePoint(int amount) { + this.lifePoint -= amount; + } + + public void increaseLifePoint(int amount) { + this.lifePoint += amount; + } + + public void setLifePoint(int lifePoint) { + this.lifePoint = lifePoint; + } + + public int getLifePoint() { + return lifePoint; + } + + public void createBoard() { + board = new Board(); + } + + public Board getBoard() { + return board; + } + + public boolean hasCard(Card card){ + for (Card boughtCard : boughtCards) { + if (card.getName().equals(boughtCard.getName())) + return true; + } + return false; + } + + public void removeCardFromBoughtCards(Card card) { + if (Card.isMonsterCard(card)) { + this.boughtCards.remove(new MonsterCard((MonsterCard) card)); + } else { + this.boughtCards.remove(new MagicCard((MagicCard) card)); + } + } +} \ No newline at end of file diff --git a/src/main/java/model/cards/Card.java b/src/main/java/model/cards/Card.java new file mode 100644 index 0000000..9ebd536 --- /dev/null +++ b/src/main/java/model/cards/Card.java @@ -0,0 +1,115 @@ +package model.cards; + +import com.google.gson.annotations.Expose; +import model.Deck; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.TreeMap; + +public class Card { + protected static HashMap allCards; + + static { + allCards = new HashMap<>(); + } + + @Expose + protected final String name; + protected final String description; + protected final CardTypes cardType; + protected final int price; +// if this boolean equals "false" so we can conclude that card is "face down" + protected transient boolean isCardFaceUp; + protected transient boolean isPowerUsed; + protected transient Deck currentDeck; + + { + isCardFaceUp = false; + isPowerUsed = false; + } + + public Card(String name, String description, CardTypes cardType, int price) { + this.name = name; + this.description = description; + this.cardType = cardType; + this.price = price; + } + + public static Card getCardByName(String name) { + return allCards.get(name); + } + + public static TreeMap getListOfCards() { + TreeMap listOfCards = new TreeMap<>(); + for (String cardName : allCards.keySet()) { + Integer cardPrice = allCards.get(cardName).getPrice(); + listOfCards.put(cardName, cardPrice); + } + return listOfCards; + } + + public static boolean isMonsterCard(Card card) { + try { + MonsterCard monsterCard = (MonsterCard) card; + return true; + } catch (Exception exception) { + return false; + } + } + + public static int findNumberOfMonsterCards(ArrayList cards) { + int numberOfMonsterCards = 0; + for (Card card : cards) { + if (Card.isMonsterCard(card)) ++numberOfMonsterCards; + } + return numberOfMonsterCards; + } + + public static void addCardToAllCards(Card card) { + allCards.put(card.getName(), card); + } + + public static HashMap getAllCards() { + return allCards; + } + + public String getName() { + return name; + } + + public void setCurrentDeck(Deck currentDeck) { this.currentDeck = currentDeck; } + + public Deck getCurrentDeck() { + return currentDeck; + } + + public CardTypes getCardType() { + return cardType; + } + + public int getPrice() { + return price; + } + + public void setPowerUsed(boolean powerUsed) { + isPowerUsed = powerUsed; + } + + public boolean isPowerUsed() { + return isPowerUsed; + } + + public String getDescription() { + return description; + } + + public Boolean getCardFaceUp() { + return isCardFaceUp; + } + + public void setCardFaceUp(Boolean cardFaceUp) { + isCardFaceUp = cardFaceUp; + } +} diff --git a/src/main/java/model/cards/CardTypes.java b/src/main/java/model/cards/CardTypes.java new file mode 100644 index 0000000..520056f --- /dev/null +++ b/src/main/java/model/cards/CardTypes.java @@ -0,0 +1,26 @@ +package model.cards; + +import com.google.gson.annotations.SerializedName; + +public enum CardTypes { + @SerializedName("Normal") + NORMAL("Normal"), + @SerializedName("Effect") + EFFECT("Effect"), + @SerializedName("Ritual") + RITUAL("Ritual"), + @SerializedName("Spell") + SPELL("Spell"), + @SerializedName("Trap") + TRAP("Trap"); + + private final String regex; + + CardTypes(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/src/main/java/model/cards/magiccard/MagicCard.java b/src/main/java/model/cards/magiccard/MagicCard.java new file mode 100644 index 0000000..396faf8 --- /dev/null +++ b/src/main/java/model/cards/magiccard/MagicCard.java @@ -0,0 +1,39 @@ +package model.cards.magiccard; + +import model.cards.Card; +import model.cards.CardTypes; + +public class MagicCard extends Card { + protected final String icon; + protected final MagicCardStatuses status; + + public MagicCard(String name, CardTypes cardType, String icon, String description, MagicCardStatuses status, int price) { + super(name, description, cardType, price); + this.icon = icon; + this.status = status; + allCards.put(name, this); + } + + public MagicCard(MagicCard magicCard) { + super(magicCard.name, magicCard.description, magicCard.cardType, magicCard.price); + this.icon = magicCard.icon; + this.status = magicCard.status; + } + + public String getIcon() { + return icon; + } + + public MagicCardStatuses getStatus() { + return status; + } + + public void print() { +// TODO: handle it --> «this.equals(null)» have error and «System.out.print» should be in the view +// if (this.equals(null)) +// System.out.print("E "); +// else if (isCardFaceUp) +// System.out.print("O "); +// else System.out.print("H "); + } +} diff --git a/src/main/java/model/cards/magiccard/MagicCardStatuses.java b/src/main/java/model/cards/magiccard/MagicCardStatuses.java new file mode 100644 index 0000000..a2540c9 --- /dev/null +++ b/src/main/java/model/cards/magiccard/MagicCardStatuses.java @@ -0,0 +1,20 @@ +package model.cards.magiccard; + +import com.google.gson.annotations.SerializedName; + +public enum MagicCardStatuses { + @SerializedName("Limited") + LIMITED("Limited"), + @SerializedName("Unlimited") + UNLIMITED("Unlimited"); + + private final String regex; + + MagicCardStatuses(String regex) { + this.regex = regex; + } + + public String getRegex() { + return regex; + } +} diff --git a/src/main/java/model/cards/monstercard/MonsterCard.java b/src/main/java/model/cards/monstercard/MonsterCard.java new file mode 100644 index 0000000..d72dedd --- /dev/null +++ b/src/main/java/model/cards/monstercard/MonsterCard.java @@ -0,0 +1,139 @@ +package model.cards.monstercard; + +import model.cards.Card; +import model.cards.CardTypes; +import model.cards.magiccard.MagicCard; + +import java.util.ArrayList; + +public class MonsterCard extends Card implements SpecialMonstersFunction { + protected final short level; + protected final MonsterCardAttributes attribute; + protected final String monsterType; + protected int attackPoints; + protected int defensePoints; + protected transient ArrayList equippedBy; +// if this boolean equals "false" so we can conclude that card is in attack position + protected transient boolean isDefensePosition; + protected transient boolean isAttacked = false; + + { + equippedBy = new ArrayList<>(); + isDefensePosition = false; + } + + public MonsterCard(String name, short level, MonsterCardAttributes attribute, String monsterType, CardTypes cardType, + int attackPoints, int defensePoints, String description, int price) { + super(name, description, cardType, price); + this.level = level; + this.attribute = attribute; + this.monsterType = monsterType; + setAttackPoints(attackPoints); + setDefensePoints(defensePoints); + allCards.put(name, this); + } + + public MonsterCard(MonsterCard monsterCard) { + super(monsterCard.name, monsterCard.description, monsterCard.cardType, monsterCard.price); + this.level = monsterCard.level; + this.attribute = monsterCard.attribute; + this.monsterType = monsterCard.monsterType; + this.attackPoints = monsterCard.attackPoints; + this.defensePoints = monsterCard.defensePoints; + } + + public short getLevel() { + return level; + } + + public MonsterCardAttributes getAttribute() { + return attribute; + } + + public String getMonsterType() { + return monsterType; + } + + public int getAttackPoints() { + return attackPoints; + } + + public void setAttackPoints(int attackPoints) { + this.attackPoints = attackPoints; + } + + public int getDefensePoints() { + return defensePoints; + } + + public void setDefensePoints(int defensePoints) { + this.defensePoints = defensePoints; + } + + public boolean isAttacked() { + return isAttacked; + } + + public void setAttacked(boolean attacked) { + isAttacked = attacked; + } + + public boolean isDefensePosition() { + return isDefensePosition; + } + + public void setDefensePosition(boolean defensePosition) { + isDefensePosition = defensePosition; + } + + public ArrayList getEquippedBy() { + return equippedBy; + } + + public void addToEquippedBy(MagicCard equippedBy) { + this.equippedBy.add(equippedBy); + } + + public void increaseAttackPoints(int amount) { + attackPoints += amount; + } + + public void decreaseAttackPoints(int amount) { + attackPoints -= amount; + } + + public void increaseDefencePoints(int amount) { + defensePoints += amount; + } + + public void decreaseDefencePoints(int amount) { + defensePoints -= amount; + } + + public void createEquippedByArrayList() { + equippedBy = new ArrayList<>(); + } + + public void settoDO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoDH(MonsterCard selectedMonster) { + this.setCardFaceUp(!isCardFaceUp); + this.isDefensePosition = true; + } + + public void settoOO(MonsterCard selectedMonster) { + this.setCardFaceUp(isCardFaceUp); + this.isDefensePosition = false; + } + + @Override + public String toString() { + if (!this.getCardFaceUp() && this.isDefensePosition) return "DH"; + else if (this.getCardFaceUp() && this.isDefensePosition) return "DO"; + else if (this.getCardFaceUp() && !this.isDefensePosition) return "OO"; + return "E "; + } +} diff --git a/src/main/java/model/cards/monstercard/MonsterCardAttributes.java b/src/main/java/model/cards/monstercard/MonsterCardAttributes.java new file mode 100644 index 0000000..4677550 --- /dev/null +++ b/src/main/java/model/cards/monstercard/MonsterCardAttributes.java @@ -0,0 +1,10 @@ +package model.cards.monstercard; + +public enum MonsterCardAttributes { + DARK, + EARTH, + FIRE, + LIGHT, + WATER, + WIND; +} diff --git a/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java b/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java new file mode 100644 index 0000000..0b73141 --- /dev/null +++ b/src/main/java/model/cards/monstercard/SpecialMonstersFunction.java @@ -0,0 +1,157 @@ +package model.cards.monstercard; + +import controller.duelmenu.DuelMenuMessages; +import model.Board; +import model.Player; + +public interface SpecialMonstersFunction { + default DuelMenuMessages attack(Player attackingPlayer, Player opponentPlayer, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + MonsterCard attackingCard = (MonsterCard) attackingPlayerBoard.getSelectedCard(); + MonsterCard opponentCard = opponentPlayerBoard.getMonstersZone()[numberToAttack]; + + if (opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack) != null) { + + switch (opponentCard.toString()) { + case "OO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayer.decreaseLifePoint(attackingCard.attackPoints - opponentCard.attackPoints); + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + DuelMenuMessages.setOpponentGotDamageInAttack(attackingCard.attackPoints - opponentCard.attackPoints); + return DuelMenuMessages.OPPONENT_GOT_DAMAGE_IN_ATTACK; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setAttackingPlayerCardDestroyed(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.ATTACKING_PLAYER_CARD_DESTROYED; + } + + case "DO": + if (attackingCard.attackPoints > opponentCard.attackPoints) { + opponentPlayerBoard.getGraveyard().add(opponentCard); + opponentPlayerBoard.getMonstersZone()[numberToAttack] = null; + return DuelMenuMessages.DEFENSE_POSITION_MONSTER_DESTROYED; + } else if (attackingCard.attackPoints == opponentCard.attackPoints) { + return DuelMenuMessages.NO_CARD_DESTROYED; + } else { +// so we can conclude that attackingCard.attackPoints < opponentCard.attackPoints + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + attackingPlayer.decreaseLifePoint(opponentCard.attackPoints - attackingCard.attackPoints); + DuelMenuMessages.setReceiveDamageByAttackingToDefenseCard(opponentCard.attackPoints - attackingCard.attackPoints); + return DuelMenuMessages.RECEIVE_DAMAGE_BY_ATTACKING_TO_DEFENSE_CARD; + } + case "DH": + break; + } + + return null; + + } else + return opponentCard.defense(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + + default DuelMenuMessages defense(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int numberToAttack) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + switch (opponentCard.getName()) { + case "Command knight": + commandKnightFunction(opponentPlayerBoard); + break; + case "Yomi Ship": + return yomiShipFunction(attackingPlayerBoard, attackingCard, opponentCard); + case "Suijin": + return suijinFunction(attackingCard); + case "Marshmallon": + return marshmallonFunction(attackingPlayer); + case "Texchanger": + return texchangerFunction(opponentCard); + case "Exploder Dragon": + return exploderDragon(attackingPlayer, opponentPlayer, attackingCard, opponentCard, numberToAttack); + } + return null; + } + + default DuelMenuMessages texchangerFunction(MonsterCard opponentCard) { + if (!opponentCard.isPowerUsed()) { + opponentCard.setPowerUsed(true); + // choosing a card ehzar??????? + return DuelMenuMessages.ATTACK_CANCELED; + } + return null; + } + + default DuelMenuMessages commandKnightFunction(Board opponentPlayerBoard) { + for (int i = 1; i <= 5; i++) { + if (opponentPlayerBoard.getMonstersZone()[i] != null && !opponentPlayerBoard.getMonstersZone()[i].getName().equals("Command knight")) { + return DuelMenuMessages.YOU_CANT_ATTACK_TO_THIS_CARD; + } + } + return null; + } + + default DuelMenuMessages yomiShipFunction(Board attackingPlayerBoard, MonsterCard attackingCard, MonsterCard opponentCard) { + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + } + return null; + } + + default DuelMenuMessages suijinFunction(MonsterCard attackingCard) { +// attackingCard.setAttackLevel(0);//TODO: undo it!! + return null; + } + + default DuelMenuMessages marshmallonFunction(Player attackingPlayer) { + attackingPlayer.decreaseLifePoint(1000); + return null; + } + + default DuelMenuMessages exploderDragon(Player attackingPlayer, Player opponentPlayer, MonsterCard attackingCard, + MonsterCard opponentCard, int number) { + Board attackingPlayerBoard = attackingPlayer.getBoard(); + Board opponentPlayerBoard = opponentPlayer.getBoard(); + + if (opponentCard.toString().equals("OO") && attackingCard.attackPoints > opponentCard.attackPoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + if (opponentCard.toString().equals("DO") || opponentCard.toString().equals("DH") && attackingCard.attackPoints > opponentCard.defensePoints) { + attackingPlayerBoard.getGraveyard().add(attackingCard); + opponentPlayerBoard.getGraveyard().add(opponentCard); + attackingPlayerBoard.getMonstersZone()[number] = null; + deleteMonsterFromZone(attackingCard, attackingPlayerBoard.getMonstersZone()); + return DuelMenuMessages.BOTH_CARDS_GET_DESTROYED; + } + return null; + } + + default void deleteMonsterFromZone(MonsterCard monster, MonsterCard[] monstersZone) { + for (int i = 1; i < monstersZone.length; i++) { + if (monstersZone[i].equals(monster)) { + monstersZone[i] = null; + break; + } + } + } +} diff --git a/src/main/java/view/DeckMenuView.java b/src/main/java/view/DeckMenuView.java index 098815f..5341692 100644 --- a/src/main/java/view/DeckMenuView.java +++ b/src/main/java/view/DeckMenuView.java @@ -1,32 +1,137 @@ -package view; - -import controller.DeckMenuController; -import controller.DeckMenuMessages; -import controller.Utils; -import model.Player; - -public class DeckMenuView { - private Player loggedInPlayer; - - public DeckMenuView(Player loggedInPlayer) { - setLoggedInPlayer(loggedInPlayer); - } - - public void setLoggedInPlayer(Player loggedInPlayer) { - this.loggedInPlayer = loggedInPlayer; - } - - public void deckMenuView() { - while (true) { - String command = Utils.getScanner().nextLine().trim(); - DeckMenuController deckMenuController = new DeckMenuController(loggedInPlayer); - Enum result = deckMenuController.findCommand(command); - - System.out.print(result); - - if (result.equals(DeckMenuMessages.EXIT_DECK_MENU)) break; - else if (result.equals(DeckMenuMessages.DECK_SHOW)) deck-show(); - } - } - - private void deck-show(); \ No newline at end of file +package view; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import controller.Utils; +import controller.deckmenu.DeckMenuController; +import controller.deckmenu.DeckMenuOutput; +import model.*; + +public class DeckMenuView { + public static Scanner scanner = Utils.getScanner(); + + private final Player loggedInPlayer; + + public DeckMenuView(Player loggedInPlayer) { + this.loggedInPlayer = loggedInPlayer; + } + + private final String[] deckMenuRegexes = { + "^deck create (?\\w+)$", + "^deck delete (?\\w+)$", + "^deck set-activate (?\\w+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck add-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck add-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck add-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--side|-s) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+) (?:--side|-s)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--side|-s) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck rm-card (?:--side|-s) (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--card|-c) (?.+) (?:--deck|-d) (?.+)$", + "^deck rm-card (?:--deck|-d) (?.+) (?:--card|-c) (?.+)$", + "^deck show (?:--all|-a)$", + "^deck show (?:--deck-name|-d) (?.+) (?:--side|-s)$", + "^deck show (?:--side|-s) (?:--deck-name|-d) (?.+)$", + "^deck show (?:--deck-name|-d) (?.+)$", + "^menu show-current$", + "^menu exit$" + }; + + public void runDeckMenu() { + Matcher commandMatcher; + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + int whichCommand; + for (whichCommand = 0; whichCommand < deckMenuRegexes.length; whichCommand++) { + commandMatcher = findMatcher(command, deckMenuRegexes[whichCommand]); + if (commandMatcher.find()) { + executeDeckMenuCommands(commandMatcher, whichCommand); + break; + } else if (whichCommand == deckMenuRegexes.length - 1) + DeckMenuOutput.getInstance().showMessage("invalid command"); + } + + } + } + + private void executeDeckMenuCommands(Matcher commandMatcher, int whichCommand) { + DeckMenuController controller = DeckMenuController.getInstance(); + switch (whichCommand) { + case 0: + controller.createDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 1: + controller.deleteDeck(commandMatcher.group("name")); + break; + case 2: + controller.setActiveDeck(commandMatcher.group("name"), loggedInPlayer); + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + String cardName = commandMatcher.group("cardName"), + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, false); + break; + case 9: + case 10: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.addCardToDeck(cardName, deckName, loggedInPlayer, true); + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, false); + break; + case 17: + case 18: + cardName = commandMatcher.group("cardName"); + deckName = commandMatcher.group("deckName"); + controller.removeCardFromDeck(cardName, deckName, loggedInPlayer, true); + break; + case 19: + controller.showAllDecks(loggedInPlayer); + break; + case 20: + case 21: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, false); + break; + case 22: + controller.showDeck(commandMatcher.group("deckName"), loggedInPlayer, true); + break; + case 23: + DeckMenuOutput.getInstance().showMessage("Deck Menu"); + break; + case 24: + MainMenuView mainMenuView = new MainMenuView(loggedInPlayer); + mainMenuView.mainMenuView(); + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } + + +} diff --git a/src/main/java/view/DuelMenuView.java b/src/main/java/view/DuelMenuView.java index 77e9c30..24661b5 100644 --- a/src/main/java/view/DuelMenuView.java +++ b/src/main/java/view/DuelMenuView.java @@ -1,127 +1,140 @@ package view; -import controller.DuelMenuController; import controller.Utils; -import model.*; +import controller.duelmenu.DuelMenuController; +import controller.duelmenu.DuelMenuMessages; +import controller.duelmenu.Phases; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; public class DuelMenuView { - private Player loggedInPlayer; - private Player opponentPlayer; - private Enum phase; - private Board loggedInPlayerBoard; - private Board opponentPlayerBoard; - private int turnFlag = 0; - - { - loggedInPlayerBoard = new Board(); - opponentPlayerBoard = new Board(); - } + private Player firstPlayer; + private Player secondPlayer; + private Phases phase; - public DuelMenuView(Player loggedInPlayer, Player opponentPlayer) { - this.loggedInPlayer = loggedInPlayer; - this.opponentPlayer = opponentPlayer; + public DuelMenuView(Player firstPlayer, Player secondPlayer) { + this.firstPlayer = firstPlayer; + this.secondPlayer = secondPlayer; } - public static void showSelectedCard(Card card) { + public static String findChooseOfPlayerInMiniGame(Player player) { + System.out.println(player.getUsername() + ", please choose between stone, paper and scissor:"); + return Utils.getScanner().nextLine().trim(); + } + public static void showGraveyard(Board board) { + if (board.getGraveyard().size() != 0) { + for (int i = 1; i <= board.getGraveyard().size(); i++) { + printCard(i , board.getGraveyard().get(i)); + } + } else System.out.println("graveyard empty"); + while (true) { + String input = Utils.getScanner().nextLine(); + if (input.equals("back")) + break; + } } - public void duelMenuView() { - String command = Utils.getScanner().nextLine().trim(); - DuelMenuController mainMenu = new DuelMenuController(loggedInPlayer, opponentPlayer, phase); - mainMenu.findCommand(command); + public static void printCard(int number, Card card) { + System.out.println(number + ". " + card.getName() + ": " + card.getDescription()); } - private void showBoard(Board playerBoard, Board opponentBoard) { - showCartInHand(opponentBoard); - showLeftCardDeck(opponentBoard);//?????????????????????? - showOpponentTrapAndSpellZone(opponentBoard); - showOpponentMonsterZone(opponentBoard); - showGrave(opponentBoard); + private static void showBoard(Board playerBoard, Board opponentBoard) { + showCardsInHand(opponentBoard); +// showLeftCardDeck(opponentBoard);//?????????????????????? + showOpponentMagicsZone(opponentBoard); + showOpponentMonstersZone(opponentBoard); + showGraveyard(opponentBoard); System.out.println("--------------------------"); - showCartInHand(playerBoard); - showLeftCardDeck(playerBoard);//???????? - showTrapAndSpellZone(playerBoard); - showMonsterZone(playerBoard); - showGrave(playerBoard); + showCardsInHand(playerBoard); +// showLeftCardDeck(playerBoard);//???????? + showMagicsZone(playerBoard); + showMonstersZone(playerBoard); + showGraveyard(playerBoard); } - private void showMonsterZone(Board board) { + private static void showMonstersZone(Board board) { MonsterCard[] monsters = board.getMonstersZone(); - monsters[5].print(); - System.out.print(monsters[5].print() + " "); - System.out.print(monsters[3].print() + " "); - System.out.print(monsters[1].print() + " "); - System.out.print(monsters[2].print() + " "); - System.out.print(monsters[4].print() + " "); - System.out.println(); +// monsters[5].print(); +// System.out.print(monsters[5].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[4].print() + " "); +// System.out.println(); } - private void showTrapAndSpellZone(Board board) { - TraoAndSpell[] spellsAndTrapsZone = board.getSpellsAndTrapsZone(); - spellsAndTrapsZone[5].print(); - spellsAndTrapsZone[3].print(); - spellsAndTrapsZone[1].print(); - spellsAndTrapsZone[2].print(); - spellsAndTrapsZone[4].print(); + private static void showMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[5].print(); + magicsZone[3].print(); + magicsZone[1].print(); + magicsZone[2].print(); + magicsZone[4].print(); } - private void showOpponentMonsterZone(Board board) { + private static void showOpponentMonstersZone(Board board) { MonsterCard[] monsters = board.getMonstersZone(); - System.out.print(monsters[4].print() + " "); - System.out.print(monsters[2].print() + " "); - System.out.print(monsters[1].print() + " "); - System.out.print(monsters[3].print() + " "); - System.out.print(monsters[5].print() + " "); +// System.out.print(monsters[4].print() + " "); +// System.out.print(monsters[2].print() + " "); +// System.out.print(monsters[1].print() + " "); +// System.out.print(monsters[3].print() + " "); +// System.out.print(monsters[5].print() + " "); } - private void showOpponentTrapAndSpellZone(Board board) { - TraoAndSpell[] spellsAndTrapsZone = board.getSpellsAndTrapsZone(); - spellsAndTrapsZone[4].print(); - spellsAndTrapsZone[2].print(); - spellsAndTrapsZone[1].print(); - spellsAndTrapsZone[3].print(); - spellsAndTrapsZone[5].print(); + private static void showOpponentMagicsZone(Board board) { + MagicCard[] magicsZone = board.getMagicsZone(); + magicsZone[4].print(); + magicsZone[2].print(); + magicsZone[1].print(); + magicsZone[3].print(); + magicsZone[5].print(); } - private void showCartInHand(Board board) { - for (int i = 0; i < board.; i++) { + private static void showCardsInHand(Board board) { + for (int i = 0; i < board.getCardsInHand().size(); i++) { System.out.print("C "); } System.out.println(); - ; } - private void showGraveyard(Board board) { - if (board.getGraveyard().size() != 0) { - for (int i = 0; i < board.getGraveyard().size(); i++) { - System.out.println(board.getGraveyard().get(i).getName() + " " + board.getGraveyard().get(i).getDescription()); - } - } else System.out.println("graveyard empty"); - while (true) { - String input = Utils.getScanner().nextLine(); - if (input.equals("back")) - break; - } - } - - - private void showCardSelected(Board board) { + private static void showSelectedCard(Board board) { if (showCardCheck(board)) { System.out.println(board.getSelectedCard().getName() + " " + board.getSelectedCard().getDescription()); } } - private boolean showCardCheck(Board board) { + private static boolean showCardCheck(Board board) { if (board.getSelectedCard() == null) { System.out.println("you have not selected card"); return false; } - if (!board.getIsMyCardSelected() && !board.getSelectedCard().isCardFaceUp()) { + if (!board.isMyCardSelected() && !board.getSelectedCard().getCardFaceUp()) { System.out.println("you cant see this card!"); return false; } return true; } + + public void duelMenuView() { + DuelMenuController duelMenuController = new DuelMenuController(); + + DuelMenuMessages resultOfInitialGame = null; + while (resultOfInitialGame == null || !resultOfInitialGame.equals(DuelMenuMessages.SHOW_TURN_PLAYER)) { + resultOfInitialGame = duelMenuController.initialGame(firstPlayer, secondPlayer); + System.out.print(resultOfInitialGame.getMessage()); + } + + while (true) { + String command = Utils.getScanner().nextLine().trim(); + DuelMenuMessages result = duelMenuController.findCommand(command); + + System.out.print(result.getMessage()); + } + } + } diff --git a/src/main/java/view/ImportExportMenuView.java b/src/main/java/view/ImportExportMenuView.java new file mode 100644 index 0000000..ee91f94 --- /dev/null +++ b/src/main/java/view/ImportExportMenuView.java @@ -0,0 +1,18 @@ +package view; + +import controller.Utils; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; + +public class ImportExportMenuView { + public void ImportExportMenuView() { + while (true) { + String command = Utils.getScanner().nextLine().trim(); + ImportExportMenuMessages result = ImportExportMenuController.findCommand(command); + + System.out.print(result.getMessage()); + + if (result.equals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU)) break; + } + } +} diff --git a/src/main/java/view/LoginMenuView.java b/src/main/java/view/LoginMenuView.java index 83aeaea..f094c8b 100644 --- a/src/main/java/view/LoginMenuView.java +++ b/src/main/java/view/LoginMenuView.java @@ -1,17 +1,16 @@ package view; -import controller.LoginMenuController; -import controller.LoginMenuMessages; import controller.Utils; +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; public class LoginMenuView { public static void loginMenuView() { while (true) { String command = Utils.getScanner().nextLine().trim(); - LoginMenuController loginMenuController = new LoginMenuController(); - Enum result = loginMenuController.findCommand(command); + LoginMenuMessages result = LoginMenuController.findCommand(command); - System.out.println(result); + System.out.println(result.getMessage()); if (result.equals(LoginMenuMessages.USER_LOGGED_IN)) LoginMenuController.loginUser(command); } diff --git a/src/main/java/view/MainMenuView.java b/src/main/java/view/MainMenuView.java index bd2dc8f..7dde978 100644 --- a/src/main/java/view/MainMenuView.java +++ b/src/main/java/view/MainMenuView.java @@ -1,6 +1,8 @@ package view; -import controller.*; +import controller.Utils; +import controller.mainmenu.MainMenuController; +import controller.mainmenu.MainMenuMessages; import model.Player; public class MainMenuView { @@ -15,12 +17,12 @@ public void setLoggedInPlayer(Player loggedInPlayer) { } public void mainMenuView() { + MainMenuController mainMenuController = new MainMenuController(loggedInPlayer); while (true) { String command = Utils.getScanner().nextLine().trim(); - MainMenuController mainMenuController = new MainMenuController(loggedInPlayer); - Enum result = mainMenuController.findCommand(command); + MainMenuMessages result = mainMenuController.findCommand(command); - System.out.print(result); + System.out.print(result.getMessage()); if (result.equals(MainMenuMessages.EXIT_MAIN_MENU) || result.equals(MainMenuMessages.USER_LOGGED_OUT)) break; diff --git a/src/main/java/view/ProfileMenuView.java b/src/main/java/view/ProfileMenuView.java index 0e6cb4e..1e1b091 100644 --- a/src/main/java/view/ProfileMenuView.java +++ b/src/main/java/view/ProfileMenuView.java @@ -1,33 +1,25 @@ package view; -import controller.MainMenuController; -import controller.ProfileMenuController; -import controller.ProfileMenuMessages; +import controller.profilemenu.ProfileMenuController; +import controller.profilemenu.ProfileMenuMessages; import controller.Utils; import model.Player; -import java.util.Scanner; - public class ProfileMenuView { - private Player loggedInPlayer; + private final Player loggedInPlayer; public ProfileMenuView(Player loggedInPlayer) { - setLoggedInPlayer(loggedInPlayer); - } - - public void setLoggedInPlayer(Player loggedInPlayer) { this.loggedInPlayer = loggedInPlayer; } public void profileMenuView() { + ProfileMenuController profileMenuController = new ProfileMenuController(loggedInPlayer); while (true) { String command = Utils.getScanner().nextLine().trim(); - ProfileMenuController profileMenuController = new ProfileMenuController(loggedInPlayer); ProfileMenuMessages result = profileMenuController.findCommand(command); - if (result.equals(ProfileMenuMessages.EXIT_MENU)) - break; - else - System.out.print(result.getMessage()); + + if (result.equals(ProfileMenuMessages.EXIT_MENU)) break; + else System.out.print(result.getMessage()); } } } diff --git a/src/main/java/view/ScoreboardMenuView.java b/src/main/java/view/ScoreboardMenuView.java index 34eca3d..57e679c 100644 --- a/src/main/java/view/ScoreboardMenuView.java +++ b/src/main/java/view/ScoreboardMenuView.java @@ -1,35 +1,40 @@ -package view; - -import controller.ScoreboardMenuController; -import controller.ScoreboardMenuMessages; -import controller.Utils; -import model.Player; - -public class ScoreboardMenuView { - private Player loggedInPlayer; - - public ScoreboardMenuView(Player loggedInPlayer) { - setLoggedInPlayer(loggedInPlayer); - } - - public void setLoggedInPlayer(Player loggedInPlayer) { - this.loggedInPlayer = loggedInPlayer; - } - - public void scoreboardMenuView() { - while (true) { - String command = Utils.getScanner().nextLine().trim(); - ScoreboardMenuController scoreboardMenuController = new ScoreboardMenuController(loggedInPlayer); - Enum result = scoreboardMenuController.findCommand(command); - - System.out.print(result); - - if (result.equals(ScoreboardMenuMessages.EXIT_SCOREBOARD_MENU)) break; - else if (result.equals(ScoreboardMenuMessages.SCOREBOARD_SHOW)) rank(); - } - } - - private void rank() { - } - -} \ No newline at end of file +package view; + +import controller.Utils; +import controller.scoreboardmenu.Scoreboard; +import controller.scoreboardmenu.ScoreboardOutput; +import model.Player; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ScoreboardMenuView { + public static Scanner scanner = Utils.getScanner(); + + public void runScoreboard() { + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + switch (command) { + case "scoreboard show": + Scoreboard.getInstance().showScoreboard(); + break; + case "menu show-current": + ScoreboardOutput.getInstance().showMessage("Scoreboard Menu"); + break; + case "menu exit": +// MainMenuView mainMenuView = new MainMenuView(); +// mainMenuView.mainMenuView(); + default: + ScoreboardOutput.getInstance().showMessage("invalid command"); + } + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } +} diff --git a/src/main/java/view/ShopMenuView.java b/src/main/java/view/ShopMenuView.java index b1b6931..0ed2331 100644 --- a/src/main/java/view/ShopMenuView.java +++ b/src/main/java/view/ShopMenuView.java @@ -1,10 +1,10 @@ package view; -import controller.ShopMenuController; -import controller.ShopMenuMessages; import controller.Utils; -import model.Card; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; import model.Player; +import model.cards.Card; import java.util.TreeMap; @@ -15,27 +15,27 @@ public ShopMenuView(Player loggedInPlayer) { setLoggedInPlayer(loggedInPlayer); } + private static void showListOfCards() { + TreeMap listOfCards = Card.getListOfCards(); + for (String cardName : listOfCards.keySet()) { + System.out.println(cardName + ": " + listOfCards.get(cardName)); + } + } + public void setLoggedInPlayer(Player loggedInPlayer) { this.loggedInPlayer = loggedInPlayer; } public void shopMenuView() { + ShopMenuController shopMenuController = new ShopMenuController(loggedInPlayer); while (true) { String command = Utils.getScanner().nextLine().trim(); - ShopMenuController shopMenuController = new ShopMenuController(loggedInPlayer); - Enum result = shopMenuController.findCommand(command); + ShopMenuMessages result = shopMenuController.findCommand(command); - System.out.print(result); + System.out.print(result.getMessage()); if (result.equals(ShopMenuMessages.EXIT_SHOP_MENU)) break; else if (result.equals(ShopMenuMessages.SHOW_ALL_CARDS)) showListOfCards(); } } - - private void showListOfCards() { - TreeMap listOfCards = Card.getListOfCards; - for (String cardName : listOfCards.descendingKeySet()) { - System.out.println(cardName + ": " + listOfCards.get(cardName)); - } - } } diff --git a/src/main/java/view/SpellCardView.java b/src/main/java/view/SpellCardView.java new file mode 100644 index 0000000..69bf703 --- /dev/null +++ b/src/main/java/view/SpellCardView.java @@ -0,0 +1,118 @@ +package view; + +import controller.Utils; +import model.Board; +import model.Player; +import model.cards.Card; +import model.cards.magiccard.MagicCard; +import model.cards.monstercard.MonsterCard; + +import java.util.ArrayList; + +public class SpellCardView extends DuelMenuView { + private SpellCardView(Player firstPlayer, Player secondPlayer) { + super(firstPlayer, secondPlayer); + } + + public static void showGraveyardsMonsterCards(Player turnPlayer, Player notTurnPlayer) { +// it used for Monster Reborn spell card + System.out.println("your graveyard monster cards:"); + showGraveyardMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent graveyard monster cards:"); + showGraveyardMonsterCards(notTurnPlayer.getBoard(), Card.findNumberOfMonsterCards(notTurnPlayer.getBoard().getGraveyard()) + 1); + } + + private static void showGraveyardMonsterCards(Board board, int startNumber) { +// it used for Monster Reborn spell card + int count = startNumber; + for (int i = 0; i < board.getGraveyard().size(); i++) { + if (Card.isMonsterCard(board.getGraveyard().get(i))) { + printCard(count, board.getGraveyard().get(i)); + ++count; + } + } + if (count == startNumber) System.out.println("There isn't any monster card."); + } + + public static String findCardNumber() { + System.out.println("choose a number:"); + return Utils.getScanner().nextLine(); + } + + public static void invalidNumber() { + System.out.println("invalid number"); + } + + public static void showFieldSpellCards(ArrayList magicCards) { + System.out.println("your field spell cards:"); + if (magicCards.size() == 0) System.out.println("There isn't any field spell card."); + else { + for (int i = 1; i <= magicCards.size(); i++) { + printCard(i, magicCards.get(i - 1)); + } + } + } + + public static void showCardsInHand(Player player) { + System.out.println("you have these cards in hand:"); + ArrayList cardsInHand = player.getBoard().getCardsInHand(); + if (cardsInHand.size() == 0) System.out.println("There isn't any card in your hand."); + else { + for (int i = 1; i <= cardsInHand.size(); i++) { + printCard(i, cardsInHand.get(i - 1)); + } + } + } + + public static void showMagicsZonesCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your spell and trap zone cards:"); + int endNumber = showMagicsZoneCards(turnPlayer, 1); + System.out.println("opponent spell and trap zone cards:"); + showMagicsZoneCards(notTurnPlayer, endNumber); + } + + private static int showMagicsZoneCards(Player player, int startNumber) { + MagicCard[] magicsZone = player.getBoard().getMagicsZone(); + if (player.getBoard().isMagicsZoneEmpty()) System.out.println("There isn't any spell and trap card."); + else { + for (int i = 1; i < magicsZone.length; i++) { + if (magicsZone[i] != null) { + printCard(startNumber, magicsZone[i]); + ++startNumber; + } + } + } + + return startNumber; + } + + public static String findNumberOfCardsToChoose() { + System.out.println("How many cards do you want to choose to destroy?"); + return Utils.getScanner().nextLine(); + } + + public static void showFaceUpMonsterCards(Player turnPlayer, Player notTurnPlayer) { + System.out.println("your face up monster cards:"); + int endNumber = showEachPlayerFaceUpMonsterCards(turnPlayer.getBoard(), 1); + System.out.println("opponent face up monster cards:"); + showEachPlayerFaceUpMonsterCards(notTurnPlayer.getBoard(), endNumber); + } + + private static int showEachPlayerFaceUpMonsterCards(Board board, int startNumber) { + if (board.getNumberOfFaceUpMonsterCards() == 0) { + System.out.println("There isn't any face up monster card."); + return startNumber; + } + + MonsterCard[] monstersZone = board.getMonstersZone(); + for (int i = 1; i < monstersZone.length; i++) { + MonsterCard monsterCard = monstersZone[i]; + if (monsterCard.getCardFaceUp()) { + printCard(startNumber, monsterCard); + ++startNumber; + } + } + + return startNumber; + } +} diff --git a/src/main/main.iml b/src/main/main.iml new file mode 100644 index 0000000..2185ddd --- /dev/null +++ b/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/cards/Monster Upgraded.csv b/src/main/resources/cards/Monster Upgraded.csv new file mode 100644 index 0000000..eae794e --- /dev/null +++ b/src/main/resources/cards/Monster Upgraded.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARTH,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARTH,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,FIRE,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/src/main/resources/cards/Monster.csv b/src/main/resources/cards/Monster.csv new file mode 100644 index 0000000..8c45a5c --- /dev/null +++ b/src/main/resources/cards/Monster.csv @@ -0,0 +1,43 @@ +Name,Level,Attribute, Monster Type , Card Type ,Atk,Def,Description,Price +Battle OX,4,EARHT,Beast-Warrior,Normal,1700,1000,"A monster with tremendous power, it destroys enemies with a swing of its axe.",2900 +Axe Raider,4,EARHT,Warrior,Normal,1700,1150,An axe-wielding monster of tremendous strength and agility.,3100 +Yomi Ship,3,WATER,Aqua,Effect,800,1400,If this card is destroyed by battle and sent to the GY: Destroy the monster that destroyed this card.,1700 +Horn Imp,4,DARK,Fiend,Normal,1300,1000,"A small fiend that dwells in the dark, its single horn makes it a formidable opponent.",2500 +Silver Fang,3,EARTH,Beast,Normal,1200,800,"A snow wolf that's beautiful to the eye, but absolutely vicious in battle.",1700 +Suijin,7,WATER,Aqua,Effect,2500,2400,"During damage calculation in your opponent's turn, if this card is being attacked: You can target the attacking monster; make that target's ATK 0 during damage calculation only (this is a Quick Effect). This effect can only be used once while this card is face-up on the field.",8700 +Fireyarou,4,FIRE,Pyro,Normal,1300,1000,A malevolent creature wrapped in flames that attacks enemies with intense fire.,2500 +Curtain of the dark ones,2,DARK,Spellcaster,Normal,600,500,"A curtain that a spellcaster made, it is said to raise a dark power.",700 +Feral Imp,4,DARK,Fiend,Normal,1300,1400,"A playful little fiend that lurks in the dark, waiting to attack an unwary enemy.",2800 +Dark magician,7,DARK,Spellcaster,Normal,2500,2100,The ultimate wizard in terms of attack and defense.,8300 +Wattkid,3,LIGHT,Thunder,Normal,1000,500,A creature that electrocutes opponents with bolts of lightning.,1300 +Baby dragon,3,WIND,Dragon,Normal,1200,700,"Much more than just a child, this dragon is gifted with untapped power.",1600 +Hero of the east,3,EARTH,Warrior,Normal,1100,1000,Feel da strength ah dis sword-swinging samurai from da Far East.,1700 +Battle warrior,3,EARTH,Warrior,Normal,700,1000,A warrior that fights with his bare hands!!!,1300 +Crawling dragon,5,EARTH,Dragon,Normal,1600,1400,"This weakened dragon can no longer fly, but is still a deadly force to be reckoned with.",3900 +Flame manipulator,3,FIRE,Spellcaster,Normal,900,1000,"This Spellcaster attacks enemies with fire-related spells such as ""Sea of Flames"" and ""Wall of Fire"".",1500 +Blue-Eyes white dragon,8,LIGHT,Dragon,Normal,3000,2500,"This legendary dragon is a powerful engine of destruction. Virtually invincible, very few have faced this awesome creature and lived to tell the tale.",11300 +Crab Turtle,8,WATER,Aqua,Ritual,2550,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Turtle Oath"". You must also offer monsters whose total Level Stars equal 8 or more as a Tribute from the field or your hand.",10200 +Skull Guardian,7,LIGHT,Warrior,Ritual,2050,2500,"This monster can only be Ritual Summoned with the Ritual Spell Card, ""Novox's Prayer"". You must also offer monsters whose total Level Stars equal 7 or more as a Tribute from the field or your hand.",7900 +Slot Machine,7,DARK,Machine,Normal,2000,2300,The machine's ability is said to vary according to its slot results.,7500 +Haniwa,2,EARTH,Rock,Normal,500,500,An earthen figure that protects the tomb of an ancient ruler.,600 +Man-Eater Bug,2,EARTH,Insect,Effect,450,600,FLIP: Target 1 monster on the field; destroy that target.,600 +Gate Guardian,11,DARK,Warrior,Effect,3750,3400,"Cannot be Normal Summoned/Set. Must first be Special Summoned (from your hand) by Tributing 1 ""Sanga of the Thunder"", ""Kazejin"", and ""Suijin"".",20000 +Scanner,1,LIGHT,Machine,Effect,0,0,"Once per turn, you can select 1 of your opponent's monsters that is removed from play. Until the End Phase, this card's name is treated as the selected monster's name, and this card has the same Attribute, Level, ATK, and DEF as the selected monster. If this card is removed from the field while this effect is applied, remove it from play.",8000 +Bitron,2,EARTH,Cyberse,Normal,200,2000,A new species found in electronic space. There's not much information on it.,1000 +Marshmallon,3,LIGHT,Fairy,Effect,300,500,"Cannot be destroyed by battle. After damage calculation, if this card was attacked, and was face-down at the start of the Damage Step: The attacking player takes 1000 damage.",700 +Beast King Barbaros,8,EARTH,Beast-Warrior,Effect,3000,1200,"You can Normal Summon/Set this card without Tributing, but its original ATK becomes 1900. You can Tribute 3 monsters to Tribute Summon (but not Set) this card. If Summoned this way: Destroy all cards your opponent controls.",9200 +Texchanger,1,DARK,Cyberse,Effect,100,100,"Once per turn, when your monster is targeted for an attack: You can negate that attack, then Special Summon 1 Cyberse Normal Monster from your hand, Deck, or GY.",200 +Leotron ,4,EARTH,Cyberse,Normal,2000,0,A territorial electronic monster that guards its own domain.,2500 +The Calculator,2,LIGHT,Thunder,Effect,0,0,The ATK of this card is the combined Levels of all face-up monsters you control x 300.,8000 +Alexandrite Dragon,4,LIGHT,Dragon,Normal,2000,100,"Many of the czars' lost jewels can be found in the scales of this priceless dragon. Its creator remains a mystery, along with how they acquired the imperial treasures. But whosoever finds this dragon has hit the jackpot... whether they know it or not.",2600 +Mirage Dragon,4,LIGHT,Dragon,Effect,1600,600,Your opponent cannot activate Trap Cards during the Battle Phase.,2500 +Herald of Creation,4,LIGHT,Spellcaster,Effect,1800,600,"Once per turn: You can discard 1 card, then target 1 Level 7 or higher monster in your Graveyard; add that target to your hand.",2700 +Exploder Dragon,3,EARTH,Dragon,Effect,1000,0,If this card is destroyed by battle and sent to the Graveyard: Destroy the monster that destroyed it. Neither player takes any battle damage from attacks involving this attacking card.,1000 +Warrior Dai Grepher,4,EARTH,Warrior,Normal,1700,1600,The warrior who can manipulate dragons. Nobody knows his mysterious past.,3400 +Dark Blade,4,DARK,Warrior,Normal,1800,1500,"They say he is a dragon-manipulating warrior from the dark world. His attack is tremendous, using his great swords with vicious power.",3500 +Wattaildragon,6,LIGHT,Dragon,Normal,2500,1000,"Capable of indefinite flight. Attacks by wrapping its body with electricity and ramming into opponents. +IMPORTANT: Capturing the ""Wattaildragon"" is forbidden by the Ancient Rules and is a Level 6 offense, the minimum sentence for which is imprisonment for no less than 2500 heliocycles.",5800 +"Terratiger, the Empowered Warrior",4,EARTH,Warrior,Effect,1800,1200,When this card is Normal Summoned: You can Special Summon 1 Level 4 or lower Normal Monster from your hand in Defense Position.,3200 +The Tricky,5,WIND,Spellcaster,Effect,2000,1200,You can Special Summon this card (from your hand) by discarding 1 card.,4300 +Spiral Serpent,8,WATER,Sea Serpent,Normal,2900,2900,"When huge whirlpools lay cities asunder, it is the hunger of this sea serpent at work. No one has ever escaped its dreaded Spiral Wave to accurately describe the terror they experienced.",11700 +Command Knight,4,Fire,Warrior,Effect,1000,1000,"All Warrior-Type monsters you control gain 400 ATK. If you control another monster, monsters your opponent controls cannot target this card for an attack.",2100 \ No newline at end of file diff --git a/src/main/resources/cards/SpellTrap.csv b/src/main/resources/cards/SpellTrap.csv new file mode 100644 index 0000000..e536e99 --- /dev/null +++ b/src/main/resources/cards/SpellTrap.csv @@ -0,0 +1,38 @@ +Name,Type ,Icon (Property),Description,Status,Price +Trap Hole,Trap,Normal,When your opponent Normal or Flip Summons 1 monster with 1000 or more ATK: Target that monster; destroy that target.,Unlimited,2000 +Mirror Force,Trap,Normal,When an opponent's monster declares an attack: Destroy all your opponent's Attack Position monsters.,Unlimited,2000 +Magic Cylinder,Trap,Normal,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, and if you do, inflict damage to your opponent equal to its ATK.",Unlimited,2000 +Mind Crush,Trap,Normal,"Declare 1 card name; if that card is in your opponent's hand, they must discard all copies of it, otherwise you discard 1 random card.",Unlimited,2000 +Torrential Tribute,Trap,Normal,When a monster(s) is Summoned: Destroy all monsters on the field.,Unlimited,2000 +Time Seal,Trap,Normal,Skip the Draw Phase of your opponent's next turn.,Limited,2000 +Negate Attack,Trap,Counter,"When an opponent's monster declares an attack: Target the attacking monster; negate the attack, then end the Battle Phase.",Unlimited,3000 +Solemn Warning,Trap,Counter,"When a monster(s) would be Summoned, OR when a Spell/Trap Card, or monster effect, is activated that includes an effect that Special Summons a monster(s): Pay 2000 LP; negate the Summon or activation, and if you do, destroy it.",Unlimited,3000 +Magic Jamamer,Trap,Counter,"When a Spell Card is activated: Discard 1 card; negate the activation, and if you do, destroy it.",Unlimited,3000 +Call of The Haunted,Trap,Continuous,"Activate this card by targeting 1 monster in your GY; Special Summon that target in Attack Position. When this card leaves the field, destroy that monster. When that monster is destroyed, destroy this card.",Unlimited,3500 +Vanity's Emptiness,Trap,Continuous,Neither player can Special Summon monsters. If a card is sent from the Deck or the field to your Graveyard: Destroy this card.,Limited,3500 +Wall of Revealing Light,Trap,Continuous,Activate by paying any multiple of 1000 Life Points. Monsters your opponent controls cannot attack if their ATK is less than or equal to the amount you paid.,Limited,3500 +Monster Reborn,Spell,Normal,Target 1 monster in either GY; Special Summon it.,Limited,2500 +Terraforming,Spell,Normal,Add 1 Field Spell from your Deck to your hand.,Limited,2500 +Pot of Greed,Spell,Normal,Draw 2 cards.,Limited,2500 +Raigeki,Spell,Normal,Destroy all monsters your opponent controls.,Limited,2500 +Change of Heart,Spell,Normal,Target 1 monster your opponent controls; take control of it until the End Phase.,Limited,2500 +Swords of Revealing Light,Spell,Normal,"After this card's activation, it remains on the field, but destroy it during the End Phase of your opponent's 3rd turn. When this card is activated: If your opponent controls a face-down monster, flip all monsters they control face-up. While this card is face-up on the field, your opponent's monsters cannot declare an attack.",Unlimited,2500 +Harpie's Feather Duster,Spell,Normal,Destroy all Spells and Traps your opponent controls.,Limited,2500 +Dark Hole,Spell,Normal,Destroy all monsters on the field.,Unlimited,2500 +Supply Squad,Spell,Continuous,"Once per turn, if a monster(s) you control is destroyed by battle or card effect: Draw 1 card.",Unlimited,4000 +Spell Absorption,Spell,Continuous,"Each time a Spell Card is activated, gain 500 Life Points immediately after it resolves.",Unlimited,4000 +Messenger of peace,Spell,Continuous,"Monsters with 1500 or more ATK cannot declare an attack. Once per turn, during your Standby Phase, pay 100 LP or destroy this card.",Unlimited,4000 +Twin Twisters,Spell,Quick-play,"Discard 1 card, then target up to 2 Spells/Traps on the field; destroy them.",Unlimited,3500 +Mystical space typhoon,Spell,Quick-play,Target 1 Spell/Trap on the field; destroy that target.,Unlimited,3500 +Ring of defense,Spell,Quick-play,When a Trap effect that inflicts damage is activated: Make that effect damage 0.,Unlimited,3500 +Yami,Spell,Field,"All Fiend and Spellcaster monsters on the field gain 200 ATK/DEF, also all Fairy monsters on the field lose 200 ATK/DEF.",Unlimited,4300 +Forest,Spell,Field,"All Insect, Beast, Plant, and Beast-Warrior monsters on the field gain 200 ATK/DEF.",Unlimited,4300 +Closed Forest,Spell,Field,All Beast-Type monsters you control gain 100 ATK for each monster in your Graveyard. Field Spell Cards cannot be activated. Field Spell Cards cannot be activated during the turn this card is destroyed.,Unlimited,4300 +Umiiruka,Spell,Field,Increase the ATK of all WATER monsters by 500 points and decrease their DEF by 400 points.,Unlimited,4300 +Sword of dark destruction,Spell,Equip,A DARK monster equipped with this card increases its ATK by 400 points and decreases its DEF by 200 points.,Unlimited,4300 +Black Pendant,Spell,Equip,The equipped monster gains 500 ATK. When this card is sent from the field to the Graveyard: Inflict 500 damage to your opponent.,Unlimited,4300 +United We Stand,Spell,Equip,The equipped monster gains 800 ATK/DEF for each face-up monster you control.,Unlimited,4300 +Magnum Shield,Spell,Equip,"Equip only to a Warrior-Type monster. Apply this effect, depending on its battle position. +● Attack Position: It gains ATK equal to its original DEF. +● Defense Position: It gains DEF equal to its original ATK.",Unlimited,4300 +Advanced Ritual Art,Spell,Ritual,This card can be used to Ritual Summon any 1 Ritual Monster. You must also send Normal Monsters from your Deck to the Graveyard whose total Levels equal the Level of that Ritual Monster.,Unlimited,3000 \ No newline at end of file diff --git a/src/main/resources/players/amir.json b/src/main/resources/players/amir.json new file mode 100644 index 0000000..867f62c --- /dev/null +++ b/src/main/resources/players/amir.json @@ -0,0 +1,17 @@ +{ + "boughtCards": [ + { + "name": "Battle OX" + }, + { + "name": "Suijin" + } + ], + "allMainDecks": [], + "sideDeck": {}, + "username": "amir", + "password": "12345", + "nickname": "amir", + "score": 0, + "money": 88400 +} \ No newline at end of file diff --git a/src/main/resources/players/parsa.json b/src/main/resources/players/parsa.json new file mode 100644 index 0000000..2825eb1 --- /dev/null +++ b/src/main/resources/players/parsa.json @@ -0,0 +1,10 @@ +{ + "boughtCards": [], + "allMainDecks": [], + "sideDeck": {}, + "username": "parsa", + "password": "newPass", + "nickname": "P", + "score": 0, + "money": 100000 +} \ No newline at end of file diff --git a/src/model/Card.java b/src/model/Card.java index 5180c5d..d9f7a94 100644 --- a/src/model/Card.java +++ b/src/model/Card.java @@ -81,4 +81,4 @@ public boolean isCardFaceUp() { //public void callCard(){} -} +} \ No newline at end of file diff --git a/src/scoreboardmenu/ScoreboardView.java b/src/scoreboardmenu/ScoreboardView.java new file mode 100644 index 0000000..fb3dd22 --- /dev/null +++ b/src/scoreboardmenu/ScoreboardView.java @@ -0,0 +1,42 @@ +package scoreboardmenu; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ScoreboardView { + public static Scanner scanner = new Scanner(System.in); + private static ScoreboardView instance; + private ScoreboardView() { + } + public static ScoreboardView getInstance() { + if (instance == null) + instance = new ScoreboardView(); + return instance; + } + + public void runScoreboard() { + String command; + while (true) { + command = scanner.nextLine().replaceAll("\\s+", " "); + switch (command) { + case "scoreboard show": + Scoreboard.getInstance().showScoreboard(); + break; + case "menu show-current": + ScoreboardOutput.getInstance().showMessage("Scoreboard Menu"); + break; + case "menu exit": + MainMenuView.mainMenuView; + default: + ScoreboardOutput.getInstance().showMessage("invalid command"); + } + } + } + + private Matcher findMatcher(String input, String regex) { + + Pattern pattern = Pattern.compile(regex); + return pattern.matcher(input); + } +} diff --git a/src/test/java/controller/ImportExportMenuControllerTest.java b/src/test/java/controller/ImportExportMenuControllerTest.java new file mode 100644 index 0000000..aea2298 --- /dev/null +++ b/src/test/java/controller/ImportExportMenuControllerTest.java @@ -0,0 +1,140 @@ +package controller; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import controller.Database; +import controller.MenuTest; +import controller.importexportmenu.ImportExportMenuController; +import controller.importexportmenu.ImportExportMenuMessages; +import model.cards.Card; +import org.apache.commons.io.FileUtils; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +class ImportExportMenuControllerTest extends MenuTest { + + @Test + void findCommandEnterAMenuMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + + result = ImportExportMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("menu exit"); + Assertions.assertEquals(ImportExportMenuMessages.EXIT_IMPORT_EXPORT_MENU, result); + + result = ImportExportMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ImportExportMenuMessages.SHOW_MENU, result); + + result = ImportExportMenuController.findCommand("menu"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandImportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("import cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_FILE, result); + + createCardJsonFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.AVAILABLE_CARD, result); + + Card.getAllCards().remove("Battle OX"); + removeNameValueFromJsonCardFile("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Battle OX"); + Card.getAllCards().remove("Battle OX"); + result = ImportExportMenuController.findCommand("import card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Battle OX.json")); + + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + removeNameValueFromJsonCardFile("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_FILE, result); + + Database.prepareGame(); + createCardJsonFile("Trap Hole"); + Card.getAllCards().remove("Trap Hole"); + result = ImportExportMenuController.findCommand("import card Trap Hole"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + + FileUtils.deleteQuietly(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/database/cards/Trap Hole.json")); + } + + void createCardJsonFile(String cardName) { + try { + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(Card.getCardByName(cardName))); + fileWriter.close(); + } catch (IOException ignored) { + } + } + + void removeNameValueFromJsonCardFile(String cardName) { + JSONParser parser = new JSONParser(); + try { + Object object = parser.parse(new FileReader("src/database/cards/" + cardName + ".json")); + JSONObject jsonObject = (JSONObject) object; + jsonObject.remove("name"); + FileWriter fileWriter = new FileWriter("src/database/cards/" + cardName + ".json"); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + fileWriter.write(gson.toJson(jsonObject)); + fileWriter.close(); + } catch (Exception ignored) { + } + } + + @Test + void findCommandExportCardMethod() { + ImportExportMenuMessages result = ImportExportMenuController.findCommand("export cardBattle OX "); + Assertions.assertEquals(ImportExportMenuMessages.INVALID_COMMAND, result); + + result = ImportExportMenuController.findCommand("export card A"); + Assertions.assertEquals(ImportExportMenuMessages.UNAVAILABLE_CARD, result); + + result = ImportExportMenuController.findCommand("export card Battle OX"); + Assertions.assertEquals(ImportExportMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/src/test/java/controller/LoginMenuControllerTest.java b/src/test/java/controller/LoginMenuControllerTest.java new file mode 100644 index 0000000..b095e9e --- /dev/null +++ b/src/test/java/controller/LoginMenuControllerTest.java @@ -0,0 +1,87 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.loginmenu.LoginMenuMessages; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; + +class LoginMenuControllerTest extends MenuTest { + @Test + void findCommandEnterAMenuMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("menu enter LogIn menU"); + Assertions.assertEquals(LoginMenuMessages.INVALID_NAVIGATION, result); + + result = LoginMenuController.findCommand("menu enter MaIn MenU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + + result = LoginMenuController.findCommand("menu enter DUEL MENU"); + Assertions.assertEquals(LoginMenuMessages.FIRST_LOGIN, result); + } + + @Test + void findCommandCheckCreateUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user create --username John 1 --nickname Johny --password 12345"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user create --U John1 --nickname Johny1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --username John2 --P 12345 --nickname Johny2"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny3 --username John3 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --N Johny4 --password 12345 --U John4"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --username John5 --nickname Johny5"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --password 12345 --nickname Johny6 --username John6"); + Assertions.assertEquals(LoginMenuMessages.USER_CREATED, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John6 --N Johny6"); + Assertions.assertEquals(LoginMenuMessages.USERNAME_EXISTS, result); + + result = LoginMenuController.findCommand("user create --P 12345 --U John7 --nickname Johny6"); + Assertions.assertEquals(LoginMenuMessages.NICKNAME_EXISTS, result); + } + + @Test + void findCommandCheckLoginUserMethod() { + LoginMenuMessages result = LoginMenuController.findCommand("user login --username John 12 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.INVALID_COMMAND, result); + + result = LoginMenuController.findCommand("user login --username John12 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + + result = LoginMenuController.findCommand("user login --username John2 --password 123456"); + Assertions.assertEquals(LoginMenuMessages.UNMATCHED_USERNAME_AND_PASSWORD, result); + + result = LoginMenuController.findCommand("user login --username John1 --password 12345"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + + result = LoginMenuController.findCommand("user login --password 12345 --username John1"); + Assertions.assertEquals(LoginMenuMessages.USER_LOGGED_IN, result); + } + + @Test + void loginUser() { + Utils.resetScanner("user logout\n"); + ByteArrayOutputStream outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --password 12345 --username John1"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + + Utils.resetScanner("user logout\n"); + outContent = Utils.setByteArrayOutputStream(); + LoginMenuController.loginUser("user login --username John1 --password 12345"); + Assertions.assertEquals("user logged out successfully!\n", outContent.toString()); + } +} \ No newline at end of file diff --git a/src/test/java/controller/MenuTest.java b/src/test/java/controller/MenuTest.java new file mode 100644 index 0000000..5df1b3c --- /dev/null +++ b/src/test/java/controller/MenuTest.java @@ -0,0 +1,20 @@ +package controller; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; + +import java.io.File; +import java.io.IOException; + +public class MenuTest { + @BeforeAll + static void prepareGame() { + Database.prepareGame(); + } + + @AfterAll + static void deletePlayersDirectory() throws IOException { + FileUtils.deleteDirectory(new File("/Users/AMF/Desktop/Yu-Gi-Oh game/Yu-Gi-Oh game/src/main/resources/players")); + } +} \ No newline at end of file diff --git a/src/test/java/controller/ProfileMenuTest.java b/src/test/java/controller/ProfileMenuTest.java new file mode 100644 index 0000000..ddad54d --- /dev/null +++ b/src/test/java/controller/ProfileMenuTest.java @@ -0,0 +1,57 @@ +package controller; + +import controller.profilemenu.ProfileMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import controller.profilemenu.ProfileMenuController; + +public class ProfileMenuTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + String userName = "parsa"; + String password = "123"; + String nickname = "P"; + new Player(userName, password, nickname); + } + + @Test + public void changeName() { + Player player = Player.getPlayerByUsername("parsa"); + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --nickname newname"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + Assertions.assertEquals("newname", player.getNickname()); + result = profileMenuController.findCommand("profile change --nickname P"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_NICKNAME_DONE, result); + } + + @Test + public void changePassword() { + Player player = Player.getPlayerByUsername("parsa"); + + ProfileMenuController profileMenuController = new ProfileMenuController(player); + ProfileMenuMessages result = profileMenuController.findCommand("profile change --password --current 12 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.WRONG_CURRENT_PASSWORD, result); + Assertions.assertEquals("123", player.getPassword()); + + result = profileMenuController.findCommand("profile change --password --current 123 --new newPass"); + Assertions.assertEquals(ProfileMenuMessages.CHANGE_PASSWORD_DONE, result); + Assertions.assertEquals("newPass", player.getPassword()); + } + + @Test + public void allError() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.INVALID_COMMAND, profileMenuController.findCommand("profile")); + Assertions.assertEquals(ProfileMenuMessages.CANT_NAVIGATE_MENU, profileMenuController.findCommand("loginmenu enter")); + } + + @Test + public void checkExit() { + ProfileMenuController profileMenuController = new ProfileMenuController(Player.getPlayerByUsername("parsa")); + Assertions.assertEquals(ProfileMenuMessages.EXIT_MENU , profileMenuController.findCommand("menu exit")); + } +} diff --git a/src/test/java/controller/ShopMenuControllerTest.java b/src/test/java/controller/ShopMenuControllerTest.java new file mode 100644 index 0000000..58d998d --- /dev/null +++ b/src/test/java/controller/ShopMenuControllerTest.java @@ -0,0 +1,77 @@ +package controller; + +import controller.loginmenu.LoginMenuController; +import controller.shopmenu.ShopMenuController; +import controller.shopmenu.ShopMenuMessages; +import model.Player; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ShopMenuControllerTest extends MenuTest { + + @BeforeAll + static void createPlayer() { + LoginMenuController.findCommand("user create --username John --P 12345 --nickname Johny"); + } + + @Test + void findCommandEnterAMenuMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu enter Login Menu "); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("menu enter LOGIN Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter main Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DuEl MEnu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter DECk MeNu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter Scoreboard MENU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter profilE MeNU"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ShoP Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + + result = shopMenuController.findCommand("menu enter ImportExport Menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_NAVIGATION, result); + } + + @Test + void findCommandTestSingleCommands() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("menu exit"); + Assertions.assertEquals(ShopMenuMessages.EXIT_SHOP_MENU, result); + + result = shopMenuController.findCommand("menu show-current"); + Assertions.assertEquals(ShopMenuMessages.SHOW_MENU, result); + + result = shopMenuController.findCommand("menu"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + } + + @Test + void findCommandBuyACardMethod() { + ShopMenuController shopMenuController = new ShopMenuController(Player.getPlayerByUsername("John")); + + ShopMenuMessages result = shopMenuController.findCommand("shop buy:)"); + Assertions.assertEquals(ShopMenuMessages.INVALID_COMMAND, result); + + result = shopMenuController.findCommand("shop buy A"); + Assertions.assertEquals(ShopMenuMessages.UNAVAILABLE_CARD, result); + + result = shopMenuController.findCommand("shop buy Battle OX"); + Assertions.assertEquals(ShopMenuMessages.EMPTY, result); + } +} \ No newline at end of file diff --git a/src/test/test.iml b/src/test/test.iml new file mode 100644 index 0000000..c2315e9 --- /dev/null +++ b/src/test/test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file