//Constants.h
#define UNCHANGED -1
#define RED 0
#define BLACK 1
//Checkers.m
/**************************************************************************************/
/**************************************************************************************/
//*Checkers application written in Objective C
//*Date begun: 2/24/24
//*Creator: Julian Ceipek
//*copyright 2009 True Star Design
/**************************************************************************************/
/**************************************************************************************/
/*******************************************RULES:*************************************/
//Every turn, a player specifies a piece to move and a location to move it.
//Pawns, designated by P#, where #=0=RED and #=1=BLACK, can only move forwards
//diagonally or jump diagonally. Chained jumps are not permitted.
//Jumping is not required.
//When a pawn reaches the opposite side of the board, it becomes a King K#.
//Kings may move and jump in any diagonal direction.
//Objective: cause the opponent to lose all pieces or movement options.
/**************************************************************************************/
#import//Objects
#import//ObjC
#import
#import "Constants.h" //Constants: RED, BLACK, UNCHANGED
//Import Classes
#import "Board.h" //Gameboard Header
//Pieces
#import "Piece.h"
#import "Pawn.h"
#import "King.h"
int gameStatus;
//Implementation of game loop is here
int main (int argc, const char * argv[]) {
printf("Welcome to Checkers!\n");
//Setup Board
Board *board = [[Board alloc] init];
[board setUpBoard];
//Loop through game
do
{
//display board
[board display];
//move piece
[board askToMovePiece];
//switch player
[board changePlayer];
gameStatus = [board testForWin];
[board incrementMoves];
} while(gameStatus == UNCHANGED);
if (gameStatus == RED)
{
printf("Player RED has won the game.");
}
else
{
printf("Player BLACK has won the game");
}
printf("The game took %d moves.", [board getMoves]);
//Release memory
[board releasePieces];
[board release];
return 0; // 0 errors encountered.
}
//Board.h
#import
#import "Pawn.h"
#import "Piece.h"
@interface Board : NSObject
{
Piece *field[8][8];
int moves;
int currPlayer;
int gameStatus;
}
-(void)setUpBoard;
-(void)display;
-(void)releasePieces;
-(int)testForWin;
-(void)changePlayer;
-(BOOL)askToMovePiece;
-(void)incrementMoves;
-(int)getMoves;
@end
//Board.m
#import
#import "Constants.h" //Constants: RED, BLACK, UNCHANGED
//Red moves down; black moves up
#import "Board.h" //Header for curr class
//Pieces
#import "Piece.h"
#import "Pawn.h"
#import "King.h"
@implementation Board
-(void)setUpBoard
{
moves = 0;
currPlayer = 0;
//Set all to blank
for (int x=0; x<8; y="0;" x="0;" x="1;" currplayer ="=" x="1;" y="0;" x="0;" currplayer =" (currPlayer+1)%2;" rcount =" 0;" bcount =" 0;" y="0;" x="0;" rcount ="=" bcount ="=" x="0;" y="0;">7 || start[1]>7)
{
start[0]=-1;
printf("Invalid Location!");
}
//Check if square is empty
else if(field[start[0]][start[1]] == nil)
{
start[0]=-1;
printf("That Square is Empty!");
}
else if([field[start[0]][start[1]] getOwner] != currPlayer)
{
start[0]=-1;
printf("That Piece Belongs To Your Opponent!");
}
else if([field[start[0]][start[1]] canMoveAtX:start[0] Y:start[1] On:field] == NO && [field[start[0]][start[1]] canJumpAtX:start[0] Y:start[1] On:field] == NO)
{
start[0]=-1;
printf("That Piece Cannot Move!");
}
}
while (start[0]==-1);
//Valid piece was chosen
printf("Where do you want to move that piece?\n");
do
{
//Ask for destination
printf("XLoc:");
scanf("%d", &end[0]);
printf("YLoc:");
scanf("%d", &end[1]);
printf("\n");
end[0]--;
end[1]--;
//Check if square is on board
if (end[0]<0>7 || end[1]>7)
{
end[0]=-1;
printf("Invalid Location!");
}
//Check if square is empty
else if(field[end[0]][end[1]] != nil)
{
end[0]=-1;
printf("That Square is not Empty!");
}
else if([field[start[0]][start[1]] movePossibleFrom:start To:end On:field] == NO)
{
end[0]=-1;
printf("That Move is Illegal!");
}
}
while (end[0]==-1);
//Valid location was chosen
//Move Piece
//Jump? (test by checking if dist between start and end is 2;
//since only diagonal movement is possible, only x coords need be compared)
if ((end[0]-start[0])*(end[0]-start[0])/2 == 2)
{
//Eliminate through capture
printf("A piece was Captured!\n");
[field[(end[0]-start[0])/2+start[0]][(end[1]-start[1])/2+start[1]] release];
field[(end[0]-start[0])/2+start[0]][(end[1]-start[1])/2+start[1]] = nil;
//Add code for multiple jumps if desired....
}
//Move Piece
field[end[0]][end[1]] = field[start[0]][start[1]];
field[start[0]][start[1]] = nil;
//Crown King if necessary
if ([field[end[0]][end[1]] isaPawn])
{
if (end[1] == 7 && [field[end[0]][end[1]] getOwner] == RED)
{
[field[end[0]][end[1]] release];
field[end[0]][end[1]] = [[King alloc] init];
[field[end[0]][end[1]] setOwnerToPlayer:RED];
}
else if (end[1] == 0 && [field[end[0]][end[1]] getOwner] == BLACK)
{
[field[end[0]][end[1]] release];
field[end[0]][end[1]] = [[King alloc] init];
[field[end[0]][end[1]] setOwnerToPlayer:BLACK];
}
}
return YES;
}
@end
//Piece.h
#import
@interface Piece : NSObject
{
int owner;
}
-(void)setOwnerToPlayer:(int)player;
-(int)getOwner;
@end
//Piece.m
#import "Piece.h"
@implementation Piece
-(int)getOwner
{
return owner;
}
-(void)setOwnerToPlayer:(int)player
{
owner = player;
}
@end
//Pawn.h
#import "Piece.h"
#import "Board.h"
@interface Pawn : Piece
{
}
-(BOOL)movePossibleFrom:(int[2])start To:(int[2])end On:(Piece*[8][8])field;
-(BOOL)canMoveAtX:(int)x Y:(int)y On:(Piece*[8][8])field;
-(BOOL)canJumpAtX:(int)x Y:(int)y On:(Piece*[8][8])field;
-(BOOL)isaPawn;
@end
//Pawn.m
#import "Pawn.h"
#import "Constants.h" //Constants: RED, BLACK, UNCHANGED
//Red moves down; black moves up
#import
@implementation Pawn
-(BOOL)movePossibleFrom:(int[2])start To:(int[2])end On:(Piece*[8][8])field
{
//Warning: Feed this function no out of bound values!
//Is Slide Possible?
if ((start[0]-end[0])*(start[0]-end[0]) == 1)
{
if ([self getOwner] == RED)
{
if ((start[1]-end[1]) == -1)
{
return YES;
}
}
if ([self getOwner] == BLACK)
{
if ((start[1]-end[1]) == 1)
{
return YES;
}
}
}
//Is Jump Possible?
if ([self getOwner] == RED)
{
if ((start[1]-end[1]) == -2)
{
//Right
if(start[0]-end[0] == -2)
{
if (field[start[0]+1][start[1]+1] != nil)
{
return YES;
}
}
//Left
if(start[0]-end[0] == 2)
{
if (field[start[0]-1][start[1]+1] != nil)
{
return YES;
}
}
}
}
if ([self getOwner] == BLACK)
{
if ((start[1]-end[1]) == 2)
{
//Right
if(start[0]-end[0] == -2)
{
if (field[start[0]+1][start[1]-1] != nil)
{
return YES;
}
}
//Left
if(start[0]-end[0] == 2)
{
if (field[start[0]-1][start[1]-1] != nil)
{
return YES;
}
}
}
}
return NO;
}
-(BOOL)canMoveAtX:(int)x Y:(int)y On:(Piece*[8][8])field
{
if ([self getOwner] == RED && y+1 <>= 0)
{
if (field[x-1][y+1] == nil)
return YES;
}
if (x+1 <>= 0)
{
if (x-1 >= 0)
{
if (field[x-1][y-1] == nil)
return YES;
}
if (x+1 <>= 0)
{
if (field[x-1][y+1] != nil)
{
return YES;
}
}
}
if ([self getOwner] == BLACK && y-2>=0)
{
//Right
if(x+2 <>= 0)
{
if (field[x-1][y-1] != nil)
{
return YES;
}
}
}
return NO;
}
-(BOOL)isaPawn
{
return YES;
}
@end
//King.h
#import "Piece.h"
@interface King : Piece
{
}
-(BOOL)movePossibleFrom:(int[2])start To:(int[2])end On:(Piece*[8][8])field;
-(BOOL)canMoveAtX:(int)x Y:(int)y On:(Piece*[8][8])field;
-(BOOL)canJumpAtX:(int)x Y:(int)y On:(Piece*[8][8])field;
-(BOOL)isaPawn;
@end
//King.m
#import "King.h"
@implementation King
-(BOOL)movePossibleFrom:(int[2])start To:(int[2])end On:(Piece*[8][8])field
{
//Warning: Feed this function no out of bound values!
//Is Slide Possible?
if ((start[0]-end[0])*(start[0]-end[0]) == 1)
{
if ((start[1]-end[1]) == -1)
{
return YES;
}
if ((start[1]-end[1]) == 1)
{
return YES;
}
}
//Is Jump Possible?
if ((start[1]-end[1]) == -2)
{
//Right
if(start[0]-end[0] == -2)
{
if (field[start[0]+1][start[1]+1] != nil)
{
return YES;
}
}
//Left
if(start[0]-end[0] == 2)
{
if (field[start[0]-1][start[1]+1] != nil)
{
return YES;
}
}
}
if ((start[1]-end[1]) == 2)
{
//Right
if(start[0]-end[0] == -2)
{
if (field[start[0]+1][start[1]-1] != nil)
{
return YES;
}
}
//Left
if(start[0]-end[0] == 2)
{
if (field[start[0]-1][start[1]-1] != nil)
{
return YES;
}
}
}
return NO;
}
-(BOOL)canMoveAtX:(int)x Y:(int)y On:(Piece*[8][8])field
{
if (y+1 <>= 0)
{
if (field[x-1][y+1] == nil)
return YES;
}
if (x+1 <>= 0)
{
if (x-1 >= 0)
{
if (field[x-1][y-1] == nil)
return YES;
}
if (x+1 <>= 0)
{
if (field[x-1][y+1] != nil)
{
return YES;
}
}
}
if (y-2>=0)
{
//Right
if(x+2 <>= 0)
{
if (field[x-1][y-1] != nil)
{
return YES;
}
}
}
return NO;
}
-(BOOL)isaPawn
{
return NO;
}
@end
Sadly, the formatting is somewhat lost by pasting the program here. Copying and pasting to a text editor such as that included in XCode and re-indenting will produce my actual code. Note that the file names are comments in boldface.
Tomorrow, I plan to figure out exactly what "@property" does and to get further in my textbook.
No comments:
Post a Comment