Minecraft bukkit scheduler and procedural instance naming - instance

This question is probably pretty obvious to any person who knows how to use Bukkit properly, and I'm sorry if I missed a solution in the others, but this is really kicking my ass and I don't know what else to do, the tutorials have been utterly useless. There are really 2 things that I need help doing:
I need to learn how to create an indefinite number of instances of an object. I figure it'd be like this:
int num = 0;
public void create(){
String name = chocolate + num;
Thingy name = new Thingy();
}
So you see what I'm saying? I need to basically change the name that is given to each new instance so that it doesn't overwrite the last one when created. I swear I've looked everywhere, I've asked my Java professor and I can't get any answers.
2: I need to learn how to use the stupid scheduler, and I can't understand anything so far. Basically, when an event is detected, 2 things are called: one method which activates instantly, and one which needs to be given a 5 second delay, then called. The code is like this:
public onEvent(event e){
Thingy thing = new Thingy();
thing.method1();
thing.doOnDelay(method2(), 100 ticks);
}
Once again, I apologize if I am not giving too many specifics, but I cannot FOR THE LIFE OF ME find anything about the Bukkit event scheduler that I can understand.
DO NOT leave me links to the Bukkit official tutorials, I cannot understand them at all and it'll be a waste of an answer. I need somebody who can help me, I am a starting plugin writer.
I've had Programming I and II with focus in Java, so many basic things I know, I just need Bukkit-specific help for the second one.
The first one has had me confused since I started programming.

Ok, so for the first question I think you want to use a data structure. Depending on what you're doing, there are different data structures to use. A data structure is simply a container that you can use to store many instances of a type of object. The data structures that are available to you are:
HashMap
HashSet
TreeMap
List
ArrayList
Vector
There are more, but these are the big ones. HashMap, HashSet, and TreeMap are all part of the Map class, which is notable for it's speedy operations. To use the hashmap, you instantiate it with HashMap<KeyThing, ValueThingy> thing = new HashMap<KeyThing, ValueThing>(); then you add elements to it with thing.put(key, value). Thn when you want to get a value out of it, you just use thing.get(key) HashMaps use an algorithm that's super fast to get the values, but a consequence of this is that the HashMap doesn't store it's entries in any particular order. Therefore when you want to loop though it with a for loop, it randomly returns it's entries (Not truly random because memory and stuff). Also, it's important to note that you can only have one of each individual key. If you try to put in a key that already exists in the map, it will over-right the value for that key.
The HashSet is like a HashMap but without storing values to go with it. It's a pretty good container if all you need to use it for is to determine if an object is inside it.
The TreeMap is one of the only maps that store it's values in a particular order. You have to provide a Comparator (something that tells if an object is less than another object) so that it knows the order to put the values if it wants them to be in ascending order.
List and ArrayList are not maps. Their elements are put in with a index address. With the List, you have to specify the number of elements you're going to be putting into it. Lists do not change size. ArrayLists are like lists in that each element can be retrieved with arrayListThing.get(index) but the ArrayList can change size. You add elements to an ArrayList by arrayListThing.add(Thing).
The Vector is a lot like an ArrayList. It actually functions about the same and I'm not quite sure what the difference between them is.
At any rate, you can use these data structures to store a lot of objects by making a loop. Here's an example with a Vector.
Vector<Thing> thing = new Vector<Thing>();
int numberofthings = 100;
for(int i = 0; i < numberofthings; i++) {
thing.add(new Thing());
}
That will give you a vector full of things which you can then iterate through with
for(Thing elem:thing) {
thing.dostuff
}
Ok, now for the second problem. You are correct that you need to use the Bukkit Scheduler. Here is how:
Make a class that extends BukkitRunnable
public class RunnableThing extends BukkitRunnable {
public void run() {
//what you want to do. You have to make this method.
}
}
Then what you want to do when you want to execute that thing is you make a new BukkitTask object using your RunnableThing
BukkitTask example = new RunnableThing().runTaskLater(plugin, ticks)
You have to do some math to figure out how many ticks you want. 20 ticks = 1 second. Other than that I think that covers all your questions.

Related

How to create a new list of Strings from a list of Longs in Kotlin? (inline if possible)

