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@17: #import "Turn.h" jens@17: #import "Player.h" jens@1: #import "GGBTextLayer.h" jens@0: #import "QuartzUtils.h" 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@10: - (IBAction) toggleRemoteOpponent: (id)sender jens@10: { jens@17: NSAssert(self.game.currentTurnNo==0,@"Game has already begun"); jens@10: Player *opponent = [self.game.players objectAtIndex: 1]; jens@10: opponent.local = !opponent.local; jens@10: } jens@10: jens@10: 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@11: // BoardView supports receiving dragged images, but you have to register for them: 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@17: [_turnSlider bind: @"value" toObject: self withKeyPath: @"game.currentTurnNo" 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@17: NSLog(@"maxTurnNo = %u, currentTurnNo = %u", jens@17: self.game.maxTurnNo,self.game.currentTurnNo); jens@17: NSLog(@"Game state = '%@'", self.game.currentTurn.boardState); jens@10: jens@17: _turnSlider.maxValue = self.game.maxTurnNo; jens@17: _turnSlider.numberOfTickMarks = self.game.maxTurnNo+1; jens@7: jens@0: Player *p = game.winner; jens@0: NSString *msg; jens@0: if( p ) { jens@10: // The game is won jens@0: [[NSSound soundNamed: @"Sosumi"] play]; jens@10: if( self.game.local ) jens@10: msg = @"%@ wins! Congratulations!"; jens@10: else jens@10: msg = p.local ?@"You Win! Congratulations!" :@"You Lose ... :-("; jens@0: } else { jens@10: // Otherwise go on to the next turn: jens@0: p = game.currentPlayer; jens@0: msg = @"Your turn, %@"; 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@17: self.game.currentTurnNo--; jens@8: else jens@8: NSBeep(); jens@8: } jens@8: jens@8: jens@8: - (IBAction) redo: (id)sender jens@8: { jens@17: if( self.game.currentTurnNo < self.game.maxTurnNo ) jens@17: self.game.currentTurnNo++; jens@8: else jens@8: NSBeep(); jens@8: } jens@8: jens@8: 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