cant find a pattern to fit neatly - how to make a large number of monsters?

S

steve mathers

Hi , fairly new to OO design. Trying to solve a problem:

problem:
I want to make a large number of different monsters. what makes
monsters different from each other is their 'abilities'. These could
such things as carrying a weapon or magic item that allows them to
perform an action, or something like an intrinsic resistance to attack
with fire, or a temporary ability ability granted by a spell cast on
them.

* I want to be able to define different monster types and different
ability types using as little memory as possible (mobile phone
platform) - a hard coded table of abilities and then another table of
monsters that lists which ability each monster has. Some sort of
factory will have to create the monster given an index into this
table. Thats not the hard part.

* I want to be able to add new monsters and new abilities to the table
without changing the inteface of the monster and ability class. I
think this is the hard part.

solution: At first thought, the decorator pattern seems right, but
because abilities can come and go all the time, it seems to be
unweildy.

I think what I want to happen is that every time the monster has to do
something that involves its characteristics which may be modified by
abilities (such as fire resistance), or it wants to perform an
optional action that an ability may bestow it with (such as hit
something with a weapon), it should interogate its entire list of
current abilities to see if they impact on that charicteristic or
action. But how to structure that process in my design?

Is there a particular pattern I should be looking at?

thanks,

Steve
 
T

thufir

steve said:
Hi , fairly new to OO design. Trying to solve a problem: [..]
I think what I want to happen is that every time the monster has to do
something that involves its characteristics which may be modified by
abilities (such as fire resistance), or it wants to perform an
optional action that an ability may bestow it with (such as hit
something with a weapon), it should interogate its entire list of
current abilities to see if they impact on that charicteristic or
action. But how to structure that process in my design?
[..]

That sounds very computationally intensive to me. Depending on the
size of the table, mightn't that create more of a strain than keeping a
mobs characteristics within a single object?

I've always heard that it's better to focus on design first and
performance second. As an alternative, what's wrong with a very simple
mob composed different "parts," like FireResistance.
 
S

stevenmathers

performance not an issue in this application, but codebase size is.
and it would be nice to be able to add new types of abilities and
monsters to the system just by adding a few bytes to a table and a
function or two to handle them, and then have a factory creatre them at
runtime.


example of the process I was thinking of:

monster object: holds intrinsic characteristics and list of optional
abiltiies

ability object: enables monster to perform some function, and/or
modifies some of its abilities.

so there is a dependency there between monster and ability, but how to
make it as weak as possible. The vector of change is definately more
types of abilities, and more types of monsters.

use case 1: monster makes a melee attack: it interrogates each of its
abilities: are you my current melee weapon, and if so, what type and
degree of damage do you do?

use case 2: monster needs to use its SPEED characetristic to determine
if it is its turn to act yet. it interogates all its current
abilities: here is my current SPEED - modify it if you will.

Perhaps there is a better system?


steve said:
Hi , fairly new to OO design. Trying to solve a problem: [..]
I think what I want to happen is that every time the monster has to do
something that involves its characteristics which may be modified by
abilities (such as fire resistance), or it wants to perform an
optional action that an ability may bestow it with (such as hit
something with a weapon), it should interogate its entire list of
current abilities to see if they impact on that charicteristic or
action. But how to structure that process in my design?
[..]

That sounds very computationally intensive to me. Depending on the
size of the table, mightn't that create more of a strain than keeping a
mobs characteristics within a single object?

I've always heard that it's better to focus on design first and
performance second. As an alternative, what's wrong with a very simple
mob composed different "parts," like FireResistance.
 
T

thufir

performance not an issue in this application, but codebase size is.
and it would be nice to be able to add new types of abilities and
monsters to the system just by adding a few bytes to a table and a
function or two to handle them, and then have a factory creatre them at
runtime.

If each monsters attributes are composed of different objects, it
should be very easy make a SuperSword class and have
bigMonster.armWith("superSword") I'd think.

I don't know how to address your codebase size concern, sorry...
example of the process I was thinking of:

