Java: Read, edit and create a text file - java

I have a Java program that creates Swords. Now, I want to store the damagevalue and name of these Swords in a text file, and be able to read these values later. What is the best way to do that?
I have two classes:
Sword.java and NewSword.java, where NewSword.java is the function to create a new sword (o.O). Here's the code:
Sword.java:
package game;
public class Sword {
public static int numberOfSwords=0;
public static void main(String [] args){
functions.NewSword.newSword("Wooden Sword", 2);
System.out.println(numberOfSwords);
}
}
and
NewSword.java:
package functions;
public class NewSword {
public static void newSword(String nameSword, int damageSword){
game.Sword.numberOfSwords++;
}
}
So:
I wish to be able to, in the function newSword(String nameSword, int damageSword), put the nameSword and the damageSword in a text file, and be able to read that... So that I can later do like: "He has a wooden sword, what's the damage?"... I want to put it in a text file, because I want to know how that works, and practice with it. Also, I think it makes it easier if I want to add features to swords, and can put those in text files as well... Hope you can help me!
EDIT: I put the function in another package, that's why it's functions.NewSword.newSword("Wooden Sword", 2);, just for the heck of it :D But also to be a bit organized...

Read throught this: http://www.tutorialspoint.com/java/java_files_io.htm
It explains everything in from creating a file to reading it and will sure help you out.
However regard kviiris commend about learning something about object oriented programming.
Heres the basic approach for your swords:
You write a class for your sword that contains all the information you need for a given sword.
public class Sword {
private String name;
private int damage;
// this is the constructor to create new swords
public Sword(String name, int damage){
this.name = name;
this.damage = damage;
}
}
Now you can access this from your main class and use it to create as many swords as you want simply with
Sword s = new Sword("wooden sword", 2);
Sword s2 = new Sword("iron sword", 20);
Note: you used the same class (Sword) but this are still 2 completely separate swords.
Thats the main use of object oriented programming.

This will compile.
Game.java
package game;
import functions.Sword;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Game {
List<Sword> swords = new ArrayList<Sword>();
public static void main(String[] args) {
Game game = new Game();
game.play();
}
public void play() {
swords.add(new Sword("Wooden sword", 2));
swords.add(new Sword("Silver sword", 4));
System.out.println(swords.size());
System.out.println(Arrays.toString(swords));
}
}
Sword.java
package functions;
public class Sword {
private final String name;
private final int damage;
public Sword(String name, int damage) {
this.name = name;
this.damage = damage;
}
public String getName() {
return name;
}
public int getDamage() {
return damage;
}
}

Related

Getting Variables From Java constructor

