• Post Reply Bookmark Topic Watch Topic
  • New Topic

Creating a new Object and then storing it in a 2d array  RSS feed

 
Greenhorn
Posts: 20
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, so this is part of a group project for class. I'm in charge in making battle work in the game. We decided we wanted to be able to have the enemies (Ugly Ogres) be stored in a 2d array so that they can "defend" each other against attacks. I've managed to confuse myself on how I'm supposed to create a new UglyOgre, and then store it in the 2d array, because it each ogre also needs a "type", which is defined in the UglyOgre class. I've only posted what I think is relevant to my question just to keep it simpler, but I can post the whole thing if its helpful

This is what I've got in the Battle Class


and this is the UglyOgre class, which is another member of my group is doing, so I only have this based on the domain level class diagram
 
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Delete '2d' and 'Java' combination before Campbell wakes up and comes here.

Why do you represent Enemies as chars? Something is very wrong with design seems. Will need to look deeper to give you some insights.
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson wrote:We decided we wanted to be able to have the enemies (Ugly Ogres) be stored in a 2d array so that they can "defend" each other against attacks.

Could you please rephrase or elaborate a bit more on this your statement. I do not understand your intention. What array of arrays have to do with defending "each other against attacks"?
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You might also could post a bit of instructions for that part you are trying to solve?
 
Nikki Johnson
Greenhorn
Posts: 20
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:Welcome to the Ranch

Delete '2d' and 'Java' combination before Campbell wakes up and comes here.

Why do you represent Enemies as chars? Something is very wrong with design seems. Will need to look deeper to give you some insights.


Uh oh, is there a way to edit my post that I'm not seeing? Array of arrays sorry, my last class was on C programming.

There aren't exactly instructions... As a group we had to pick a project for OOD class, and we decided on a game, admittedly it seems we might be in a bit over our heads... but it's far too late to change  directions now. The Enemies represented as chars was part of the design other group member came up with, but for my own part, I didn't think anything of it at the time.

So the point of an array of array is that when each UglyOgre is created, it is put in either [1][0], [1][1] or [1][2]. Then when the player attacks, the ogre has a chance to move in front of another one to prevent it from getting attacked. Say the ogre in [1][0] is attacked, then the ogre from [1][1] can move to [0][0] and take damage instead of the [1][0] ogre.
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson wrote:Uh oh, is there a way to edit my post that I'm not seeing?

Don't worry about that, he might forgive you

Nikki Johnson wrote:So the point of an array of array is that when each UglyOgre is created, it is put in either [1][0], [1][1] or [1][2]. Then when the player attacks, the ogre has a chance to move in front of another one to prevent it from getting attacked. Say the ogre in [1][0] is attacked, then the ogre from [1][1] can move to [0][0] and take damage instead of the [1][0] ogre.

So you are trying to represent a battle field, so to speak. Like:
loc 1loc 2loc 3
loc 4loc 5loc 6
loc 7loc 8loc 9

But you need to have Player, Enemy classes too probably. With the char's is a bit awkward to represent all that.
 
Nikki Johnson
Greenhorn
Posts: 20
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, that is kind of what we are trying to do with the battle field.

There is a player class, and an enemies class, both of the constructors use chars as parameters.... this was a bad idea?
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson wrote:I've managed to confuse myself on how I'm supposed to create a new UglyOgre, and then store it in the 2d array, because it each ogre also needs a "type", which is defined in the UglyOgre class.

This reveals your intention. So you need player and enemy classes (in your case UglyOgre.. or something), both classes could implement Fighters interface, so you could have something similar to
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Now, is that design optimum, well, need to try and see. Let's see what others think.
 
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the OgreType supposed to represent? What are the different values it can have?

Why does the UglyOgre class have the ogreArray in it? That's smelly. The way you describe it, either the ogreArray is a reflection of the playing field/grid, or it's the grid itself.  That's bad. The playing field/grid should be a separate class itself.  Your design is like if you were trying to create a game of Chess and you had the chessBoard array to track where each piece was in a ChessPlayer object. That's the same kind of bad design as what your teammate has come up with in this ogreArray.

