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@10: jens@10: #import jens@10: @class GGBLayer, Bit, BitHolder, Player, Turn; jens@0: @protocol BitHolder; jens@0: jens@0: jens@0: /** Abstract superclass. Keeps track of the rules and turns of a game. */ jens@10: @interface Game : NSObject jens@0: { jens@1: GGBLayer *_board; jens@0: NSArray *_players; jens@10: Player *_winner; jens@10: NSMutableArray *_turns; jens@10: unsigned _currentTurnNo; jens@10: NSMutableDictionary *_extraValues; jens@10: BOOL _requireConfirmation; jens@0: } jens@0: jens@10: #pragma mark Class properties: jens@10: jens@10: /** The name used to identify this class of game in URLs. jens@10: (By default it just returns the class name with the "Game" suffix removed.) */ jens@8: + (NSString*) identifier; jens@8: jens@10: /** The human-readable name of this class of game. jens@0: (By default it just returns the class name with the "Game" suffix removed.) */ jens@0: + (NSString*) displayName; jens@0: jens@10: /** Is this game's board wider than it's high? */ jens@4: + (BOOL) landscapeOriented; jens@4: jens@10: jens@10: /** Designated initializer: override this if your subclass needs additional initialization. */ jens@10: - (id) init; jens@10: jens@10: /** Convenience initializer that calls -init, -setBoard:, and -nextTurn. */ jens@10: - (id) initNewGameWithBoard: (GGBLayer*)board; jens@10: jens@10: /** NSCoding initializer. Calls -init, but then restores saved payers, states, moves. */ jens@10: - (id) initWithCoder: (NSCoder*)decoder; jens@10: jens@10: /** NSCoding method to save Game to an archive. */ jens@10: - (void) encodeWithCoder: (NSCoder*)coder; jens@10: jens@10: jens@0: @property (readonly, copy) NSArray *players; jens@10: @property (readonly) Player *currentPlayer, *winner, *remotePlayer; jens@10: @property (readonly, getter=isLocal) BOOL local; // Are all players local? jens@0: jens@10: @property (retain) GGBLayer *board; // The root layer for the game. jens@10: jens@10: @property (readonly) NSArray *turns; jens@10: @property (readonly) Turn *currentTurn, *latestTurn; jens@10: @property (readonly) unsigned maxTurnNo; jens@10: @property unsigned currentTurnNo; jens@7: @property (readonly) BOOL isLatestTurn; jens@7: jens@15: /** Check this before the user begins a move action (mouse-down on a bit, etc.) jens@15: It's YES if it's OK to move, or NO if the current move is finished or it's another player's turn. */ jens@15: @property (readonly) BOOL okToMove; jens@15: jens@10: @property BOOL requireConfirmation; jens@10: - (void) cancelCurrentTurn; jens@10: - (void) confirmCurrentTurn; jens@8: jens@8: jens@10: #pragma mark Methods for subclasses to implement: jens@7: jens@10: /** An icon for a player (usually the same as the image of the player's pieces.) */ jens@10: - (CGImageRef) iconForPlayer: (int)playerIndex; jens@0: jens@7: jens@0: /** Should return YES if it is legal for the given bit to be moved from its current holder. jens@0: Default implementation always returns YES. */ jens@0: - (BOOL) canBit: (Bit*)bit moveFrom: (id)src; jens@0: jens@0: /** Should return YES if it is legal for the given Bit to move from src to dst. jens@0: Default implementation always returns YES. */ jens@0: - (BOOL) canBit: (Bit*)bit moveFrom: (id)src to: (id)dst; jens@0: jens@7: jens@0: /** Should handle any side effects of a Bit's movement, such as captures or scoring. jens@0: Does not need to do the actual movement! That's already happened. jens@0: It should end by calling -endTurn, if the player's turn is over. jens@0: Default implementation just calls -endTurn. */ jens@0: - (void) bit: (Bit*)bit movedFrom: (id)src to: (id)dst; jens@0: jens@3: /** Called on mouse-down/touch of an *empty* BitHolder. Should return a Bit if jens@3: it's OK to place a new Bit there; else nil. */ jens@3: - (Bit*) bitToPlaceInHolder: (id)holder; jens@3: jens@0: /** Called instead of the above if a Bit is simply clicked, not dragged. jens@0: Should return NO if the click is illegal (i.e. clicking an empty draw pile in a card game.) jens@0: Default implementation always returns YES. */ jens@0: - (BOOL) clickedBit: (Bit*)bit; jens@0: jens@0: @end