I'm new to Java programming, sorry if this is a dumb question.
I find it hard to word this question properly, but I have an assignment to create a aircraft class that can make aircraft land, takeoff etc. And need to test it using Testclass. When the new object are entered it automatically assigns a unique ID to the aircraft in the constructor.
I can do this using a instance method fine as it has a return value which is returned to to Testclass. The question wants me to do this in the constructor itself, however, the constructor never returns anything. So the variable never gets sent to the Testclass. I clearly am not understanding OOP properly. Even when I try to just use a getter method to get the ID created in the constructor it gives me the initialized variable before the the constructor has worked on this. This is the code I have so far and its completely wrong I know but if someone could point me in the right direction or tell me how to word this question better it would be a massive help.
// I need to enter 3 aircraft into the system in the testclass
public class Aircraft {
private int aircraftID;
private static int lastID;
private String airportcode;
private int ID = 100;
private int count;
public Aircraft(int a, int b, int c){
// Constructor
// Assign ID
this.ID = a;
lastID = ID;
ID++;
this.ID =b;
lastID = ID;
ID++;
}
}
OK, you want to create an Aircraft that has an automatically-assigned unique identifier, and can take off and land. That implies you need a field for tracking the identifier, a field for tracking whether it's in the air (or not), and methods for the take off and land operations. You also need a static field for generating the unique identifiers. (Note that this implementation isn't thread safe.)
private class Aircraft {
private static int staticId = 0;
private int uniqueId = 0;
private boolean onGround = true; // Aircraft start on the ground in this implementation
public Aircraft(){
this.uniqueId = staticId; // putting this line first makes uniqueId zero-indexed in effect
staticId++;
}
public void land(){
onGround = true;
}
public void takeoff(){
onGround = false;
}
public boolean isFlying(){
return !onGround; // If it's not on the ground, it's flying
}
public int getUniqueId(){
return uniqueId;
}
}
Unit tests checks all of the methods and expected functionality of the class in question:
import org.junit.Test;
import static org.junit.Assert.*;
import Aircraft;
class Testclass {
private final Aircraft aircraft = new Aircraft();
#Test
public void hasId(){
aircraft.getUniqueId() >= 0;
}
#Test
public void canLand(){
assertTrue(aircraft.land());
}
#Test
public void canTakeOff(){
assertTrue(aircraft.takeOff());
}
#Test
public void checkFlightOperationsAreTrackedCorrectly(){
aircraft.land();
assertFalse(aircraft.isFlying());
aircraft.takeOff();
assertTrue(aircraft.isFlying());
}
}
As pointed out a constructor does not return anything (the simplified version is that with new it returns an object instance). I am kinda guessing at what you are trying to acomplish, but I'll have a go anyways. It seems to me that you are trying to cram the construction of 3 objects into one constructor - which is why your constructor has 3 parameters. Also you are playing havoc with the IDs.
I have removed all the variables that I didnt quite understand, leaving only ID that increments with each instantiated Aircraft. The #Override is mainly just for show.
public class Aircraft {
private int aircraftID;
private static int lastID = 0;
#Override
public String toString(){
return "Aircraft_" + this.aircraftID;
}
public Aircraft() {
lastID++;
this.aircraftID = lastID;
}
}
I took the liberty and wrote the TestClass just to see if we have the same thing in mind. Again the printAircraft() method is for show.
public class TestClass {
private List<Aircraft> aircrafts;
public TestClass(){
aircrafts = new ArrayList<>();
}
public void addAircraft(Aircraft a){
aircrafts.add(a);
}
public void printAircraft(){
Iterator<Aircraft> it = aircrafts.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
and to test it, we create and instance of TestClass add 3 Aircraft instances and print out the contents
public static void main(String[] args) {
TestClass tc = new TestClass();
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.printAircraft();
}
This would be the case if you are to write the TestClass. If that is given, it would help to know what it looks like - maybe that would help us understand better.

What does Java static object mean?

What is the advantage if we make object as static? Seeking detailed explanation !!
Well you can make a Variable static, and this Var is refering to an Object, Why would it be good? well a static means that it will be visible to all aplication (well also depends of its package visibility, public, protected, default, private)
Why would be good? well maybe you're creating an "static object" in order to use it in diferent objects for example a game, look i made one ("of course it is an example")
public class Dummy {
static Player player = new Player("Yussef");
public static void main(String[] args) {
stageOne();
satageTwo();
}
static void stageOne(){
System.out.println("Ready? Go");
System.out.println(player);
System.out.println("Ouch an enemy hit me");
player.setLife(80);
System.out.println(player);
}
static void satageTwo(){
System.out.println("Good, now you're in next level");
System.out.println(player);
System.out.println("Ouch an enemy hit me");
System.out.println("Ouch an enemy hit me");
player.setLife(40);
System.out.println(player);
}
}
class Player{
private String name;
private int life;
Player(String name){
this.name = name;
life = 100;
}
#Override
public String toString() {
return "My name is: "+name+" And mi actual life is: "+life;
}
public void setLife(int life) {
this.life = life;
}
}
Now Imagine inspite of using the same class, i would've made more Clases, or more players, well the poit is this: My player will have the same life in all my game, and same name, so no matter what stage i play i will have the same attributs or changed them maybe ;).
It is an example i thought, hope it could help u

JAVA/SPIGOT: How can I make a variable called from non static classes?

I'm very new with Java and was introduced to it by creating Minecraft plugins. I am currently using Spigot and want a variable to be accessed through another class. In this plugin, I want players to be able to create a Hero that has certain abilities. The two classes that I use are below.
package me.placerwiz;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public class Moba extends JavaPlugin {
StompCooldown a;
#Override
public void onEnable() {
getServer().getPluginManager().registerEvents(new MenuClick(this), this);
new PlayerListener(this);
new StompAbility(this);
getLogger().info("This plugin has been enabled!");
a = new StompCooldown(this);
a.runTaskTimer(this, 20, 20);
getCommand("pearl").setExecutor(new WarpAbility());
getCommand("menu").setExecutor(this);
}
#Override
public void onDisable() {
}
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("Menu") && sender instanceof Player) {
Player player = (Player) sender;
player.openInventory(Menu.getMenu());
return true;
}
return false;
}
public static void sircunningham1_1(String args[]) {
SirCunningham_1_1 getLoadout = new SirCunningham_1_1();
getLoadout.heroChosen();
}
public static void sircunningham2_1(String args[]) {
SirCunningham_2_1 getLoadout = new SirCunningham_2_1();
getLoadout.heroChosen();
}
public void gotHero(String heroChoice) {
if (heroChoice == "") {
}
}
public boolean heroTest(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("hero") && sender instanceof Player) {
Player player = (Player) sender;
player.openInventory(Menu.getMenu());
return true;
}
return false;
}}
The code above is my main class, Moba. In this code, a variable called heroChoice is received from the other class. The only problem from this is that I want the code to get what the player has selected as the hero. When it gets the hero, I want it to get the hero that the player has selected. Is there anyway I can get a variable sent to the Moba class after the player clicks on the final inventory item. It might need to use this class where the player selects the final ability for the hero "Sir Cunningham". (See code below)
package me.placerwiz;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class SirCunningham_2_1{
static String hero;
public static Inventory getMenu(){
Inventory inv = Bukkit.createInventory(null, 18, ChatColor.GREEN + ChatColor.BOLD.toString() + "Choose ultimate ability!");
ItemStack item = new ItemStack(Material.IRON_BOOTS);
ItemMeta meta = item.getItemMeta();
List<String> lore = new ArrayList<String>();
lore.add(" ");
lore.add(ChatColor.YELLOW + "Thoughts of glory inspire your team to");
lore.add(ChatColor.YELLOW + " win this battle! Everyone on your team");
lore.add(ChatColor.YELLOW + " gains a buff!");
meta.setLore(lore);
meta.setDisplayName(ChatColor.GOLD + ChatColor.BOLD.toString() + "Glory");
item.setItemMeta(meta);
inv.addItem(item);
return inv;
}
#EventHandler
public static void onClick(InventoryClickEvent event) {
if (!ChatColor.stripColor(event.getInventory().getName()).equalsIgnoreCase("Choose ultimate ability!"))
return;
Player player = (Player) event.getWhoClicked();
event.setCancelled(true);
if(event.getCurrentItem()==null || event.getCurrentItem().getType()==Material.AIR || !event.getCurrentItem().hasItemMeta()){
player.closeInventory();
return;
}
if(event.getCurrentItem().getType() == Material.IRON_BOOTS){
player.closeInventory();
String hero = "SirCunnigham_2_1";
player.openInventory(Customizer.getMenu());
}
else{
player.sendMessage(ChatColor.GREEN + "[" + ChatColor.YELLOW + "MOBA" + ChatColor.GREEN + "]" + ChatColor.GOLD + "-Under Construction-");
player.closeInventory();
}
}
public static void heroChosen(){
String heroChoice = hero;
Moba sendLoadout = new Moba();
sendLoadout.gotHero(heroChoice);
}
}
All I need to get this to work is to have the String hero (from the if event above) to equal the String heroChoice. Thanks for reading this far and I hope this will get solved. It means a lot to me!
Do not "hide" a variable! You have a static variable named "hero" of type String but you have created another one with the same type and the same name of the static one. So you want to get the name of the hero.
Declaring that variable static you make that variable equal to all of the instances of that class.
Keep reading if you want to know the real solution.
Note, using OOP (Object-Oriented Programming) is a more efficient way to do this.
From what I understood from the question, you want associate an hero name to a player.
You can simply do it with an HashMap.
public static HashMap<Player,String> playerHero = new HashMap<Player,String>();
or if you're using Java 8
public static HashMap<Player,String> playerHero = new HashMap<>();
To add a player AND a hero name do
MyClass.playerHero.put(player, heroName);
To get the heroName from the player:
MyClass.playerHero.get(player);
To get the players from the heroName:
You can make a method:
public static List<Player> getPlayers(String heroName){
List<Player> players = new ArrayList<Player>();
for(Map.Entry<Player,String> e : MyClass.playerHero.entrySet()){
if(e.getValue().equalsIgnoreCase(heroName)){
players.add(e.getKey());
}
}
return players;
}
All these variables are static, so we can access them with MyClass.variableName
All these methods are static, so we can access them with MyClass.method(parameters);
Hope this helped!
You could use the static modifier for heroChoice and all methods that work with your variable, but this is not best practice because in many cases you will not be able to use static and even for this case, you can't make the Bukkit API's EventHandlers static. So what do you do? Its simple.
Use OOP, pass instance of invoking object's variable through constructor
Every object can have constructors, the constructors contain code that will be run when an instance of that object is created. You can also pass paremters to a constructor just like you would a method. As a result, you can simply pass the variable you want from one class into the constructor of the other and store it. For example:
class Car { //my class Car
double topSpeedMPH; //when a Car is created, it needs to get a top speed
public Car(double topSpeedMPH) { //public constructor for Car, requires a double parameter
this.topSpeedMPH = topSpeedMPH; //set the class' topSpeedMPH variable to the local one
}
}
Then in the invoking code:
double speed = 10;
Car fordFusion = new Car(speed);
So for your code specifically:
class Moba {
String heroChoice; //Moba has heroChoice stored
public Moba(String choice) { //Moba constructor, requires a String (which is the choice)
this.heroChoice = choice; //stores the parameter String to use later
}
}
class SirCunningham_2_1 {
public void heroChosen(){
String heroChoice = hero;
Moba sendLoadout = new Moba(heroChoice);
sendLoadout.gotHero(heroChoice);
}
}
Another solution: Use OOP, pass instance of the entire invoking object through constructor using this keyword
The previous solution is great for just one variable, but what if I wanted to be able to access multiple variables from another object? It would be rather inconvenient to make each of them individual parameters. Luckily, there is a good way to do this. Simply pass the entire instance through. The following example (using Car again) shows it:
class Motor {
Car myCar;
double topSpeed;
double accel;
public Motor(Car c) { //require instance of car
this.myCar = c;
this.topSpeed = myCar.topSpeed; //get values from instance
this.accel = myCar.secondsTo60;
}
}
class Car {
Motor m;
double topSpeed = 108;
double secondsTo60 = 8;
int seats = 4;
public Car() {
m = new Motor(this); //use this keyword to pass entire instance
}
void startEngine() {
System.out.println("Vroom Vroom!");
}
}
A big advantage to this solution is that I could even use methods from the other class:
public Motor(Car c) { //require instance of car
this.myCar = c;
this.topSpeed = myCar.topSpeed; //get values from instance
this.accel = myCar.secondsTo60;
myCar.startEngine();
}

