Skip to content

Commit

Permalink
Add QuartzCore framework, Board View delegate, some fixes to BoardVie…
Browse files Browse the repository at this point in the history
…w (but it’s still buggy), add animation to Piece View, add move navigation to chess game model, fix initialization of SFMDocument, implement delegate in window controller, fix tests
  • Loading branch information
daylen committed Jan 12, 2014
1 parent 7e13c34 commit d093e35
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 45 deletions.
6 changes: 6 additions & 0 deletions Stockfish.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
77924AFD187E72940019C56E /* SFMParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 77924AFC187E72940019C56E /* SFMParser.mm */; };
77924AFF187E77770019C56E /* SFMParserTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 77924AFE187E77770019C56E /* SFMParserTest.mm */; };
779925D9188273C800EAAEDD /* SFMChessGameTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 779925D8188273C800EAAEDD /* SFMChessGameTest.mm */; };
779925DC1882914B00EAAEDD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 779925DB1882914B00EAAEDD /* QuartzCore.framework */; };
77C1BD7A187E7DB500FB2EF9 /* PositionTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 77C1BD79187E7DB500FB2EF9 /* PositionTest.mm */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -152,6 +153,8 @@
77924AFC187E72940019C56E /* SFMParser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SFMParser.mm; path = Stockfish/SFMParser.mm; sourceTree = "<group>"; };
77924AFE187E77770019C56E /* SFMParserTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SFMParserTest.mm; sourceTree = "<group>"; };
779925D8188273C800EAAEDD /* SFMChessGameTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SFMChessGameTest.mm; sourceTree = "<group>"; };
779925DA18828B6B00EAAEDD /* SFMBoardViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SFMBoardViewDelegate.h; path = Stockfish/SFMBoardViewDelegate.h; sourceTree = "<group>"; };
779925DB1882914B00EAAEDD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
77C1BD79187E7DB500FB2EF9 /* PositionTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PositionTest.mm; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand All @@ -160,6 +163,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
779925DC1882914B00EAAEDD /* QuartzCore.framework in Frameworks */,
77050672187CE43300BA4635 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -179,6 +183,7 @@
77050665187CE43300BA4635 = {
isa = PBXGroup;
children = (
779925DA18828B6B00EAAEDD /* SFMBoardViewDelegate.h */,
773DE97018822DF8009156C3 /* Piece PDFs */,
7752FF4818810B34003E82B3 /* View */,
7715B8AD187E8981006F2366 /* Model */,
Expand All @@ -204,6 +209,7 @@
77050670187CE43300BA4635 /* Frameworks */ = {
isa = PBXGroup;
children = (
779925DB1882914B00EAAEDD /* QuartzCore.framework */,
77050671187CE43300BA4635 /* Cocoa.framework */,
77050693187CE43400BA4635 /* XCTest.framework */,
77050673187CE43300BA4635 /* Other Frameworks */,
Expand Down
2 changes: 2 additions & 0 deletions Stockfish/SFMBoardView.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import <Cocoa/Cocoa.h>
#import "SFMBoardViewDelegate.h"

#include "../Chess/position.h"

Expand All @@ -16,6 +17,7 @@ using namespace Chess;

@property (nonatomic) BOOL boardIsFlipped;
@property (nonatomic) Position *position;
@property (nonatomic) id <SFMBoardViewDelegate> delegate;

- (void)displayPossibleMoveHighlightsForPieceOnSquare:(Square)sq;

Expand Down
81 changes: 61 additions & 20 deletions Stockfish/SFMBoardView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@ @implementation SFMBoardView
CGFloat squareSideLength;

#pragma mark - Setters

- (void)setPosition:(Chess::Position *)position
{
_position = position;
NSLog(@"setting position");

assert(position->is_ok());

// Invalidate pieces array
self.pieces = [NSMutableArray new];
Expand Down Expand Up @@ -90,12 +94,6 @@ - (id)initWithFrame:(NSRect)frame
[self.boardShadow setShadowBlurRadius:BOARD_SHADOW_BLUR_RADIUS];
[self.boardShadow setShadowColor:[NSColor colorWithWhite:0 alpha:0.75]]; // Gray

// Chess init
init_direction_table();
init_bitboards();
Position::init_zobrist();
Position::init_piece_square_tables();

self.position = new Position([FEN_START_POSITION UTF8String]);

}
Expand All @@ -105,6 +103,7 @@ - (id)initWithFrame:(NSRect)frame
#pragma mark - Draw
- (void)drawRect:(NSRect)dirtyRect
{
NSLog(@"Draw rect");
// Draw a felt background
NSGraphicsContext *context = [NSGraphicsContext currentContext];
[context saveGraphicsState];
Expand Down Expand Up @@ -158,9 +157,12 @@ - (void)drawRect:(NSRect)dirtyRect

// Draw pieces
for (SFMPieceView *pieceView in self.pieces) {
CGPoint coordinate = [self coordinatesForSquare:pieceView.square leftOffset:leftInset topOffset:topInset sideLength:squareSideLength];
[pieceView setFrame:NSMakeRect(coordinate.x, coordinate.y, squareSideLength, squareSideLength)];
[pieceView setNeedsDisplay:YES];
// Only redraw if resizing or if we haven't drawn yet or if the board has been flipped
if (pieceView.frame.size.width == 0 || [self inLiveResize]) {
CGPoint coordinate = [self coordinatesForSquare:pieceView.square leftOffset:leftInset topOffset:topInset sideLength:squareSideLength];
[pieceView setFrame:NSMakeRect(coordinate.x, coordinate.y, squareSideLength, squareSideLength)];
[pieceView setNeedsDisplay:YES];
}
}

// Draw highlights
Expand Down Expand Up @@ -206,30 +208,69 @@ - (Square)squareForCoordinates:(NSPoint)point
number = (int) (point.y - top) / (int) sideLength;
number = 7 - number;
}
assert(letter >= 0 && letter <= 7 && number >= 0 && number <= 7);
if (!(letter >= 0 && letter <= 7 && number >= 0 && number <= 7)) {
return SQ_NONE;
}
return static_cast<Square>(8 * number + letter);
}

#pragma mark - Interaction

- (void)mouseUp:(NSEvent *)theEvent
{
if (YES) { // numHighlightedSquares > 0
NSPoint event_location = [theEvent locationInWindow];
NSPoint local_point = [self convertPoint:event_location fromView:nil];
Square clickedSquare = [self squareForCoordinates:local_point leftOffset:leftInset topOffset:topInset sideLength:squareSideLength];
int letter = clickedSquare % 8;
int number = clickedSquare / 8;
NSLog(@"YOU CLICKED: %c%d", 'a'+letter, number+1);
if (numHighlightedSquares > 0) {
NSPoint clickLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
Square clickedSquare = [self squareForCoordinates:clickLocation leftOffset:leftInset topOffset:topInset sideLength:squareSideLength];

if (clickedSquare == SQ_NONE) {
NSLog(@"Did not actually click a square!");
}

// Get the clicked square
// See if clicked square was in the highlighted squares
// Handle promotion
for (int i = 0; i < numHighlightedSquares; i++) {
if (highlightedSquares[i] == clickedSquare) {
assert(self.delegate != nil);
Move theMove = [self.delegate doMoveFrom:selectedSquare
to:clickedSquare]; // Update the model
UndoInfo u;
self.position->do_move(theMove, u); // Update view
[self animatePieceOnSquare:selectedSquare to:clickedSquare];
}
}

// TODO Handle promotion
}
numHighlightedSquares = 0;
[self setNeedsDisplay:YES];
}

- (void)animatePieceOnSquare:(Square)fromSquare to:(Square)toSquare
{
[self animatePieceOnSquare:fromSquare to:toSquare promotion:NO_PIECE_TYPE];
}

- (void)animatePieceOnSquare:(Square)fromSquare to:(Square)toSquare promotion:(PieceType)desiredPromotionPiece
{
// TODO handle promotion
SFMPieceView *thePiece;
SFMPieceView *capturedPiece;
for (SFMPieceView *pieceView in self.pieces) {
if (pieceView.square == fromSquare) {
thePiece = pieceView;
}
if (pieceView.square == toSquare) {
capturedPiece = pieceView;
}
}

if (capturedPiece) {

} else {
[thePiece moveTo:[self coordinatesForSquare:toSquare leftOffset:leftInset topOffset:topInset sideLength:squareSideLength]];
}

// TODO update internal data structure
}

- (void)displayPossibleMoveHighlightsForPieceOnSquare:(Chess::Square)sq
{
selectedSquare = sq;
Expand Down
20 changes: 20 additions & 0 deletions Stockfish/SFMBoardViewDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// SFMBoardViewDelegate.h
// Stockfish
//
// Created by Daylen Yang on 1/12/14.
// Copyright (c) 2014 Daylen Yang. All rights reserved.
//

#import <Foundation/Foundation.h>

#include "../Chess/position.h"

using namespace Chess;

@protocol SFMBoardViewDelegate <NSObject>

- (Move)doMoveFrom:(Square)fromSquare to:(Square)toSquare promotion:(PieceType)desiredPieceType;
- (Move)doMoveFrom:(Square)fromSquare to:(Square)toSquare;

@end
17 changes: 11 additions & 6 deletions Stockfish/SFMChessGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,27 @@ using namespace Chess;
@property NSMutableDictionary *tags;
@property NSMutableArray *moves; // Lazy
@property NSString *moveText;
@property int currentMoveIndex;
@property Position *startPosition;
@property Position *currPosition;

#pragma mark - Init
#pragma mark - Init and Set Up
- (id)initWithWhite:(SFMPlayer *)p1 andBlack:(SFMPlayer *)p2;
- (id)initWithTags:(NSDictionary *)tags andMoves:(NSString *)moves; // Saves the tags and move text

#pragma mark - Preparation
- (void)populateMovesFromMoveText; // Actually load the game

#pragma mark - Moves
- (void)doMove:(Move)move;
#pragma mark - Doing Moves
- (Move)doMoveFrom:(Square)fromSquare to:(Square)toSquare promotion:(PieceType)desiredPieceType;
- (void)doMoveFrom:(Square)fromSquare to:(Square)toSquare;

#pragma mark - Navigation
- (BOOL)atBeginning;
- (BOOL)atEnd;
- (void)goBackOneMove;
- (void)goForwardOneMove;
- (void)goToBeginning;
- (void)goToEnd;
- (void)goToPly:(int)ply;

#pragma mark - Export
- (NSString *)pgnString; // PGN string for this game

Expand Down
70 changes: 62 additions & 8 deletions Stockfish/SFMChessGame.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@
#include "../Chess/move.h"
#include "../Chess/san.h"

@interface SFMChessGame()

@property int currentMoveIndex;

@end

@implementation SFMChessGame

#pragma mark - Init
#pragma mark - Init and Set Up
- (id)initWithWhite:(SFMPlayer *)p1 andBlack:(SFMPlayer *)p2
{
self = [super init];
Expand All @@ -34,8 +40,11 @@ - (id)initWithWhite:(SFMPlayer *)p1 andBlack:(SFMPlayer *)p2
self.moves = [NSMutableArray new];
self.moveText = nil;
self.currentMoveIndex = 0;

self.startPosition = new Position([FEN_START_POSITION UTF8String]);
self.currPosition = new Position([FEN_START_POSITION UTF8String]);
assert(self.startPosition->is_ok());
assert(self.currPosition->is_ok());
}
return self;
}
Expand All @@ -52,7 +61,6 @@ - (id)initWithTags:(NSMutableDictionary *)tags andMoves:(NSString *)moves
return self;
}

#pragma mark - Preparation
- (void)populateMovesFromMoveText
{
[self convertToChessMoveObjects:[SFMParser parseMoves:self.moveText]];
Expand Down Expand Up @@ -97,13 +105,12 @@ - (void)convertToChessMoveObjects:(NSArray *)movesAsText

}

#pragma mark - Moves
- (void)doMove:(Move)move
{

}
#pragma mark - Doing Moves

- (Move)doMoveFrom:(Square)fromSquare to:(Square)toSquare promotion:(PieceType)desiredPieceType
{
assert(self.currPosition->is_ok());
self.currPosition->print();
assert(square_is_ok(fromSquare));
assert(square_is_ok(toSquare));
assert(desiredPieceType == NO_PIECE_TYPE ||
Expand Down Expand Up @@ -143,9 +150,56 @@ - (void)doMoveFrom:(Square)fromSquare to:(Square)toSquare
{
[self doMoveFrom:fromSquare to:toSquare promotion:NO_PIECE_TYPE];
}
- (BOOL)atEnd {

#pragma mark - Navigation

- (BOOL)atBeginning
{
return self.currentMoveIndex == 0;
}
- (BOOL)atEnd
{
return self.currentMoveIndex == [self.moves count];
}
- (void)goBackOneMove
{
if (![self atBeginning]) {
self.currentMoveIndex--;
SFMChessMove *chessMove = self.moves[self.currentMoveIndex];
Move move = chessMove.move;
UndoInfo undoInfo = chessMove.undoInfo;
self.currPosition->undo_move(move, undoInfo);
}
}
- (void)goForwardOneMove
{
if (![self atEnd]) {
SFMChessMove *chessMove = self.moves[self.currentMoveIndex];
Move move = chessMove.move;
UndoInfo undoInfo = chessMove.undoInfo;
self.currPosition->do_move(move, undoInfo);
self.currentMoveIndex++;
}
}
- (void)goToBeginning
{
while (![self atBeginning]) {
[self goBackOneMove];
}
}
- (void)goToEnd
{
while (![self atEnd]) {
[self goForwardOneMove];
}
}
- (void)goToPly:(int)ply
{
[self goToBeginning];
for (int i = 0; i < ply && ![self atEnd]; i++) {
[self goForwardOneMove];
}
}

#pragma mark - Export

Expand Down
5 changes: 4 additions & 1 deletion Stockfish/SFMDocument.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ - (id)init
{
self = [super init];
if (self) {
// We have to call all these init methods, or else Chess::Position
// might crash

init_mersenne();
init_direction_table();
init_bitboards();
Expand All @@ -42,7 +45,7 @@ - (id)init

- (id)initWithType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
self = [super init];
self = [self init];
if (self) {
self.pgnFile = [SFMPGNFile new];
}
Expand Down
1 change: 1 addition & 0 deletions Stockfish/SFMPieceView.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ using namespace Chess;
- (id)initWithPieceType:(Piece)pieceType
onSquare:(Square)square
boardView:(SFMBoardView *)boardView;
- (void)moveTo:(NSPoint)point;

@end

0 comments on commit d093e35

Please sign in to comment.