Im wondering how i would go about using a bag in the game im making. The bag is supposed to hold 2 items that can be found in different rooms around the "map" and when both these items are found the game can be completed by finding the boss room. The bag is supposed to be its own java class. And how do i make the player activate these items?
rum4 and rum6 is the item rooms for anyone wondering.
(I dont want anyone to finish this game for me, i just want some help)
//Sorry for the swedish text.
//This is obviously not all of the code but the rest of it is not neccessary.
import java.util.Scanner;
public class Spel
{
public static void main(String[] args) {
Rum start = new Rum("Du är i en mörk och fuktig källare."," En källare. ");
Rum rum1 = new Rum("Du är mitt i en snöstorm!", "En snöstorm. ");
Rum rum2 = new Rum("Du hittade ett svärd!", "Ett hus. ");
Rum rum3 = new Rum("Du gick in i en fälla, slå över 3 för att fly norrut.", "En skog. ");
Rum rum4 = new Rum("Jaha... här fanns det ingenting.", "En äng. ");
start.north = rum1;
start.east = rum2;
start.south = rum3;
rum1.south = start;
rum1.east = rum4;
rum2.west = start;
rum2.north = rum4;
rum3.fälla = new trap();
rum3.north = start;
rum4.west = rum1;
rum4.south = rum2;
Rum current = start;
while(true) {
System.out.println(current);
System.out.println("Vart vill du gå? (n,s,v,o)");
char c = new Scanner(System.in).next().charAt(0);
switch(c) {
case 'n':
current = current.north;
break;
case 's':
current = current.south;
break;
case 'v':
current = current.west;
break;
case 'o':
current = current.east;
break;
}
if (current.fälla != null){
current.fälla.rulla();
}
// if (monster){
// System.out.println("Du kan nu döda monsteret");
if(current == null) {
System.out.println("Du ramlar av världen och dör †††");
System.out.println("Försök igen");
current = start;
}
}
I would create a class Bag with two Items
public class Bag {
Item item1;
Item item2;
}
public class Item {
<any item properties here>
}
In that case, I believe you need a class for Item, and types of items for the specific effects.
public abstract class Item {
public abstract void useItemOn(Entity target);
}
public class Entity {
private int maxHitPoints;
private int hitPoints;
private boolean isDead;
...
public void inflictDamage(int damage) {
hitPoints -= damage;
if(hitPoints < 0) {
this.isDead = true;
}
}
public void heal(int healPoints) {
hitPoints += healPoints;
if(hitPoints > maxHitPoints) {
this.hitPoints = maxHitPoints;
}
}
...
}
public class Player extends Entity {
...
}
public class Enemy extends Entity {
...
}
public Bomb extends Item {
#Override
public void useItemOn(Entity target) {
target.inflictDamage(20);
}
}
public Potion extends Item {
#Override
public void useItemOn(Entity target) {
target.heal(20);
}
}
Then
public class Bag {
private List<Item> items;
public Bag() {
this(new ArrayList<Item>());
}
public Bag(List<Item> items) {
this.items = items;
}
public List<Item> getItems() {
return items;
}
}
You can of course use smarter way to store Items to not mix them up, as you still need to figure out if something is a potion or a bomb.
But anyways, using it is simple, you need to take an item from the list, use it on an entity, then remove it from the list if it's a consumable.
Can someone find the boss room before they found the items? If no: how do you prevent it?
What you have to do when using my solution:
Create the bag at the begin of the game
Whenever one of the items was found: call the setFirstItemFound or setSecondItemFound method.
I don't know how you want to enable the boss room, but you can check if i should be findable by using the method "isBothItemsFound()"
Please notice, that this solution only works if there are only two items needed. If later like 10 items needed i would recommend you to make use of a hashTbale, a list or any equal "stacking" classes
public class Bag {
private static boolean firstItemFound = false;
private static boolean secondItemFound = false;
public Bag() {
super();
firstItemFound = false;
secondItemFound = false;
}
/* Sets the status to of the first Item to found */
public static void setFirstItemFound() {
firstItemFound = true;
}
/* Checks if the first item has been found */
public static boolean isFirstItemFound() {
return firstItemFound;
}
/* Sets the status to of the second Item to found */
public static boolean isFSecondItemFound() {
return secondItemFound;
}
/* Checks if the second item has been found */
public static void setSecondItemFound() {
secondItemFound = true;
}
/* Checks if both items has been found */
public static boolean isBothItemsFound() {
boolean bothItemsFound = false;
if (firstItemFound && secondItemFound){
bothItemsFound = true;
}
return bothItemsFound;
}
/* Sets the status to of both Items to not found */
public static void clearBag() {
firstItemFound = false;
secondItemFound = false;
}
}
You could maybe create some Player class to store all player data, and put Bag in it to hold items for example in:
HashMap<String, Item> itemsByName;
and always check when adding a new item to it if size 2 is not over exceeded.
Related
I'm building a simplified inventory program for a "hardware store" in Java. I want to register the items by name and quantity into an array, and also remove or change the quantity if the item gets sold.
i believe i'm done with 80 percent of the work. I just can't figure out how to remove or change the object after storing it. Has this something to do with the equals(Object obj) method? I'm finding it hard to understand how to use the method in my case.
Class for the hardware items:
public class Items {
private String item;
private String quantity;
public Items(){
}
public String getName() {
return item;
}
public String getType() {
return item;
}
public String getQuantity() {
return quantity;
}
public void setItem(String item) {
this.item=item;
}
public void setQuantity(String quantity) {
this.quantity=quantity;
}
}
--
public class Hardware {
public static void main(String[] args) {
List<Items> allItems =new ArrayList<Items>();
Scanner input = new Scanner(System.in);
int choice;
while(true){
System.out.println("Inventory\n");
System.out.print("1.) Add new items to your inventory. \n");
System.out.print("2.) Delete items from your inventory.\n");
System.out.print("3.) Change quantity of an item.\n");
System.out.print("6.) Exit\n");
System.out.print("\nEnter Your Menu Choice: ");
choice = input.nextInt();
Scanner in = new Scanner(System.in);
switch(choice){
case 1:
Items myItems = new Items();
System.out.println("Item:");
myItems.setItem(in.nextLine());
System.out.println("Quantity?");
myItems.setQuantity(in.nextLine());
allItems.add(myItems);
System.out.println(allItems);
System.out.println("The inventory contains the following items:");
for(int i = 0; i < allItems.size(); i++) {
System.out.println(allItems.get(i).getName());
}
break;
case 6:
System.out.println("Exiting Program...");
System.exit(0);
break;
default :
System.out.println("This is not a valid Menu Option! Please Select Another");
break;
}
}
}
}
You should implement the equals method in the Items class like this:
public boolean equals(Object object){
if(this == object){
return true;
}
if(object instanceof Items){
Items newItem = (Item) object;
return item.equals(newItem.item) && quantity.equals(newItem.quantity);
}
return false;
}
Then for the removing and changing options, create an Item object with the user inputs, and loop over through the List, compare each Item object with the one created with the user inputs, until you find the desired object, and then perform the necessary action.
A playlist is considered a repeating playlist if any of the songs contain a reference to a previous song in the playlist. Otherwise, the playlist will end with the last song which points to null.
I need to Implement a function isRepeatingPlaylist that, returns true if a playlist is repeating or false if it is not.
For example, the following code prints "true" as both songs point to each other.
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
first.setNextSong(second);
second.setNextSong(first);
System.out.println(first.isRepeatingPlaylist());
Again, this is not a homework exercise, I am doing coding challenges because when I read theory about programming concepts, I can almost understand, but when faced with writing a program I don't know where to start, or how to apply.
public class Song {
private String name;
private Song nextSong;
public Song(String name) {
this.name = name;
}
public void setNextSong(Song nextSong) {
this.nextSong = nextSong;
}
public boolean isRepeatingPlaylist() {
//throw new UnsupportedOperationException("Waiting to be implemented.");
List<String> list = new ArrayList<String>();
list.add(one);
list.add(two);
list.add(three);
list.add(four);
if list.contains()
return true;
else
return false;
}
public static void main(String[] args) {
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
Song third = new Song("a test");
Song fourth = new Song("survivor");
first.setNextSong(second);
second.setNextSong(first);
System.out.println(first.isRepeatingPlaylist();
}
}
You can loop through the playlist and add every song to a set on condition it is not yet in the set. Once you reach the end of the list your list is not a repeating list. If you find a song which exists already in the set, you have a repeating list.
public boolean isRepeatingList(Song firstSong)
{
Set<Song> uniqueSongs=new HashSet<>();
uniqueSongs.add(firstSong);
Song current=firstSong;
while(current.getNextSong()!=null)
{
if(uniqueSongs.contains(current.getNextSong()))
return true;
// add the song to the set, and assign current to the next song
uniqueSongs.add(current=current.getNextSong());
}
// we reached the end of the list without finding any doubles, so:
return false;
}
Please check the answer below:
public boolean isRepeatingPlaylist() {
Song slow = this.nextSong;
Song fast = slow == null ? null : slow.nextSong;
while (fast != null) {
if (slow == this || slow == fast)
return true;
slow = slow.nextSong;
fast = fast.nextSong;
if (fast != null)
fast = fast.nextSong;
}
return false;
}
I think this might work:
public boolean isRepeatingPlaylist()
{
Set<Song> songs = new HashSet<Song>();
songs.add(this);
Song current = this.getNextSong();
//if you did not implment a getter for the nextSong property I think you should
while (current.getNextSong() != null && !songs.contains(current.getNextsong())) {
songs.add(current);
current = current.getNextSong();
}
return songs.contains(current.getNextsong());
}
Edit 1: As mentioned in the comments of this answer, the == in some cases might not be the best because it compares the memory location of each object. In order to fix this issue, implementing the methods hashCode() and equals() are recommended, if you don't know what they are, try reading this.
This problem can be consider the classic problem: linked list has a circle or not.You can find method from here to solve but for your it's not easy to construct linked list,we use another method to solve this problem:count the nextSong,code like this:
public static boolean isRepeatingPlaylist(List<Song> songs) {
int counts = 0;
for (Song song : songs) {
if (null !=song.getNextSong()){
counts ++;
}
}
return songs.size() - counts != 1;
}
The issue with most answers ( esp. one by Conffusion ) is that its not talking about hasCode() & equals(...) method for Song class even though approach is correct. uniqueSongs.contains will not give correct result if these two methods are not properly implemented.
OP has also not shown structure of Song class.
Second thing in code samples of OP is that which class should have which responsibility is not clear & if I already have a custom linkedlist then Java ArrayList won't be needed - though I have added both versions. Use of words - array & arrayList in question title is confusing because OP has a traditional LinkedList & that has noting to do with Java while arrayList is a Java specific DS.
public class Song {
private String data;
private Song nextSong;
public Song(String data) {
this.data=data;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Song getNextSong() {
return nextSong;
}
public void setNextSong(Song nextSong) {
this.nextSong = nextSong;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Song other = (Song) obj;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data)) {
return false;
}
return true;
}
}
Ideally , there should be a PlayList class to create playlist and method isRepeatingPlaylist should belong there. I have added in main driver class for simplicity ,
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class RepetablePlaylist {
public static void main(String[] args) {
// Begin - construct Song list
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
Song third = new Song("a test");
Song fourth = new Song("survivor");
first.setNextSong(second);
second.setNextSong(first);
List<Song> list = new ArrayList<>();
list.add(first);
list.add(second);
list.add(third);
list.add(fourth);
// End - construct Song list
boolean isRepeatable = isRepeatingPlaylist(list);
System.out.println(" isRepeatable : "+isRepeatable);
isRepeatable = isRepeatingPlaylist(first);
System.out.println(" isRepeatable : "+isRepeatable);
}
private static boolean isRepeatingPlaylist(List<Song> playList) {
Set<Song> previous = new HashSet<>();
for(Song song : playList) {
if(song.getNextSong() != null && previous.contains(song.getNextSong())) {
return true;
}
previous.add(song);
}
return false;
}
private static boolean isRepeatingPlaylist(Song head) {
Set<Song> previous = new HashSet<>();
Song currentNode = head;
while(currentNode.getNextSong() != null ) {
if(previous.contains(currentNode.getNextSong())) {
return true;
}
previous.add(currentNode);
currentNode=currentNode.getNextSong();
}
return false;
}
}
I used this code, it will work but the site tells that it is not correct.
Is it ok to add another int member to the class?
public class Song {
private String name;
private Song nextSong;
private int rep = 0 ;
public Song(String name) {
this.name = name;
}
public void setNextSong(Song nextSong) {
this.nextSong = nextSong;
}
public boolean isRepeatingPlaylist() {
if (this.nextSong == null){
return false;
} else {
rep++;
if (rep > 1){
return true;
}
return this.nextSong.isRepeatingPlaylist();
}
}
public static void main(String[] args) {
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
first.setNextSong(second );
second.setNextSong(first );
System.out.println(first.isRepeatingPlaylist());
}
}
Please check the answer below:
using System.Collections.Generic;
public bool IsRepeatingPlaylist()
{
HashSet<Song> songs = new HashSet<Song>();
Song current = this;
while (current.NextSong != null && !songs.Contains(current.NextSong))
{
songs.Add(current);
current = current.NextSong;
}
return songs.Contains(current.NextSong);
}
This is my c++ code, it runs greatly!
#include <stdexcept>
#include <iostream>
#include <string>
#include <set>
using namespace std;
class Song
{
public:
Song(std::string name): name(name), nextSong(NULL) {}
void next(Song* song)
{
this->nextSong = song;
}
bool isRepeatingPlaylist()
{
set<string> playlist;
Song *temp=this;
while(temp->nextSong!=NULL){
if (!playlist.insert(temp->name).second) return true;
temp=temp->nextSong;
}
return false;
}
private:
const std::string name;
Song* nextSong;
};
#ifndef RunTests
int main()
{
Song* first = new Song("Hello");
Song* second = new Song("Eye of the tiger");
first->next(second);
second->next(first);
std::cout << std::boolalpha << first->isRepeatingPlaylist();
}
#endif */
I am doing a simple sch program to add friends, which is to add objects into an arraylist. I followed everything but my method befriend() doesn't seem to work.
When i manually test using the .add() in the main, it works. Where am i doing wrongly?
import java.util.*;
public class NetworkFriends {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Person me = new Person("Aloysius", 1);
ArrayList<Person> myList = new ArrayList<Person>(Arrays.asList(me.getFriendList()));
Person p1 = new Person("Gorgon", 2);
Person p2 = new Person("Eddy", 3);
me.befriend(p1);
for(Person i : myList) {
System.out.println("Name: " + i.getName());
}
}
}
class Person
{
private int id;
private String name;
private ArrayList<Person> friendList;
private static int runningNum = 0;
private static int friendsLimit = 5;
private String degree;
private int degreeNum;
/* Constructor - 1 param */
public Person(String name, int degreeNum)
{
//Implement your code here..
//Initialize all necessary variable(s)
this.name = name;
friendList = new ArrayList<Person>(5);
this.degree = degree;
this.degreeNum = degreeNum;
}
public void befriend(Person p){
//Implement your code here..
ArrayList<Person> anotherList = new ArrayList<Person>(Arrays.asList(p.getFriendList()));
for(Person i : friendList) {
if(!isFriend(this) && friendList.size() < 5) {
friendList.add(p);
anotherList.add(this);
}
else if(!isFriend(this) && friendList.size() == 5) {
System.out.println("Friends limit reached");
}
else {
System.out.println("Already in friend list");
}
}
}
}
public boolean isFriend(Person p){
//Implement your code here..
boolean isItAFriend = true;
for(Person i : friendList) {
if(friendList.contains(p)) {
isItAFriend = true;
}
else {
isItAFriend = false;
}
}
return isItAFriend;
}
The problem is with the foreach loop in your befriend method. You are creating a new Person with the constructor that creates a empty friend list with an initial size of 5, but is still empty.
In your befriend method, you then are looping for each friend in this empty list. So the code within the loop will not be executed and the friend is never added to a list.
I suspect you want to do something like this: (and as this looks like homework I will only give you pseudo-code)
Is the person already a friend
Yes - nothing needs to be done or give feedback and return
No - Continue
Have they reached their friend limit
Yes - display feedback and return
No - Continue
Add the friend
I'm writing a game-like program and it has a class that has to act as an item. Normally I would just keep it as an item but every one has to wait 10 game-days in order to start doing what it's meant to. Is there a way to update the days in all the classes at once? I've tried to use a static method but you can't use instance variables in those so it didn't work. I've thought about possibly making a code that expands every time a new instance is made but I can't find anything i can understand about it. Is there any way to add to a method, make this an item, anything? This is what I have at the moment:
public class Tree
{
private boolean fullGrown;
private int day;
private int APDay; //apples per day
private static int totalApples;
public Tree()
{
fullGrown = false;
day = 0;
APDay = (int) (Math.random()*2) + 4;
}
public void updateDay()
{
day = day + 1;
if (day == 10) fullGrown = true;
if (fullGrown == true) totalApples = totalApples + APDay;
}
public void skipGrowth()
{
fullGrown = true;
}
}
Although this works, you have to update the day for every instance separately. I need a way to update all the instances at the same time. This will also be used by a code and not the actual interface, just in case that's helpful.
Observer and factory pattern looks like a good candidate here.
I hope the code below explain rest to you
public interface DayEventListener {
public void onDay10(DayEvent DayEvent);
}
public class DayEvent {
//... pojo
}
public class AwesomeGame {
private List<DayEventListener> dayEventListenerList = new ArrayList<>();
public void addDayListener(DayEventListener del) {
dayEventListener.add(del);
}
public void fireDay10Event(DayEvent de) {
for(DayEventListener del : dayEventListenerList) {
del.onDay10(de);
}
}
public class Item implements DayEventListener {
//All constructors should be private
public static Item buildItem() {
Item Item = new Item();
awesomeGame.addDayEventListener(Item);
return item;
}
}
so I did some research and while I was working on another project I discovered that i could use a vector to keep track of all my instances, so here is that class:
import java.util.Vector;
public class catcher
{
private static Vector allInstances = new Vector();
private int catchLeft;
private String name;
public catcher(String name)
{
catchLeft = Integer.parseInt(name.substring(name.indexOf("#") + 1, name.length()));
catchLeft--;
this.name = name;
if (catchLeft != 0) allInstances.add(this);
}
public static synchronized Vector getAllInstances()
{
return (Vector) (allInstances.clone());
}
public boolean check(String name, boolean change)
{
boolean foo;
if (this.name.equals(name))
{
if (change == true) catchLeft--;
foo = true;
}
else foo = false;
if (catchLeft <= 0) this.finalize();
return foo;
}
public void finalize()
{
allInstances.removeElement(this);
}
public static void clear()
{
allInstances.clear();
}
}
now that I have a record of all the instances, I used this method in another class to assess all the instances:
import java.util.Iterator;
import java.util.Vector;
public class recipe
{
private boolean checkForList(String name, boolean add)
{
Iterator list = catcher.getAllInstances().iterator();
boolean running = true;
boolean booleanReturn = true;
while (running == true)
{
if (list.hasNext())
{
catcher Foo = (catcher) (list.next());
if (Foo.check(name, false) == true)
{
Foo.check(name, true);
running = false;
booleanReturn = true;
}
}
else
{
if (add == true) new catcher(name);
running = false;
booleanReturn = false;
}
}
return booleanReturn;
}
}
I'm sure that this can be modified to update the classes instead of just accessing them.
I really don't understand the principle of Object Oriented Design??
So I have classes
Map class holds rooms and connects all of rooms , places all of hazards randomly into rooms, return the particulate room, and return the random rooms.
and
Player class that play turns, move player from room to another, shoot into rooms and play games.
also
Room class as follow.
import java.util.ArrayList;
public class Room
{
private int myRoomID;
private ArrayList<Room> myNeighbours;
private boolean myHasBats;
private boolean myHasPit;
private boolean myHasWumpus;
public Room(int id) {
myRoomID = id;
myNeighbours = new ArrayList<Room>();
}
public int getRoomID() {
return myRoomID;
}
public ArrayList<Room> getNeighbours() {
return myNeighbours;
}
public void connectTo(Room room) {
myNeighbours.add(room);
}
public boolean hasBats() {
return myHasBats;
}
public void setHasBats(boolean flag) {
myHasBats = flag;
}
public boolean hasPit() {
return myHasPit;
}
public void setHasPit(boolean flag) {
myHasPit = flag;
}
public boolean hasWumpus() {
return myHasWumpus;
}
public void setHasWumpus(boolean flag) {
myHasWumpus = flag;
}
public void checkBats() {
boolean bats = false;
for (Room r : myNeighbours) {
if (r.hasBats()) {
bats = true;
}
}
if (bats) {
System.out.println("I hear squeaking!");
}
}
public void checkPit() {
boolean pit = false;
for (Room r : myNeighbours) {
if (r.hasPit()) {
pit = true;
}
}
if (pit) {
System.out.println("I feel a draft!");
}
}
public void checkWumpus() {
boolean wumpus = false;
for (Room r : myNeighbours) {
if (r.hasWumpus()) {
wumpus = true;
}
}
if (wumpus) {
System.out.println("I smell a wumpus!");
}
}
public boolean enter(Player player) {
System.out.println("You are in Room " + myRoomID);
System.out.print("Exits lead to rooms");
for (Room r : myNeighbours) {
System.out.print(" " + r.getRoomID());
}
System.out.println();
checkBats();
checkPit();
checkWumpus();
if (myHasBats) {
System.out.println("A flock of bats picks you up and carries you off to another room!");
return player.moveRandom();
}
else if (myHasPit) {
System.out.println("You fall into a bottomless pit!");
return true;
}
else if (myHasWumpus) {
System.out.println("You have been eaten by a wumpus!");
return true;
}
return false;
}
public boolean shoot()
if (myHasWumpus) {
System.out.println("You killed the Wumpus!");
return true;
}
else {
System.out.println("Your arrow falls with a clatter to the floor!");
return false;
}
}
And I want to change this so that the wumpus needs to be shot more than once (you choose how many times) to be killed. Each time it is shot it runs to a random neighbouring room (not the one the player is in).
I am assuming that I need to change public boolean shoot() method into loop and call public Room getRandomRoom() as below.
But I really don't understand how to do this, especially because the use of boolean method is very confusing to me.
Does anyone know where I can find a information to learn the basic's of Object Oriented Design?
public Room getRandomRoom() {
Random rng = new Random();
int i = rng.nextInt(Map.NUM_ROOMS);
return myRooms.get(i);
}
Later on we are going to use implements in the class to separate all of hazards into classes. but for not they are all in Map and Room class.
Well without a wumpus class that's going to be messy and limited and even more inefficient. Your problem isn't that you don't get OO, it's that you are being restricted from using it.
Without out the class.
You are goingto have to add a myWumpusShotCount to room
Then in your shoot function, add 1 to it, test to see if it's 3 and if so kill it else random choose a room and set hasWumpus and WumpusShotCount in it
If you had a wumpus class it would have a property room , and another for how many bullets it had shipped and a behaviour when shot, ie the state of the wumpus and the behaviours of wumpus would be implemented by wumpus, not room. That's OO.
With the help of Tony Hopkinson, I have come up with this code but it doesn't compile yet. It says can not find symbol - method getRandomRoom() To call the methodgetRandomRoom();` from Map class.
To send wumpus to the room another room randomly
public boolean shoot() {
if (myHasWumpus) {
myWumpusShotCount = 3;
for(int i = 0; i< myWumpusShotCount; i++){
if(myWumpusShotCount<=i){
System.out.println("You killed the Wumpus!");
return true;
}
else {
Room wRoom = getRandomRoom();
System.out.println("You killed the Wumpus!");
return false;
myWumpusShotCount++;
}
System.out.println("Your arrow falls with a clatter to the floor!");
return false;
}
System.out.println("You killed the Wumpus!");
return true;
}
}
System.out.println("Your arrow falls with a clatter to the floor!");
return false;
}