Also, don't use names that blatantly or even subtly reveal implementation details. References to implementation are almost never appropriate when it comes to names. The word "array" in the name ogreArray is a blatant reference to an implementation detail.  What's the intent of the ogreArray?  If it's to track ogre positions on the field of play, then name the array ogrePositions instead.  Notice how when I tried to explain what the purpose of that array is, I actually said the intent? The phrase "to track ogre positions" has the more appropriate name to assign the thing in your program. 

Bottom line: Choose names that will make your code reveal intent and hide implementation.  This is what Abstraction is about and it's a very important concept to keep in mind when you're trying to come up with any kind of design.
 
Saloon Keeper
Posts: 7993
143
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You need to separate your concerns. It would be very annoying for your application to work with an array of arrays, if you can just work with a BattleField class instead. The BattleField class concerns itself with keeping track of the locations of UglyOgres. It does NOT concern itself with the creation of UglyOgres. This separation will make it much easier for you to reason about your code and to extend it:
 
Marshal
Posts: 56600
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You may find a List of Lists easier to use than an array.
Who told you that you have a 2D array? I had better rant and rave about 2D, so Liutauras isn't making empty threats. What you are showing is an array of arrays, which is different from a 2D array. It is actually better, because you are allowed “jagged” arrays. C supports 2D arrays (at least it used to; more recent implementations seem to implement 2D arrays as arrays of arrays, but this probably varies from implementation to implementation).
You are confusing yourself because you have made a basic mistake elsewhere. You have created a class with the same name as a class in the java.lang package. Now you think there is some sort of interconvertibility between your Character class and the java.lang.Character class, and there is some interconvertibility between your Character class and a char. There is some sort of interconvertibility between the java.lang.Character class and a char, however. It is called boxing and unboxing. You cannot make subclasses of java.lang.Character anyway.
I suggest you start by calling your superclass something different which won't cause this confusion. So you end up with
public class UglyOgre extends Ogre
public class Ogre extends Monster
public class Monster extends Warrior

or similar.I am sure you can think of better names. As Liutauras says, why are you using a char to represent a warrior? That doesn't sound right to me.

Depending on how experienced you are you might consider a so‑called circular list for the behaviour of moving to the front to protect other warriors. Or a circular array.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A "type" is most often best represented as an enum. The typical example is a PlayingCard, which can have a suit and a rank. Here's how you'd define that in Java:


You could declare the enums outside of Card but I choose to declare them as part of Card to show that they only make sense in the context of the Card class. I'm trying to use this organization to show a strong relationship between Card and Card.Suit and Card.Rank.

For your design, what are these "ogre types" you're trying to represent with a char?  Does the Enemy class have their own "enemy types" as well? How are these types used in the game?
 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:. . . Don't worry about that, he might forgive you . . .
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:This separation will make it much easier for you to reason about your code and ...

A very nice way to put it. Reminds me of Ward Cunningham when he explains the Debt Metaphor (BTW, that link is to the original Wiki, the mother of all Wikis, and Ward is the father)
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson wrote:The Enemies represented as chars was part of the design other group member came up with

Probably as a first thing you need to do is to inform your colleagues so they would stop doing whatever they are doing based on that design you have been given.
Most likely They will need to amend their tasks based on the new design you are going to propose them. How much of work going to be to re-do don't know. Could be everything.
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What Stephan suggested, I'd go even a bit further (since you are doing OOP assignment), changing x and y coordinates to Location object.

So, that bit (and others Stephan suggested, which includes coordinates)
Stephan wrote:

Could become

Note: javadocs comments are a bit out of sync in my version, in particular @throws ...
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:
Nikki Johnson wrote:The Enemies represented as chars was part of the design other group member came up with

Probably as a first thing you need to do is to inform your colleagues so they would stop doing whatever they are doing based on that design you have been given.
Most likely They will need to amend their tasks based on the new design you are going to propose them. How much of work going to be to re-do don't know. Could be everything.


Another reason to cite Ward Cunningham and the Debt Metaphor. If you keep moving forward with a bad design and don't refactor to clean up the design as you learn more about it, you will end up creating a mess on top of a mess on top of a mess and so on.

This is the lesson learned (and way too often, NOT learned) by many programmers, that if you keep moving forward with a bad design that makes the code difficult to reason, understand, and work with, sooner or later your rate of progress will become ZERO because of the challenges that accompany the bad design and the limitations they impose on you. When that happens, you will realize you have failed and your project along with you.