Going through rooms in a text based game in Java

I hope this isn't too amateurish for you guys but I'm having a hard time creating a small text-based game in Java using objects. So far I've wrote classes for Player, Item(this will be for later use, for now I have simpler goals), Room, Inventory(again, for later use) and the Main Class. What should I use to keep track of my location? I want to go through locations back-and-forth like in Zork (example go north, go south etc.) I thought about using an ArrayList that would contain every location, but again this stumbles me even more. What I wrote so far:
class Player{
//int healthPoints; for later use
private String playerName;
public void setPlayerName(String playerNameParam)
{
playerName=playerNameParam;
}
public String getPlayerName(){
return playerName;
}
}
class Item{
private String itemName;
public void setItemName(String itemNameParam)
{
itemName=itemNameParam;
}
public String getItemName()
{
return itemName;
}
}
class ExitRoom{
}
class Room{
private String roomName;
public void setRoomName(String roomNameParam){
roomName=roomNameParam;
}
public String getRoomName(){
return roomName;
}
private String roomDescription;
public void setRoomDescription(String roomDescriptionParam){
roomDescription=roomDescriptionParam;
}
public String getRoomDescription(){
return roomDescription;
}
}
class Inventory{
private ArrayList<Item> items= new ArrayList<Item>();
public boolean findItem(String itemToFind)
{
for(int i=0;i<items.size();i++){
if(items.get(i).getItemName()==itemToFind){
return true;
}
}
return false;
}
}
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
Player player = new Player();
boolean gameRunning=true;
while(gameRunning){
System.out.println("Welcome to TextBasedGamev1!"
+ "Before beginning, please enter your name");
String name=scanner.nextLine();
player.setPlayerName(name);
Room forestWelcome=new Room();
Room forestSouth=new Room();
Room forestNorth=new Room();
Room abandonedHouse=new Room();
}
Any help is really appreciated!
A possible approach (not necessarily the best) would be to store in each room the connections to other rooms. For example:
enum Direction {
NORTH, SOUTH, EAST, WEST;
}
class Room {
private Map<Direction, Room> connections;
...
}
Generally the aproach is using a matrix with each cell and a Point to mark the position of the player, for example
Class Map {
private Room[][] matrix;
private Player player;
...
}
class Player{
private Point position;
....
}
Text adventures are actually state machines.
You might want to look at the 3 free chapters of the book I've been writing on Artificial Intelligence in C# for Games, as it covers this and Java and C# are quite similar.
http://unseenu.wikispaces.com/Game+AI+in+C-Sharp