I have a list of Longs in Kotlin and I want to make them strings for UI purposes with maybe some prefix or altered in some way. For example, adding "$" in the front or the word "dollars" at the end.
I know I can simply iterate over them all like:
val myNewStrings = ArrayList<String>()
longValues.forEach { myNewStrings.add("$it dollars") }
I guess I'm just getting nitpicky, but I feel like there is a way to inline this or change the original long list without creating a new string list?
EDIT/UPDATE: Sorry for the initial confusion of my terms. I meant writing the code in one line and not inlining a function. I knew it was possible, but couldn't remember kotlin's map function feature at the time of writing. Thank you all for the useful information though. I learned a lot, thanks.
You are looking for a map, a map takes a lambda, and creates a list based on the result of the lambda
val myNewStrings = longValues.map { "$it dollars" }
map is an extension that has 2 generic types, the first is for knowing what type is iterating and the second what type is going to return. The lambda we pass as argument is actually transform: (T) -> R so you can see it has to be a function that receives a T which is the source type and then returns an R which is the lambda result. Lambdas doesn't need to specify return because the last line is the return by default.
You can use the map-function on List. It creates a new list where every element has been applied a function.
Like this:
val myNewStrings = longValues.map { "$it dollars" }
In Kotlin inline is a keyword that refers to the compiler substituting a function call with the contents of the function directly. I don't think that's what you're asking about here. Maybe you meant you want to write the code on one line.
You might want to read over the Collections documentation, specifically the Mapping section.
The mapping transformation creates a collection from the results of a
function on the elements of another collection. The basic mapping
function is
map().
It applies the given lambda function to each subsequent element and
returns the list of the lambda results. The order of results is the
same as the original order of elements.
val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 })
For your example, this would look as the others said:
val myNewStrings = longValues.map { "$it dollars" }
I feel like there is a way to inline this or change the original long list without creating a new string list?
No. You have Longs, and you want Strings. The only way is to create new Strings. You could avoid creating a new List by changing the type of the original list from List<Long> to List<Any> and editing it in place, but that would be overkill and make the code overly complex, harder to follow, and more error-prone.
Like people have said, unless there's a performance issue here (like a billion strings where you're only using a handful) just creating the list you want is probably the way to go. You have a few options though!
Sequences are lazily evaluated, when there's a long chain of operations they complete the chain on each item in turn, instead of creating an intermediate full list for every operation in the chain. So that can mean less memory use, and more efficiency if you only need certain items, or you want to stop early. They have overhead though so you need to be sure it's worth it, and for your use-case (turning a list into another list) there are no intermediate lists to avoid, and I'm guessing you're using the whole thing. Probably better to just make the String list, once, and then use it?
Your other option is to make a function that takes a Long and makes a String - whatever function you're passing to map, basically, except use it when you need it. If you have a very large number of Longs and you really don't want every possible String version in memory, just generate them whenever you display them. You could make it an extension function or property if you like, so you can just go
fun Long.display() = "$this dollars"
val Long.dollaridoos: String get() = "$this.dollars"
print(number.display())
print(number.dollaridoos)
or make a wrapper object holding your list and giving access to a stringified version of the values. Whatever's your jam
Also the map approach is more efficient than creating an ArrayList and adding to it, because it can allocate a list with the correct capacity from the get-go - arbitrarily adding to an unsized list will keep growing it when it gets too big, then it has to copy to another (larger) array... until that one fills up, then it happens again...

Efficiently make a view of (or copy) a subset of a large HashMap in Kotlin

