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@10
|
23 |
|
jens@10
|
24 |
#import <Foundation/Foundation.h>
|
jens@10
|
25 |
@class GGBLayer, Bit, BitHolder, Player, Turn;
|
jens@0
|
26 |
@protocol BitHolder;
|
jens@0
|
27 |
|
jens@0
|
28 |
|
jens@0
|
29 |
/** Abstract superclass. Keeps track of the rules and turns of a game. */
|
jens@10
|
30 |
@interface Game : NSObject <NSCoding>
|
jens@0
|
31 |
{
|
jens@16
|
32 |
GGBLayer *_table;
|
jens@0
|
33 |
NSArray *_players;
|
jens@10
|
34 |
Player *_winner;
|
jens@10
|
35 |
NSMutableArray *_turns;
|
jens@10
|
36 |
unsigned _currentTurnNo;
|
jens@10
|
37 |
NSMutableDictionary *_extraValues;
|
jens@10
|
38 |
BOOL _requireConfirmation;
|
jens@0
|
39 |
}
|
jens@0
|
40 |
|
jens@10
|
41 |
#pragma mark Class properties:
|
jens@10
|
42 |
|
jens@10
|
43 |
/** The name used to identify this class of game in URLs.
|
jens@10
|
44 |
(By default it just returns the class name with the "Game" suffix removed.) */
|
jens@8
|
45 |
+ (NSString*) identifier;
|
jens@8
|
46 |
|
jens@10
|
47 |
/** The human-readable name of this class of game.
|
jens@0
|
48 |
(By default it just returns the class name with the "Game" suffix removed.) */
|
jens@0
|
49 |
+ (NSString*) displayName;
|
jens@0
|
50 |
|
jens@10
|
51 |
/** Is this game's board wider than it's high? */
|
jens@4
|
52 |
+ (BOOL) landscapeOriented;
|
jens@4
|
53 |
|
jens@10
|
54 |
|
jens@10
|
55 |
/** Designated initializer: override this if your subclass needs additional initialization. */
|
jens@10
|
56 |
- (id) init;
|
jens@10
|
57 |
|
jens@16
|
58 |
/** Convenience initializer that calls -init, -setTable:, and -nextTurn. */
|
jens@16
|
59 |
- (id) initNewGameWithTable: (GGBLayer*)table;
|
jens@10
|
60 |
|
jens@10
|
61 |
/** NSCoding initializer. Calls -init, but then restores saved payers, states, moves. */
|
jens@10
|
62 |
- (id) initWithCoder: (NSCoder*)decoder;
|
jens@10
|
63 |
|
jens@10
|
64 |
/** NSCoding method to save Game to an archive. */
|
jens@10
|
65 |
- (void) encodeWithCoder: (NSCoder*)coder;
|
jens@10
|
66 |
|
jens@10
|
67 |
|
jens@0
|
68 |
@property (readonly, copy) NSArray *players;
|
jens@10
|
69 |
@property (readonly) Player *currentPlayer, *winner, *remotePlayer;
|
jens@10
|
70 |
@property (readonly, getter=isLocal) BOOL local; // Are all players local?
|
jens@0
|
71 |
|
jens@16
|
72 |
@property (retain) GGBLayer *table; // The root layer for the game.
|
jens@10
|
73 |
|
jens@10
|
74 |
@property (readonly) NSArray *turns;
|
jens@10
|
75 |
@property (readonly) Turn *currentTurn, *latestTurn;
|
jens@10
|
76 |
@property (readonly) unsigned maxTurnNo;
|
jens@10
|
77 |
@property unsigned currentTurnNo;
|
jens@7
|
78 |
@property (readonly) BOOL isLatestTurn;
|
jens@7
|
79 |
|
jens@15
|
80 |
/** Check this before the user begins a move action (mouse-down on a bit, etc.)
|
jens@15
|
81 |
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
|
82 |
@property (readonly) BOOL okToMove;
|
jens@15
|
83 |
|
jens@10
|
84 |
@property BOOL requireConfirmation;
|
jens@10
|
85 |
- (void) cancelCurrentTurn;
|
jens@10
|
86 |
- (void) confirmCurrentTurn;
|
jens@8
|
87 |
|
jens@8
|
88 |
|
jens@10
|
89 |
#pragma mark Methods for subclasses to implement:
|
jens@7
|
90 |
|
jens@10
|
91 |
/** An icon for a player (usually the same as the image of the player's pieces.) */
|
jens@10
|
92 |
- (CGImageRef) iconForPlayer: (int)playerIndex;
|
jens@0
|
93 |
|
jens@7
|
94 |
|
jens@0
|
95 |
/** Should return YES if it is legal for the given bit to be moved from its current holder.
|
jens@0
|
96 |
Default implementation always returns YES. */
|
jens@0
|
97 |
- (BOOL) canBit: (Bit*)bit moveFrom: (id<BitHolder>)src;
|
jens@0
|
98 |
|
jens@0
|
99 |
/** Should return YES if it is legal for the given Bit to move from src to dst.
|
jens@0
|
100 |
Default implementation always returns YES. */
|
jens@0
|
101 |
- (BOOL) canBit: (Bit*)bit moveFrom: (id<BitHolder>)src to: (id<BitHolder>)dst;
|
jens@0
|
102 |
|
jens@7
|
103 |
|
jens@0
|
104 |
/** Should handle any side effects of a Bit's movement, such as captures or scoring.
|
jens@0
|
105 |
Does not need to do the actual movement! That's already happened.
|
jens@0
|
106 |
It should end by calling -endTurn, if the player's turn is over.
|
jens@0
|
107 |
Default implementation just calls -endTurn. */
|
jens@0
|
108 |
- (void) bit: (Bit*)bit movedFrom: (id<BitHolder>)src to: (id<BitHolder>)dst;
|
jens@0
|
109 |
|
jens@3
|
110 |
/** Called on mouse-down/touch of an *empty* BitHolder. Should return a Bit if
|
jens@3
|
111 |
it's OK to place a new Bit there; else nil. */
|
jens@3
|
112 |
- (Bit*) bitToPlaceInHolder: (id<BitHolder>)holder;
|
jens@3
|
113 |
|
jens@0
|
114 |
/** Called instead of the above if a Bit is simply clicked, not dragged.
|
jens@0
|
115 |
Should return NO if the click is illegal (i.e. clicking an empty draw pile in a card game.)
|
jens@0
|
116 |
Default implementation always returns YES. */
|
jens@0
|
117 |
- (BOOL) clickedBit: (Bit*)bit;
|
jens@0
|
118 |
|
jens@0
|
119 |
@end
|