Source/DemoBoardView.m
author Jens Alfke <jens@mooseyard.com>
Sat Jul 05 17:46:43 2008 -0700 (2008-07-05)
changeset 11 436cbdf56810
parent 10 6c78cc6bd7a6
child 17 ccc5ed68222d
permissions -rw-r--r--
* Improved drag-and-drop (supports CandyBar)
* Fixed DiscPiece
* Inheritable layer styles
etc.
     1 /*  This code is based on Apple's "GeekGameBoard" sample code, version 1.0.
     2     http://developer.apple.com/samplecode/GeekGameBoard/
     3     Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved.
     4 
     5     Redistribution and use in source and binary forms, with or without modification, are permitted
     6     provided that the following conditions are met:
     7 
     8     * Redistributions of source code must retain the above copyright notice, this list of conditions
     9       and the following disclaimer.
    10     * Redistributions in binary form must reproduce the above copyright notice, this list of
    11       conditions and the following disclaimer in the documentation and/or other materials provided
    12       with the distribution.
    13 
    14     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
    15     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
    16     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
    17     BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    18     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
    19     PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
    20     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
    21     THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    22 */
    23 #import "DemoBoardView.h"
    24 #import "Game.h"
    25 #import "GGBTextLayer.h"
    26 #import "QuartzUtils.h"
    27 
    28 
    29 @implementation DemoBoardView
    30 
    31 
    32 /** Class names of available games */
    33 static NSString* const kMenuGameNames[] = {@"KlondikeGame", @"CheckersGame", @"HexchequerGame",
    34                                            @"TicTacToeGame", @"GoGame"};
    35 
    36 /** Class name of the current game. */
    37 static NSString* sCurrentGameName = @"CheckersGame";
    38 
    39 
    40 - (IBAction) toggleRemoteOpponent: (id)sender
    41 {
    42     NSAssert(self.game.currentTurn==0,@"Game has already begun");
    43     Player *opponent = [self.game.players objectAtIndex: 1];
    44     opponent.local = !opponent.local;
    45 }
    46 
    47 
    48 - (void) startGameNamed: (NSString*)gameClassName
    49 {
    50     [super startGameNamed: gameClassName];
    51     
    52     Game *game = self.game;
    53     [game addObserver: self 
    54            forKeyPath: @"currentPlayer"
    55               options: NSKeyValueObservingOptionInitial
    56               context: NULL];
    57     [game addObserver: self
    58            forKeyPath: @"winner"
    59               options: 0 
    60               context: NULL];
    61     
    62     self.window.title = [(id)[game class] displayName];
    63 }
    64 
    65 
    66 - (CGRect) gameBoardFrame
    67 {
    68     CGRect bounds = [super gameBoardFrame];
    69     bounds.size.height -= 32;                   // Leave room for headline
    70     return CGRectInset(bounds,4,4);
    71 }
    72 
    73 
    74 - (BOOL)canBecomeKeyView        {return YES;}
    75 - (BOOL)acceptsFirstResponder   {return YES;}
    76 
    77 
    78 - (void) awakeFromNib
    79 {
    80     srandomdev();
    81     
    82     // BoardView supports receiving dragged images, but you have to register for them:
    83     [self registerForDraggedTypes: [NSImage imagePasteboardTypes]];
    84     [self registerForDraggedTypes: [NSArray arrayWithObject: NSFilenamesPboardType]];
    85     
    86     CGRect bounds = self.layer.bounds;
    87     self.layer.backgroundColor = GetCGPatternNamed(@"Background.png");
    88         
    89     bounds.size.height -= 32;
    90     _headline = [GGBTextLayer textLayerInSuperlayer: self.layer
    91                                            withText: nil
    92                                            fontSize: 24
    93                                           alignment: kCALayerWidthSizable | kCALayerMinYMargin];
    94     
    95     [self startGameNamed: sCurrentGameName];
    96     
    97     [_turnSlider bind: @"value"    toObject: self withKeyPath: @"game.currentTurn" options: nil];
    98 }
    99 
   100 
   101 - (IBAction) startGameFromMenu: (id)sender
   102 {
   103     sCurrentGameName = kMenuGameNames[ [sender tag] ];
   104     [self startGameNamed: sCurrentGameName];
   105 }
   106 
   107 
   108 - (void)observeValueForKeyPath:(NSString *)keyPath 
   109                       ofObject:(id)object 
   110                         change:(NSDictionary *)change
   111                        context:(void *)context
   112 {
   113     Game *game = self.game;
   114     if( object == game ) {
   115         NSLog(@"maxTurn = %u, currentTurn = %u", 
   116               self.game.maxTurn,self.game.currentTurn);
   117         NSLog(@"Game state = '%@'", self.game.stateString);
   118 
   119         _turnSlider.maxValue = self.game.maxTurn;
   120         _turnSlider.numberOfTickMarks = self.game.maxTurn+1;
   121         
   122         Player *p = game.winner;
   123         NSString *msg;
   124         if( p ) {
   125             // The game is won
   126             [[NSSound soundNamed: @"Sosumi"] play];
   127             if( self.game.local )
   128                 msg = @"%@ wins! Congratulations!";
   129             else
   130                 msg = p.local ?@"You Win! Congratulations!" :@"You Lose ... :-(";
   131         } else {
   132             // Otherwise go on to the next turn:
   133             p = game.currentPlayer;
   134             msg = @"Your turn, %@";
   135         }
   136         _headline.string = [NSString stringWithFormat: msg, p.name];
   137     }
   138 }
   139 
   140 
   141 - (IBAction) undo: (id)sender
   142 {
   143     if( self.game.currentTurn > 0 )
   144         self.game.currentTurn--;
   145     else
   146         NSBeep();
   147 }
   148 
   149 
   150 - (IBAction) redo: (id)sender
   151 {
   152     if( self.game.currentTurn < self.game.maxTurn )
   153         self.game.currentTurn++;
   154     else
   155         NSBeep();
   156 }
   157 
   158 
   159 #pragma mark -
   160 #pragma mark NSAPPLICATION DELEGATE:
   161 
   162 
   163 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
   164 {
   165     return YES;
   166 }
   167 
   168 @end