I am trying to create a subhashmap from a huge hashmap without copy the original one.
currently I use this:
val map = hashMapOf<Job, Int>()
val copy = HashMap(map)
listToRemoveFromCopy.forEach { copy.remove(it) }
this cost me around 50% of my current algorithm. Because java is calculating the hash of the job really often.
I only want the map minus the listToRemoveFromCopy in a new variable without removing the listToRemoveFromCopy elements from the original list.
anyone know this?
Thanks for help
First, you need to cache the hashcode for Job because any approach you use will be inefficient if you cannot have a set or a map of Job objects that operate at top speed.
Hopefully, the parts that make it a hashcode are immutable otherwise it should not be used as a key. It is very dangerous to mutate a key hashcode/equals while in use in a map or set. You should cache it on the first call to hashCode() so that you do not incur a cost until then unless you are sure you will always need it.
Then change listToRemoveFromCopy to be a Set so it can be efficiently used in many ways. You need to do the prior step before this.
Now you have multiple options. The most efficient is:
Guava has a utility function Maps.filterKeys which returns a view into a map, and you can create a predicate that works against a Set of the items to remove.
val removeKeys = listToRemoveFromCopy.toSet()
val mapView = Maps.filterKeys(map, Predicates.not(Predicates.in(removeKeys)))
But be sure to note some methods on the view are not very efficient. If you avoid those methods, this will be the top performing option:
Many of the filtered map's methods, such as size(), iterate across every key/value mapping in the underlying map and determine which satisfy the filter. When a live view is not needed, it may be faster to copy the filtered map and use the copy.
If you need to make a copy instead, you have a few approaches:
Use filterKeys on the map to create a new map in one shot. This is good if the remove list might be a larger percentage of the total keys.
val removeKeys = listToRemoveFromCopy.toSet()
val newMap = map.filterKeys { it !in removeKeys }
Another tempting option you should be careful about is the minus - operator which copies the full map and then removes the items. It can use the listToRemoveFromCopy as-is without it being a set, but the full map copy might undo the benefit. So do not do this unless the remove list is a small percentage of keys.
val newMapButSlower = map - listToRemoveFromCopy
You could pick one model over the other depending on the ratio between map size and remove list size, find a breaking point that works for your "huge".
Implementing your own view into the map to avoid a copy is possible, but not trivial (and by that I mean very complex). Every method you override has to do the correct thing at all times (including the map's own hashCode and equals), and other views would have to be created around the key set and values. The entrySet would be nasty to get right. I'd look for a pre-written solution before attempting your own (the Guava one above or other). This zero-copy model would be the most efficient solution but the most code and is what I would do in the same case if "huge" meant significant processing time. There is a lot that you can get wrong with this approach if you misunderstand any part of the implementation contract.
You could wrap the Guava solution with one that maintains the size attribute as items are manipulated and therefore be efficient for that case. You can also write a more efficient solution if you know the original map is read-only. For ideas, check out the Guava implementation of FilteredKeyMap and its ancestor AbstractFilteredMap.
In summary, likely the caching of your hashcode is going to give you the biggest result for the effort. Start there. You'll need it to do even for the Guava approach.
In addition to Axel's direct answer:
Could calculating the hashcode of a Job be optimised?  If the calculation can't be sped up, could it cache the result?  (There's ample precedent for this, including java.lang.String.)  Or if the class isn't under your control, could you create a delegate/wrapper that overrides the hashcode calculation?
You can use filterKeys function. It will iterate map only once
val copy = map.filterKeys { it !in listToRemoveFromCopy }

Where to locate certain functionality - in the object class methods or in the application code?

