Source/DemoBoardView.m
author Jens Alfke <jens@mooseyard.com>
Fri Mar 07 11:43:02 2008 -0800 (2008-03-07)
changeset 0 e9f7ba4718e1
child 1 3eb7be1dd7b6
permissions -rw-r--r--
Initial check-in into Mercurial. Branched from 1.0 release of Apple's sample code. No longer requires garbage collection. Fixed some memory leaks of CG objects. Fixed a bug when advancing to the 8th row in the Checkers game.
jens@0
     1
/*  This code is based on Apple's "GeekGameBoard" sample code, version 1.0.
jens@0
     2
    http://developer.apple.com/samplecode/GeekGameBoard/
jens@0
     3
    Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved.
jens@0
     4
jens@0
     5
    Redistribution and use in source and binary forms, with or without modification, are permitted
jens@0
     6
    provided that the following conditions are met:
jens@0
     7
jens@0
     8
    * Redistributions of source code must retain the above copyright notice, this list of conditions
jens@0
     9
      and the following disclaimer.
jens@0
    10
    * Redistributions in binary form must reproduce the above copyright notice, this list of
jens@0
    11
      conditions and the following disclaimer in the documentation and/or other materials provided
jens@0
    12
      with the distribution.
jens@0
    13
jens@0
    14
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
jens@0
    15
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
jens@0
    16
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
jens@0
    17
    BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
jens@0
    18
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
jens@0
    19
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
jens@0
    20
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
jens@0
    21
    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
jens@0
    22
*/
jens@0
    23
#import "DemoBoardView.h"
jens@0
    24
#import "Game.h"
jens@0
    25
#import "QuartzUtils.h"
jens@0
    26
jens@0
    27
jens@0
    28
/**  WARNING: THIS CODE REQUIRES GARBAGE COLLECTION!
jens@0
    29
 **  This sample application uses Objective-C 2.0 garbage collection.
jens@0
    30
 **  Therefore, the source code in this file does NOT perform manual object memory management.
jens@0
    31
 **  If you reuse any of this code in a process that isn't garbage collected, you will need to
jens@0
    32
 **  add all necessary retain/release/autorelease calls, and implement -dealloc methods,
jens@0
    33
 **  otherwise unpleasant leakage will occur!
jens@0
    34
 **/
jens@0
    35
jens@0
    36
jens@0
    37
@implementation DemoBoardView
jens@0
    38
jens@0
    39
jens@0
    40
/** Class names of available games */
jens@0
    41
static NSString* const kMenuGameNames[] = {@"KlondikeGame", @"CheckersGame", @"HexchequerGame",
jens@0
    42
                                           @"TicTacToeGame", @"GoGame"};
jens@0
    43
jens@0
    44
/** Class name of the current game. */
jens@0
    45
static NSString* sCurrentGameName = @"KlondikeGame";
jens@0
    46
jens@0
    47
jens@0
    48
- (void) startGameNamed: (NSString*)gameClassName
jens@0
    49
{
jens@0
    50
    [super startGameNamed: gameClassName];
jens@0
    51
    
jens@0
    52
    Game *game = self.game;
jens@0
    53
    [game addObserver: self 
jens@0
    54
           forKeyPath: @"currentPlayer"
jens@0
    55
              options: NSKeyValueObservingOptionInitial
jens@0
    56
              context: NULL];
jens@0
    57
    [game addObserver: self
jens@0
    58
           forKeyPath: @"winner"
jens@0
    59
              options: 0 
jens@0
    60
              context: NULL];
jens@0
    61
    
jens@0
    62
    self.window.title = [(id)[game class] displayName];
jens@0
    63
}
jens@0
    64
jens@0
    65
jens@0
    66
- (CGRect) gameBoardFrame
jens@0
    67
{
jens@0
    68
    CGRect bounds = [super gameBoardFrame];
jens@0
    69
    bounds.size.height -= 32;                   // Leave room for headline
jens@0
    70
    return CGRectInset(bounds,4,4);
jens@0
    71
}
jens@0
    72
jens@0
    73
jens@0
    74
- (void) awakeFromNib
jens@0
    75
{
jens@0
    76
    srandomdev();
jens@0
    77
    
jens@0
    78
    [self registerForDraggedTypes: [NSImage imagePasteboardTypes]];
jens@0
    79
    [self registerForDraggedTypes: [NSArray arrayWithObject: NSFilenamesPboardType]];
jens@0
    80
    
jens@0
    81
    CGRect bounds = self.layer.bounds;
jens@0
    82
    self.layer.backgroundColor = GetCGPatternNamed(@"/Library/Desktop Pictures/Small Ripples graphite.png");
jens@0
    83
        
jens@0
    84
    bounds.size.height -= 32;
jens@0
    85
    _headline = AddTextLayer(self.layer,
jens@0
    86
                             nil, [NSFont boldSystemFontOfSize: 24], 
jens@0
    87
                             kCALayerWidthSizable | kCALayerMinYMargin);
jens@0
    88
    
jens@0
    89
    [self startGameNamed: sCurrentGameName];
jens@0
    90
}
jens@0
    91
jens@0
    92
jens@0
    93
- (void) startGameFromMenu: (id)sender
jens@0
    94
{
jens@0
    95
    sCurrentGameName = kMenuGameNames[ [sender tag] ];
jens@0
    96
    [self startGameNamed: sCurrentGameName];
jens@0
    97
}
jens@0
    98
jens@0
    99
jens@0
   100
- (void)observeValueForKeyPath:(NSString *)keyPath 
jens@0
   101
                      ofObject:(id)object 
jens@0
   102
                        change:(NSDictionary *)change
jens@0
   103
                       context:(void *)context
jens@0
   104
{
jens@0
   105
    Game *game = self.game;
jens@0
   106
    if( object == game ) {
jens@0
   107
        Player *p = game.winner;
jens@0
   108
        NSString *msg;
jens@0
   109
        if( p ) {
jens@0
   110
            [[NSSound soundNamed: @"Sosumi"] play];
jens@0
   111
            msg = @"%@ wins! Congratulations!";
jens@0
   112
        } else {
jens@0
   113
            p = game.currentPlayer;
jens@0
   114
            msg = @"Your turn, %@";
jens@0
   115
        }
jens@0
   116
        _headline.string = [NSString stringWithFormat: msg, p.name];
jens@0
   117
    }
jens@0
   118
}
jens@0
   119
jens@0
   120
jens@0
   121
- (IBAction) enterFullScreen: (id)sender
jens@0
   122
{
jens@0
   123
    [super enterFullScreen: sender];
jens@0
   124
    [self startGameNamed: sCurrentGameName];        // restart game so it'll use the new size
jens@0
   125
}
jens@0
   126
jens@0
   127
jens@0
   128
#pragma mark -
jens@0
   129
#pragma mark NSAPPLICATION DELEGATE:
jens@0
   130
jens@0
   131
jens@0
   132
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
jens@0
   133
{
jens@0
   134
    return YES;
jens@0
   135
}
jens@0
   136
jens@0
   137
@end