Ivan Vučica avatar Ivan Vučica committed 5eeb39b

Added saving the game. Added undo. Added srand(). Updated how game over is handled.

Comments (0)

Files changed (8)

     
     NSTextField * _scoreLabel;
     BOOL _askedForRestart;
+    NSUndoManager *_undoManager;
 }
 @property (nonatomic, assign) int score;
 @property (nonatomic, assign) BOOL enabled;
 @property (nonatomic, retain) NSSet * previouslyHighlightedGroup;
 @property (nonatomic, assign) IBOutlet NSTextField * scoreLabel;
+@property (nonatomic, retain) NSUndoManager * undoManager;
+
+-(void)prepareRandomizedPlayfield;
+
 -(NSSet*)pelletsOfSameColorFromPellet:(SGPelletView*)startPellet;
 -(int)scoreForPelletGroup:(NSSet*)pelletGroup;
 -(void)mouseEnteredPellet:(SGPelletView*)pellet;
 -(void)mouseUpOnPellet:(SGPelletView*)pellet;
 -(void)mouseDownOnPellet:(SGPelletView*)pellet;
 
+-(NSData*)archivedState;
+-(void)restoreFromData:(NSData*)data;
 @end
 @synthesize enabled=_enabled;
 @synthesize previouslyHighlightedGroup=_previouslyHighlightedGroup;
 @synthesize scoreLabel=_scoreLabel;
+@synthesize undoManager=_undoManager;
 
 -(id)initWithFrame:(NSRect)frameRect
 {
     self.enabled = YES;
     
     self.wantsLayer = YES;
+    
+    //[self prepareRandomizedPlayfield];
+    
+    return self;
+}
+
+-(void)prepareRandomizedPlayfield
+{
     _pellets = [[NSMutableDictionary dictionaryWithCapacity:COUNTX*COUNTY] retain];
     for(int j = 0; j < COUNTY; j++)
     {
             [self addSubview:pellet];
         }
     }
-        
-    return self;
+
 }
+
 -(void)dealloc
 {
     for(NSTrackingArea * area in self.trackingAreas)
     
     self.scoreLabel = nil;
     self.previouslyHighlightedGroup = nil;
+    self.undoManager = nil;
     
     [super dealloc];
 }
         return;
     }
     
+    [[self.undoManager prepareWithInvocationTarget:self] restoreFromData:[self archivedState]];
+    
     // disable user interaction for a while
     self.enabled = NO;    
     [self performSelector:@selector(reenable)
         
         _askedForRestart = YES;
         int result = NSRunAlertPanel(@"Game over", @"Your score is %d. Play some more?", @"Yes", @"No", nil, self.score);
+        [self.window close];
         if(result == NSAlertDefaultReturn)
         {
-            [[NSApp delegate] newDocument:nil];
+            [[NSDocumentController sharedDocumentController] newDocument:nil];
         }
     }
 }
     
     [self setEnabled:YES];
 }
-- (void)updateScoreLabel
+-(void)updateScoreLabel
 {
     self.scoreLabel.stringValue = [NSString stringWithFormat:@"Score: %d", self.score];
 }
+
+-(NSData*)archivedState
+{
+    NSDictionary * state = [NSDictionary dictionaryWithObjectsAndKeys:
+                            
+                            _pellets, @"pellets", 
+                            [NSNumber numberWithInt:_score], @"score",
+                            nil];
+    
+    return [NSKeyedArchiver archivedDataWithRootObject:state];
+}
+
+-(void)restoreFromData:(NSData*)data
+{
+    [[self.undoManager prepareWithInvocationTarget:self] restoreFromData:[self archivedState]];
+
+    NSDictionary * state = [NSKeyedUnarchiver unarchiveObjectWithData:data];
+    
+    [_pellets release];
+    _pellets = [[state objectForKey:@"pellets"] retain];
+    _score = [[state objectForKey:@"score"] intValue];
+    
+    [self renderFromDict];
+    [self updateScoreLabel];
+}
+-(void)renderFromDict
+{
+    
+    for(SGPelletView * pv in [[self.subviews copy] autorelease])
+    {
+        if([pv isKindOfClass:[SGPelletView class]])
+        {
+            [pv removeFromSuperview];
+        }
+    }
+    
+    for(NSString * key in _pellets)
+    {
+        [[_pellets objectForKey:key] removeFromSuperview];
+        [self addSubview:[_pellets objectForKey:key]];
+    }
+}
+
 @end
 
 #import <Cocoa/Cocoa.h>
 
-@interface SGDocument : NSDocument
+@class SGBoardView;
+@interface SGDocument : NSDocument {
+    SGBoardView *boardView;
+    NSData * _dataToRestoreFrom;
+}
 
+@property (assign) IBOutlet SGBoardView *boardView;
+@property (retain) NSData * dataToRestoreFrom;
 @end
 //
 
 #import "SGDocument.h"
+#import "SGBoardView.h"
 
 @implementation SGDocument
