Game Design: Data structures for Stackable Attributes (DFP, HP, MP, etc) in an RPG (VB.Net) - vb.net

I'm wrangling with issues regarding how character equipment and attributes are stored within my game.
My characters and equippable items have 22 different total attributes (HP, MP, ATP, DFP). A character has their base-statistics and can equip up to four items at one time.
For example:
BASE ATP: 55
WEAPON ATP: 45
ARMOR1 ATP: -10
ARMOR2 ATP: -5
ARMOR3 ATP: 3
Final character ATP in this case would be 88.
I'm looking for a way to implement this in my code. Well, I already have this implemented but it isn't elegant. Right now, I have ClassA that stores these attributes in an array. Then, I have ClassB that takes five ClassA and will add up the values and return the final attribute.
However, I need to emphasize that this isn't an elegant solution.
There has to be some better way to access and manipulate these attributes, including data structures that I haven't thought of using. Any suggestions?
EDIT: I should note that there are some restrictions on these attributes that I need to be put in place. E.g., these are the baselines.
For instance, the character's own HP and MP cannot be more than the baseline and cannot be less than 0, whereas the ATP and MST can be. I also currently cannot enforce these constraints without hacking what I currently have :(

Make an enum called CharacterAttributes to hold each of STR, DEX, etc.
Make an Equipment class to represent any equippable item. This class will have a Dictionary which is a list of any stats modified by this equipment. For a sword that gives +10 damage, use Dictionary[CharacterAttributes.Damage] = 10. Magic items might influence more than one stat, so just add as many entries as you like.
The equipment class might also have an enum representing which inventory it slots to (Boots, Weapon, Helm).
Your Character class will have a List to represent current gear. It will also have a dictionary of CharacterAttributes just like the equipment class, which represents the character's base stats.
To calculate final stats, make a method in your Character class something like this:
int GetFinalAttribute(CharacterAttributes attribute)
{
int x = baseStats[attribute];
foreach (Equipment e in equipment)
{
if (e.StatModifiers[attribute] != null)
{
x += e.StatModifiers[attribute];
}
}
// do bounds checking here, e.g. ensure non-negative numbers, max and min
return x;
}
I know this is C# and your post was tagged VB.NET, but it should be easy to understand the method. I haven't tested this code so apologies if there's a syntax error or something.

Related

Linking Text to an Integer Objective C