monster object: holds intrinsic characteristics and list of optional
abiltiies

instead of a list of abilities, try for objects :)
ability object: enables monster to perform some function, and/or
modifies some of its abilities.

As in a sword object, or fireResistant object, of which a particular
Monster type object would be composed. That is, each object would
"have-a" object, or objects :)
so there is a dependency there between monster and ability, but how to
make it as weak as possible. The vector of change is definately more
types of abilities, and more types of monsters.

Composition works very well at encapsulating data, which allows you to
change dependant classes to a larger degree.
use case 1: monster makes a melee attack: it interrogates each of its
abilities: are you my current melee weapon, and if so, what type and
degree of damage do you do?

public class BunchOfMonsters {
public static void main (String args[]) {
Creature blobMonster = new Monster("blob"); //"blob" is a
monster type
blobMonster.armWith("sword"); //sword is a type of weapon
//have a list of monsters
}
}

public class Monster implements Creature {
public void armWith(String wep){
if (wep == "sword") {
Item aSword = new Sword(); } //give sword to monster
instance
//Sword implements Item
}

public void attack() {
// find best weapon
// find target
}
}

use case 2: monster needs to use its SPEED characetristic to determine
if it is its turn to act yet. it interogates all its current
abilities: here is my current SPEED - modify it if you will.

how about each instance of Monster has an instance of Melee? Using
Timer() each melee object determines when it gets to move. This object
would then determine whether to fight or flee?
Perhaps there is a better system?

<http://robocode.alphaworks.ibm.com/home/home.html>

AFAIK this uses a "tick" idea, where there's a list of 'bots which gets
iterated through once/sec; this is less complex than having a Melee
class.
 
T

thufir

performance not an issue in this application, but codebase size is.
and it would be nice to be able to add new types of abilities and
monsters to the system just by adding a few bytes to a table and a
function or two to handle them, and then have a factory creatre them at
runtime.

If each monsters attributes are composed of different objects, it
should be very easy make a SuperSword class and have
bigMonster.armWith("superSword") I'd think.

I don't know how to address your codebase size concern, sorry...
example of the process I was thinking of:

monster object: holds intrinsic characteristics and list of optional
abiltiies

instead of a list of abilities, try for objects :)
ability object: enables monster to perform some function, and/or
modifies some of its abilities.

As in a sword object, or fireResistant object, of which a particular
Monster type object would be composed. That is, each object would
"have-a" object, or objects :)
so there is a dependency there between monster and ability, but how to
make it as weak as possible. The vector of change is definately more
types of abilities, and more types of monsters.

Composition works very well at encapsulating data, which allows you to
change dependant classes to a larger degree.
use case 1: monster makes a melee attack: it interrogates each of its
abilities: are you my current melee weapon, and if so, what type and
degree of damage do you do?

public class BunchOfMonsters {
public static void main (String args[]) {
Creature blobMonster = new Monster("blob"); //"blob" is a
monster type
blobMonster.armWith("sword"); //sword is a type of weapon
//have a list of monsters
}
}

public class Monster implements Creature {
public void armWith(String wep){
if (wep == "sword") {
Item aSword = new Sword(); } //give sword to monster
instance
//Sword implements Item
}

public void attack() {
// find best weapon
// find target
}
}

use case 2: monster needs to use its SPEED characetristic to determine
if it is its turn to act yet. it interogates all its current
abilities: here is my current SPEED - modify it if you will.

how about each instance of Monster has an instance of Melee? Using
Timer() each melee object determines when it gets to move. This object
would then determine whether to fight or flee?
Perhaps there is a better system?

<http://robocode.alphaworks.ibm.com/home/home.html>

AFAIK this uses a "tick" idea, where there's a list of 'bots which gets
iterated through once/sec; this is less complex than having a Melee
class.
 
T

thufir.hawat

performance not an issue in this application, but codebase size is.
and it would be nice to be able to add new types of abilities and
monsters to the system just by adding a few bytes to a table and a
function or two to handle them, and then have a factory creatre them at
runtime.

