Compare commits

...

9 Commits

Author SHA1 Message Date
a135ec80ec Improved error checks for Map 2018-02-28 23:57:45 +01:00
a16a07846b Added wall width to map. 2017-11-30 18:50:26 +01:00
22a1b5a0d7 Merge branch 'WorldNavigation' of https://github.com/EpicKnarvik97/pokemon-cmd into WorldNavigation 2017-11-30 18:41:40 +01:00
9a3a01c082 Added more stuff in test.
We are still missing the actual function to place a structure on the map, but we are quite close.
2017-11-30 18:40:13 +01:00
9d949f3926
Delete Run.bat 2017-11-29 16:15:47 +01:00
99dd30975b
Delete Compile.bat 2017-11-29 16:15:40 +01:00
18664c9b17 Updated .gitignore 2017-11-29 16:07:49 +01:00
fc74f55c85 Added more object types.
Added Map and Structure. Created a working map int Test.java, but Structures are still not implemented.
2017-11-29 15:50:43 +01:00
ad09ee4b1d Added a proposal of the new Tile object.
This is just a proposal of the new Tile object, an may be changed at any time.
Allowing it to return an integer on onWalk lets us easier do tasks like looking for wild pokemon, from anywhere in the program.
It cannot be used as it is now, but it can be used once we are finished with the other necessary classes.
2017-11-29 10:50:15 +01:00
15 changed files with 1021 additions and 793 deletions

8
.gitignore vendored
View File

@ -23,3 +23,11 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Script files
*.bat
*.sh
#IDEA files
*.xml
*.iml

View File

