jens@0: /* This code is based on Apple's "GeekGameBoard" sample code, version 1.0. jens@0: http://developer.apple.com/samplecode/GeekGameBoard/ jens@0: Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved. jens@0: jens@0: Redistribution and use in source and binary forms, with or without modification, are permitted jens@0: provided that the following conditions are met: jens@0: jens@0: * Redistributions of source code must retain the above copyright notice, this list of conditions jens@0: and the following disclaimer. jens@0: * Redistributions in binary form must reproduce the above copyright notice, this list of jens@0: conditions and the following disclaimer in the documentation and/or other materials provided jens@0: with the distribution. jens@0: jens@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR jens@0: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jens@0: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI- jens@0: BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES jens@0: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jens@0: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN jens@0: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF jens@0: THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jens@0: */ jens@0: #import "DemoBoardView.h" jens@0: #import "Game.h" jens@1: #import "GGBTextLayer.h" jens@0: #import "QuartzUtils.h" jens@0: jens@0: jens@0: /** WARNING: THIS CODE REQUIRES GARBAGE COLLECTION! jens@0: ** This sample application uses Objective-C 2.0 garbage collection. jens@0: ** Therefore, the source code in this file does NOT perform manual object memory management. jens@0: ** If you reuse any of this code in a process that isn't garbage collected, you will need to jens@0: ** add all necessary retain/release/autorelease calls, and implement -dealloc methods, jens@0: ** otherwise unpleasant leakage will occur! jens@0: **/ jens@0: jens@0: jens@0: @implementation DemoBoardView jens@0: jens@0: jens@0: /** Class names of available games */ jens@0: static NSString* const kMenuGameNames[] = {@"KlondikeGame", @"CheckersGame", @"HexchequerGame", jens@0: @"TicTacToeGame", @"GoGame"}; jens@0: jens@0: /** Class name of the current game. */ jens@7: static NSString* sCurrentGameName = @"CheckersGame"; jens@0: jens@0: jens@0: - (void) startGameNamed: (NSString*)gameClassName jens@0: { jens@0: [super startGameNamed: gameClassName]; jens@0: jens@0: Game *game = self.game; jens@0: [game addObserver: self jens@0: forKeyPath: @"currentPlayer" jens@0: options: NSKeyValueObservingOptionInitial jens@0: context: NULL]; jens@0: [game addObserver: self jens@0: forKeyPath: @"winner" jens@0: options: 0 jens@0: context: NULL]; jens@0: jens@0: self.window.title = [(id)[game class] displayName]; jens@0: } jens@0: jens@0: jens@0: - (CGRect) gameBoardFrame jens@0: { jens@0: CGRect bounds = [super gameBoardFrame]; jens@0: bounds.size.height -= 32; // Leave room for headline jens@0: return CGRectInset(bounds,4,4); jens@0: } jens@0: jens@0: jens@8: - (BOOL)canBecomeKeyView {return YES;} jens@8: - (BOOL)acceptsFirstResponder {return YES;} jens@8: jens@8: jens@0: - (void) awakeFromNib jens@0: { jens@0: srandomdev(); jens@0: jens@0: [self registerForDraggedTypes: [NSImage imagePasteboardTypes]]; jens@0: [self registerForDraggedTypes: [NSArray arrayWithObject: NSFilenamesPboardType]]; jens@0: jens@0: CGRect bounds = self.layer.bounds; jens@1: self.layer.backgroundColor = GetCGPatternNamed(@"Background.png"); jens@0: jens@0: bounds.size.height -= 32; jens@1: _headline = [GGBTextLayer textLayerInSuperlayer: self.layer jens@1: withText: nil jens@1: fontSize: 24 jens@1: alignment: kCALayerWidthSizable | kCALayerMinYMargin]; jens@0: jens@0: [self startGameNamed: sCurrentGameName]; jens@7: jens@7: [_turnSlider bind: @"value" toObject: self withKeyPath: @"game.currentTurn" options: nil]; jens@0: } jens@0: jens@0: jens@8: - (IBAction) startGameFromMenu: (id)sender jens@0: { jens@0: sCurrentGameName = kMenuGameNames[ [sender tag] ]; jens@0: [self startGameNamed: sCurrentGameName]; jens@0: } jens@0: jens@0: jens@0: - (void)observeValueForKeyPath:(NSString *)keyPath jens@0: ofObject:(id)object jens@0: change:(NSDictionary *)change jens@0: context:(void *)context jens@0: { jens@0: Game *game = self.game; jens@0: if( object == game ) { jens@7: NSLog(@"maxTurn = %u, currentTurn=%u", self.game.maxTurn,self.game.currentTurn); jens@7: _turnSlider.maxValue = self.game.maxTurn; jens@7: _turnSlider.numberOfTickMarks = self.game.maxTurn+1; jens@7: jens@0: Player *p = game.winner; jens@0: NSString *msg; jens@0: if( p ) { jens@0: [[NSSound soundNamed: @"Sosumi"] play]; jens@0: msg = @"%@ wins! Congratulations!"; jens@0: } else { jens@0: p = game.currentPlayer; jens@0: msg = @"Your turn, %@"; jens@7: NSLog(@"Game state = '%@'", self.game.stateString); jens@0: } jens@0: _headline.string = [NSString stringWithFormat: msg, p.name]; jens@0: } jens@0: } jens@0: jens@0: jens@8: - (IBAction) undo: (id)sender jens@8: { jens@8: if( self.game.currentTurn > 0 ) jens@8: self.game.currentTurn--; jens@8: else jens@8: NSBeep(); jens@8: } jens@8: jens@8: jens@8: - (IBAction) redo: (id)sender jens@8: { jens@8: if( self.game.currentTurn < self.game.maxTurn ) jens@8: self.game.currentTurn++; jens@8: else jens@8: NSBeep(); jens@8: } jens@8: jens@8: jens@0: - (IBAction) enterFullScreen: (id)sender jens@0: { jens@0: [super enterFullScreen: sender]; jens@0: [self startGameNamed: sCurrentGameName]; // restart game so it'll use the new size jens@0: } jens@0: jens@0: jens@0: #pragma mark - jens@0: #pragma mark NSAPPLICATION DELEGATE: jens@0: jens@0: jens@0: - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender jens@0: { jens@0: return YES; jens@0: } jens@0: jens@0: @end