If each monsters attributes are composed of different objects, it
should be very easy make a SuperSword class and have
bigMonster.armWith("superSword") I'd think.

I don't know how to address your codebase size concern, sorry...
example of the process I was thinking of:

monster object: holds intrinsic characteristics and list of optional
abiltiies

instead of a list of abilities, try for objects :)
ability object: enables monster to perform some function, and/or
modifies some of its abilities.

As in a sword object, or fireResistant object, of which a particular
Monster type object would be composed. That is, each object would
"have-a" object, or objects :)
so there is a dependency there between monster and ability, but how to
make it as weak as possible. The vector of change is definately more
types of abilities, and more types of monsters.

Composition works very well at encapsulating data, which allows you to
change dependant classes to a larger degree.
use case 1: monster makes a melee attack: it interrogates each of its
abilities: are you my current melee weapon, and if so, what type and
degree of damage do you do?

public class BunchOfMonsters {
public static void main (String args[]) {
Creature blobMonster = new Monster("blob"); //"blob" is a
monster type
blobMonster.armWith("sword"); //sword is a type of weapon
//have a list of monsters
}
}

public class Monster implements Creature {
public void armWith(String wep){
if (wep == "sword") {
Item aSword = new Sword(); } //give sword to monster
instance
//Sword implements Item
}

public void attack() {
// find best weapon
// find target
}
}

use case 2: monster needs to use its SPEED characetristic to determine
if it is its turn to act yet. it interogates all its current
abilities: here is my current SPEED - modify it if you will.

how about each instance of Monster has an instance of Melee? Using
Timer() each melee object determines when it gets to move. This object
would then determine whether to fight or flee?
Perhaps there is a better system?

<http://robocode.alphaworks.ibm.com/home/home.html>

AFAIK this uses a "tick" idea, where there's a list of 'bots which gets
iterated through once/sec; this is less complex than having a Melee
class.
 
C

Chris Uppal

thufir said:
Creature blobMonster = new Monster("blob");
blobMonster.armWith("sword");

Shouldn't you also have:

blobMonster.armWith("arm");

in there somewhere ?

;-)


-- chris
 
C

Chris Uppal

performance not an issue in this application, but codebase size is.
and it would be nice to be able to add new types of abilities and
monsters to the system just by adding a few bytes to a table and a
function or two to handle them, and then have a factory creatre them at
runtime.

I think you are heading in the direction of a fairly complicated and abstract
bit of object modelling; I suggest that you take a step back and consider how
much flexibility you actually /need/. Also I'd suggest that, whatever degree
of flexibility you finally choose to implement, you try designing a version of
the system (and doing a small trial implementation) /without/ considering the
memory footprint -- you may find that you've gone up an over-abstract blind
alley.

It is one thing to able to mix and match different amounts of each of some
pre-defined list of "abilities" to build new and terrible monsters. That's
easy enough to do using classical OO. But wanting to be able to give monsters
new /kinds/ of ability with the same ease, will require a higher level of
abstraction; quite possibly your eventual system would look more like a
knowledge-representation kit, or a Lisp interpreter.

You might find that a hybrid approach would work. Most of your logic "knows"
about hardwired abilities (speed for instance) which every monster has to some
degree (possibly zero or even negative) and has specific code for handling
those aspects (e.g. using strength(), currentLoad(), and currentNumberOfArms()
to determine whether the monster can pick something up). In addition you have
a (much) less flexible, but more data-driven extension mechanism for adding a
little colour to your monsters. E.g. you could have Attack and Defence
classes, where:

class Attack
{
String name;
float strength;
int attackID;
}

class Defence
{
String name;
float strength;
int attackID;
}

and the idea is that you can add new Attack and Defence objects easily
(representing intrinsic abilities or abilities conferred by objects/events),
but your actual logic for dealing with them is very limited -- you just
consider every Defence with the same attackID as each launched Attack, and
add/subtract all the strengths before using that to change the victim's
lifeForce(). Or you could generalise that a bit -- e.g. each Attack and
Defence might have a defined effect on all of the victims pre-defined
attributes (speed etc.).

