Beispiel #1
0
int main(int argc, char** argv) {

  struct Tile* t = Tile_new('f');
  printf("tile %c\n", t->color);

  struct Board* b = Board_new(9,9);
  struct Tile* t2 = Board_get(b,0,0);
  
  printf("tile %c\n", t2->color);


  Board_print(b);

  Board_randomize(b);

  Board_print(b);

  struct Board* b2 = Board_clone(b);

  int matches;

  matches = Board_check_matching_at(b2, 0, 4);

  printf("board matches %i\n", matches);

  return 0;
}
Beispiel #2
0
/*
 * Retrieves a list of all jump moves currently possible for a player.
 *
 * @params: (player) - the player whose moves are to be put in the list
 * @return: a LinkedList struct of jump moves currently possible for the player, or NULL if any allocation errors occurred
 */
static struct LinkedList* getPossibleJumps (char** board, int player){
	struct LinkedList* jumpMoves = LinkedList_new(&PossibleMove_free);
	if(jumpMoves == NULL){ //allocation failed
		return NULL;
	}
	
	for (int x = 1; x <= Board_SIZE; x++){
		for (int y = 1; y <= Board_SIZE; y++){			
			if (Board_evalPiece(board, x, y, player) <= 0){
				continue;
			}
			for (int i = -1; i <= 1; i += 2){
				for (int j = -1; j <= 1; j += 2){
					struct Tile* destTile = NULL;
					if (!isInRange(x+i,y+j) || !isInRange(x+2*i,y+2*j)){
						continue;
					}
					int pieceIsKing = Board_evalPiece(board, x, y, player) == 3;
					if (pieceIsKing){
						destTile = canKingCaptureInDirection(board, x, y, i, j);
					}
					else{
						int enemyNearby = Board_evalPiece(board, x+i, y+j, player) < 0;
						int enemyIsCapturable = Board_isEmpty(board, x+2*i, y+2*j);
						if(enemyNearby && enemyIsCapturable){
							destTile = Tile_new(x+2*i, y+2*j);
							if (destTile == NULL){ // allocation failed
								return NULL;
							}
						}
					}
					if (!destTile){
						continue;
					}
					struct LinkedList* jumpSteps = LinkedList_new(&Tile_free);
					if (jumpSteps == NULL){ // allocation failed
						Tile_free(destTile);
						return NULL;
					}
					LinkedList_add(jumpSteps, destTile);
					struct PossibleMove* possibleJumpMove = PossibleMove_new(x, y, jumpSteps, board);
					if (possibleJumpMove == NULL){ // allocation failed
						Tile_free(destTile);
						LinkedList_free(jumpSteps);
						return NULL;
					}
					populateJumpList(jumpMoves, possibleJumpMove);
				}
			}
		}	
	}
	return jumpMoves;
}
/* 
 * Creates a new PossibleMove structure, consisting of the starting tile,
 * a list of tiles that are part of the move itself, and the state of the
 * board after this particular move has been carried out. 
 *
 * @params: start - a pointer to the starting tile, 
            moves - a pointer to the list of individual tile moves, 
 *          board - the board before the move
 * @return: NULL if any allocation errors occurred, the structure otherwise
 */
struct PossibleMove* PossibleMove_new(int x, int y, struct LinkedList* steps, char** board){
	struct PossibleMove* move;
	move = (struct PossibleMove*)calloc(1, sizeof(struct PossibleMove));
	if (!move){
		return NULL;
	}	
	move->start = Tile_new(x, y);
	if (!(move->start)){
		free(move);
		return NULL;
	}
	move->steps = steps;
	move->board = Board_getPossibleBoard(board, move);
	return move;
}
Beispiel #4
0
/*
 * Gets a list of all single step moves currently possible for a player.
 *
 * @params: (player) - the player whose moves are to be put in the list
 * @return: a list of single step moves currently possible for the player, or NULL if any allocation errors occurred 
 */
