Exemple #1
0
int piece_equal(QuartoPiece *a, QuartoPiece *b)
{
	if(is_valid_piece(a) && is_valid_piece(b)){
		return ((a->piece & b->piece) > 0) || ((a->xor & b->xor) > 0);
	}else{
		return 0;
	}
}
Exemple #2
0
int pieces_equal(QuartoPiece *a, QuartoPiece *b, QuartoPiece *c, QuartoPiece *d)
{
	if(is_valid_piece(a) && is_valid_piece(b) && is_valid_piece(c) && is_valid_piece(d)){
		return ((a->piece & b->piece & c->piece & d->piece) > 0) || 
			((a->xor & b->xor & c->xor & d->xor) > 0);
	}else{
		return 0;
	}
}
Exemple #3
0
int set_piece(QuartoBoard *board, int x, int y, QuartoPiece *piece)
{
	if(board->size < 16 && is_valid_piece(piece)){
		SET_PIECE(x, y, board->board, *piece);
		board->size += 1;
		return 1;
	}else{
		return 0;
	}
}
Exemple #4
0
int prep_available(QuartoBoard *board, int *available)
{
	for(int i = 0; i < 16; i++){
		//Because C doesn't like to place information in a new array
		//we need to do it explicit to ensure that none of the elements
		//are 0 by default
		available[i] = 1;
	}
	QuartoPiece tmp;
	int res = 16;
	for(int i = 0; i < 4; i++){
		for(int j = 0; j < 4; j++){
			tmp = GET_PIECE(i, j, board->board);
			if(is_valid_piece(&tmp)){
				available[tmp.piece] = 0;
				res--;
			}
		}
	}
	return res;
}
Exemple #5
0
int maxValue(QuartoPiece a, QuartoBoard *board, MinimaxRes *res, int numPly, int alpha, int beta)
{
	int local_alpha = -10000000;
	for(int i = 0; i < 4; i++){
		for(int j = 0; j < 4; j++){
			if(!is_valid_piece(&GET_PIECE(j, i, board->board))){
				QuartoBoard newB = *board;
				set_piece(&newB, j, i, &a);
				int won = quarto_win(&newB);
				if(newB.size == 16){
					//This placement filled up the board which means that
					//we can't go further down so we just update the x, j
					//and return the value of this end state
					res->x = j;
					res->y = i;
					return won*100;
				}else if(won){
					//This is the maximum we can get, which means that we won the game
					//no reason to go further down since this lead to a victory
					res->x = j;
					res->y = i;
					return 100;
				}else if(numPly == 0){
					//We have reached the bottom of the recursion
					//and we need only evaluate the possible placements
					//of the piece that we have gotten
					int quarto_value = quarto_herustic(&newB);
					if(quarto_value > local_alpha){
						local_alpha = quarto_value;
						res->x = j;
						res->y = i;
					}
					if(local_alpha >= beta) return local_alpha;
				}else{
					int pieces_left[16]; //Array with 0 or 1 to indicate if the pieces
					//in that index is available
					prep_available(&newB, pieces_left);
					for(int k = 0; k < 16; k++){
						if(pieces_left[k]){
							MinimaxRes r;
							int value = minValue(create_piece_from_int(k), 
									&newB, &r, numPly-1,
									local_alpha, beta);
							if(value > local_alpha){
								//The value we got from below is better
								//than what we have currently found
								//which means we need to keep this
								//position and update our alpha
								res->x = j;
								res->y = i;
								res->next_piece = k;
								local_alpha = value;
							}
							//If alpha is lager than beta there is
							//no use continuing because the min node above
							//will always chose the path that lead to beta
							if(local_alpha >= beta) return local_alpha;
						}
					}
				}
			}
		}
	}
	return local_alpha;
}
Exemple #6
0
int pieces_triple(QuartoBoard *board, QuartoPiece *a, QuartoPiece *b, QuartoPiece *c, QuartoPiece *d, TriplePiece *tp)
{
    int available[16];
    prep_available(board, available);
    QuartoPiece g;
    int piece_count;
    
	if(is_valid_piece(a) && is_valid_piece(b) && is_valid_piece(c) && !is_valid_piece(d)){
		if(((a->piece & b->piece & c->piece) > 0) || ((a->xor & b->xor & c->xor) > 0)){
		    piece_count=0;
		    for(int i=0; i<16; i++){
		        if(available[i]){
		            g = create_piece_from_int(i);
		            if(pieces_equal(a, b, c, (&g))){
		                piece_count++;
		            }
		        }
		    }
		    if(piece_count>0){
		        tp->a = a;
		        tp->b = b;
		        tp->c = c;
		        return piece_count;
		    }
		}
	}else if(is_valid_piece(a) && is_valid_piece(b) && !is_valid_piece(c) && is_valid_piece(d)){
		if (((a->piece & b->piece & d->piece) > 0) || ((a->xor & b->xor & d->xor) > 0)){
		    piece_count=0;
		    for(int i=0; i<16; i++){
		        if(available[i]){
		            g = create_piece_from_int(i);
		            if(pieces_equal(a, b, d, (&g))){
		                piece_count++;
		            }
		        }
		    }
		    if(piece_count>0){
                tp->a = a;
		        tp->b = b;
		        tp->c = d;
		       return piece_count;
		    }
		}
	}else if(is_valid_piece(a) && !is_valid_piece(b) && is_valid_piece(c) && is_valid_piece(d)){
		if (((a->piece & c->piece & d->piece) > 0) || ((a->xor & c->xor & d->xor) > 0)){
		    piece_count=0;
		    for(int i=0; i<16; i++){
		        if(available[i]){
		            g = create_piece_from_int(i);
		            if(pieces_equal(a, d, c, (&g))){
		                piece_count++;
		            }
		        }
		    }
		    if(piece_count>0){
                tp->a = a;
		        tp->b = c;
		        tp->c = d;
		        return piece_count;
		    }
		}
	}else if(!is_valid_piece(a) && is_valid_piece(b) && is_valid_piece(c) && is_valid_piece(d)){
		if (((d->piece & b->piece & c->piece) > 0) || ((d->xor & b->xor & c->xor) > 0)){
		    piece_count=0;
		    for(int i=0; i<16; i++){
		        if(available[i]){
		            g = create_piece_from_int(i);
		            if(pieces_equal(d, b, c, (&g))){
		                piece_count++;
		            }
		        }
		    }
		    if(piece_count>0){
                tp->a = c;
		        tp->b = b;
		        tp->c = d;
		        return piece_count;
		    }
		}
	}
	return 0;
}
Exemple #7
0
int minValue(QuartoPiece a, QuartoBoard *board, MinimaxRes *res, int numPly, int alpha, int beta)
{
	int local_beta = 1000000;
	for(int i = 0; i < 4; i++){
		for(int j = 0; j < 4; j++){
			if(!is_valid_piece(&GET_PIECE(j, i, board->board))){
				QuartoBoard newB = *board;
				set_piece(&newB, j, i, &a);
				int won = quarto_win(&newB);
				if(newB.size == 16){
					//This placement filled up the board which means that
					//we can't go further down so we just update the x, j
					//and return the value of this end state
					res->x = j;
					res->y = i;
					return won*-100;
				}else if(won){
					//This is the maximum we can get, which means that we won the game
					//no reason to go further down since this lead to a victory
					res->x = j;
					res->y = i;
					return -100;
				}else if(numPly == 0){
					//We have reached the bottom of the recursion
					//and we need only evaluate the possible placements
					//of the piece that we have gotten
					int quarto_value = quarto_herustic(&newB)*(-1);
					if(quarto_value < local_beta){
						local_beta = quarto_value;
						res->x = j;
						res->y = i;
					}
					if(local_beta <= alpha) return local_beta;
				}else{
					int pieces_left[16]; //Array with 0 or 1 to indicate if the pieces
					//in that index is available
					prep_available(&newB, pieces_left);
					for(int k = 0; k < 16; k++){
						if(pieces_left[k]){
							MinimaxRes r;
							int value = maxValue(create_piece_from_int(k),
								       	&newB, &r, numPly-1, 
									alpha, local_beta);
							if(value < local_beta){
								//The value we got from below is smaller
								//than the best beta we have found which
								//means we want that, so we need to update
								//x, y and update beta
								res->x = j;
								res->y = i;
								res->next_piece = k;
								local_beta = value;
							}
							//Our beta value is smaller than alpha
							//which means that the max "node" above
							//will always chose the path which leads
							//to that alpha value and there is no use
							//in recursing any more
							if(local_beta <= alpha) return local_beta;
						}
					}
				}
			}
		}
	}
	return local_beta;
}
Exemple #8
0
// manages the users turn, game state user input loop
int user_turn(char board[BOARD_SIZE][BOARD_SIZE], COLOR color){
	get_all_moves(board, color);
	if (moves_head == NULL) return WIN_POS;
	char *word1;
	char *command = NULL;
	Move* new_move = NULL;
	int ret_val;
	while (1){
		printf(ENTER_YOUR_MOVE);
		if (new_move != NULL) clear_old_moves(new_move);
		new_move = malloc(sizeof(Move));
		new_move->dest = malloc(sizeof(Pos) * 2 * BOARD_SIZE);
		new_move->next = NULL;
		if (command != NULL) free(command);
		command = input2str(stdin);
		word1 = strtok(command, " ");
		if (strcmp(word1, "quit") == 0){
			ret_val = QUIT;
			break;
		}
		else if (strcmp(word1, "get_moves") == 0){
			print_moves(moves_head);
			continue;
		}
		else if (strcmp(word1, "move") == 0){
			char * piece_coor1 = strtok(NULL, " <,>");
			char * piece_coor2 = strtok(NULL, " <,>");
			new_move->piece.col = piece_coor1[0] - 'a';
			new_move->piece.row = atoi(piece_coor2) - 1;
			if (!is_valid_pos(new_move->piece)){
				printf(WRONG_POSITION);
				continue;
			}
			int i = 0;
			char * dest_coor1 = strtok(NULL, " <,>to");
			char * dest_coor2 = strtok(NULL, " <,>to");
			while (dest_coor1 != NULL){
				new_move->dest[i].col = dest_coor1[0] - 'a';
				new_move->dest[i].row = atoi(dest_coor2) - 1;
				if (!is_valid_pos(new_move->dest[i])){
					i = -1;
					break;
				}
				i++;
				dest_coor1 = strtok(NULL, " <,>[]");
				if (dest_coor1 != NULL) dest_coor2 = strtok(NULL, " <,>[]");
			}
			if (i == -1){
				printf(WRONG_POSITION);
				continue;
			}
			if (!is_valid_piece(board, new_move, color)){
				printf(NO_DISC);
				continue;
			}
			new_move->dest = realloc(new_move->dest, sizeof(Pos) * i);
			new_move->captures = i;
			Move * move2do = is_valid_move(moves_head, new_move);
			if (move2do == NULL){
				printf(ILLEGAL_MOVE);
				continue;
			}
			else{
				exc_move(board, move2do);
				print_board(board);
				ret_val = GAME_ON;
				break;
			}
		}
		else printf(ILLEGAL_COMMAND);
	}
	free(command);
	clear_old_moves(new_move);
	clear_old_moves(moves_head);
	return ret_val;
}