-- chris
 
H

H. S. Lahman

Responding to Mathers....
Hi , fairly new to OO design. Trying to solve a problem:

problem:
I want to make a large number of different monsters. what makes
monsters different from each other is their 'abilities'. These could
such things as carrying a weapon or magic item that allows them to
perform an action, or something like an intrinsic resistance to attack
with fire, or a temporary ability ability granted by a spell cast on
them.

* I want to be able to define different monster types and different
ability types using as little memory as possible (mobile phone
platform) - a hard coded table of abilities and then another table of
monsters that lists which ability each monster has. Some sort of
factory will have to create the monster given an index into this
table. Thats not the hard part.

* I want to be able to add new monsters and new abilities to the table
without changing the inteface of the monster and ability class. I
think this is the hard part.

solution: At first thought, the decorator pattern seems right, but
because abilities can come and go all the time, it seems to be
unweildy.

I think what I want to happen is that every time the monster has to do
something that involves its characteristics which may be modified by
abilities (such as fire resistance), or it wants to perform an
optional action that an ability may bestow it with (such as hit
something with a weapon), it should interogate its entire list of
current abilities to see if they impact on that charicteristic or
action. But how to structure that process in my design?

I don't think this is a design pattern issue; I think it is more of a
tactical OOP optimization of a basic OOA/D. Per your first asterisk you
have:

[Monster]
+ type
| *
|
|
| *
[Ability]

which can be reified to:

[Monster]
+ type
| *
|
|
| 1
[AbilitySet]
| 1
|
|
| *
[Ability]

So each Monster has a reference to a table of its specific abilities.
(If you need to navigate the other way, each Ability has a reference to
a table of the Monsters with that Ability.)

As an OOP optimization you can eliminate the collections by being clever
about the identity of Abilities. Assuming the total number of Abilities
is relatively limited, you can implement AbilitySet as a bitmap
attribute of Monster where the bit position is the index into a fixed
array of Ability references accessed by a static Ability::find(index).
If the bit is set, the Monster has that Ability. Ability has a static
table of its instances that is updated as the instances are created.

The factory that creates Monsters can use external configuration data to
obtain the bitmap value for a particular Monster type based on the
Monster.type attribute. That can be read directly from a database. If
the user can create custom monsters, then one can store the bitmap and
the new type attribute for future reference.

This pretty much limits memory to M Monsters + N Abilities + 1 static
Ability table. The price will be performance in searching the bitmap
and checking the Abilities to see if they are relevant.

Note that at the cost of more bitmap attributes in Monster, one can also
save the searching. The basic idea is to cross-reference Abilities with
the Monster behaviors in exactly the same way:

[Monster]
+ type
| *
|
|
| *
[BehaviorSet]
| 1
|
|
| *
[Ability]

where each BehaviorSet is a list of references to the Abilities that are
relevant to a particular Monster behavior. In effect there is a
BehaviorSet bitmap for each behavior that Monster has. These would be
initialized in the same way as the first case.

The next issue is providing a generic interface to Ability. From the
examples cited, it seems that Abilities provide rather simple parametric
data that affects or enables certain Monster behaviors. That is,
Ability has no intrinsic behaviors. If so, I would suggest Ability be
in a form similar to an A-V pair. (There are many variations, such as
XML strings.)

Then the relevant Monster behavior can test the the attribute name to
determine how to apply the value in its context. (The direct search via
AbilitySet would simply ignore attributes that were not relevant to the
behavior in hand.) Then there is only one interface needed:
getAttribute and getValue. (Note there is nothing to prevent an Ability
from have multiple A-V pairs; the interface just has to be slightly more
flexible.)

[This sort of parametric polymorphism is a sort of analysis pattern,
BTW. I have a number of examples that might be of interest on my blog
in the section on invariants.]

