score:2
Scala's collections generally don't assume that you'll be manipulating them while they're using a method like foreach
(or executing a for loop). If you want to do things that way, the easiest class to use is Java's java.util.concurrent.ConcurrentSkipListMap
.
// This helps you use Java collections like Scala ones
import collection.JavaConversions._
case class Monster(name: String, hp: Int) {}
val horde = new java.util.concurrent.ConcurrentSkipListMap[Int,Monster]
horde put (0, Monster("wolf",7))
horde put (1, Monster("orc",3))
for (h <- horde) println(h) // Prints out both
Iterator.iterate(Option(horde.firstEntry)) {
case None => None
case Some(e) =>
val m = e.getValue
if (m.name=="wolf") horde.remove(1) // Kill the orc
else if (m.name=="orc") horde.remove(0) // Kill the wolf
Option(horde.higherEntry(e.getKey))
}.takeWhile(_.isDefined).foreach(_=>())
for (h <- horde) println(h) // Prints out just the wolf
Now, granted, this is rather a mess, but it does work, and it gives nice random access to your monsters. You have to maintain the keys in a sensible order, but that's not too hard.
Alternatively, as others have indicated, you could add an isAlive
or isDead
method, and only act on monsters that are alive. Then, after you've passed through the list once, you .filter(_.isAlive)
to throw away all the dead monsters (or .filter(! _.isDead)
), and run it again.
score:0
If you delete an entry in an array, this element would be null.
Therefore you should check every element of your array, e.g.:
for(int i = 0; i <= array.lenght - 1; i++) {
// check null
if(array[i] != null) {
// do stuff
}
}
Hope this helped, have Fun!
score:0
make a copy of the original array, and traverse the copy. if a monster would remove a monster, it would be removed only from the original
score:0
Deleting elements from an array while looping over it is generally a horrible idea. What if you delete an element before you reach it in the loop? Should you not actually delete it until the end of the loop, or should you skip over it?
I recommend something more like this:
var monsters = ... initial list of monsters ...
monsters = for (m <- monsters; if m.alive) yield { m.act; m }
Take advantage of yield
and if
in conjunction with the for loop, which allows you to build a new list.
score:1
EDIT: This first graph misinterperets your question. However, my solution should still work for you.
What you're asking for is a thread-safe array - one that can be accessed by multiple "threads" of execution at a time. Seeing as you're new to Java, my guess is that your game is not going to be multithreaded, and so if you delete an item in an array, that's going to happen for sure before your next loop runs.
That said, if you really want to, you can add a "monster.dead" boolean function to your array, and set that to true whenever a monster dies. In your loop, then, you'd say:
for( i <- 0 to monsters.length-1)
if (monsters[i].dead == false)
monsters(i).act
Most likely, though, you won't run into this issue.
Edit: just reread your post, and realized that you'll be deleting monsters as your array is running. Remember that each line you execute happens sequentially, so when you remove monsters[i], it will be gone the next time the for loop is evaluated. If you have an array of monsters with 5 monsters in it and you delete the second one, when the loop executes again,
monsters.length - 1
is going to evaluate to 3 now. You'll never run into a moment where you hit a deleted array element.
score:2
I would either use a conditional statement to check the monster's isAlive
property in the loop before I called act
, or do that check inside the act
method itself.
score:2
I imagine that your monster[i] is not going to die on his turn, but rather off some other hapless monster?
If you're hooked on arrays, or don't mind the processing time (and for what you're doing, i reckon you don't care), just keep a boolean on each monster of isDead. If a monster dies due to some ... i dunno, reason, just mark the "isDead" as true.
Then, in your monster "act" method, just check if the monster "isDead" or not.
After each loop, you can just prune the list to keep the alive monsters (move all the ones that are alive to a new list and begin again, prune the list in place, whatever is easier for you).
Source: stackoverflow.com
Related Query
- How to make sure the next item in an mutable Array is really next one when looping?
- How to make sure only one Akka JAR makes it on the classpath?
- When using CRUDify, how do I make sure that when a record is saved, the 'owner' field of the record is automatically set to be the logged-in user?
- How to get the element index when mapping an array in Scala?
- How do I make the "Java Hot Spot MaxPermSize" warning go away when using IntelliJ or Play?
- SBT: How to make one task depend on another in multi-project builds, and not run in the root project?
- When should I use Scala's Array instead of one of the other collections?
- How can I force the type of an array when initialized in Scala?
- How do make the JVM recognize a scala.Array[T] as a java array T[] in a polymorphic method call?
- How Scala Array apply method returns the value at the index when the implementation is simply throw new error
- How to ignore an item when generating the json string if the value is None?
- How to split a String by "-" only when the following character is a digit and the previous one is a letter? Java/Scala
- How does one replace the first matching item in a list in Scala?
- How to delete duplicates from a file when other fields are varying. We have to just remove the duplicates based on one column
- How to make ENTER do go to the selected type or method when using Ensime global search with Emacs --no-window?
- Play2 and Anorm, how do I make the One in a One to Many relationship aware of it's Manys
- How do I explode multiple columns of arrays in a Spark Scala dataframe when the columns contain arrays that line up with one another?
- How to create instance from Json when one of the constructor params is initialized by default?
- How to compose futures when the container item is an Either
- Using scala, how do I compare two class types when one has a $ at the end?
- In Scala, how can I get the max date from an array of maps where one of the keys in the map is "date"?
- How to check if value of one column is in the array of another column in Apache Spark?
- How do I make sure a function receives the same parameter type as the current object?
- How do I make sure the path in a Scala Spray URI does not have a trailing slash?
- Scala ProcessLogger & Future: How can I make sure all line callbacks are called BEFORE the onComplete block?
- Scala: understanding how to make my method return the proper return type of Array
- How do I use Java lambda to return an array of bytes when I am using the Algebird library?
- Akka: How to extract a value in one graph stage and use it in the next
- map two array column to each other and make columns from one of the arrays colum Scala
- After creating a File, how do I make sure it getting downloaded to the default download folder?
More Query from same tag
- Why does scala not infer the right type when wrapping EitherT?
- Slick/Scala - how do I access fields of the mapped projection/projected table part of a join in a where query
- How to pass Json content type in akka http
- Meaning of <% in Scala and use in abstract class definition
- Create a common library in Play framework
- How to convert a String into DateTime format?
- gradle windows java.io.IOException: CreateProcess error=206, filename is too long
- Need help trying to parse file and create map in scala
- how t send message to actor from sbt shell
- Scala - wrapping functions with default parameter values
- Writing to a file in Apache Spark
- Add new column of Map Datatype to Spark Dataframe in scala
- def with no args
- Difference between >> and >>> in Scala
- Uncompress and read gz files from S3 - Scala
- Scala Set - default behavior
- Creating data frames in Spark using Sets in Scala
- How do I represent postgres `bytea` type in slick 2.0.1?
- Loop through dataframe and update the lookup table simultaneously: spark scala
- Cannot get system variables in scala
- iterating in scala with limited range of records
- How to eval a string val in Scala?
- Why can a top-level val in a method body shadow a method argument in Scala?
- What is the equivalent of "@SpringBootApplication(exclude={SecurityAutoConfiguration.class})" in scala?
- Validation: implicit scalaz.Bind not found
- Benefit of defining a trait whose purpose is only to mix into an object?
- IntelliJ - How to run current program regardless of errors in unrelative files
- Compile errors when adding Joda-Time via sbt, but runs fine if I add it though my ide?
- Flink fails to load ProducerRecord class with LinkageError at runtime
- Getting this error - public key protected PKCS12 not supported