Source/DemoBoardView.m
author Jens Alfke <jens@mooseyard.com>
Mon Jul 14 21:46:09 2008 -0700 (2008-07-14)
changeset 17 ccc5ed68222d
parent 11 436cbdf56810
child 26 e7a464fb6d39
permissions -rw-r--r--
Updated DemoBoardView and the xcode project to work with the latest sources.
     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 "Turn.h"
    26 #import "Player.h"
    27 #import "GGBTextLayer.h"
    28 #import "QuartzUtils.h"
    29 
    30 
    31 @implementation DemoBoardView
    32 
    33 
    34 /** Class names of available games */
    35 static NSString* const kMenuGameNames[] = {@"KlondikeGame", @"CheckersGame", @"HexchequerGame",
    36                                            @"TicTacToeGame", @"GoGame"};
    37 
    38 /** Class name of the current game. */
    39 static NSString* sCurrentGameName = @"CheckersGame";
    40 
    41 
    42 - (IBAction) toggleRemoteOpponent: (id)sender
    43 {
    44     NSAssert(self.game.currentTurnNo==0,@"Game has already begun");
    45     Player *opponent = [self.game.players objectAtIndex: 1];
    46     opponent.local = !opponent.local;
    47 }
    48 
    49 
    50 - (void) startGameNamed: (NSString*)gameClassName
    51 {
    52     [super startGameNamed: gameClassName];
    53     
    54     Game *game = self.game;
    55     [game addObserver: self 
    56            forKeyPath: @"currentPlayer"
    57               options: NSKeyValueObservingOptionInitial
    58               context: NULL];
    59     [game addObserver: self
    60            forKeyPath: @"winner"
    61               options: 0 
    62               context: NULL];
    63     
    64     self.window.title = [(id)[game class] displayName];
    65 }
    66 
    67 
    68 - (CGRect) gameBoardFrame
    69 {
    70     CGRect bounds = [super gameBoardFrame];
    71     bounds.size.height -= 32;                   // Leave room for headline
    72     return CGRectInset(bounds,4,4);
    73 }
    74 
    75 
    76 - (BOOL)canBecomeKeyView        {return YES;}
    77 - (BOOL)acceptsFirstResponder   {return YES;}
    78 
    79 
    80 - (void) awakeFromNib
    81 {
    82     srandomdev();
    83     
    84     // BoardView supports receiving dragged images, but you have to register for them:
    85     [self registerForDraggedTypes: [NSImage imagePasteboardTypes]];
    86     [self registerForDraggedTypes: [NSArray arrayWithObject: NSFilenamesPboardType]];
    87     
    88     CGRect bounds = self.layer.bounds;
    89     self.layer.backgroundColor = GetCGPatternNamed(@"Background.png");
    90         
    91     bounds.size.height -= 32;
    92     _headline = [GGBTextLayer textLayerInSuperlayer: self.layer
    93                                            withText: nil
    94                                            fontSize: 24
    95                                           alignment: kCALayerWidthSizable | kCALayerMinYMargin];
    96     
    97     [self startGameNamed: sCurrentGameName];
    98     
    99     [_turnSlider bind: @"value"    toObject: self withKeyPath: @"game.currentTurnNo" options: nil];
   100 }
   101 
   102 
   103 - (IBAction) startGameFromMenu: (id)sender
   104 {
   105     sCurrentGameName = kMenuGameNames[ [sender tag] ];
   106     [self startGameNamed: sCurrentGameName];
   107 }
   108 
   109 
   110 - (void)observeValueForKeyPath:(NSString *)keyPath 
   111                       ofObject:(id)object 
   112                         change:(NSDictionary *)change
   113                        context:(void *)context
   114 {
   115     Game *game = self.game;
   116     if( object == game ) {
   117         NSLog(@"maxTurnNo = %u, currentTurnNo = %u", 
   118               self.game.maxTurnNo,self.game.currentTurnNo);
   119         NSLog(@"Game state = '%@'", self.game.currentTurn.boardState);
   120 
   121         _turnSlider.maxValue = self.game.maxTurnNo;
   122         _turnSlider.numberOfTickMarks = self.game.maxTurnNo+1;
   123         
   124         Player *p = game.winner;
   125         NSString *msg;
   126         if( p ) {
   127             // The game is won
   128             [[NSSound soundNamed: @"Sosumi"] play];
   129             if( self.game.local )
   130                 msg = @"%@ wins! Congratulations!";
   131             else
   132                 msg = p.local ?@"You Win! Congratulations!" :@"You Lose ... :-(";
   133         } else {
   134             // Otherwise go on to the next turn:
   135             p = game.currentPlayer;
   136             msg = @"Your turn, %@";
   137         }
   138         _headline.string = [NSString stringWithFormat: msg, p.name];
   139     }
   140 }
   141 
   142 
   143 - (IBAction) undo: (id)sender
   144 {
   145     if( self.game.currentTurn > 0 )
   146         self.game.currentTurnNo--;
   147     else
   148         NSBeep();
   149 }
   150 
   151 
   152 - (IBAction) redo: (id)sender
   153 {
   154     if( self.game.currentTurnNo < self.game.maxTurnNo )
   155         self.game.currentTurnNo++;
   156     else
   157         NSBeep();
   158 }
   159 
   160 
   161 #pragma mark -
   162 #pragma mark NSAPPLICATION DELEGATE:
   163 
   164 
   165 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
   166 {
   167     return YES;
   168 }
   169 
   170 @end