*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
(e-mail address removed)
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog (under constr): http://pathfinderpeople.blogs.com/hslahman
(888)-OOA-PATH
 
T

thufir

Here's a slightly more fleshed out idea to mull over, coming from the
OOP paradigm :)

I'm looking into how to make a MonsterMeleeTicker object for each
Monster instance. MonsterMeleeTicker.setRate(3) would mean, perhaps,
that every three seconds this monster can do one thing, be it
fight/flee/boogie. Any pointers on what MonsterMeleeTicker should look
like?

All criticisms welcome, of course!

/////////////////////code//////////////////////////
package atreides.monsters;

import java.util.*;

public class TestDriveMonsters{

private static List<Monster> list = new ArrayList<Monster>();

public TestDriveMonsters(){
System.out.println("TestDriveMonsters..");
}//TestDriveMonsters

public static void makeMonsters(){
System.out.println("..makeMonsters");
for (int i=0; i>5; i++){
list.add(new Monster());
}//for
}//makeMonsters

public static void main (String args[]) {
System.out.println("..main");
}//main
}//TestDriveMonsters


/////////////////////////code/////////////////////
package atreides.monsters;

public class Monster{

public Monster(){}//Monster

public static void main (String args[]) {
System.out.println("main..");
}//main
}//Monster
 
S

stevenmathers

I see people can tell where Im coming from with this. It really helps
to have someone else state the problem and solution in different
language.

Finally I think I can define the problem in a clear way:

A monster has characteristics which are _common_ to all monsters, such
as Speed or the ability to resist certain types of damage, even if that
resistance is 0.
These simple characteristics are represented as attributes in the class
Monster.

A monster has optional characteristics and/or behaviour which is
represented by a list of Abilities. A sword ability, a resistance to
fire ability of +50%, a wand of Increase Speed, etc...

Adding new monsters is easy, you just create a monster with a different
name, different values for its characteristics and give it a different
starting set of abilities.

The most important thing with this design is to make the definition of
new abilities as easy as possible. I want a code-efficient, elegant
way to define a new ability - the more abilities I have, the more
different types of monsters I can easilly create. Of secondary
importance is the impact of defining new characteristics.

Whenever a new characteristic is defined, or a new ability defined, it
must not change the interface between Monster and Ability. Thats a
maintainance nightmare.

I propose to use something like the Command Pattern between Monster and
Ability. Monster creates a command such as 'modify this speed
attribute', sends it to all its abilities, and those abilities may or
may not satisfy the request.

So when I define a new ability, I just have to define the command it
responds to, and also the response itself. I think broadly there are
three types of response an ability can have:

1) modify a value passed in (i.e. yes, I modify speed, and here is your
modified speed result)
2) perform a function and return the result (i.e: 'yes, I am your
currently wielded melee weapon, and I do 10 physical damage')
3) apply an ability to a target Monster. i.e a wand of increase speed
gives the Monster the ability to apply an 'increase speed' ability to a
target Monster.

so... to fully define a new type of ability, I need to define the
strategy by which it is invoked (largely a GUI strategy issue), and/or
the command it responds to, and the strategy it applies apon either
being invoked or receiving that command.

So I propose to use a type of strategy pattern to implement the
response of an ability to a request.

that way I can define new abilities in one table, and have a factory
create them using the table ID.

i.e.

ability #5
name: "increase speed effect"
invoking strategy: NONE
command: SPEED_MODFIY
execute strategy: VALUE_MODIFIER
execute param: +50%

ability #6
name: " wand of speed"
invoking strategy: AQUIRE_TARGET
command: NONE
execute strategy: ADD_ABILITY
execute param: ability #5

and so on...
I think its reasonable, but id be glad to hear otherwise
 
T

thufir

A monster has characteristics which are _common_ to all monsters, such
as Speed or the ability to resist certain types of damage, even if that
resistance is 0.
These simple characteristics are represented as attributes in the class
Monster.

as in:
int damageStrength = 99;

or

Damage strength = new Damage();