static struct LinkedList* getPossibleSingleMoves (char** board, int player){
	struct LinkedList* possibleSingleMoves = LinkedList_new(&PossibleMove_free);
	if (possibleSingleMoves == NULL){
		return NULL;
	}
	int forward = (player == BLACK) ? -1 : 1; /* for each player's different direction of "forward" */
	for (int x = 1; x <= Board_SIZE; x++){
		for (int y = 1; y <= Board_SIZE; y++){
			if (Board_evalPiece(board, x, y, player) <= 0){ //this tile doesn't contain one of this player's pieces
				continue;
			} 
			for (int sideward = -1; sideward <= 1; sideward += 2){
				for (int k = -Board_SIZE; k <= Board_SIZE; k++){
					if (!isInRange(x+k*sideward, y+k)){
						continue;
					}	
					int pieceIsKing = Board_evalPiece(board, x, y, player) == 3;
					if (!pieceIsKing && k != forward){
						continue;
					}	
					if(Board_isEmpty(board, x+k*sideward, y+k)){
						struct Tile* destTile = Tile_new(x+k*sideward, y+k);
						if (destTile == NULL){ // allocation failed
							return NULL;
						}
						struct LinkedList* singleSteps = LinkedList_new(&Tile_free);
						if (singleSteps == NULL){ // allocation failed
							Tile_free(destTile);
							return NULL;
						}
						LinkedList_add(singleSteps, destTile);
						struct PossibleMove* possibleSingleMove = PossibleMove_new(x, y, singleSteps, board);
						if (possibleSingleMove == NULL){ // allocation failed
							Tile_free(destTile);
							LinkedList_free(singleSteps);
							return NULL;
						}
						LinkedList_add(possibleSingleMoves, possibleSingleMove);
					}
					if (!pieceIsKing && k == forward){
						break;
					}
				}
			}
		}
	}
	return possibleSingleMoves;
}
Beispiel #5
0
/*
 * Checks whether a king in a given position can capture an enemy in a given direction
 *
 * @params: (x, y) - the coordinates of the given position
 *          (dirX, dirY) - the coordinates if the direction
 * @return: NULL if no such enemy exists, the tile of the enemy otherwise
 */
static struct Tile* canKingCaptureInDirection(char** board, int x, int y, int dirX, int dirY){
	int player = Board_getColor(board, x, y);
	int i = 1;
	int foundFirstEnemyInThisDirection = 0;
	while(isInRange(x+(i+1)*dirX, y+(i+1)*dirY)){
		int enemyNearby = Board_evalPiece(board, x+i*dirX, y+i*dirY, player)<0;
		int enemyIsCapturable = Board_isEmpty(board, x+(i+1)*dirX, y+(i+1)*dirY);
		if (enemyNearby && enemyIsCapturable && !foundFirstEnemyInThisDirection){
			return Tile_new(x+(i+1)*dirX, y+(i+1)*dirY);
		}
		if (enemyNearby){
			foundFirstEnemyInThisDirection = 1; // to eliminate the possibility of capturing several pieces in one jump
		}
		i++;
	}
	return NULL;
}
Beispiel #6
0
/*
 * Populates the list of possible jumps, recursively.
 *
 * @params: (possibleJumps) - the list to be populated
 *          (possibleMove) - the move that parts of it will be populated in the list.
 */
static void populateJumpList(struct LinkedList* possibleJumps, struct PossibleMove* possibleMove){
	struct Tile* lastStep = PossibleMove_getLastStep(possibleMove);
	char** board = possibleMove->board;
	int x = lastStep->x;
	int y = lastStep->y;
	
	//checking if another jump is possible after current last jump
	int found = 0;
	for (int i = -1; i <= 1; i += 2){
		for (int j = -1; j <= 1; j += 2){
			if (!isInRange(x+i,y+j) || !isInRange(x+2*i,y+2*j)){
				continue;
			}
			struct Tile* currentLastStep = PossibleMove_getLastStep(possibleMove);
			int player = Board_getColorByTile(possibleMove->board, currentLastStep);
			int enemyNearby = (Board_evalPiece(board, x+i, y+j, player) < 0);
			int enemyIsCapturable = Board_isEmpty(board,x+2*i, y+2*j);
			int justCrowned = (player == WHITE && y == Board_SIZE) || (player == BLACK && y == 1);
			if(enemyNearby && enemyIsCapturable && !justCrowned){ //found another possible jump after current last step
				struct PossibleMove* currentMoveClone = PossibleMove_clone(possibleMove);
				struct LinkedList* currentSteps = currentMoveClone->steps;
				struct Tile* extraTile = Tile_new(x+2*i, y+2*j);
				LinkedList_add(currentSteps, extraTile);
				
				char oldX = currentLastStep->x;
				int oldY = currentLastStep->y;
				int newX = extraTile->x;
				int newY = extraTile->y;
				Board_move(currentMoveClone->board, oldX, oldY, newX, newY);
				
				populateJumpList(possibleJumps, currentMoveClone);			
				found = 1;
			}
		}
	}
	if (found){
		PossibleMove_free(possibleMove);
		return;
	}
	LinkedList_add(possibleJumps, possibleMove);	
}