Friday, March 09, 2007

General Statistics 101

http://flyingsheep.com/dicetest/test.asp
Goals for today
 I'd eventually like to be able to roll a complete character and have the computer tell me which archetype those statistic would best fit (e.g. what type of character I should create, unless I choose to re-roll).

Task List
 1 Add a second statistic to my character.
 2 Generalize the statistic class.
 3 Add the remaining statistic to my character.
 4 Define Archetype minimum statistics
 5 Write and test comparison program.

Ritual
 First, I'll move my passing tests (that I don't plan on modifying today) into the successful tests page. I'll eventually need multiple categorized pages of successful tests, but not today.

1 Second Statistic
 That was easy. A little copy/paste in the validation function, but I'll clean it up later (Copy/Paste once is acceptable, I think. Copy/Paste seven times indicates the time to generalize).

2 Generalize Statistic.
 I'm a bit worried about my dependence on Intellisense, and stuff I've been reading suggests that it doesn't work with multiple nested classes. Still, I think that multiple nested classes is, in this case, the way to go. A Character should contain multiple Statistics.
 The reason for generalizing at this point is in anticipation of multiple different objects (Characters, Archetypes, Abilities) using the same Statistic objects.
 I'm a bit confused about how to proceed. Then I realize I don't have a failing test.  Ah, I write a test to walk through the statistics collection (which doesn't exist yet), and it fails.
 For the first, I need to disable error ignoring in RunGenericTest, because I need the additional diagnostic information. I re-enable it afterwards. I'm also reduced to throwing in some "Response.Write"s to help debug, although that smells a bit.
 Ok, So Strength is using the new Statistic class (which I simplified as a public Name/Value pair, although I expect it to get more complex soon). I'll finish converting Agility, and clean up unused references to the hardcoded names in the class.
 Getting "Object doesn't support this property or method " error. Need to beef up my objCharacter.DebugPrint function.
 Disabled Error Ignoring again. I may want to add that as a switch (now that I've find my new friend Execute). Something like blnTreatErrorsAsFatal.

3 Add the remaining statistic to my character.
 Found this http://www.thehaws.org/add_quiz.shtml cute little quiz to determine your real life Dungeons and Dragons Stats. The author was nice enough to leave in some default values for impatient people like me.
 I'm slightly annoyed that Strength has a different format (e.g. 3d6 + d100), but I'm going to ignore that. Game Designer's prerogative. Also turns out that there's no statistic for Agility. Hmm...
 Ah, the powers of generalization. Just adding one line per statistic should handle all the programming and testing. Six lines of code later, and my character is feeling much more multi-dimensional. Oh, I suppose I should test it.

This character is named Gunthar and is a Barbarian.
This character has 6 statistics.
Gunthar has a Strength of 11.
Gunthar has a Intelligence of 12.
Gunthar has a Wisdom of 6.
Gunthar has a Dexterity of  9.
Gunthar has a Constitution of 14.
Gunthar has a Charisma of 11.

 Sweet.

4 Define Archetype minimum statistics
 Some simple rules: Fighters - minimum Strength 9; Mages - minimum 9 Intelligence; Clerics - minimum 9 Wisdom; Thieves - min 9 Dexterity.
 Now I'm at a bit of a quandary. I don't want to compare objCharacter.Statistic("name").value to objArchetype.MinimumRequiredStatistic("name").value. I don't like doing comparisons by "name" - the danger of trying to compare "Strength" and "Strength" is too great (with my less than stellar spelling ability). I want canonical Statistics, with IDs and Named constants like STATISTIC_STRENGTH = 1. I want a global object that defines which statistics exist and exposes an enumerated list.
 However, I also want to be able to add new statistics later. I guess I want a FindStatisticByName("Strength") so that I can use them both as string aliases and constants.  Let's start down that path.
 CStatistic is sort of an instance of a statistic. This will also give me the first stuff to put into my StartUp pre-test function.
 Oops. Wrote a bunch of code without a failing test. I've got to get into the right habits. Two syntax errors. I'm coding too much between tests.
 OK, new plan for today. I'll write up some tests for this new Canonical Statistics object. I'm still not sure if it should be global, or should be passed around.
 Adding a DebugPrint function to this new object.
 My previous tests have been more like commands - CreateBasicCharacter. I exercise the functionality, but don't check for results (except for the errors being thrown). For this new class, I'm going to be specific (as there are specific things I want to check, such as disallowing the addition of duplicates). Nice - I can use the DebugPrint function to ensure that the object is the same after attempting to add a duplicate.
 New Assert Function - AssertNumbersMatch(). Funny how I needed AssertNumberInRange first. Works. I like how the code and the tests have a symbiotic relationship - each validates the other.
 Time to clean up, set up tasks for next time, and log off, with all tests passing.

0 Comments:

Post a Comment

<< Home