[..]
So I propose to use a type of strategy pattern to implement the
response of an ability to a request.

Heh, I need to check out all these patterns :)
that way I can define new abilities in one table, and have a factory
create them using the table ID.

i.e.

ability #5
name: "increase speed effect"
invoking strategy: NONE
command: SPEED_MODFIY
execute strategy: VALUE_MODIFIER
execute param: +50%
[..]
public class IncreaseSpeedEffect{
boolean invokingStrategy = false;
double executeParam = 0.50;}

and then in, say, TestDriveMonsters:
Monster aMonster = new Monster();
aMonster.getInvokingStrategy();

although I don't know what invokingStrategy does!

FWIW, here's some java, where each monster now has a melee object. the
same idiom can be followed to add other attributes, such as a Strategy
class object.

C:\>
C:\>cd java\sources\atreides\monsters

C:\java\sources\atreides\monsters>dir
Volume in drive C has no label.
Volume Serial Number is #####

Directory of C:\java\sources\atreides\monsters

01/25/2005 05:06p <DIR> .
01/25/2005 05:06p <DIR> ..
01/25/2005 05:59p 494 Monster.java
01/25/2005 05:53p 469 MonsterTask.java
01/24/2005 11:26p 694
TestDriveMonsters.java
3 File(s) 1,657 bytes
2 Dir(s) 4,220,837,888 bytes free

C:\java\sources\atreides\monsters>type Monster.java
package atreides.monsters;


public class Monster{

java.util.Timer melee = new java.util.Timer();

public Monster(){}//Monster

//this method will determine how many moves a
//monster takes. The larger the period the
//slower the monster, the smaller the period
//the faster. assumes positive values.

public void setScheduleMelee(long period){
System.out.println("..setScheduleMelee");
MonsterTask dummyTask = new MonsterTask();
java.util.Date nowDate = new java.util.Date();
melee.schedule(dummyTask,nowDate,period);
}//setScheduleMelee

public static void main (String args[]) {
System.out.println("main..");
}//main
}//Monster

C:\java\sources\atreides\monsters>type MonsterTask.java
package atreides.monsters;


public class MonsterTask
extends java.util.TimerTask
implements java.lang.Runnable{

public MonsterTask(){}//MonsterTask

public boolean cancel(){
return false;
}//cancel

public void run(){
System.out.println("..run");
}//run

public long scheduledExecutionTime(){
return 0;
}//scheduledExecutionTime


public static void main (String args[]) {
System.out.println("main..");
}//main
}//MonsterTask

C:\java\sources\atreides\monsters>type
TestDriveMonsters.java
package atreides.monsters;

import java.util.*;



public class TestDriveMonsters{

private static List<Monster> list = new ArrayList<Monster>();

public TestDriveMonsters(){

System.out.println("TestDriveMonsters..");
}//TestDriveMonsters

public static void makeMonsters(){
System.out.println("..makeMonsters");
for (int i=0; i<5; i++){
list.add(new Monster());
}//for
}//makeMonsters

public static void setTimer(){
System.out.println("..addTimer");
for (Monster monster:list){
}//for
}//setTimer

public static void main (String args[]) {
System.out.println("..main");
makeMonsters();
setTimer();
}//main
}//TestDriveMonsters

C:\java\sources\atreides\monsters>
 
L

Lew Bloch

But how to structure that process in my design?
Is there a particular pattern I should be looking at?

Interesting problem.

Some of your space problems and complexity go away if you are willing to
store references as object (e.g., monster) attributes. A reference is
larger than an index, but it simplifies things tremendously.

Allow me to essay a crude but, one hopes, illustrative object design,
then you can pick it apart for flaws such as being too big for an
embedded system.

First, let me say that I won't speak to patterns as such. I am thinking
in terms of composition and inheritance.

I posit the following types (interfaces, ideally):

Ability { ... }

Weapon extends Ability { ... }

Act
{
Set< Ability > abilities = new LinkedHashSet< Ability >();
....
}

