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