diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..1c2fda5
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/libraries/checkstyle_8_36_2_all.xml b/.idea/libraries/checkstyle_8_36_2_all.xml
new file mode 100644
index 0000000..598585c
--- /dev/null
+++ b/.idea/libraries/checkstyle_8_36_2_all.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..0cafb79
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f576a4e
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..a77990e
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..9661ac7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4ea9cb4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,44 @@
+
+
+# Tema POO - GwentStone
+
+

+
+#### Assignment Link: [https://ocw.cs.pub.ro/courses/poo-ca-cd/teme/tema](https://ocw.cs.pub.ro/courses/poo-ca-cd/teme/tema)
+
+
+## Skel Structure
+
+* src/
+ * checker/ - checker files
+ * fileio/ - contains classes used to read data from the json files
+ * main/
+ * Main - the Main class runs the checker on your implementation. Add the entry point to your implementation in it. Run Main to test your implementation from the IDE or from command line.
+ * Test - run the main method from Test class with the name of the input file from the command line and the result will be written
+ to the out.txt file. Thus, you can compare this result with ref.
+* input/ - contains the tests in JSON format
+* ref/ - contains all reference output for the tests in JSON format
+
+## Tests
+
+1. test01_game_start - 3p
+2. test02_place_card - 4p
+3. test03_place_card_invalid - 4p
+4. test04_use_env_card - 4p
+5. test05_use_env_card_invalid - 4p
+6. test06_attack_card - 4p
+7. test07_attack_card_invalid - 4p
+8. test08_use_card_ability - 4p
+9. test09_use_card_ability_invalid -4p
+10. test10_attack_hero - 4p
+11. test11_attack_hero_invalid - 4p
+12. test12_use_hero_ability_1 - 4p
+13. test13_use_hero_ability_2 - 4p
+14. test14_use_hero_ability_invalid_1 - 4p
+15. test15_use_hero_ability_invalid_2 - 4p
+16. test16_multiple_games_valid - 5p
+17. test17_multiple_games_invalid - 6p
+18. test18_big_game - 10p
+
+
+
diff --git a/checkstyle.txt b/checkstyle.txt
new file mode 100644
index 0000000..5eee862
--- /dev/null
+++ b/checkstyle.txt
@@ -0,0 +1,2 @@
+Starting audit...
+Audit done.
diff --git a/input/test01_game_start.json b/input/test01_game_start.json
new file mode 100644
index 0000000..425dc6a
--- /dev/null
+++ b/input/test01_game_start.json
@@ -0,0 +1,291 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 5,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 5,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 0,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 1230021,
+ "playerOneHero": {
+ "mana": 2,
+ "description": "Premium card: An army is not sufficient, he is ready obliterate, it is time for chaos.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Premium card: Time to show who we are, the low-class was never scared of you.",
+ "colors": [
+ "Brown",
+ "Pink",
+ "Purple"
+ ],
+ "name": "King Mudface"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerTurn"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test02_place_card.json b/input/test02_place_card.json
new file mode 100644
index 0000000..72e38f4
--- /dev/null
+++ b/input/test02_place_card.json
@@ -0,0 +1,487 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 0,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 4214251,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Premium card: Glory to all we see, glory to all he is, glory to everyone who will try to escape him.",
+ "colors": [
+ "Black",
+ "Red",
+ "Grey"
+ ],
+ "name": "Lord Royce"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Premium card: Her majesty rule is absolute, every non-believer will suffer.",
+ "colors": [
+ "Black",
+ "Red"
+ ],
+ "name": "Empress Thorina"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test03_place_card_invalid.json b/input/test03_place_card_invalid.json
new file mode 100644
index 0000000..3fdb5b7
--- /dev/null
+++ b/input/test03_place_card_invalid.json
@@ -0,0 +1,515 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 0,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 222890,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Premium card: An army is not sufficient, he is ready obliterate, it is time for chaos.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 2
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test04_use_environment_card.json b/input/test04_use_environment_card.json
new file mode 100644
index 0000000..90bc4e9
--- /dev/null
+++ b/input/test04_use_environment_card.json
@@ -0,0 +1,482 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 0,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 666666,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Premium card: Glory to all we see, glory to all he is, glory to everyone who will try to escape him.",
+ "colors": [
+ "Black",
+ "Red",
+ "Grey"
+ ],
+ "name": "Lord Royce"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Standard card: His voice is tremor, his ways are dirty, but true to his purpose.",
+ "colors": [
+ "Brown",
+ "Pink",
+ "Purple"
+ ],
+ "name": "King Mudface"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test05_use_environment_card_invalid.json b/input/test05_use_environment_card_invalid.json
new file mode 100644
index 0000000..0521b8b
--- /dev/null
+++ b/input/test05_use_environment_card_invalid.json
@@ -0,0 +1,888 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 15,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 3,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 15,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 179485,
+ "playerOneHero": {
+ "mana": 2,
+ "description": "Premium card: An army is not sufficient, he is ready obliterate, it is time for chaos.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Standard card: Every ancestor reached glory, now it is his time to rule.",
+ "colors": [
+ "Yellow",
+ "Brown"
+ ],
+ "name": "Lord Royce"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 1,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 1,
+ "y": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 3
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test06_attack_card.json b/input/test06_attack_card.json
new file mode 100644
index 0000000..eb0946f
--- /dev/null
+++ b/input/test06_attack_card.json
@@ -0,0 +1,488 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 9932921,
+ "playerOneHero": {
+ "mana": 2,
+ "description": "Standard card: Every ancestor reached glory, now it is his time to rule.",
+ "colors": [
+ "Yellow",
+ "Brown"
+ ],
+ "name": "Lord Royce"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Premium card: Her majesty rule is absolute, every non-believer will suffer.",
+ "colors": [
+ "White",
+ "Black",
+ "Grey"
+ ],
+ "name": "Empress Thorina"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 3,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test07_attack_card_invalid.json b/input/test07_attack_card_invalid.json
new file mode 100644
index 0000000..f7d0c71
--- /dev/null
+++ b/input/test07_attack_card_invalid.json
@@ -0,0 +1,582 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 5251213,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Premium card: Time to show who we are, the low-class was never scared of you.",
+ "colors": [
+ "Brown",
+ "Pink",
+ "Purple"
+ ],
+ "name": "King Mudface"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Standard card: Exact precision is her mantra, emotion is for the weak.",
+ "colors": [
+ "Black",
+ "Red"
+ ],
+ "name": "Empress Thorina"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 0
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 3
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 2
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 2
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test08_use_card_ability.json b/input/test08_use_card_ability.json
new file mode 100644
index 0000000..25f060b
--- /dev/null
+++ b/input/test08_use_card_ability.json
@@ -0,0 +1,663 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 882661,
+ "playerOneHero": {
+ "mana": 2,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Premium card: Glory to all we see, glory to all he is, glory to everyone who will try to escape him.",
+ "colors": [
+ "Black",
+ "Red",
+ "Grey"
+ ],
+ "name": "Lord Royce"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 2
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 2
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 2
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 1
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 1
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test09_use_card_ability_invalid.json b/input/test09_use_card_ability_invalid.json
new file mode 100644
index 0000000..1fa9e9d
--- /dev/null
+++ b/input/test09_use_card_ability_invalid.json
@@ -0,0 +1,578 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 124579,
+ "playerOneHero": {
+ "mana": 2,
+ "description": "Standard card: Every ancestor reached glory, now it is his time to rule.",
+ "colors": [
+ "Black",
+ "Red",
+ "Grey"
+ ],
+ "name": "Lord Royce"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Standard card: Exact precision is her mantra, emotion is for the weak.",
+ "colors": [
+ "Black",
+ "Red"
+ ],
+ "name": "Empress Thorina"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test10_attack_hero.json b/input/test10_attack_hero.json
new file mode 100644
index 0000000..08d5c01
--- /dev/null
+++ b/input/test10_attack_hero.json
@@ -0,0 +1,567 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 664666,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 3,
+ "description": "Premium card: Glory to all we see, glory to all he is, glory to everyone who will try to escape him.",
+ "colors": [
+ "Black",
+ "Red",
+ "Grey"
+ ],
+ "name": "Lord Royce"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test11_attack_hero_invalid.json b/input/test11_attack_hero_invalid.json
new file mode 100644
index 0000000..7208315
--- /dev/null
+++ b/input/test11_attack_hero_invalid.json
@@ -0,0 +1,540 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 4,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 4,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 8,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 122952,
+ "playerOneHero": {
+ "mana": 2,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 3,
+ "description": "Standard card: Exact precision is her mantra, emotion is for the weak.",
+ "colors": [
+ "Black",
+ "Red"
+ ],
+ "name": "Empress Thorina"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 1
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test12_use_hero_ability_1.json b/input/test12_use_hero_ability_1.json
new file mode 100644
index 0000000..81e063c
--- /dev/null
+++ b/input/test12_use_hero_ability_1.json
@@ -0,0 +1,444 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 8,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 7,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 4,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 929885,
+ "playerOneHero": {
+ "mana": 1,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 1,
+ "description": "Premium card: Glory to all we see, glory to all he is, glory to everyone who will try to escape him.",
+ "colors": [
+ "Black",
+ "Red",
+ "Grey"
+ ],
+ "name": "Lord Royce"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 1,
+ "y": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test13_use_hero_ability_1_invalid.json b/input/test13_use_hero_ability_1_invalid.json
new file mode 100644
index 0000000..a2a9995
--- /dev/null
+++ b/input/test13_use_hero_ability_1_invalid.json
@@ -0,0 +1,552 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ }
+ ],
+ [
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 0,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 449528,
+ "playerOneHero": {
+ "mana": 2,
+ "description": "Premium card: Her majesty rule is absolute, every non-believer will suffer.",
+ "colors": [
+ "White",
+ "Black",
+ "Grey"
+ ],
+ "name": "Empress Thorina"
+ },
+ "playerTwoHero": {
+ "mana": 3,
+ "description": "Standard card: Every ancestor reached glory, now it is his time to rule.",
+ "colors": [
+ "Yellow",
+ "Brown"
+ ],
+ "name": "Lord Royce"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 3,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test14_use_hero_ability_2.json b/input/test14_use_hero_ability_2.json
new file mode 100644
index 0000000..66ec668
--- /dev/null
+++ b/input/test14_use_hero_ability_2.json
@@ -0,0 +1,456 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 8,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 8,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 4,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 8,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 4,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 519508,
+ "playerOneHero": {
+ "mana": 1,
+ "description": "Standard card: His voice is tremor, his ways are dirty, but true to his purpose.",
+ "colors": [
+ "Brown",
+ "White"
+ ],
+ "name": "King Mudface"
+ },
+ "playerTwoHero": {
+ "mana": 1,
+ "description": "Premium card: Her majesty rule is absolute, every non-believer will suffer.",
+ "colors": [
+ "Black",
+ "Red"
+ ],
+ "name": "Empress Thorina"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test15_use_hero_ability_2_invalid.json b/input/test15_use_hero_ability_2_invalid.json
new file mode 100644
index 0000000..4441452
--- /dev/null
+++ b/input/test15_use_hero_ability_2_invalid.json
@@ -0,0 +1,539 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 7,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 749713,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Standard card: His voice is tremor, his ways are dirty, but true to his purpose.",
+ "colors": [
+ "Brown",
+ "White"
+ ],
+ "name": "King Mudface"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Premium card: An army is not sufficient, he is ready obliterate, it is time for chaos.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 1,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 1,
+ "y": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 2
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test16_multiple_games_valid.json b/input/test16_multiple_games_valid.json
new file mode 100644
index 0000000..1cbee31
--- /dev/null
+++ b/input/test16_multiple_games_valid.json
@@ -0,0 +1,923 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 10,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 4,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 4,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 8,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 10,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 8,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 8,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 229020,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Premium card: An army is not sufficient, he is ready obliterate, it is time for chaos.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Premium card: Time to show who we are, the low-class was never scared of you.",
+ "colors": [
+ "Brown",
+ "Pink",
+ "Purple"
+ ],
+ "name": "King Mudface"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ }
+ ]
+ },
+ {
+ "startGame": {
+ "playerOneDeckIdx": 0,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 935132,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Standard card: His voice is tremor, his ways are dirty, but true to his purpose.",
+ "colors": [
+ "Brown",
+ "Pink",
+ "Purple"
+ ],
+ "name": "King Mudface"
+ },
+ "playerTwoHero": {
+ "mana": 3,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 2
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 2
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 2
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerOneWins"
+ },
+ {
+ "command": "getPlayerTwoWins"
+ },
+ {
+ "command": "getTotalGamesPlayed"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test17_multiple_games_invalid.json b/input/test17_multiple_games_invalid.json
new file mode 100644
index 0000000..015cd7a
--- /dev/null
+++ b/input/test17_multiple_games_invalid.json
@@ -0,0 +1,1001 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 10,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 10,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 8,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 8,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 0,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 339331,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Standard card: Exact precision is her mantra, emotion is for the weak.",
+ "colors": [
+ "White",
+ "Black",
+ "Grey"
+ ],
+ "name": "Empress Thorina"
+ },
+ "playerTwoHero": {
+ "mana": 2,
+ "description": "Standard card: Exact precision is her mantra, emotion is for the weak.",
+ "colors": [
+ "Black",
+ "Red"
+ ],
+ "name": "Empress Thorina"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getTotalGamesPlayed"
+ },
+ {
+ "command": "getPlayerTwoWins"
+ },
+ {
+ "command": "getPlayerOneWins"
+ }
+ ]
+ },
+ {
+ "startGame": {
+ "playerOneDeckIdx": 1,
+ "playerTwoDeckIdx": 1,
+ "shuffleSeed": 615605,
+ "playerOneHero": {
+ "mana": 2,
+ "description": "Premium card: An army is not sufficient, he is ready obliterate, it is time for chaos.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw"
+ },
+ "playerTwoHero": {
+ "mana": 3,
+ "description": "Standard card: Every ancestor reached glory, now it is his time to rule.",
+ "colors": [
+ "Yellow",
+ "Brown"
+ ],
+ "name": "Lord Royce"
+ },
+ "startingPlayer": 2
+ },
+ "actions": [
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 1,
+ "y": 0
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 1
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 3,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getTotalGamesPlayed"
+ },
+ {
+ "command": "getPlayerTwoWins"
+ },
+ {
+ "command": "getPlayerOneWins"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/input/test18_big_game.json b/input/test18_big_game.json
new file mode 100644
index 0000000..db36d6c
--- /dev/null
+++ b/input/test18_big_game.json
@@ -0,0 +1,1089 @@
+{
+ "playerOneDecks": {
+ "nrCardsInDeck": 15,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ ]
+ },
+ "playerTwoDecks": {
+ "nrCardsInDeck": 15,
+ "nrDecks": 2,
+ "decks": [
+ [
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ ]
+ },
+ "games": [
+ {
+ "startGame": {
+ "playerOneDeckIdx": 0,
+ "playerTwoDeckIdx": 0,
+ "shuffleSeed": 510001,
+ "playerOneHero": {
+ "mana": 3,
+ "description": "Standard card: His voice is tremor, his ways are dirty, but true to his purpose.",
+ "colors": [
+ "Brown",
+ "Pink",
+ "Purple"
+ ],
+ "name": "King Mudface"
+ },
+ "playerTwoHero": {
+ "mana": 3,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw"
+ },
+ "startingPlayer": 1
+ },
+ "actions": [
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 0
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 2
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 2
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ }
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 2,
+ "y": 0
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 1
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 2
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0
+ },
+ {
+ "command": "getCardAtPosition",
+ "x": 0,
+ "y": 0
+ },
+ {
+ "command": "getFrozenCardsOnTable"
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2
+ },
+ {
+ "command": "getPlayerTurn"
+ },
+ {
+ "command": "endPlayerTurn"
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 2
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 2,
+ "y": 3
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 1
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ }
+ },
+ {
+ "command": "getCardsOnTable"
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2
+ },
+ {
+ "command": "getTotalGamesPlayed"
+ },
+ {
+ "command": "getPlayerTwoWins"
+ },
+ {
+ "command": "getPlayerOneWins"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/lib/jackson-annotations-2.13.3.jar b/lib/jackson-annotations-2.13.3.jar
new file mode 100644
index 0000000..60a3ddb
Binary files /dev/null and b/lib/jackson-annotations-2.13.3.jar differ
diff --git a/lib/jackson-core-2.13.3.jar b/lib/jackson-core-2.13.3.jar
new file mode 100644
index 0000000..7e2086d
Binary files /dev/null and b/lib/jackson-core-2.13.3.jar differ
diff --git a/lib/jackson-databind-2.13.3.jar b/lib/jackson-databind-2.13.3.jar
new file mode 100644
index 0000000..a27e9d7
Binary files /dev/null and b/lib/jackson-databind-2.13.3.jar differ
diff --git a/lib/lombok.jar b/lib/lombok.jar
new file mode 100644
index 0000000..3a985fe
Binary files /dev/null and b/lib/lombok.jar differ
diff --git a/ref/ref_test01_game_start.json b/ref/ref_test01_game_start.json
new file mode 100644
index 0000000..7ba8278
--- /dev/null
+++ b/ref/ref_test01_game_start.json
@@ -0,0 +1,135 @@
+[
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1,
+ "output": {
+ "mana": 2,
+ "description": "Premium card: An army is not sufficient, he is ready obliterate, it is time for chaos.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw",
+ "health": 30
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2,
+ "output": {
+ "mana": 2,
+ "description": "Premium card: Time to show who we are, the low-class was never scared of you.",
+ "colors": [
+ "Brown",
+ "Pink",
+ "Purple"
+ ],
+ "name": "King Mudface",
+ "health": 30
+ }
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test02_place_card.json b/ref/ref_test02_place_card.json
new file mode 100644
index 0000000..4da00f5
--- /dev/null
+++ b/ref/ref_test02_place_card.json
@@ -0,0 +1,327 @@
+[
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 9
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 11
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test03_place_card_invalid.json b/ref/ref_test03_place_card_invalid.json
new file mode 100644
index 0000000..45920ba
--- /dev/null
+++ b/ref/ref_test03_place_card_invalid.json
@@ -0,0 +1,374 @@
+[
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0,
+ "error": "Cannot place environment card on table."
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0,
+ "error": "Not enough mana to place card on table."
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0,
+ "error": "Not enough mana to place card on table."
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0,
+ "error": "Cannot place environment card on table."
+ },
+ {
+ "command": "placeCard",
+ "handIdx": 0,
+ "error": "Cannot place card on table since row is full."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 10
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 11
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ],
+ []
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2,
+ "output": []
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1,
+ "output": []
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test04_use_environment_card.json b/ref/ref_test04_use_environment_card.json
new file mode 100644
index 0000000..10bb061
--- /dev/null
+++ b/ref/ref_test04_use_environment_card.json
@@ -0,0 +1,183 @@
+[
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 15
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 11
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ }
+ ],
+ [],
+ [],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test05_use_environment_card_invalid.json b/ref/ref_test05_use_environment_card_invalid.json
new file mode 100644
index 0000000..39d56e2
--- /dev/null
+++ b/ref/ref_test05_use_environment_card_invalid.json
@@ -0,0 +1,324 @@
+[
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 3,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 2,
+ "error": "Not enough mana to use environment card."
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 3,
+ "error": "Chosen card is not of type environment."
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 3,
+ "error": "Chosen row does not belong to the enemy."
+ },
+ {
+ "command": "useEnvironmentCard",
+ "handIdx": 0,
+ "affectedRow": 2,
+ "error": "Cannot steal enemy card since the player's row is full."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 17
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 25
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ []
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test06_attack_card.json b/ref/ref_test06_attack_card.json
new file mode 100644
index 0000000..fd27cb1
--- /dev/null
+++ b/ref/ref_test06_attack_card.json
@@ -0,0 +1,247 @@
+[
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 4
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 4
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 0
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test07_attack_card_invalid.json b/ref/ref_test07_attack_card_invalid.json
new file mode 100644
index 0000000..f565697
--- /dev/null
+++ b/ref/ref_test07_attack_card_invalid.json
@@ -0,0 +1,239 @@
+[
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ },
+ "error": "Attacker card is frozen."
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 4
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 3,
+ "y": 0
+ },
+ "error": "Attacked card is not of type 'Tank'."
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 1
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 0
+ },
+ "error": "Attacker card has already attacked this turn."
+ },
+ {
+ "command": "cardUsesAttack",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 1
+ },
+ "error": "Attacked card does not belong to the enemy."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 13
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 12
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ],
+ [],
+ [
+ {
+ "mana": 4,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test08_use_card_ability.json b/ref/ref_test08_use_card_ability.json
new file mode 100644
index 0000000..0405e23
--- /dev/null
+++ b/ref/ref_test08_use_card_ability.json
@@ -0,0 +1,299 @@
+[
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 4
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 4
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 11
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 7
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 4,
+ "attackDamage": 3,
+ "health": 2,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 1,
+ "description": "Standard card: Corruption is easy, you always wanted it, now I help you embrace it.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerDeck",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test09_use_card_ability_invalid.json b/ref/ref_test09_use_card_ability_invalid.json
new file mode 100644
index 0000000..67c79ed
--- /dev/null
+++ b/ref/ref_test09_use_card_ability_invalid.json
@@ -0,0 +1,304 @@
+[
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ },
+ "error": "Attacker card is frozen."
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 0,
+ "y": 0
+ },
+ "error": "Attacked card is not of type 'Tank'."
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 3,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 1,
+ "y": 0
+ },
+ "error": "Attacker card has already attacked this turn."
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 2,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 1
+ },
+ "error": "Attacked card does not belong to the enemy."
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 4
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "cardUsesAbility",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "cardAttacked": {
+ "x": 2,
+ "y": 1
+ },
+ "error": "Attacked card does not belong to the current player."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 14
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 11
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 8,
+ "health": 1,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 3,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test10_attack_hero.json b/ref/ref_test10_attack_hero.json
new file mode 100644
index 0000000..b2cc6ff
--- /dev/null
+++ b/ref/ref_test10_attack_hero.json
@@ -0,0 +1,326 @@
+[
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 4
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1,
+ "output": {
+ "mana": 3,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw",
+ "health": 25
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2,
+ "output": {
+ "mana": 3,
+ "description": "Premium card: Glory to all we see, glory to all he is, glory to everyone who will try to escape him.",
+ "colors": [
+ "Black",
+ "Red",
+ "Grey"
+ ],
+ "name": "Lord Royce",
+ "health": 24
+ }
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 6
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1,
+ "output": {
+ "mana": 3,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Red",
+ "Black",
+ "Purple"
+ ],
+ "name": "General Kocioraw",
+ "health": 20
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2,
+ "output": {
+ "mana": 3,
+ "description": "Premium card: Glory to all we see, glory to all he is, glory to everyone who will try to escape him.",
+ "colors": [
+ "Black",
+ "Red",
+ "Grey"
+ ],
+ "name": "Lord Royce",
+ "health": 12
+ }
+ },
+ {
+ "gameEnded": "Player one killed the enemy hero."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 5
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 7
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test11_attack_hero_invalid.json b/ref/ref_test11_attack_hero_invalid.json
new file mode 100644
index 0000000..f30fb5b
--- /dev/null
+++ b/ref/ref_test11_attack_hero_invalid.json
@@ -0,0 +1,290 @@
+[
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1,
+ "output": {
+ "mana": 2,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw",
+ "health": 30
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2,
+ "output": {
+ "mana": 3,
+ "description": "Standard card: Exact precision is her mantra, emotion is for the weak.",
+ "colors": [
+ "Black",
+ "Red"
+ ],
+ "name": "Empress Thorina",
+ "health": 18
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 2,
+ "y": 1
+ },
+ "error": "Attacker card is frozen."
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 5
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 1,
+ "output": {
+ "mana": 2,
+ "description": "Standard card: Absolute order, a soldier must devote his life to his General.",
+ "colors": [
+ "Green",
+ "Yellow"
+ ],
+ "name": "General Kocioraw",
+ "health": 30
+ }
+ },
+ {
+ "command": "getPlayerHero",
+ "playerIdx": 2,
+ "output": {
+ "mana": 3,
+ "description": "Standard card: Exact precision is her mantra, emotion is for the weak.",
+ "colors": [
+ "Black",
+ "Red"
+ ],
+ "name": "Empress Thorina",
+ "health": 18
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ },
+ "error": "Attacked card is not of type 'Tank'."
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 3,
+ "y": 1
+ },
+ "error": "Attacker card has already attacked this turn."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 14
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 16
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "attackDamage": 4,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test12_use_hero_ability_1.json b/ref/ref_test12_use_hero_ability_1.json
new file mode 100644
index 0000000..e7ca6aa
--- /dev/null
+++ b/ref/ref_test12_use_hero_ability_1.json
@@ -0,0 +1,161 @@
+[
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 6
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 6
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 7,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test13_use_hero_ability_1_invalid.json b/ref/ref_test13_use_hero_ability_1_invalid.json
new file mode 100644
index 0000000..8d20d94
--- /dev/null
+++ b/ref/ref_test13_use_hero_ability_1_invalid.json
@@ -0,0 +1,215 @@
+[
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3,
+ "error": "Selected row does not belong to the enemy."
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 0,
+ "error": "Not enough mana to use hero's ability."
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 2,
+ "error": "Hero has already attacked this turn."
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 1,
+ "error": "Selected row does not belong to the enemy."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 13
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 11
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Standard card: Everything is sacred to him, all is but a gift from the saints.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [],
+ [
+ {
+ "mana": 4,
+ "attackDamage": 1,
+ "health": 8,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 7,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Standard card: The dragon was unleashed, run for your lives.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Red",
+ "Yellow"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test14_use_hero_ability_2.json b/ref/ref_test14_use_hero_ability_2.json
new file mode 100644
index 0000000..7f9d1d9
--- /dev/null
+++ b/ref/ref_test14_use_hero_ability_2.json
@@ -0,0 +1,139 @@
+[
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 8,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 4
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 4
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 8,
+ "health": 6,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [],
+ []
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Standard card: The days are cold and so are we. We hope we can close our eyes again.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test15_use_hero_ability_2_invalid.json b/ref/ref_test15_use_hero_ability_2_invalid.json
new file mode 100644
index 0000000..eea3b88
--- /dev/null
+++ b/ref/ref_test15_use_hero_ability_2_invalid.json
@@ -0,0 +1,277 @@
+[
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3,
+ "error": "Selected row does not belong to the current player."
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 6,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 3,
+ "attackDamage": 7,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 3,
+ "error": "Hero has already attacked this turn."
+ },
+ {
+ "command": "useHeroAbility",
+ "affectedRow": 1,
+ "error": "Selected row does not belong to the current player."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 9
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 10
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [
+ {
+ "mana": 3,
+ "attackDamage": 8,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 5,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 7,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 5,
+ "health": 6,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 6,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 1,
+ "health": 2,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Blue"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test16_multiple_games_valid.json b/ref/ref_test16_multiple_games_valid.json
new file mode 100644
index 0000000..9967f16
--- /dev/null
+++ b/ref/ref_test16_multiple_games_valid.json
@@ -0,0 +1,494 @@
+[
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": []
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "gameEnded": "Player two killed the enemy hero."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 5
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Standard card: Thrown from the highest cliff, revenge will be his glory.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Black",
+ "Yellow"
+ ],
+ "name": "The Ripper"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 1
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ }
+ ]
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 7,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 1
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 7,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 4
+ },
+ {
+ "gameEnded": "Player one killed the enemy hero."
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 4
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 6
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Pink",
+ "Purple"
+ ],
+ "name": "The Cursed One"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Standard card: A drink can always be served, with the blood of his enemies.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ ],
+ [],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 7,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 5,
+ "description": "Premium card: You shall not pass, you shall not prevail, you shall perish.",
+ "colors": [
+ "Black",
+ "White",
+ "Green"
+ ],
+ "name": "Warden"
+ },
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ []
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 1,
+ "description": "Premium card: The fury of hell is upon us, please kill us.",
+ "colors": [
+ "Blue",
+ "Green",
+ "White"
+ ],
+ "name": "Firestorm"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "White"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerOneWins",
+ "output": 1
+ },
+ {
+ "command": "getPlayerTwoWins",
+ "output": 1
+ },
+ {
+ "command": "getTotalGamesPlayed",
+ "output": 2
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test17_multiple_games_invalid.json b/ref/ref_test17_multiple_games_invalid.json
new file mode 100644
index 0000000..44998cd
--- /dev/null
+++ b/ref/ref_test17_multiple_games_invalid.json
@@ -0,0 +1,535 @@
+[
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 0
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "gameEnded": "Player two killed the enemy hero."
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Red",
+ "Blue",
+ "Pink"
+ ],
+ "name": "Berserker"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 1,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Death incarnate. No better time to die than now.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": []
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 1,
+ "attackDamage": 0,
+ "health": 2,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Yellow",
+ "White"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ },
+ {
+ "command": "getTotalGamesPlayed",
+ "output": 1
+ },
+ {
+ "command": "getPlayerTwoWins",
+ "output": 1
+ },
+ {
+ "command": "getPlayerOneWins",
+ "output": 0
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 1
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 3
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 1,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 0
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 1,
+ "y": 1
+ },
+ "error": "Attacked card is not of type 'Tank'."
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 7,
+ "health": 1,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 2
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ },
+ {
+ "gameEnded": "Player one killed the enemy hero."
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 3,
+ "description": "Premium card: Nobody suspects an outcast, not even the Gods.",
+ "colors": [
+ "Black",
+ "White",
+ "Red"
+ ],
+ "name": "The Cursed One"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 1,
+ "description": "Standard card: He has seen everything, his mind has never been asleep since the making of the realm.",
+ "colors": [
+ "Brown",
+ "Blue"
+ ],
+ "name": "Warden"
+ }
+ ],
+ [
+ {
+ "mana": 2,
+ "attackDamage": 6,
+ "health": 3,
+ "description": "Standard card: Trained by the best, nothing will catch him off-guard.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: All is white. My mouth is frozen and I must scream.",
+ "colors": [
+ "White",
+ "Grey",
+ "Black"
+ ],
+ "name": "Winterfell"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getTotalGamesPlayed",
+ "output": 2
+ },
+ {
+ "command": "getPlayerTwoWins",
+ "output": 1
+ },
+ {
+ "command": "getPlayerOneWins",
+ "output": 1
+ }
+]
\ No newline at end of file
diff --git a/ref/ref_test18_big_game.json b/ref/ref_test18_big_game.json
new file mode 100644
index 0000000..b464f1b
--- /dev/null
+++ b/ref/ref_test18_big_game.json
@@ -0,0 +1,465 @@
+[
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 1
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": []
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 3
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 0
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 2,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 3
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 4,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 2,
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 3
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 1
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "useAttackHero",
+ "cardAttacker": {
+ "x": 0,
+ "y": 0
+ },
+ "error": "Attacked card is not of type 'Tank'."
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 1,
+ "output": 5
+ },
+ {
+ "command": "getEnvironmentCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getCardAtPosition",
+ "output": {
+ "mana": 2,
+ "attackDamage": 2,
+ "health": 5,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ },
+ {
+ "command": "getFrozenCardsOnTable",
+ "output": []
+ },
+ {
+ "command": "getPlayerMana",
+ "playerIdx": 2,
+ "output": 1
+ },
+ {
+ "command": "getPlayerTurn",
+ "output": 2
+ },
+ {
+ "gameEnded": "Player one killed the enemy hero."
+ },
+ {
+ "command": "getCardsOnTable",
+ "output": [
+ [
+ {
+ "mana": 2,
+ "attackDamage": 3,
+ "health": 5,
+ "description": "Premium card: Fear him. Your last breath is now.",
+ "colors": [
+ "Purple",
+ "Yellow"
+ ],
+ "name": "Berserker"
+ }
+ ],
+ [
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 4,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Ravished by the winds of hell, no soul is to be forgiven.",
+ "colors": [
+ "Orange",
+ "Red",
+ "Black"
+ ],
+ "name": "The Ripper"
+ },
+ {
+ "mana": 4,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ }
+ ],
+ [
+ {
+ "mana": 4,
+ "attackDamage": 5,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Premium card: No matter how many, his body will fight. Save your breath for the Mountain is strong.",
+ "colors": [
+ "Brown",
+ "Black",
+ "Grey"
+ ],
+ "name": "Goliath"
+ },
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 4,
+ "description": "Standard card: When he is near, close your eyes. They betray your mind.",
+ "colors": [
+ "Yellow",
+ "Orange",
+ "Red"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 3,
+ "attackDamage": 2,
+ "health": 8,
+ "description": "Standard card: A warrior who is never afraid of battle, no matter the costs",
+ "colors": [
+ "Red",
+ "Purple"
+ ],
+ "name": "Goliath"
+ }
+ ],
+ [
+ {
+ "mana": 1,
+ "attackDamage": 1,
+ "health": 3,
+ "description": "Premium card: His presence is not known even by ghosts, success at all costs.",
+ "colors": [
+ "Black",
+ "Grey",
+ "Blue"
+ ],
+ "name": "Sentinel"
+ }
+ ]
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 1,
+ "output": [
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Red",
+ "White",
+ "Grey"
+ ],
+ "name": "Heart Hound"
+ },
+ {
+ "mana": 2,
+ "description": "Premium card: Your mind is ours. Your body is ours. Stop begging.",
+ "colors": [
+ "Green",
+ "Black"
+ ],
+ "name": "Heart Hound"
+ }
+ ]
+ },
+ {
+ "command": "getCardsInHand",
+ "playerIdx": 2,
+ "output": [
+ {
+ "mana": 5,
+ "attackDamage": 4,
+ "health": 3,
+ "description": "Premium card: Insanity is always an option, now it is an absolute.",
+ "colors": [
+ "Red",
+ "Black"
+ ],
+ "name": "Miraj"
+ },
+ {
+ "mana": 2,
+ "attackDamage": 0,
+ "health": 4,
+ "description": "Premium card: The will of Gods has been spoken, obey and you shall be saved...or not.",
+ "colors": [
+ "Green",
+ "Yellow",
+ "Blue"
+ ],
+ "name": "Disciple"
+ }
+ ]
+ },
+ {
+ "command": "getTotalGamesPlayed",
+ "output": 1
+ },
+ {
+ "command": "getPlayerTwoWins",
+ "output": 0
+ },
+ {
+ "command": "getPlayerOneWins",
+ "output": 1
+ }
+]
\ No newline at end of file
diff --git a/src/checker/Checker.java b/src/checker/Checker.java
new file mode 100644
index 0000000..abce9cb
--- /dev/null
+++ b/src/checker/Checker.java
@@ -0,0 +1,168 @@
+package checker;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+public final class Checker {
+ private static int gitScore;
+ private static int readmeScore;
+ private static int totalScore = 0;
+
+ private Checker() {
+ }
+
+ private static void calculateScoreGit() {
+ System.out.print(".GIT score = ");
+
+ Path path = Paths.get(".git");
+ if (Files.exists(path)) {
+ gitScore = CheckerConstants.FIVE_POINTS;
+ System.out.println(gitScore + "/5");
+ } else {
+ gitScore = CheckerConstants.ZERO_POINTS;
+ System.out.println(gitScore + "/5");
+ }
+ }
+
+ private static void calculateScoreReadme() {
+ System.out.println("-----------------------------------------------------");
+ System.out.print("README score = ");
+ Path path1 = Paths.get("README");
+ Path path2 = Paths.get("README.md");
+ Path path3 = Paths.get("README.txt");
+
+ if (Files.exists(path1) || Files.exists(path2) || Files.exists(path3)) {
+ readmeScore = CheckerConstants.FIVE_POINTS;
+ System.out.println(readmeScore + "/5");
+
+ } else {
+ readmeScore = CheckerConstants.ZERO_POINTS;
+ System.out.println(readmeScore + "/5");
+ }
+ }
+
+ /**
+ * This method is used to calculate total score of the implementation and checkstyle
+ */
+ public static void calculateScore() throws IOException {
+ System.out.println();
+ calculateScoreAllTests();
+ int checkstyleScore = calculateScoreCheckstyle();
+ calculateScoreGit();
+ calculateScoreReadme();
+
+ int finalScore = totalScore + gitScore + readmeScore + checkstyleScore;
+ System.out.println("-----------------------------------------------------");
+ System.out.println("FINAL SCORE = " + finalScore + "/100");
+
+ if (finalScore == CheckerConstants.MAX_POINTS) {
+ System.out.println("\nAcum ca ai terminat, sigur esti un..."
+ + " https://www.youtube.com/watch?v=1LZZYemqLyU");
+ }
+ }
+
+ /**
+ * This method is used to calculate the score of checkstyle
+ */
+ private static int calculateScoreCheckstyle() {
+ return Checkstyle.testCheckstyle();
+ }
+
+ /**
+ * This method is used to calculate score of implementation
+ *
+ * 18 tests (80 points maximum)
+ */
+ private static void calculateScoreAllTests() throws IOException {
+ File directory = new File(CheckerConstants.TESTS_PATH);
+ Path path = Paths.get(CheckerConstants.RESULT_PATH);
+ if (!Files.exists(path)) {
+ Files.createDirectories(path);
+ }
+ List listFile = Arrays.asList(Objects.requireNonNull(directory.list()));
+ Collections.sort(listFile);
+ for (String file : listFile) {
+ totalScore += calculateScore(file);
+ }
+
+ System.out.println("-----------------------------------------------------");
+ System.out.println("TESTS = " + totalScore + "/80");
+ }
+
+ /**
+ * This method calculates the score of only one single test
+ * @return the score of that test
+ */
+ public static int calculateScore(final String input) {
+ if (checkOutput(input)) {
+ System.out.print(input + " ");
+ for (int i = 1; i <= CheckerConstants.LEN_LONGEST_TEST_NAME - input.length(); i++) {
+ System.out.print("-");
+ }
+ System.out.println("--------------------------------------------- PASSED (+"
+ + getScoreForTest(input) + ")");
+ return getScoreForTest(input);
+ } else {
+ System.out.print(input + " ");
+ for (int i = 1; i <= CheckerConstants.LEN_LONGEST_TEST_NAME - input.length(); i++) {
+ System.out.print("-");
+ }
+ System.out.println("--------------------------------------------- FAILED (+0)");
+ return 0;
+ }
+ }
+
+ /**
+ * @param file the test you want to check
+ * @return
+ * if the two files are equal or not
+ */
+ private static boolean checkOutput(final String file) {
+ ObjectMapper mapper = new ObjectMapper();
+
+ try {
+ JsonNode output = mapper.readTree(new File(CheckerConstants.OUT_PATH + file));
+ JsonNode ref = mapper.readTree(new File(CheckerConstants.REF_PATH + file));
+ return output.equals(ref);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ /**
+ * @param input the test you want to calculate score for
+ * @return the score of that test
+ */
+ private static int getScoreForTest(final String input) {
+
+ if (input.contains(CheckerConstants.GAME_START)) {
+ return CheckerConstants.GAME_START_POINTS;
+ }
+
+ if (input.contains(CheckerConstants.MULTIPLE_GAMES_VALID)) {
+ return CheckerConstants.MULTIPLE_GAMES_VALID_POINTS;
+ }
+
+ if (input.contains(CheckerConstants.MULTIPLE_GAMES_INVALID)) {
+ return CheckerConstants.MULTIPLE_GAMES_INVALID_POINTS;
+ }
+
+ if (input.contains(CheckerConstants.BIG_GAME)) {
+ return CheckerConstants.BIG_GAME_POINTS;
+ }
+
+ return CheckerConstants.SINGLE_GAME_POINTS;
+ }
+}
diff --git a/src/checker/CheckerConstants.java b/src/checker/CheckerConstants.java
new file mode 100644
index 0000000..52a3d6f
--- /dev/null
+++ b/src/checker/CheckerConstants.java
@@ -0,0 +1,34 @@
+package checker;
+
+/**
+ * The class contains the minimum of constants needed.
+ *
+ * You can define your own constants here or create separate files.
+ */
+public final class CheckerConstants {
+ private CheckerConstants() {
+ }
+
+ // checker constants
+ public static final Integer BIG_TEST_POINTS = 3;
+ public static final Integer MAXIMUM_ERROR_CHECKSTYLE = 30;
+ public static final Integer CHECKSTYLE_POINTS = 10;
+ public static final String TESTS_PATH = "input/";
+ public static final String OUT_PATH = "result/out_";
+ public static final String REF_PATH = "ref/ref_";
+ public static final String RESULT_PATH = "result";
+ public static final String OUT_FILE = "out.txt";
+ public static final String GAME_START = "game_start";
+ public static final String MULTIPLE_GAMES_VALID = "multiple_games_valid";
+ public static final String MULTIPLE_GAMES_INVALID = "multiple_games_invalid";
+ public static final String BIG_GAME = "big_game";
+ public static final Integer GAME_START_POINTS = 3;
+ public static final Integer SINGLE_GAME_POINTS = 4;
+ public static final Integer MULTIPLE_GAMES_VALID_POINTS = 5;
+ public static final Integer MULTIPLE_GAMES_INVALID_POINTS = 6;
+ public static final Integer BIG_GAME_POINTS = 10;
+ public static final int MAX_POINTS = 100;
+ public static final int FIVE_POINTS = 5;
+ public static final int ZERO_POINTS = 0;
+ public static final int LEN_LONGEST_TEST_NAME = 40;
+}
diff --git a/src/checker/Checkstyle.java b/src/checker/Checkstyle.java
new file mode 100644
index 0000000..aafa9be
--- /dev/null
+++ b/src/checker/Checkstyle.java
@@ -0,0 +1,58 @@
+package checker;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * Checker to verify the coding style
+ */
+public final class Checkstyle {
+ private Checkstyle() {
+ //constructor for checkstyle
+ }
+ /**
+ * DO NOT MODIFY
+ */
+ public static int testCheckstyle() {
+ ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar",
+ "src/checker/checkstyle-8.36.2-all.jar", "-c",
+ "src/checker/poo_checks.xml", "./");
+
+ processBuilder.redirectErrorStream(true);
+ File log = new File("checkstyle.txt");
+ processBuilder.redirectOutput(log);
+
+ try {
+ Process process = processBuilder.start();
+ process.waitFor();
+
+ Path path = Paths.get("checkstyle.txt");
+ long lineCount = Files.lines(path).count();
+
+ long errors = 0;
+ if (lineCount > 2) {
+ errors = lineCount - CheckerConstants.BIG_TEST_POINTS;
+ }
+ System.out.println("-----------------------------------------------------");
+ System.out.println("Checkstyle: "
+ + ((errors <= CheckerConstants.MAXIMUM_ERROR_CHECKSTYLE) ? "Ok" : "Failed"));
+ System.out.println("Checkstyle errors: " + errors);
+ System.out.println("-----------------------------------------------------");
+ System.out
+ .println("CHECKSTYLE = "
+ + ((errors <= CheckerConstants.MAXIMUM_ERROR_CHECKSTYLE)
+ ? "10/10" : "0/10"));
+ System.out
+ .println("-----------------------------------------------------");
+ return (errors <= CheckerConstants.MAXIMUM_ERROR_CHECKSTYLE)
+ ? CheckerConstants.CHECKSTYLE_POINTS : 0;
+
+ } catch (IOException | InterruptedException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+}
diff --git a/src/checker/checkstyle-8.36.2-all.jar b/src/checker/checkstyle-8.36.2-all.jar
new file mode 100644
index 0000000..0a3a367
Binary files /dev/null and b/src/checker/checkstyle-8.36.2-all.jar differ
diff --git a/src/checker/checkstyle.sh b/src/checker/checkstyle.sh
new file mode 100644
index 0000000..d234341
--- /dev/null
+++ b/src/checker/checkstyle.sh
@@ -0,0 +1,24 @@
+GOOD_CODE_STYLE=`echo -ne "Starting audit...\nAudit done.\n"`
+BAD_CODE_STYLE=0
+
+function checkCheckstyle
+{
+ echo -ne "\nCheckstyle.....................................\t"
+ java -jar checkstyle-7.3-all.jar -c poo_checks.xml * > checkstyle.txt
+
+ YOUR_CODE_STYLE=`cat checkstyle.txt`
+
+ if [[ "$GOOD_CODE_STYLE" != "$YOUR_CODE_STYLE" ]]; then
+ echo -ne "FAIL\n"
+ BAD_CODE_STYLE=`cat checkstyle.txt | grep -o 'Checkstyle ends with [0-9]* errors.' | grep -o '[0-9]*'`
+ echo $BAD_CODE_STYLE
+
+ if [[ $BAD_CODE_STYLE -lt 30 ]]; then
+ BAD_CODE_STYLE=0
+ else
+ BAD_CODE_STYLE=20
+ fi
+ else
+ echo -ne "OK\n"
+ fi
+}
\ No newline at end of file
diff --git a/src/checker/poo_checks.xml b/src/checker/poo_checks.xml
new file mode 100644
index 0000000..80dcbb2
--- /dev/null
+++ b/src/checker/poo_checks.xml
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/fileio/ActionsInput.java b/src/fileio/ActionsInput.java
new file mode 100644
index 0000000..dc782ca
--- /dev/null
+++ b/src/fileio/ActionsInput.java
@@ -0,0 +1,101 @@
+package fileio;
+
+public final class ActionsInput {
+ private String command;
+ private int handIdx;
+ private Coordinates cardAttacker;
+ private Coordinates cardAttacked;
+ private int affectedRow;
+ private int playerIdx;
+ private int x;
+ private int y;
+
+ public ActionsInput() {
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ public void setCommand(final String command) {
+ this.command = command;
+ }
+
+ public int getHandIdx() {
+ return handIdx;
+ }
+
+ public void setHandIdx(final int handIdx) {
+ this.handIdx = handIdx;
+ }
+
+ public Coordinates getCardAttacker() {
+ return cardAttacker;
+ }
+
+ public void setCardAttacker(final Coordinates cardAttacker) {
+ this.cardAttacker = cardAttacker;
+ }
+
+ public Coordinates getCardAttacked() {
+ return cardAttacked;
+ }
+
+ public void setCardAttacked(final Coordinates cardAttacked) {
+ this.cardAttacked = cardAttacked;
+ }
+
+ public int getAffectedRow() {
+ return affectedRow;
+ }
+
+ public void setAffectedRow(final int affectedRow) {
+ this.affectedRow = affectedRow;
+ }
+
+ public int getPlayerIdx() {
+ return playerIdx;
+ }
+
+ public void setPlayerIdx(final int playerIdx) {
+ this.playerIdx = playerIdx;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(final int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(final int y) {
+ this.y = y;
+ }
+
+ @Override
+ public String toString() {
+ return "ActionsInput{"
+ + "command='"
+ + command + '\''
+ + ", handIdx="
+ + handIdx
+ + ", cardAttacker="
+ + cardAttacker
+ + ", cardAttacked="
+ + cardAttacked
+ + ", affectedRow="
+ + affectedRow
+ + ", playerIdx="
+ + playerIdx
+ + ", x="
+ + x
+ + ", y="
+ + y
+ + '}';
+ }
+}
diff --git a/src/fileio/CardInput.java b/src/fileio/CardInput.java
new file mode 100644
index 0000000..0ed6d7d
--- /dev/null
+++ b/src/fileio/CardInput.java
@@ -0,0 +1,84 @@
+package fileio;
+
+import java.util.ArrayList;
+
+public final class CardInput {
+ private int mana;
+ private int attackDamage;
+ private int health;
+ private String description;
+ private ArrayList colors;
+ private String name;
+
+ public CardInput() {
+ }
+
+ public int getMana() {
+ return mana;
+ }
+
+ public void setMana(final int mana) {
+ this.mana = mana;
+ }
+
+ public int getAttackDamage() {
+ return attackDamage;
+ }
+
+ public void setAttackDamage(final int attackDamage) {
+ this.attackDamage = attackDamage;
+ }
+
+ public int getHealth() {
+ return health;
+ }
+
+ public void setHealth(final int health) {
+ this.health = health;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(final String description) {
+ this.description = description;
+ }
+
+ public ArrayList getColors() {
+ return colors;
+ }
+
+ public void setColors(final ArrayList colors) {
+ this.colors = colors;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "CardInput{"
+ + "mana="
+ + mana
+ + ", attackDamage="
+ + attackDamage
+ + ", health="
+ + health
+ + ", description='"
+ + description
+ + '\''
+ + ", colors="
+ + colors
+ + ", name='"
+ + ""
+ + name
+ + '\''
+ + '}';
+ }
+}
diff --git a/src/fileio/Coordinates.java b/src/fileio/Coordinates.java
new file mode 100644
index 0000000..e802b37
--- /dev/null
+++ b/src/fileio/Coordinates.java
@@ -0,0 +1,34 @@
+package fileio;
+
+public final class Coordinates {
+ private int x, y;
+
+ public Coordinates() {
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(final int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(final int y) {
+ this.y = y;
+ }
+
+ @Override
+ public String toString() {
+ return "Coordinates{"
+ + "x="
+ + x
+ + ", y="
+ + y
+ + '}';
+ }
+}
diff --git a/src/fileio/DecksInput.java b/src/fileio/DecksInput.java
new file mode 100644
index 0000000..1312b13
--- /dev/null
+++ b/src/fileio/DecksInput.java
@@ -0,0 +1,48 @@
+package fileio;
+
+import java.util.ArrayList;
+
+public final class DecksInput {
+ private int nrCardsInDeck;
+ private int nrDecks;
+ private ArrayList> decks;
+
+ public DecksInput() {
+ }
+
+ public int getNrCardsInDeck() {
+ return nrCardsInDeck;
+ }
+
+ public void setNrCardsInDeck(final int nrCardsInDeck) {
+ this.nrCardsInDeck = nrCardsInDeck;
+ }
+
+ public int getNrDecks() {
+ return nrDecks;
+ }
+
+ public void setNrDecks(final int nrDecks) {
+ this.nrDecks = nrDecks;
+ }
+
+ public ArrayList> getDecks() {
+ return decks;
+ }
+
+ public void setDecks(final ArrayList> decks) {
+ this.decks = decks;
+ }
+
+ @Override
+ public String toString() {
+ return "InfoInput{"
+ + "nr_cards_in_deck="
+ + nrCardsInDeck
+ + ", nr_decks="
+ + nrDecks
+ + ", decks="
+ + decks
+ + '}';
+ }
+}
diff --git a/src/fileio/GameInput.java b/src/fileio/GameInput.java
new file mode 100644
index 0000000..acc0fd1
--- /dev/null
+++ b/src/fileio/GameInput.java
@@ -0,0 +1,37 @@
+package fileio;
+
+import java.util.ArrayList;
+
+public final class GameInput {
+ private StartGameInput startGame;
+ private ArrayList actions;
+
+ public GameInput() {
+ }
+
+ public StartGameInput getStartGame() {
+ return startGame;
+ }
+
+ public void setStartGame(final StartGameInput startGame) {
+ this.startGame = startGame;
+ }
+
+ public ArrayList getActions() {
+ return actions;
+ }
+
+ public void setActions(final ArrayList actions) {
+ this.actions = actions;
+ }
+
+ @Override
+ public String toString() {
+ return "GameInput{"
+ + "startGame="
+ + startGame
+ + ", actions="
+ + actions
+ + '}';
+ }
+}
diff --git a/src/fileio/Input.java b/src/fileio/Input.java
new file mode 100644
index 0000000..2c69af2
--- /dev/null
+++ b/src/fileio/Input.java
@@ -0,0 +1,48 @@
+package fileio;
+
+import java.util.ArrayList;
+
+public final class Input {
+ private DecksInput playerOneDecks;
+ private DecksInput playerTwoDecks;
+ private ArrayList games;
+
+ public Input() {
+ }
+
+ public ArrayList getGames() {
+ return games;
+ }
+
+ public void setGames(final ArrayList games) {
+ this.games = games;
+ }
+
+ public DecksInput getPlayerOneDecks() {
+ return playerOneDecks;
+ }
+
+ public void setPlayerOneDecks(final DecksInput playerOneDecks) {
+ this.playerOneDecks = playerOneDecks;
+ }
+
+ public DecksInput getPlayerTwoDecks() {
+ return playerTwoDecks;
+ }
+
+ public void setPlayerTwoDecks(final DecksInput playerTwoDecks) {
+ this.playerTwoDecks = playerTwoDecks;
+ }
+
+ @Override
+ public String toString() {
+ return "Input{"
+ + "player_one_decks="
+ + playerOneDecks
+ + ", player_two_decks="
+ + playerTwoDecks
+ + ", games="
+ + games
+ + '}';
+ }
+}
diff --git a/src/fileio/StartGameInput.java b/src/fileio/StartGameInput.java
new file mode 100644
index 0000000..eb10b5f
--- /dev/null
+++ b/src/fileio/StartGameInput.java
@@ -0,0 +1,79 @@
+package fileio;
+
+public final class StartGameInput {
+ private int playerOneDeckIdx;
+ private int playerTwoDeckIdx;
+ private int shuffleSeed;
+ private CardInput playerOneHero;
+ private CardInput playerTwoHero;
+ private int startingPlayer;
+
+ public StartGameInput() {
+ }
+
+ public int getPlayerOneDeckIdx() {
+ return playerOneDeckIdx;
+ }
+
+ public void setPlayerOneDeckIdx(final int playerOneDeckIdx) {
+ this.playerOneDeckIdx = playerOneDeckIdx;
+ }
+
+ public int getPlayerTwoDeckIdx() {
+ return playerTwoDeckIdx;
+ }
+
+ public void setPlayerTwoDeckIdx(final int playerTwoDeckIdx) {
+ this.playerTwoDeckIdx = playerTwoDeckIdx;
+ }
+
+ public int getShuffleSeed() {
+ return shuffleSeed;
+ }
+
+ public void setShuffleSeed(final int shuffleSeed) {
+ this.shuffleSeed = shuffleSeed;
+ }
+
+ public CardInput getPlayerOneHero() {
+ return playerOneHero;
+ }
+
+ public void setPlayerOneHero(final CardInput playerOneHero) {
+ this.playerOneHero = playerOneHero;
+ }
+
+ public CardInput getPlayerTwoHero() {
+ return playerTwoHero;
+ }
+
+ public void setPlayerTwoHero(final CardInput playerTwoHero) {
+ this.playerTwoHero = playerTwoHero;
+ }
+
+ public int getStartingPlayer() {
+ return startingPlayer;
+ }
+
+ public void setStartingPlayer(final int startingPlayer) {
+ this.startingPlayer = startingPlayer;
+ }
+
+ @Override
+ public String toString() {
+ return "StartGameInput{"
+ + "playerOneDeckIdx="
+ + playerOneDeckIdx
+ + ", playerTwoDeckIdx="
+ + playerTwoDeckIdx
+ + ", shuffleSeed="
+ + shuffleSeed
+ + ", playerOneHero="
+ + playerOneHero
+ + ", playerTwoHero="
+ + playerTwoHero
+ + ", startingPlayer="
+ + startingPlayer
+ + '}';
+ }
+}
diff --git a/src/main/Main.java b/src/main/Main.java
new file mode 100644
index 0000000..55ccf4b
--- /dev/null
+++ b/src/main/Main.java
@@ -0,0 +1,77 @@
+package main;
+
+import checker.Checker;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import checker.CheckerConstants;
+import fileio.Input;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Objects;
+
+/**
+ * The entry point to this homework. It runs the checker that tests your implentation.
+ */
+public final class Main {
+ /**
+ * for coding style
+ */
+ private Main() {
+ }
+
+ /**
+ * DO NOT MODIFY MAIN METHOD
+ * Call the checker
+ * @param args from command line
+ * @throws IOException in case of exceptions to reading / writing
+ */
+ public static void main(final String[] args) throws IOException {
+ File directory = new File(CheckerConstants.TESTS_PATH);
+ Path path = Paths.get(CheckerConstants.RESULT_PATH);
+
+ if (Files.exists(path)) {
+ File resultFile = new File(String.valueOf(path));
+ for (File file : Objects.requireNonNull(resultFile.listFiles())) {
+ file.delete();
+ }
+ resultFile.delete();
+ }
+ Files.createDirectories(path);
+
+ for (File file : Objects.requireNonNull(directory.listFiles())) {
+ String filepath = CheckerConstants.OUT_PATH + file.getName();
+ File out = new File(filepath);
+ boolean isCreated = out.createNewFile();
+ if (isCreated) {
+ action(file.getName(), filepath);
+ }
+ }
+
+ Checker.calculateScore();
+ }
+
+ /**
+ * @param filePath1 for input file
+ * @param filePath2 for output file
+ * @throws IOException in case of exceptions to reading / writing
+ */
+ public static void action(final String filePath1,
+ final String filePath2) throws IOException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ Input inputData = objectMapper.readValue(new File(CheckerConstants.TESTS_PATH + filePath1),
+ Input.class);
+
+ ArrayNode output = objectMapper.createArrayNode();
+
+ //TODO add here the entry point to your implementation
+
+ ObjectWriter objectWriter = objectMapper.writerWithDefaultPrettyPrinter();
+ objectWriter.writeValue(new File(filePath2), output);
+ }
+}
diff --git a/src/main/Test.java b/src/main/Test.java
new file mode 100644
index 0000000..866a21d
--- /dev/null
+++ b/src/main/Test.java
@@ -0,0 +1,41 @@
+package main;
+
+import checker.CheckerConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Scanner;
+
+/**
+ * Use this if you want to test on a specific input file
+ */
+public final class Test {
+ /**
+ * for coding style
+ */
+ private Test() {
+ }
+
+ /**
+ * @param args input files
+ * @throws IOException in case of exceptions to reading / writing
+ */
+ public static void main(final String[] args) throws IOException {
+ File directory = new File(CheckerConstants.TESTS_PATH);
+ File[] inputDir = directory.listFiles();
+
+ if (inputDir != null) {
+ Arrays.sort(inputDir);
+
+ Scanner scanner = new Scanner(System.in);
+ String fileName = scanner.next();
+ for (File file : inputDir) {
+ if (file.getName().equalsIgnoreCase(fileName)) {
+ Main.action(file.getName(), CheckerConstants.OUT_FILE);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/tema.iml b/tema.iml
new file mode 100644
index 0000000..988ef24
--- /dev/null
+++ b/tema.iml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file