Monster
{
Set< Ability > abilities = new LinkedHashSet< Ability >();
....
}

GameMaster
{
Set< Ability > allAbilities = new LinkedHashSet< Ability >();
Set< Act > allActs = new LinkedHashSet< Act >();
....
}

Ability would be immutable, objects that report their state, such as
speed augmentation factor, but never change it.

At game setup, the master GameMaster object would initialize its lists
with all available objects for the game to use. When a Monster gains,
say, an Ability, it inserts a reference to an object from the GameMaster
master "allAbilities" list into its private "abilities" list. The
instance is shared by the GameMaster and by all Monsters that "have" it.

This is relatively compact because you share instances between Monsters
rather than have them add a
new Ability();
to their private lists each time.

The tricky part is to design Ability behaviors to support actions
performed by different Monsters. One way is to make them completely
passive - report factors that trigger Monster behaviors. For example,
the Monster might have

public void attemptAct( Act act, GameThing thing )
throws GameException
{
/* load required factors, e.g., speed, from Monster */
act.loadBaseFactors( this );

for( Ability a : act.getAbilities() )
{
if ( act.requires( a ) && ! abilities.contains( a ) )
{
return;
}
act.modifyFactors( a ); // apply mods from the ability
}

act.execute( thing ); // throws GameException
}

The Act object, "act", has to know how to perform its deed upon the
passed "thing" - e.g., how to attack a Monster (subclass of GameThing).
First it loads its attack factor (in this case) from the Monster's
base attributes like strength. Then it examines each used Ability for
how it affects those factors. The attack Act should know to add one to
"strength" upon seeing a strengthPotion Ability, or subtract one for a
fever Ability.

After the Ability modification loop, the Act tries to do its thing
(attack) to its GameThing target (other Monster), using its modified
(attack) factors. (It can likewise scoop Abilitys from the target to
calculate defensive capability.)

This is a crude sketch, and optimizations suggest themselves almost
immediately. The main point is that Ability objects are passive, so
they can be shared and thus save memory.

Actually, complete passiveness is not required, only immutability. The
Ability class can define reentrant methods - no changes to the Ability's
members, only to method parameters and stack variables.

Incidentally, the Act object can be reused as each Monster gets its turn
to try it. This also saves memory.

I don't know J2ME so if java.util.LinkedHashSet isn't available use any
java.util.Set, or failing that, roll your own with similar characteristics.
 
T

Thufir Hawat

Lew Bloch wrote:
[..]
Actually, complete passiveness is not required, only immutability. The
Ability class can define reentrant methods - no changes to the Ability's
members, only to method parameters and stack variables.

Incidentally, the Act object can be reused as each Monster gets its turn
to try it. This also saves memory.

I don't know J2ME so if java.util.LinkedHashSet isn't available use any
java.util.Set, or failing that, roll your own with similar
characteristics.

Why did you select LinkedHashSet over LinkedHashMap? That's not really
my question, though. I'm more interested in the use of "Hash" in a
collection. A Hash is a sort of unique id for each instance? I
believe it to be related to the toString() default method in that
hashCode() is so similar:

public int hashCode()
Returns a hash code value for this enumeration value. The hash code
is just this enumeration value's integer value.


public String toString()
Returns a string value corresponding to this enumeration value.




"A map cannot contain duplicate keys"
<http://java.sun.com/docs/books/tutorial/collections/interfaces/index.html>

That sounds like a Set, to me. Whether one is preferable (in J2ME or
J2SE) over the other might be contentious (?), their common quality of
"Hashness" is new and interesting to me...
 
U

Utilisateur PC Libre Service

One solution to this problems :

-Use the MetaCalss design pattern (MonsterKind is an abstract class, an
instance of Monster have exactly one MonsterKing - MonterKing is a kind of
singleton for the race, and each Monster is associated with its arm)

-Use the strategy design pattern to associate a "way to calculate damages"
to a weapon.

Search the web for inforations about these patterns :)

Regards,
Lucien.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top