Source/DemoBoardView.m
author snej@snej.local
Sun Jan 11 00:02:27 2009 -0800 (2009-01-11)
changeset 26 e7a464fb6d39
parent 17 ccc5ed68222d
permissions -rw-r--r--
Added ball graphics to Xcode project, which fixes the Go game. Fixed Tic-Tac-Toe. Fixed an exception in the demo app when changing games.
     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     [self.game removeObserver: self 
    53            forKeyPath: @"currentPlayer"];
    54     [self.game removeObserver: self
    55            forKeyPath: @"winner"];
    56 
    57     [super startGameNamed: gameClassName];
    58     
    59     [self.game addObserver: self 
    60            forKeyPath: @"currentPlayer"
    61               options: NSKeyValueObservingOptionInitial
    62               context: NULL];
    63     [self.game addObserver: self
    64            forKeyPath: @"winner"
    65               options: 0 
    66               context: NULL];
    67     
    68     self.window.title = [(id)[self.game class] displayName];
    69 }
    70 
    71 
    72 - (CGRect) gameBoardFrame
    73 {
    74     CGRect bounds = [super gameBoardFrame];
    75     bounds.size.height -= 32;                   // Leave room for headline
    76     return CGRectInset(bounds,4,4);
    77 }
    78 
    79 
    80 - (BOOL)canBecomeKeyView        {return YES;}
    81 - (BOOL)acceptsFirstResponder   {return YES;}
    82 
    83 
    84 - (void) awakeFromNib
    85 {
    86     srandomdev();
    87     
    88     // BoardView supports receiving dragged images, but you have to register for them:
    89     [self registerForDraggedTypes: [NSImage imagePasteboardTypes]];
    90     [self registerForDraggedTypes: [NSArray arrayWithObject: NSFilenamesPboardType]];
    91     
    92     CGRect bounds = self.layer.bounds;
    93     self.layer.backgroundColor = GetCGPatternNamed(@"Background.png");
    94         
    95     bounds.size.height -= 32;
    96     _headline = [GGBTextLayer textLayerInSuperlayer: self.layer
    97                                            withText: nil
    98                                            fontSize: 24
    99                                           alignment: kCALayerWidthSizable | kCALayerMinYMargin];
   100     
   101     [self startGameNamed: sCurrentGameName];
   102     
   103     [_turnSlider bind: @"value"    toObject: self withKeyPath: @"game.currentTurnNo" options: nil];
   104 }
   105 
   106 
   107 - (IBAction) startGameFromMenu: (id)sender
   108 {
   109     sCurrentGameName = kMenuGameNames[ [sender tag] ];
   110     [self startGameNamed: sCurrentGameName];
   111 }
   112 
   113 
   114 - (void)observeValueForKeyPath:(NSString *)keyPath 
   115                       ofObject:(id)object 
   116                         change:(NSDictionary *)change
   117                        context:(void *)context
   118 {
   119     Game *game = self.game;
   120     if( object == game ) {
   121         NSLog(@"maxTurnNo = %u, currentTurnNo = %u", 
   122               self.game.maxTurnNo,self.game.currentTurnNo);
   123         NSLog(@"Game state = '%@'", self.game.currentTurn.boardState);
   124 
   125         _turnSlider.maxValue = self.game.maxTurnNo;
   126         _turnSlider.numberOfTickMarks = self.game.maxTurnNo+1;
   127         
   128         Player *p = game.winner;
   129         NSString *msg;
   130         if( p ) {
   131             // The game is won
   132             [[NSSound soundNamed: @"Sosumi"] play];
   133             if( self.game.local )
   134                 msg = @"%@ wins! Congratulations!";
   135             else
   136                 msg = p.local ?@"You Win! Congratulations!" :@"You Lose ... :-(";
   137         } else {
   138             // Otherwise go on to the next turn:
   139             p = game.currentPlayer;
   140             msg = @"Your turn, %@";
   141         }
   142         _headline.string = [NSString stringWithFormat: msg, p.name];
   143     }
   144 }
   145 
   146 
   147 - (IBAction) undo: (id)sender
   148 {
   149     if( self.game.currentTurn > 0 )
   150         self.game.currentTurnNo--;
   151     else
   152         NSBeep();
   153 }
   154 
   155 
   156 - (IBAction) redo: (id)sender
   157 {
   158     if( self.game.currentTurnNo < self.game.maxTurnNo )
   159         self.game.currentTurnNo++;
   160     else
   161         NSBeep();
   162 }
   163 
   164 
   165 #pragma mark -
   166 #pragma mark NSAPPLICATION DELEGATE:
   167 
   168 
   169 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
   170 {
   171     return YES;
   172 }
   173 
   174 @end