Invest five minutes and listen to Ward Cunningham explain the Debt Metaphor. If you remember what he says and take appropriate action from it, this lesson will save you countless hours of grief and suffering throughout the time you spend writing code in your lifetime. Seriously, this is a basic lesson that all programmers should learn.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:What Stephan suggested, I'd go even a bit further (since you are doing OOP assignment), changing x and y coordinates to Location object.

[pedantic]

This is what's called reification - you turn two separate data points (x and y) into a real object.  It seems like Location is the canonical reification example; it's the same example given by Corey Haines in his book, Understanding the Four Rules of Simple Design. That small 70+ page book has a lot of good design lessons in it. I wish more folks would get it, read it, and apply those lessons.

[/pedantic]
 
Nikki Johnson
Greenhorn
Posts: 20
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Whew!!! OK, so I took Liutauras Vilda advice and did something more like this to fix my problems

This reveals your intention. So you need player and enemy classes (in your case UglyOgre.. or something), both classes could implement Fighters interface, so you could have something similar to



and got ahold of one of my group partners to fix the char parameter problem, which is making everything *compile* swimmingly, but I won't know if anything actually works until we all get together and put our classes together.

To Junilu Lacar's point,
Bottom line: Choose names that will make your code reveal intent and hide implementation.  This is what Abstraction is about and it's a very important concept to keep in mind when you're trying to come up with any kind of design.

I will definitely remember to do this in the future   and I will check out that Ward Cunningham link  and the Corey Haines book asap.

For some clarification, ogreType is meant to define whether each ogre created is either i=Ice, f=Fire, or n=Normal, hence why we were using chars to show which kind was created.

Stephan van Hulst, I'm quickly learning that we should have made more classes to separate concerns... My entire Battle class is a mess, and this has definitely been a learning experience in what should be separated and how.

Campbell Ritchie, I'm not sure where I picked up called what I have a 2D array, but I will remember in the future that it is array of arrays   Also, I didn't realize, and apparently neither did my fellow project-mates, that Character was already a class in the java.lang.package. Duly noted! Thank you!

Generally, me and my fellow classmates working on this project are very new to java, this class being the first one for most of us, and it seems we might have gotten over enthusiastic about what we can accomplish. I'll fix what I can in the little time I have based on all of your help Thank you!



 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:
This is what's called reification - you turn two separate data points (x and y) into a real object.

@OP
And it is not only that it adds stronger semantics to your game design, so you could discuss your API with colleagues in a spoken language, but makes it easier to adapt it for changes.

Imagine in a new version, two point o (2.0) of your game there will be a need of attackers from up in the air. X and Y points would no longer be sufficient to satisfy that, while Location still would hold the idea of position within the battle field.

My professor used to say: "if your code isn't ready for changes at any given point of time, there are serious errors in it, which needs to be addressed immediately".

As you see, there are quite few places to think about them well. Bring your friends here and let them to read all other advises given by the guys, so your teammates would be on the same page with you.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson wrote:
and got ahold of one of my group partners to fix the char parameter problem, which is making everything *compile* swimmingly, but I won't know if anything actually works until we all get together and put our classes together.

Ah, another thing I wish they'd teach you before pushing y'all into the deep end: how to unit test and integration test your code/designs. You'd be well served by learning something about JUnit and how to write automated tests. If you're up for a real challenge, read a little bit about Test-Driven Development and try to do it.
 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson wrote:. . . whether each ogre created is either i=Ice, f=Fire, or n=Normal, hence why we were using chars to show which kind was created.
Aaaaaaaaaaaaaaaaaah!
Now, that is crying out for an enum type. Read about enums in the Java® Language Specification (=JLS) (that is one of the few parts of the JLS coming anywhere near being easy to read, and it mentions cards), and the Java™ Tutorials
[We] didn't realize . . . that Character was already a class in the java.lang.package.
Lots of people make that mistake; it shouldn't be too difficult to correct. You will have problems if you leave your Character class lying around; when October comes and you can't get methods in java.lang.Character to work and can't understand why, it is probably because you have another class with the same simple name.
. . . me and my fellow classmates working on this project are very new to java
In which case you won't know how to use a circular list or a circular array.
Thank you!
That's a pleasure
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Whew!!! OK, so I took Liutauras Vilda advice and did something more like this to fix my problems