It's been a very long time since I touched object oriented programming, so I'm a bit rusty and would appreciate your insight.
Given a class, for example CDPlayer, that includes the field numberOfTracks and currentTrack and the methods getCurrentTrack and setCurrentTrack, where should I put the functionality to set the current track to a random track? In a method such as setRandomTrack inside this class, or in the application code outside this class (e.g. player1.setCurrentTrack(randomnumbergeneratingcode))?
What are the pros and cons of each of these approaches? Which is easier to use, change and maintain? The above example is quite simple, but how do things change when I want e.g. the random number generation to be flexible - one CDPlayer instance to use a normal distribution for randomising, another to use a flat distribution, another to use a distribution defined by some set of numbers, and so forth.
EDIT
Thanks for the three replies so far.
Consider an extension to the op... After a decent amount of coding it becomes clear that on numerous occasions we've had to, in the application code, change current the track to the track three before it but only on Thursdays (which potentially has non-trivial conditional logic to work properly). It's clear that we're going to have to do so many times more throughout the dev process. This functionality isn't going to be user facing (it's useless as far as users would be concerned), it's just something that we need to set on many occasions in the code for some reason.
Do we created a setThreeTracksBeforeOnThursdays method in the class and break the tight representative model of a CD player that this class has, or do we absolutely stick to the tight representative model and keep this functionality in the application code, despite the pain it adds to the application code? Should the design wag the developers or should the developers wag the design?
Well there is no real benefit to where the code is besides that its more readable.
But in some cases it could be less redundant to put the code in the class, it all depends on the language. For example:
C# code in the class:
private Random random = new Random();
public void setRandomTrack()
{
setCurrentTrack(random.NextInt());
}
C# code outside the class:
Random random = new Random();
CDPlayer player = new CDPlayer()
player.setCurrentTrack(random.NextInt());
The code outside has to create a Random Generator outside the class to generate a random integer, you might have to create the Random Generator more than once if its not visible to the class where you calling it from.
If it is a function that all CD players have, then it should be inside the CDPlayer class.
If it is a function that just a few CD players have, then you should inherit the CDPlayer class and put the function in the child class.
If it is a function that no CD player has, then there is no reason to include it in the class. Does it make sense for the CDPlayer class to know about picking random tracks? If not, it should be implemented outside the class.
The pro of putting it inside CDPlayer is that it will be a single method call, and that the function is pretty typical of CD players so it "feels right".
A con of putting it in your application is that it requires two calls, one to get the number of tracks so you can generate the random number, and one to set it.
A con of putting it in CDPlayer is that the class needs to know about random numbers. In this particular case, it's simple enough to use a standard library, but if this were some top security CIA CD player that could be an issue. (Just noticed youvedited your post to hint at something similar)
I'd put the code in CDPlayer, (and add a method to change the random number generator, the fancy term for this is Dependency Injection) but this post hopefully gives you a few of the pros and cons.
Let's try to implement this feature. What are requirements for playing random track?
it should be random (of course),
it should be not current track (nobody wants to hear current track five times in a row if there other tracks to play)
you should pick track from those which exist in player (track number should not exceed count of tracks).
I will use C#:
Random random = new Random();
CDPlayer player = new CDPlayer();
// creates list of track indexes, e.g. { 1, 2, 3, 4, 5, 6, 7 }
var tracksNotPlayed = Enumerable.Range(0, player.NumberOfTracks - 1).ToList();
if(tracksNotPlayed.Count == 0)
// initialize list again, or stop
int index = random.Next(tracksNotPlayed.Count);
int nextTrack = tracksNotPlayed[index];
player.SetCurrentTrack(nextTrack);
tracksNotPlayed.Remove(nextTrack);
That looks like feature envy to me - some other class uses data from player to implement this functionality. Not good. Let's do some refactoring - move all this stuff into player:
public void PlayRandomTrack() // Shuffle
{
if(tracksNotPlayed.Count == 0)
tracksNotPlayed = Enumerable.Range(0, numberOfTracks - 1).ToList();
int index = random.Next(tracksNotPlayed.Count);
int nextTrack = tracksNotPlayed[index];
SetCurrentTrack(nextTrack);
tracksNotPlayed.Remove(nextTrack);
}
It looks better and it's much easier to use outside:
CDPlayer player = new CDPlayer();
player.PlayRandomTrack();
Also if you are implementing something like Winamp (it has two modes - shuffle playing and sequential playing when it automatically plays songs one by one) then consider to move this logic into some Strategy (or it should be Iterator?), which will have two implementations - sequential and shuffle, and will know nothing about player - it's responsibility will be picking number in some range (number of tracks or collection being enumerated should be passed):
public abstract class CollectionIterator<T>
{
public CollectionIterator(IEnumerable<T> source)
{
// save source
}
abstract int GetNextItemIndex();
}
The player will use this iterators/strategies to play next item:
public void PlayTrack()
{
SetCurrentTrack(iterator.GetNextItemIndex());
}
So, we have clear separation of responsibilities here - client uses player to listen music, player knows how to play music, and iterator knows how to pick next item from collection. You can create ThursdaysCollectionIterator if you want some other sequences on Thursdays. That will keep your player and client code untouched.

C++ How to keep track of local variables/objects

Firstly, i am sorry if the title does not properly describe my problem, but i could not think of a better one. =/
I am trying to make a game where all entities that I need to draw on the screen are children of an Actor class.
The actor class has a virtual function called "virtual void drawMe()" that is overridden by the children to specify how it should be drawn.
Ergo, at the end of the game loop, I want to draw all actors. I created a "vector allActors" to help me with this and every time I create a new actor I do this: "allActors.push_back( &newActor )". So far so good (I think).
To draw them at the end of the loop I iterate through all elements in allActors and call "allActors[i]->drawMe()" for each one.
But I discovered that this method will not work for actors that I created locally, like the bullets created when the character shoots (they are created inside an if statement).
I think it is because while I save the address of the bullets in the allActors vector, the actors themselves are destroyed after the if statement ends, so it's an address to nothing.
example:
if ( characterShot == true)
{
Bullet newBullet;
allActors.push_back( &newBullet );
characterShot = false;
}
I have no idea of how to do this in a way that it works, because I can only create the bullet actors IF the character shoots!
Please help me figure out a better and more functional way to do what I want.
Thank you in advance!
Allocate the object dynamically:
allActors.push_back(new Bullet);
Note that the lifetime management will be a genuine nightmare; you should make the container elements some sort of smart pointer (ideally std::unique_ptr<Bullet> or some suitable base class).
You're right in your assumption that you're pushing an address to a local object that then goes out of scope. Doing this should cause your application to be quite unstable.
Allocate the object on the heap instead, using a smart pointer that keeps track of the lifetime of the object for you:
allActors.push_back(tr1::shared_ptr<Bullet>(new Bullet));
This gives you another problem: You have to remove the bullet from the allActors array once it hits the target.

Newbie question: how do I create a class to hold data in Visual Basic Studio?

I'm really sorry. This must seem like an incredibly stupid question, but unless I ask I'll never figure it out. I'm trying to write a program to read in a csv file in Visual Basic (tried and gave up on C#) and I asked a friend of mine who is much better at programming than I am. He said I should create a class to hold the data that I read in.
The problem is, I've never created a class before, not in VB, Java, or anything. I know all the terms associated with classes, I understand at a high level how classes work no problem. But I suck at the actual details of making one.
So here's what I did:
Public Class TsvData
Property fullDataSet() As Array
Get
Return ?????
End Get
Set(ByVal value As Array)
End Set
End Property
End Class
I got as far as the question marks and I'm stuck.
The class is going to hold a lot of data, so I made it an array. That could be a bad move. I don't know. All i know is that it can't be a String and it certainly can't be an Integer or a Float.
As for the Getter and Setter, the reason I put the question marks in is because I want to return the whole array there. The class will eventually have other properties which are basically permutations of the same data, but this is the full set that I will use when I want to save it out or something. Now I want to return the whole Array, but typing "Return fullDataSet()" doesn't seem like a good idea. I mean, the name of the property is "fullDataSet()." It will just make some kind of loop. But there is no other data to return.
Should I Dim yet another array inside the property, which already is an array, and return that instead?
Instead of writing your own class, you could get yourself familiar with the pre-defined class System.Data.DataTable and then use that for holding CSV data.
In the last few years that I've been programming, I've never actually used a multi-dimensional array, and I'd advise you not to use them, either. There's usually ways of achieving the same with a better data structure. For example, consider creating a class (let's call it CsvRecord) that holds only one record; that is, only one line from the CSV file. Then use any of the standard collection types from the System.Collections.Generic namespace (e.g. List(Of CsvRecord)) to hold the entire data (ie. all lines) in the CSV file. This effectively reduces the problem to, "How do I read in one line of CSV data?"
If you want to take suggestion #2 even further, do as cHao says and don't simply lay out the information you've read as a CsvRecord; instead, create an object that reflects the actual content. For example, if your CSV file contains product–price information, call your CSV record class ProductInfo or something more fitting.
If, however, you want to go on with your current approach, you will need a backing field for the property, as demonstrated by Philipp's answer. Your property then becomes a "façade" that only delegates to this backing field. This is not absolutely necessary: You could simply make the backing field Public and let the user of your class access it directly, though that is not considered a good practice.
Ideally, you ought to have a class representing the specific data you want to read in. Setting an entire array at once is asking for trouble; some programs that read {C,T}SV files will freak out if all rows don't have the same number of columns, which is exceedingly easy to do if you can set the data to be an array of arbitrary length.
If you're trying to represent arbitrary data, frankly, you'd do just as well to use a List(Of String). If it's meant to be a table, you could instead read in the first line and make it a list as above (let's call it "headers"), and then make each row a Dictionary(Of String, String). (Let's call each row "row", and the collection (a list of these dictionary objects) "rows".) Just read in the line, split it like you did the first, and say something like row(headers(column number)) = value for each column, and then stuff it into 'rows'.
Or, you could use the data classes (System.Data.DataTable and System.Data.DataSet would do wonders here).
Usually you use a private member to store the actual data:
Public Class TsvData
Private _fullDataSet As String()
Public Property FullDataSet() As String()
Get
Return _fullDataSet
End Get
Set(ByVal value As String())
_fullDataSet = value
End Set
End Property
Note that this is an instance of bad design since it couples a concept to a concrete representation and allows the clients of the class to modify the internals without any error checking. Returning a ReadOnlyCollection or some dedicated container would be better.