@ -1,2 +0,0 @@
javac -cp java java/Game.java
jar cvfm Game.jar manifest.txt -C java config/Pokemon.txt java/*.class

View File

@ -1 +0,0 @@
java -jar Game.jar -Dfile.encoding=UTF-8

21
Test/MapTest.java Normal file
View File

@ -0,0 +1,21 @@
class MapTest {
public static void main(String[] args) {
Tile rock = new Tile('■', true, "NONE");
Tile empty = new Tile(' ', false, "NONE");
Map map = new Map(10, 10, 5, 5, empty, rock);
Tile wallTopRight = new Tile('╗', true, "NONE");
Tile wallTopLeft = new Tile('╔', true, "NONE");
Tile wallBottomRight = new Tile('╝', true, "NONE");
Tile wallBottomLeft = new Tile('╚', true, "NONE");
Tile wallSide = new Tile('║', true, "NONE");
Tile wallLying = new Tile('═', true, "NONE");
Tile roof = new Tile(' ', true, "NONE");
Tile door = new Tile('╼', false, "TELEPORT", 10, 10);
Tile player = new Tile('P', false, "NONE");
Tile[][] tiles = {{wallTopLeft, wallSide, wallBottomLeft}, {wallLying, roof, door}, {wallTopRight, wallSide, wallBottomRight}};
new Structure("House", tiles);
map.generateStructure("House", 4, 2);
map.placeTile(player, 8, 8);
System.out.println(map);
}
}

File diff suppressed because it is too large Load Diff

3
java/Direction.java Normal file
View File

@ -0,0 +1,3 @@
public enum Direction {
NORTH, SOUTH, EAST, WEST;
}

View File

@ -10,7 +10,7 @@ import java.text.ParseException;
/** Simulates the game Pokémon. */
public class Game {
public static Scanner in = new Scanner(System.in);
private static final Scanner in = new Scanner(System.in);
public static void main(String[] args) {
ArrayList<Pokemon> pokemon = readPokemon();
@ -21,12 +21,12 @@ public class Game {
Trainer player = new Trainer(name, randomTeam(), createInventory());
boolean done = false;
Pokemon opponentPokemon = null;
Pokemon opponentPokemon;
Pokemon trainersPokemon = null;
Pokeball currentPokeball = null;
Potion currentPotion = null;
boolean fleeSuccess = false;
Pokemon pokemonToHeal = null;
Pokeball currentPokeball;
Potion currentPotion;
boolean fleeSuccess;
Pokemon pokemonToHeal;
opponentPokemon = randomPokemon(pokemon);
System.out.printf("A wild %s appeared.%n", opponentPokemon.getName());
@ -187,7 +187,7 @@ public class Game {
* @param pokemonList List of pokemon to search.
* @param target The pokemon to remove.
*/
public static void pokemonFainted(ArrayList<Pokemon> pokemonList, Pokemon target) {
private static void pokemonFainted(ArrayList<Pokemon> pokemonList, Pokemon target) {
for (int i = 0; i < pokemonList.size(); i++) {
if (pokemonList.get(i).equals(target)) {
pokemonList.remove(i);
@ -199,7 +199,7 @@ public class Game {
* Gives a trainer necessary starting items.
* @return A list of items.
*/
public static Inventory createInventory() {
private static Inventory createInventory() {
Inventory inventory = new Inventory();
inventory.addPokeball("Poke Ball", "A device for catching wild Pokémon. It's thrown like a ball at a Pokémon, comfortably encapsulating its target.", 15);
inventory.addPokeball("Great ball", "A good, high-performance Poké Ball that provides a higher Pokémon catch rate than a standard Poké Ball.", 10);
@ -218,7 +218,7 @@ public class Game {
* @param pokemon The list to choose from.
* @return A Pokemon object, or null if the list is empty.
*/
public static Pokemon randomPokemon(ArrayList<Pokemon> pokemon) {
private static Pokemon randomPokemon(ArrayList<Pokemon> pokemon) {
if (pokemon.size() > 0) {
return pokemon.get((int)(Math.random() * pokemon.size()));
} else {
@ -230,14 +230,14 @@ public class Game {
* Reads pokemon from Pokemon.txt to an ArrayList.
* @return An ArrayList of pokemon objects.
*/
public static ArrayList<Pokemon> readPokemon() {
ArrayList<Pokemon> pokemon = new ArrayList<Pokemon>();
private static ArrayList<Pokemon> readPokemon() {
ArrayList<Pokemon> pokemon = new ArrayList<>();
try (Scanner file = new Scanner(new File("config/Pokemon.txt"))) {
while (file.hasNextLine()) {
pokemon.add(new Pokemon(file.nextLine()));
}
} catch (FileNotFoundException e) {
/** If the file is compiled as jar, this will prevent an empty list. */
/* If the file is compiled as jar, this will prevent an empty list. */
try (Scanner file = new Scanner(Game.class.getResourceAsStream("/config/Pokemon.txt"))) {
while (file.hasNextLine()) {
pokemon.add(new Pokemon(file.nextLine()));
@ -252,7 +252,7 @@ public class Game {
* @param pokemon A list of pokemon objects.
* @return A pokemon object.
*/
public static Pokemon pick(ArrayList<Pokemon> pokemon) {
private static Pokemon pick(ArrayList<Pokemon> pokemon) {
int index = (int)(Math.random() * (pokemon.size()));
Pokemon randomPokemon = pokemon.get(index);
pokemon.remove(index);
@ -264,7 +264,7 @@ public class Game {
* @param pokemonList List of Pokemon objects to save.
* @param savefile The file to write to.
*/
public static void savePokemon(ArrayList<Pokemon> pokemonList, String savefile) {
private static void savePokemon(ArrayList<Pokemon> pokemonList, String savefile) {
try (PrintWriter file = new PrintWriter(savefile)) {
for (Pokemon pokemon : pokemonList) {
file.println(pokemon.saveString());
@ -277,10 +277,10 @@ public class Game {
/**
* Saves all items in a list to a text file.
* @param itemList List of Item objects to save.
* @param savefile The file to write to.
* @param inventory The items of a player
* @param savefile The file to write to.
*/
public static void saveInventory(Inventory inventory, String savefile) {
private static void saveInventory(Inventory inventory, String savefile) {
try (PrintWriter file = new PrintWriter(savefile)) {
for (Pokeball pokeball : inventory.getPokeballs()) {
file.println(pokeball.saveString());
@ -300,17 +300,15 @@ public class Game {
* @param savefile The file to write to.
* @return A list of pokemon or null on failiure.
*/
public static ArrayList<Pokemon> loadPokemon(String savefile) {
ArrayList<Pokemon> pokemon = new ArrayList<Pokemon>();
private static ArrayList<Pokemon> loadPokemon(String savefile) {
ArrayList<Pokemon> pokemon = new ArrayList<>();
try (Scanner file = new Scanner(new File(savefile))) {
NumberFormat format = NumberFormat.getInstance(Locale.ENGLISH);
while (file.hasNextLine()) {
String[] data = file.nextLine().split(";");
try {
pokemon.add(new Pokemon(data[0], Integer.parseInt(data[1]), Integer.parseInt(data[2]), Integer.parseInt(data[3]), format.parse(data[4]).doubleValue(), Integer.parseInt(data[5]), Integer.parseInt(data[6]), Integer.parseInt(data[7])));
} catch (NumberFormatException e) {
System.out.println("Malformed number " + e);
} catch (ParseException e) {
} catch (NumberFormatException | ParseException e) {
System.out.println("Malformed number " + e);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Invalid savefile: " + savefile);
@ -330,9 +328,9 @@ public class Game {
* @param savefile The file to write to.
* @return A list of items or null on failiure.
*/
public static Inventory loadInventory(String savefile) {
ArrayList<Pokeball> pokeballs = new ArrayList<Pokeball>();
ArrayList<Potion> potions = new ArrayList<Potion>();
private static Inventory loadInventory(String savefile) {
ArrayList<Pokeball> pokeballs = new ArrayList<>();
ArrayList<Potion> potions = new ArrayList<>();
try (Scanner file = new Scanner(new File(savefile))) {
String next = "";
while (file.hasNextLine() && !next.equals(":NEXTLIST:")) {
@ -364,9 +362,9 @@ public class Game {
return new Inventory(pokeballs, potions);
}
public static ArrayList<Pokemon> randomTeam() {
private static ArrayList<Pokemon> randomTeam() {
ArrayList<Pokemon> temporary = readPokemon();
ArrayList<Pokemon> pokemon = new ArrayList<Pokemon>();
ArrayList<Pokemon> pokemon = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
pokemon.add(pick(temporary));
}

View File

@ -2,13 +2,13 @@ import java.util.ArrayList;
import java.util.Scanner;
public class Inventory {
public static Scanner in = new Scanner(System.in);
private ArrayList<Pokeball> pokeballs;
private ArrayList<Potion> potions;
private static final Scanner in = new Scanner(System.in);
private final ArrayList<Pokeball> pokeballs;
private final ArrayList<Potion> potions;
public Inventory() {
this.pokeballs = new ArrayList<Pokeball>();
this.potions = new ArrayList<Potion>();
this.pokeballs = new ArrayList<>();
this.potions = new ArrayList<>();
}
public Inventory(ArrayList<Pokeball> pokeballs, ArrayList<Potion> potions) {
@ -18,20 +18,16 @@ public class Inventory {
public void addPokeball(String name, String description, int amount) {
Pokeball pokeball = new Pokeball(name, description, amount, Pokeball.Pokeballs.valueOf(name.toUpperCase().replace(" ", "")));
if (pokeball != null) {
this.pokeballs.add(pokeball);
}
this.pokeballs.add(pokeball);
}
public void addPotion(String name, String description, int amount, boolean alive) {
Potion potion = new Potion(name, description, amount, Potion.Potions.valueOf(name.toUpperCase().replace(" ", "")), alive);
if (potion != null) {
this.potions.add(potion);
}
this.potions.add(potion);
}
public ArrayList<Pokeball> getPokeballs() {
ArrayList<Pokeball> pokeballs = new ArrayList<Pokeball>();
ArrayList<Pokeball> pokeballs = new ArrayList<>();
for (Pokeball pokeball : this.pokeballs) {
if (pokeball.getAmount() > 0) {
pokeballs.add(pokeball);
@ -41,7 +37,7 @@ public class Inventory {
}
public ArrayList<Potion> getPotions() {
ArrayList<Potion> potions = new ArrayList<Potion>();
ArrayList<Potion> potions = new ArrayList<>();
for (Potion potion : this.potions) {
if (potion.getAmount() > 0) {
potions.add(potion);

89
java/Map.java Normal file
View File

@ -0,0 +1,89 @@
class Map {
private final Tile[][] tiles;
private int fullWidth;
private int fullHeight;
public Map(int width, int height, int wWidth, int wHeight, Tile empty, Tile wall) {
this.fullHeight = height + (2 * wHeight);
this.fullWidth = width + (2 * wWidth);
Tile[][] map = new Tile[this.fullWidth][this.fullHeight];
for (int i = 0; i < this.fullWidth; i++) {
for (int j = 0; j < this.fullHeight; j++) {
if (i < wWidth || i >= width + wWidth || j < wHeight || j >= height + wHeight) {
map[i][j] = wall;
} else {
map[i][j] = empty;
}
}
}
this.tiles = map;
}
private Tile[][] getTiles() {
return this.tiles;
}
public void generateStructure(String name, int x, int y) throws IllegalArgumentException {
for (Structure structure : Structure.getStructures()) {
if (name.equals(structure.getName())) {
this.placeStructure(structure, x, y);
return;
}
}
throw new IllegalArgumentException("Invalid structure name.");
}
private void placeStructure(Structure structure, int x, int y) throws IllegalArgumentException {
if (x < 0 || y < 0 || this.fullWidth < x + structure.getWidth() || this.fullHeight < y + structure.getHeight()) {
throw new IllegalArgumentException("The structure is misplaced or does not fit.");
}
Tile[][] tiles = structure.getTiles();
for (int i = 0; i < structure.getWidth(); i++) {
for (int j = 0; j < structure.getHeight(); j++) {
if (!tiles[i][j].isSolid()) {
switch (structure.getDoorDirection()) {
case NORTH:
if (this.tiles[x+i][y+j-1].isSolid()) {
throw new IllegalArgumentException("A structure is blocked");
}
break;
case SOUTH:
if (this.tiles[x+i][y+j+1].isSolid()) {
throw new IllegalArgumentException("A structure is blocked");
}
break;
case WEST:
if (this.tiles[x+i-1][y+j].isSolid()) {
throw new IllegalArgumentException("A structure is blocked");
}
break;
case EAST:
if (this.tiles[x+i+1][y+j].isSolid()) {
throw new IllegalArgumentException("A structure is blocked");
}
}
}
this.tiles[x+i][y+j] = tiles[i][j];
}
}
}
public void placeTile(Tile tile, int x, int y) {
if (x < 0 || y < 0 || x >= this.tiles.length || y >= this.tiles[0].length) {
throw new IllegalArgumentException("Invalid tile position");
}
this.tiles[x][y] = tile;
}
public String toString() {
Tile[][] tiles = this.getTiles();
StringBuilder str = new StringBuilder();
for (int i = 0; i < tiles.length; i++) {
for (int j = 0; j < tiles.length; j++) {
str.append(tiles[j][i].toChar());
}
str.append("\n");
}
return str.toString();
}
}

View File

@ -1,10 +1,10 @@
import java.util.ArrayList;
public class Pokeball {
public static enum Pokeballs { POKEBALL, GREATBALL, ULTRABALL, MASTERBALL }
private String name;
private String description;
private Pokeballs type;
public enum Pokeballs { POKEBALL, GREATBALL, ULTRABALL, MASTERBALL }
private final String name;
private final String description;
private final Pokeballs type;
private int amount;
public Pokeball(String name, String description, int amount, Pokeballs type) {

View File

@ -2,13 +2,13 @@ import java.util.Random;
import java.util.ArrayList;
public class Pokemon {
private String name;
private final String name;
private int healthPoints;
private int maxHealthPoints;
private int strength;
private double criticalChance;
private Random random;
private int catchRate;
private final double criticalChance;
private final Random random;
private final int catchRate;
private int exp;
private int level;
private int fleeCount;
@ -79,7 +79,7 @@ public class Pokemon {
/**
* Checks if a pokemon has not taken any damage or is fully healed.
* @param return True if health is full. False otherwise.
* @return True if health is full. False otherwise.
*/
public boolean isDamaged() {
return this.healthPoints < this.maxHealthPoints;
@ -110,7 +110,7 @@ public class Pokemon {
/**
* Captures a wild pokemon.
* @param current The pokemon list the pokemon belongs to.
* @param catcher The pokemon list of the trainer.
* @param trainer The trainer who is capturing.
*/
private void capture(ArrayList<Pokemon> current, Trainer trainer) {
trainer.addPokemon(this);
@ -136,16 +136,16 @@ public class Pokemon {
/**
* Damages a pokemon.
* @param How many hitpoints are to be deducted.
* @param damageTaken How many hitpoints are to be deducted.
*/
public void damage(int damageTaken) {
private void damage(int damageTaken) {
this.healthPoints = Math.max(this.healthPoints -= damageTaken, 0);
System.out.printf("%s takes %d damage and is left with %d/%d HP%n", this.name, damageTaken, this.healthPoints, this.maxHealthPoints);
}
/**
* Gives a pokemon exp after each successfull battle. Also handles leveling up.
* @target Which pokemon did we beat.
* @param target Which pokemon did we beat.
*/
private void giveEXP(Pokemon target) {
int exp = (100 * target.level)/7;

View File

@ -1,11 +1,9 @@
import java.util.ArrayList;
public class Potion {
public static enum Potions { POTION, SUPERPOTION, HYPERPOTION, MAXPOTION, REVIVE }
private String name;
private String description;
private Potions type;
private boolean alive;
public enum Potions { POTION, SUPERPOTION, HYPERPOTION, MAXPOTION, REVIVE }
private final String name;
private final String description;
private final Potions type;
private final boolean alive;
private int amount;
public Potion(String name, String description, int amount, Potions type) {

58
java/Structure.java Normal file
View File

@ -0,0 +1,58 @@
import java.util.ArrayList;
class Structure {
private static final ArrayList<Structure> structures = new ArrayList<>();
private final Tile[][] tiles;
private final String name;
public Structure(String name, Tile[][] tiles) {
this.name = name;
this.tiles = tiles;
structures.add(this);
}
public String getName() {
return this.name;
}
public Tile[][] getTiles() {
return this.tiles;
}
public static ArrayList<Structure> getStructures() {
return structures;
}
public int getWidth() {
return this.tiles.length;
}
public Direction getDoorDirection() {
for (int x = 0; x < this.getWidth(); x++) {
for (int y = 0; y < this.getHeight(); y++) {
if (!tiles[x][y].isSolid()) {
if (y == tiles[x].length - 1) {
return Direction.SOUTH;
} else if (y == 0) {
return Direction.NORTH;
} else if (x == 0) {
return Direction.WEST;
} else if (x == tiles.length - 1) {
return Direction.EAST;
}
}
}
}
return null;
}
public int getHeight() {
int max = 0;
for (Tile[] tile : this.tiles) {
if (tile.length > max) {
max = tile.length;
}
}
return max;
}
}

60
java/Tile.java Normal file
View File

@ -0,0 +1,60 @@
public class Tile {
private final char representation;
private final boolean solid;
private enum Action { TELEPORT, NONE, ENCOUNTER, MENUBATTLE, MENUSHOP }
private final Action action;
private int[] teleportTarget;
public Tile (char representation, boolean solid, String action) throws IllegalArgumentException {
this.representation = representation;
this.solid = solid;
this.action = Action.valueOf(action.toUpperCase());
if (this.action != Action.TELEPORT) {
this.teleportTarget = null;
} else {
throw new IllegalArgumentException("A teleport tile must have a valid target.");
}
}
public Tile (char representation, boolean solid, String action, int x, int y) throws IllegalArgumentException {
this.representation = representation;
this.solid = solid;
this.action = Action.valueOf(action.toUpperCase());
if (this.action == Action.TELEPORT) {
this.teleportTarget = new int[]{x, y};
} else {
throw new IllegalArgumentException("A non-teleport tile can't have a teleport target.");
}
}
public char toChar() {
return this.representation;
}
public int[] getTeleportTarget() {
return this.teleportTarget;
}
public boolean isSolid() {
return this.solid;
}
public int onWalk() {
if (this.solid) {
System.out.println("You bumped against an immovable structure.");
return -1;
} else {
switch (this.action) {
case TELEPORT:
return 1;
case ENCOUNTER:
return 2;
case MENUBATTLE:
return 3;
case MENUSHOP:
return 4;
}
}
return 0;
}
}

View File

@ -1,13 +1,13 @@
import java.util.ArrayList;
import java.util.Scanner;
public class Trainer {
public static Scanner in = new Scanner(System.in);
String name;
class Trainer {
private static final Scanner in = new Scanner(System.in);
private final String name;
private ArrayList<Pokemon> pokemon;
private Inventory inventory;
public Trainer(String name, ArrayList<Pokemon> pokemon, Inventory inventory) {
Trainer(String name, ArrayList<Pokemon> pokemon, Inventory inventory) {
this.name = name;
this.pokemon = pokemon;
this.inventory = inventory;
@ -30,7 +30,7 @@ public class Trainer {
}
public ArrayList<Pokemon> getConsciousPokemon() {
ArrayList<Pokemon> pokemon = new ArrayList<Pokemon>();
ArrayList<Pokemon> pokemon = new ArrayList<>();
for (Pokemon singlePokemon : this.pokemon) {
if (singlePokemon.isConscious()) {
pokemon.add(singlePokemon);
@ -39,8 +39,8 @@ public class Trainer {
return pokemon;
}
public ArrayList<Pokemon> getFaintedPokemon() {
ArrayList<Pokemon> pokemon = new ArrayList<Pokemon>();
private ArrayList<Pokemon> getFaintedPokemon() {
ArrayList<Pokemon> pokemon = new ArrayList<>();
for (Pokemon singlePokemon : this.pokemon) {
if (!singlePokemon.isConscious()) {
pokemon.add(singlePokemon);
@ -55,7 +55,7 @@ public class Trainer {
/** Lists all currently available pokemon for the trainer.*/
public void availablePokemon(boolean alive) {
ArrayList<Pokemon> pokemonList = null;
ArrayList<Pokemon> pokemonList;
if (alive) {
pokemonList = this.getConsciousPokemon();
} else {
@ -76,11 +76,11 @@ public class Trainer {
/**
* Asks the user for the name of a pokemon and returns it.
* @param pokemonList A list of available pokemon
* @return A pokemon object or null.
* @param alive Are we looking for alive pokemon?
* @return A pokemon object or null.
*/
public Pokemon choosePokemon(boolean alive) {
ArrayList<Pokemon> pokemonList = null;
ArrayList<Pokemon> pokemonList;
if (alive) {
pokemonList = this.getConsciousPokemon();
} else {