Adding new objects to an ArrayList in constructor

I am trying to add newly created objects to an ArrayList in the constructor of a class. The new objects are being created in another class in the main method.
Main method:
public static void main(String[] args) {
// TODO code application logic here
Player p1 = new Player("Peter");
}
My Player class:
public class Player {
protected static int age;
protected static String name;
protected static ArrayList players = new ArrayList();
Player(String aName) {
name = aName;
age = 15;
players.add(new Player()); // i know this doesn't work but trying along these lines
}
}
You have to edit the line
players.add(new Player());
to
players.add(this);
Also, there is no need to make the age and name static
I suggest you should have the following code instead
import java.util.ArrayList;
public class Player {
protected int age; //static is removed
protected String name; // static is removed
protected static ArrayList<Player> players = new ArrayList<Player>(); //this is not a best practice to have a list of player inside player.
Player(String aName) {
name = aName;
age = 15;
players.add(this); // i know this doesn't work but trying along these lines
}
public static void main(String[] args) {
// TODO code application logic here
Player p1 = new Player("Peter");
}
}
It sounds like you're actually asking how to refer to the instance you're constructing.
That's what the this keyword does.
This post is old, but for someone with similiar needs I suggest doing it like this:
Main class:
public static void main(String[] args) {
//TODO code application logic here
java.util.List<Player> players = new java.util.ArrayList<>(); //list to hold all players
Player p1 = new Player("Peter"); //test player
players.add(p1); //adding test player to the list
players.add(new Player("Peter")); //also possible in this case to add test player without creating variable for it.
}
Player class:
public class Player {
private final int age = 15; //if you always going to use 15 as a age like in your case it could be final. if not then pass it to constructor and initialize the same way as the name.
private String name;
Player(String name) { //variable name can be the same as one in class, just add this prefix to indicated you are talking about the one which is global class variable.
this.name = name;
}
}
Generally you should avoid using static keyword on variables which supposed to be different in each instance of that class. Avoid having object of itself inside.

Categories