The goal of this post is to find a more efficient way to create this method. Right now, as I start adding more and more values, I'm going to have a very messy and confusing app. Any help is appreciated!
I am making a workout app and assign an integer value to each workout. For example:
Where the number is exersiceInt:
01 is High Knees
02 is Jumping Jacks
03 is Jog in Place
etc.
I am making it so there is a feature to randomize the workout. To do this I am using this code:
-(IBAction) setWorkoutIntervals {
exerciseInt01 = 1 + (rand() %3);
exerciseInt02 = 1 + (rand() %3);
exerciseInt03 = 1 + (rand() %3);
}
So basically the workout intervals will first be a random workout (between high knees, jumping jacks, and jog in place). What I want to do is make a universal that defines the following so I don't have to continuously hard code everything.
Right now I have:
-(void) setLabelText {
if (exerciseInt01 == 1) {
exercise01Label.text = [NSString stringWithFormat:#"High Knees"];
}
if (exerciseInt01 == 2) {
exercise01Label.text = [NSString stringWithFormat:#"Jumping Jacks"];
}
if (exerciseInt01 == 3) {
exercise01Label.text = [NSString stringWithFormat:#"Jog in Place"];
}
}
I can already tell this about to get really messy once I start specifying images for each workout and start adding workouts. Additionally, my plan was to put the same code for exercise02Label, exercise03Label, etc. which would become extremely redundant and probably unnecessary.
What I'm thinking would be perfect if there would be someway to say
exercise01Label.text = exercise01Int; (I want to to say that the Label's text equals Jumping Jacks based on the current integer value)
How can I make it so I only have to state everything once and make the code less messy and less lengthy?
Three things for you to explore to make your code easier:
1. Count from zero
A number of things can be easier if you count from zero. A simple example is if your first exercise was numbered 0 then your random calculation would just be rand() % 3 (BTW look up uniform random number, there are much better ways to get a random number).
2. Learn about enumerations
An enumeration is a type with a set of named literal values. In (Objective-)C you can also think of them as just a collection of named integer values. For example you might declare:
typedef enum
{
HighKnees,
JumpingJacks,
JogInPlace,
ExerciseKindCount
} ExerciseCount;
Which declares ExerciseCount as a new type with 4 values. Each of these is equivalent to an integer, here HighKnees is equivalent to 0 and ExerciseKindCount to 3 - this should make you think of the first thing, count from zero...
3. Discover arrays
An array is an ordered collection of items where each item has an index - which is usually an integer or enumeration value. In (Objective-)C there are two basic kinds of arrays: C-style and object-style represented by NSArray and NSMutableArray. For example here is a simple C-style array:
NSString *gExerciseLabels[ExerciseKindCount] =
{ #"High Knees",
#"Jumping Jacks",
#"Jog in Place"
}
You've probably guessed by now, the first item of the above array has index 0, back to counting from zero...
Exploring these three things should quickly show you ways to simplify your code. Later you may wish to explore structures and objects.
HTH
A simple way to start is by putting the exercise names in an array. Then you can access the names by index. eg - exerciseNames[exerciseNumber]. You can also make the list of exercises in an array (of integers). So you would get; exerciseNames[exerciseTable[i]]; for example. Eventually you will want an object to define an exercise so that you can include images, videos, counts, durations etc.

How to Structure Lists

I am working on a vb.net auto-focus routine and have the image processing part worked out, basically I do some edge detection, convert to gray-scale and then measure the standard deviation to work out the most 'in focus' point of the image.
I have done this with a number of images, and it almost comes out as a normal distribution, now I want to start to integrate this with my microscope and a stepper motor.
The concept is that I would move through a lower and upper limit on the stepper motor, and measure the above through live-view, recording the values in a list. In my case the two things I want to record are the position, and the double standard deviation value.
I am wondering what the best way to record these are, should it be
recorded as a typed list, or a dictionary or another method?
Once I record all of these values, I would want to go through the values to conduct some simple analysis of them, so if that was the case
how would I then be able to determine the average, min, max etc?
My first attempt of storing the information was in a typed list, where I had essentially done the below;
Public ZPositions As New List(Of Zfocus)
Public Class Zfocus
Public Position As Integer
Public GreyStDev As Double
End Class
The second way was to use a dictionary;
Public ZPosition As New Dictionary(Of Integer, Double)
However in both cases, I am not sure how I can either pull out a single maximum position value (e.g. Position integer,) or from the dictionary the position value (integer) which (sort of) corrosponds to the best auto-focus position.
The Third added bonus, is to be able to pull out any postions above a
specific value, which may corrospond to having some focus information
within them for focus stacking?
Many thanks
Big thanks to jmcilhinney, this solved my issue and works a treat!
Went with a strongly typed list (the ZFocus list) and then I could do the below;
MaxPosition = ZPositions.First(Function(zp1) zp1.GreyStDev = ZPositions.Max(Function(zp2) zp2.GreyStDev))
This allowed be to set up an auto-focus routine which loops through a number of images (as a test), stores the position (e.g. image number in this case) and the intensity edge information, and at the end then pull out the strongest intensity information which forms the best auto-focus point in my case

Best Pattern Applyable to Sudoku?

I'm trying to make a Sudoku game, and I gathered the following validations to each number inserted:
Number must be between 1 and 9;
Number must be unique in the line;
Number must be unique in the column;
Number must be unique in the sub-matrix.
As I'm repeating too much the "Number must be unique in..." rule, I made the following design:
There are 3 kinds of groups, ColumnGroup, LineGroup, and SubMatrixGroup (all of them implement the GroupInterface);
GroupInterface has a method public boolean validate(Integer number);
Each cell is related to 3 groups, and it must be unique between the groups, if any of them doesn't evaluate to true, number isn't allowed;
Each cell is an observable, making the group an observer, that reacts to one Cell change attempt.
And that s*cks.
I can't find what's wrong with my design. I just got stuck with it.
Any ideas of how I can make it work?
Where is it over-objectified? I can feel it too, maybe there is another solution that would be more simple than that...
Instead of having 3 validator classes, an abstract GroupInterface, an observable, etc., you can do it with a single function.
Pseudocode ahead:
bool setCell(int cellX, int cellY, int cellValue)
{
m_cells[x][y] = cellValue;
if (!isRowValid(y) || !isColumnValid(x) || !isSubMatrixValid(x, y))
{
m_cells[x][y] = null; // or 0 or however you represent an empty cell
return false;
}
return true;
}
What is the difference between a ColumnGroup, LineGroup and SubMatrixGroup? IMO, these three should simply be instances of a generic "Group" type, as the type of the group changes nothing - it doesn't even need to be noted.
It sounds like you want to create a checker ("user attempted to write number X"), not a solver. For this, your observable pattern sounds OK (with the change mentioned above).
Here (link) is an example of a simple sudoku solver using the above-mentioned "group" approach.

Defining the structure of hierarchical data versus actually storing the data

I'm trying to develop a survey application that can deal with various types of responses, such as boolean, multiple choice, as well as ranges from 1-5, 1-10, 1-100, -2 to +2, even decimal values. So, I've created a hierarchy of Response types:
class Response {
String name
}
class BooleanResponse extends Response {
boolean score
}
class SimpleGradeResponse extends Response {
char score // A-F
}
class ComplexGradeResponse extends Response {
char score // A-F
char modifier // +, -, blank
}
class IntegerResponse extends Response {
int min, max, score
}
class DecimalResponse extends Response {
double min, max, score
}
I think of that as the metadata. It describes the survey response types. You could have question 1 that's an IntegerResponse from 1 to 10, question 2 that's an IntegerResponse from 0-100, question 3 that's a DecimalResponse, etc.
Where I'm uncertain is where to store the actual responses from users. Do you mingle the scores in with the metadata, as I've done with the score field above? That seems awkward, since every range-type response carries with it the min and max.
What I really want (I think) is to be able to curry the range response parameters to create a new type, and then reflect that type in a table of actual responses. So, a question that takes a 1-10 range would be a row in IntegerResponse with min=1 and max=10. But how does the ActualResponse table (I need to improve the naming convention, once I figure this out!) hold a score and refer to the curried IntegerResponse with min and max set?
If there is a better way to approach this whole problem, I'm eager to hear it.
Thanks,
Lee
min and max should rather be stored in a Question object, or even in QuestionType - depending on how flexible the system should be in runtime.
Will there be arbitrary limitations to different kinds of Responses? Data structure hugely depends on it. You can either hardcode different Response types or support them in runtime. First approach is one order of magnitude simpler.

Value Randomization / Scaling Utilities for iPhone?

I work with a lot of random numbers to create constantly shifting textures. I'm getting tired of doing things like:
((rand() % 1000) / 10) + 100
when I really want something like
[randomUtils randomNumberBetween:100 and:200]
Additonally, I'd like to be able to manipulate weights of the randomization, so that, for example, my values would tend to fall closer to 100, and only rarely approach 200.
Does something like this exist already, or should I just write it myself?
This is, IMO, a nice use for a class with mostly (if not all) class methods. For example, you could create a class called RURandomUtilities. Within the class you could do:
+ (NSInteger) randomNumberBetween:(NSInteger) start and:(NSInteger) end
{
return ((rand() % (start - end) +start);
}
and so on. Depending on if you need lots of instances going of different random numbers, you could make these classes that are instantiated with basic parameters for weighting and seeds.
If you need consistent performance of all random numbers across your applications, local static singletons could be used to hold the weighting. The only instantiated object would be the class itself.