+@synthesize boardView;
+@synthesize dataToRestoreFrom = _dataToRestoreFrom;
 - (id)init
 {
     self = [super init];
     if (self) {
+        
     }
     return self;
 }
 {
     [super windowControllerDidLoadNib:aController];
     
+    if(self.dataToRestoreFrom)
+        [boardView restoreFromData:self.dataToRestoreFrom];
+    else
+        [boardView prepareRandomizedPlayfield];
+    boardView.undoManager = self.undoManager;
+    
 }
 - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
 {
     /*
     NSException *exception = [NSException exceptionWithName:@"UnimplementedMethod" reason:[NSString stringWithFormat:@"%@ is unimplemented", NSStringFromSelector(_cmd)] userInfo:nil];
     @throw exception;
+    
+    return nil;
      */
-    return nil;
+    
+    return [boardView archivedState];
 }
 - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
 {
      You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
      */
     
+    /*
      NSException *exception = [NSException exceptionWithName:@"UnimplementedMethod" reason:[NSString stringWithFormat:@"%@ is unimplemented", NSStringFromSelector(_cmd)] userInfo:nil];
      @throw exception;
+     */
+    
+    self.dataToRestoreFrom = data;
+    return YES;
+}
+
++(BOOL)autosavesInPlace
+{
+    return YES;
 }
 @end
 							<string key="NSFrame">{{373, 480}, {209, 62}}</string>
 							<reference key="NSSuperview" ref="439893737"/>
 							<reference key="NSWindow"/>
-							<reference key="NSNextKeyView"/>
 							<bool key="NSViewIsLayerTreeHost">YES</bool>
 							<int key="NSViewLayerContentsRedrawPolicy">2</int>
 							<string key="NSReuseIdentifierKey">_NS:1505</string>
 				</object>
 				<object class="IBConnectionRecord">
 					<object class="IBOutletConnection" key="connection">
+						<string key="label">boardView</string>
+						<reference key="source" ref="1021"/>
+						<reference key="destination" ref="22355606"/>
+					</object>
+					<int key="connectionID">543</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBOutletConnection" key="connection">
 						<string key="label">scoreLabel</string>
 						<reference key="source" ref="22355606"/>
 						<reference key="destination" ref="763152060"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>{{380, 396}, {480, 360}}</string>
-					<integer value="1"/>
+					<boolean value="NO"/>
 					<string>SGBackgroundView</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 				<reference key="dict.values" ref="0"/>
 			</object>
 			<nil key="sourceID"/>
-			<int key="maxID">542</int>
+			<int key="maxID">543</int>
 		</object>
 		<object class="IBClassDescriber" key="IBDocument.Classes">
 			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
 				<object class="IBPartialClassDescription">
 					<string key="className">SGDocument</string>
 					<string key="superclassName">NSDocument</string>
+					<object class="NSMutableDictionary" key="outlets">
+						<string key="NS.key.0">boardView</string>
+						<string key="NS.object.0">SGBoardView</string>
+					</object>
+					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
+						<string key="NS.key.0">boardView</string>
+						<object class="IBToOneOutletInfo" key="NS.object.0">
+							<string key="name">boardView</string>
+							<string key="candidateClassName">SGBoardView</string>
+						</object>
+					</object>
 					<object class="IBClassDescriptionSource" key="sourceIdentifier">
 						<string key="majorKey">IBProjectSource</string>
 						<string key="minorKey">./Classes/SGDocument.h</string>
     
     return self;
 }
+-(id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super initWithCoder:aDecoder];
+    if(!self)
+        return nil;
+    
+    self.stoneImage = [NSImage imageNamed:@"pellet_white"];
+    self.wantsLayer = YES;
+
+    self.pelletColor = [aDecoder decodeIntForKey:@"pelletColor"];
+    self.highlighted = [aDecoder decodeBoolForKey:@"highlighted"];
+    self.identifier = [aDecoder decodeObjectForKey:@"identifier"];
+    self.alive = [aDecoder decodeBoolForKey:@"alive"];
+
+    return self;
+}    
 -(void)dealloc
 {
     for(NSTrackingArea * area in self.trackingAreas)
 }
 
 
+-(void)encodeWithCoder:(NSCoder *)aCoder
+{
+    [super encodeWithCoder:aCoder];
+    [aCoder encodeInt:self.pelletColor forKey:@"pelletColor"];
+    [aCoder encodeBool:self.highlighted forKey:@"highlighted"];
+    [aCoder encodeObject:self.identifier forKey:@"identifier"];
+    [aCoder encodeBool:self.alive forKey:@"alive"];
+}
+
 @end

SameGameAppDelegate.h

 
 @class SGBoardView;
 @interface SameGameAppDelegate : NSObject <NSApplicationDelegate> {
-    NSWindow *window;
-    SGBoardView *boardView;
 }
 
-@property (assign) IBOutlet NSWindow *window;
-@property (assign) IBOutlet SGBoardView *boardView;
 
 @end

SameGameAppDelegate.m

 
 @implementation SameGameAppDelegate
 
-@synthesize window;
-@synthesize boardView;
-
 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
 	// Insert code here to initialize your application 
-    self.window.acceptsMouseMovedEvents = YES;
+
+    srand(time(NULL));
 }
 /*
 -(IBAction)newDocument:(id)sender
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.