Saving High Scores
I'm trying to get my game to save a high score list. I really don't care about format but I figured I'd just use NSMutableDictionary and then write that out to a file as updated. For some reason though, I get a lot of bad access calls trying to do this. I can't figure it out and have been trying all sorts of things yesterday and this morning but nothing seemed to work. I get a bad access call both when trying to display the high score list as well as checking if the player beat a high score. Anyone know what's going wrong? Perhaps I shouldn't use NSMutableDictionary? If not, how do I just write to files otherwise (never done it with Obj-C)?
Code:
(init code)
highScores = [NSMutableDictionary dictionaryWithContentsOfFile:
[@"~/Library/Application Support/wtmhs.plist" stringByExpandingTildeInPath]];
if(highScores == nil)
{
highScores = [NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],
@"Nobody",[NSNumber numberWithInt:5],nil]
forKeys:[NSArray arrayWithObjects:
@"Name1",@"Score1",@"Name2",@"Score2",
@"Name3",@"Score3",@"Name4",@"Score4",
@"Name5",@"Score5",@"Name6",@"Score6",
@"Name7",@"Score7",@"Name8",@"Score8",
@"Name9",@"Score9",@"Name10",@"Score10",nil]];
[highScores writeToFile:[@"~/Library/Application Support/wtmhs.plist"
stringByExpandingTildeInPath] atomically:YES];
}Code:
(testing if player beat a score)
if(myScore > [[highScores objectForKey:@"Score1"] intValue])
{
[highScores removeObjectsForKeys:[NSArray arrayWithObjects:@"Score1",nil]];
[highScores setObject:[NSString stringWithFormat:@"%d",myScore] forKey:@"Score1"];
[newScoreDisplay setStringValue:[NSString stringWithFormat:@"You got a score of %d",myScore]];
[newScorePlace setStringValue:@"earning you first place!"];
[newScoreWindow makeKeyAndOrderFront:newScoreWindow];
newPlace = 1;
}
else if(myScore > [[highScores objectForKey:@"Score2"] intValue])
{
[highScores removeObjectsForKeys:[NSArray arrayWithObjects:@"Score2",nil]];
[highScores setObject:[NSString stringWithFormat:@"%d",myScore] forKey:@"Score2"];
[newScoreDisplay setStringValue:[NSString stringWithFormat:@"You got a score of %d",myScore]];
[newScorePlace setStringValue:@"earning you second place!"];
[newScoreWindow makeKeyAndOrderFront:newScoreWindow];
newPlace = 2;
}
(etc)Code:
(adding new name)
[highScores removeObjectsForKeys:[NSArray arrayWithObjects:keyToRemove,nil]];
[highScores setObject:[newScoreName stringValue] forKey:keyToRemove];
[highScores writeToFile:[@"~/Library/Application Support/wtmhs.plist" stringByExpandingTildeInPath] atomically:YES];Code:
(displaying. runs when high score window opens)
[scoreText setStringValue:[NSString stringWithFormat:@"%@: %@\n%@: %@\n%@: %@\n%@: %@\n%@: %@\n%@: %@\n%@: %@\n%@: %@\n%@: %@\n%@: %@\n",
[highScores objectForKey:@"Name1"],[highScores objectForKey:@"Score1"],
[highScores objectForKey:@"Name2"],[highScores objectForKey:@"Score2"],
[highScores objectForKey:@"Name3"],[highScores objectForKey:@"Score3"],
[highScores objectForKey:@"Name4"],[highScores objectForKey:@"Score4"],
[highScores objectForKey:@"Name5"],[highScores objectForKey:@"Score5"],
[highScores objectForKey:@"Name6"],[highScores objectForKey:@"Score6"],
[highScores objectForKey:@"Name7"],[highScores objectForKey:@"Score7"],
[highScores objectForKey:@"Name8"],[highScores objectForKey:@"Score8"],
[highScores objectForKey:@"Name9"],[highScores objectForKey:@"Score9"],
[highScores objectForKey:@"Name10"],[highScores objectForKey:@"Score10"]]];
did you remember to retain highScores? NSMutableDictionary's +dictionaryWithContentsOfFile method returns an autoreleased object. You have to retain it if you want to keep using it outside your init method.
Also, perhaps you should re-think you data structure. Maybe it would make more sense to do something like this:
- have an NSMutableArray of players
- each player is an NSMutableDictionary
- there are 2 keys for each player: @"name" and @"score"
- the value associated with @"name" is an NSString
- the value associated with @"score" is an NSNumber
- have an NSMutableArray of players
- each player is an NSMutableDictionary
- there are 2 keys for each player: @"name" and @"score"
- the value associated with @"name" is an NSString
- the value associated with @"score" is an NSNumber
Thanks. Retaining it was all it took to work right.
Would rethiking the structure do anything for performance? I think I'm just going to keep it this way because it works and I don't really see the downside of an ugly high scores file that the user will never see (except when it nicely formats it and draws it to the screen).
Would rethiking the structure do anything for performance? I think I'm just going to keep it this way because it works and I don't really see the downside of an ugly high scores file that the user will never see (except when it nicely formats it and draws it to the screen).
Nick Wrote:Would rethiking the structure do anything for performance?
No. However, using the structure I suggested would make it easier for you to add and remove players. It would also reduce the amount of code you'd have to write.
Hm. I have a couple other things I'd like to add and then I'll consider doing it that way. I already wrote all the code to do it this way but I'm always up for learning new things and ways of doing things. Thanks for the help.
no problem
Also, if you're interested, I made some code available on my website that implements a high score class in C++ (complete with file i/o and everything) if you want to use it or just take a look at it:
http://web.newsguy.com/malarkey/freecode.html
http://web.newsguy.com/malarkey/freecode.html
The brains and fingers behind Malarkey Software (plus caretaker of the world's two brattiest felines).
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| High Scores | ChrisPol | 2 | 2,442 |
Aug 22, 2007 05:56 PM Last Post: ChrisPol |
|
| Saving data to file | _Event_Horizon | 2 | 2,638 |
Oct 28, 2005 06:53 AM Last Post: _Event_Horizon |
|
| High Scores | kodex | 0 | 1,895 |
Aug 1, 2005 04:39 PM Last Post: kodex |
|
| Saving/Loading... | CarbonX | 6 | 3,766 |
Sep 25, 2004 07:47 AM Last Post: Steven |
|
| High Scores in Cocoa | BeyondCloister | 17 | 6,261 |
Apr 25, 2003 03:58 AM Last Post: OneSadCookie |
|