Dont get fooled by cows. It was only one of ideas.
These guys (including Stephan, Campbell, Junilu) are way more experienced than me, try few approaches, and see which one makes most sense in your case.
 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:. . . Invest five minutes and listen to Ward Cunningham explain the Debt Metaphor. . . .
I particularly liked what he said about ¾ of the way along:-
. . . the idea that you could write code poorly with the intention of doing a good job later . . .
That worries me; we hear people say that sort of thing on this forum often enough.

Another facet of the debt metaphor is that the sooner you pay it off, the less interest you pay; the sooner you correct the structure of your code the less hard work you will have. And any hard work will be fruitful rather than fruitless.
 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson wrote:. . . I won't know if anything actually works until we all get together and put our classes together. . . .
You need to know whether it works before you put things together. You need to decide a design, and for each class a specification. That can be simplified to its public interface and documentation. Remember the documentation is the contract of each class and method; Liutauras has shown you how to write it in the documentation comments. Then you need to test each class and each method in it, with “normal” and “abnormal” inputs, which is probably the simplest version of unit testing. Note what Junilu told you about test driven development.
[additional]Then you will know that your code works before you combine it with your colleagues'.
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson wrote:this class being the first one for most of us, and it seems we might have gotten over enthusiastic about what we can accomplish.

Don't worry. In which case you don't want to see my first attempt to create a networking game app, which ended up in:
Junilu Lacar wrote:realize you have failed and your project along with you.

But then I didn't come for an advice
 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras points out that Stephan was showing you documentation comments first. So Stephan shou‍ld get most of the credit. Apologies for my mistake.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Junilu Lacar wrote:. . . Invest five minutes and listen to Ward Cunningham explain the Debt Metaphor. . . .
I particularly liked what he said about ¾ of the way along:-
. . . the idea that you could write code poorly with the intention of doing a good job later . . .
That worries me; we hear people say that sort of thing on this forum often enough.

Yeah, that's a lie that many programmers make themselves believe. There's never time to come back and refactor. Refactor as you go. Don't leave any messes behind. Or as Uncle Bob likes to say, "The only way to go fast is to go well."

Another facet of the debt metaphor is that the sooner you pay it off, the less interest you pay; the sooner you correct the structure of your code the less hard work you will have. And any hard work will be fruitful rather than fruitless.

One common misconception about the debt metaphor is that its "currency" is Quality. As Ward pointed out, you never want to write code poorly, meaning you never want to sacrifice quality. Your code, no matter your lack of true understanding of what it should do, should always be easy to work with, should always be well-factored.

In a workshop on Technical Debt at SPLASH 2013, we noted that the currency of "Technical Debt" is Time.  This is based on Ward's statement that "... rushing software out the door to get some experience with it was a good idea, but that of course, you would eventually go back and as you learned things about that software you would repay that loan by refactoring the program to reflect your experience as you acquired it." 

The less time you spend making the design and code "correct" up front (often leading to analysis & design paralysis), the sooner you can get some experience with running software. The sooner you can get experience with running software, the sooner you can learn about what it really should be doing (Test-Driven Development). The more time you spend repaying this initial debt by refactoring the code and design to reflect your current understanding of it, the less "interest" time you'll pay debugging, dealing with production problems, and trying to figure out what the code is doing later on.  If you don't pay that debt by taking the time to make the code and design reflect your understanding of the software, that is when, as Ward says, "that program simply does not contain any understanding and all efforts to work on it take longer and longer. In other words, the interest is total -- you'll make zero progress."

This is the idea that is lost to those who mislead themselves about "refactoring later, if and when we have time."  There never is time, and by the time you do get into so much trouble that you're forced to MAKE time, it's too late. You can't MAKE time. You have to TAKE time up front to save time (and grief) in the end.

I like to say this about Test-Driven Development: The goal is not to get it right the first time; it's to get it right in the end.
 
Liutauras Vilda
Sheriff
Posts: 4931
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikki Johnson, have a cow, your topic has been chosen to publish in our April's journal
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!