Esempio n. 1
0
void upgradePieces_ButtonClick(control* input)
{
	char piece = ResolveLetterFromButtonName(input->name);

	chosenMove->new_disc = piece;
	if (is_move_in_move_list(chosenMove, curMovesList) == true){

		make_move(board, chosenMove);
		SwitchButtonHighlight(gameSelectedSquare_control);
		gameSelectedSquare_control = NULL;

		curSettings->next_turn = get_opposite_color(curSettings->next_turn);
		free_move_list(curMovesList);
		curMovesList = NULL;
		free_move_list(posMovesFromCurPos);
		posMovesFromCurPos = NULL;
		free(chosenMove);
		chosenMove = NULL;
		Game();
	}

	// DrawTree
	if (-1 == FlipTree(&error_global))
	{
		guiQuit = -1;
		return;
	}
}
Esempio n. 2
0
int ComputerTurn(char** error)
{
	if (gameOver == false && tie == false){
		struct move_list* best_move_list = NULL;
		int number_of_boards_evaluated = 0;

		int current_move_grade = get_best_moves(curSettings->minimax_depth, board, get_opposite_color(curSettings->user_color), curMovesList, &best_move_list, &number_of_boards_evaluated);

		// Check for errors
		if (FAILED_ERROR == current_move_grade) {
			free_move_list(curMovesList);
			curMovesList = NULL;
			free_move_list(best_move_list);
			best_move_list = NULL;
			*error = "ERROR: Failed getting best moves.";
			return -1;
		}

		// Make the move
		make_move(board, &best_move_list->mov);

		curSettings->next_turn = get_opposite_color(curSettings->next_turn);
		free_move_list(curMovesList);
		curMovesList = NULL;
		free_move_list(posMovesFromCurPos);
		posMovesFromCurPos = NULL;
		free(chosenMove);
		chosenMove = NULL;
		free_move_list(best_move_list);
		Game();
	}
	return 0;
}
Esempio n. 3
0
void GameBoardMainMenu_ButtonClick(control* input)
{
	free_move_list(curMovesList);
	curMovesList = NULL;
	free_move_list(posMovesFromCurPos);
	posMovesFromCurPos = NULL;
	free(chosenMove);
	chosenMove = NULL;
	free(curSettings);

	MainMenu();
}
Esempio n. 4
0
void GameBoardSave_ButtonClick(control* input)
{
	isSaveMode = true;

	free_move_list(curMovesList);
	curMovesList = NULL;
	free_move_list(posMovesFromCurPos);
	posMovesFromCurPos = NULL;
	free(chosenMove);
	chosenMove = NULL;

	SaveLoadMenu();
}
Esempio n. 5
0
static int negamax_algo(struct chessboard *c, int color, int depth, int alpha, int beta)
{
	struct move_list *l;
	struct raw_move m;
	int n;
	int val, best_val = INT_MIN;

	if (!depth)
		return !color ? calculate_board_heuristic(c) : -calculate_board_heuristic(c);

	l = allocate_move_list();
	for (int i = 0; i < 16; i++) {
		n = enumerate_moves(c, (color << 4) | i, l);
		expanded_moves += n;

		for (int j = 0; j < n; j++) {
			get_move(l, j, &m.sx, &m.sy, &m.dx, &m.dy);

			execute_raw_move(c, &m);
			evaluated_moves++;

			val = -negamax_algo(c, !color, depth - 1, -beta, -alpha);

			unwind_raw_move(c, &m);

			best_val = max(best_val, val);
			alpha = max(alpha, val);
			if (alpha >= beta)
				break;
		}
	}

	free_move_list(l);
	return best_val;
}
Esempio n. 6
0
static void
ParseOptGameList(SourceFileType file_type)
{   Move *move_list = NULL;

    while(ParseGame(&move_list) && !finished_processing()) {
        if(file_type == NORMALFILE) {
            DealWithGame(move_list);
        }
        else if(file_type == CHECKFILE) {
            DealWithGame(move_list);
        }
        else if(file_type == ECOFILE) {
            if(move_list != NULL) {
                DealWithEcoLine(move_list);
            }
            else {
                fprintf(GlobalState.logfile,"ECO line with zero moves.\n");
                report_details(GlobalState.logfile);
            }
        }
        else {
            /* Unknown type. */
            free_tags();
            free_move_list(move_list);
        }
        move_list = NULL;
        setup_for_new_game();
    }
}
Esempio n. 7
0
        /* Break up a single line of moves into a list of moves
         * comprising a positional variation.
         * In doing so, set GlobalState.depth_of_positional_search
         * if this variation is longer than the default.
         */
static Move *
compose_positional_variation(char *line)
{   char *move;
    /* Build a linked list of the moves of the variation. */
    Move *head = NULL, *tail = NULL;
    Boolean Ok = TRUE;
    /* Keep track of the depth. */
    unsigned depth = 0;

    move = strtok(line," ");
    while(Ok && (move != NULL) && (*move != '*')){
        if((move = strip_move_number(move)) == NULL){
            /* Only a move number. */
        }
        else{
            Move *next = decode_move((unsigned char *) move);

            if(next == NULL){
                fprintf(GlobalState.logfile,"Failed to identify %s\n",move);
                Ok = FALSE;
            }
            else{
                /* Chain it on to the list. */
                if(tail == NULL){
                    head = next;
                    tail = next;
                }
                else{
                    tail->next = next;
                    tail = next;
                }
                next->next = NULL;
            }
            depth++;
        }
        /* Pick up the next likely move. */
        move = strtok(NULL," ");
    }
    if(Ok){
        /* Determine whether the depth of this variation exceeds
         * the current default.
         * Depth is counted in move pairs.
         * Add some extras, in order to be surer of catching transpositions.
         */
        depth = ((depth+1) / 2) + 4;
        if(depth > GlobalState.depth_of_positional_search){
            GlobalState.depth_of_positional_search = depth;
        }
    }
    else{
        if(head != NULL){
            free_move_list(head);
        }
        head = NULL;
    }
    return head;
}
Esempio n. 8
0
void
add_positional_variation_from_line(char *line)
{
    if(non_blank_line(line)){
        Move *next_variation = compose_positional_variation(line);
        if(next_variation != NULL){
            /* We need a NULL fen string, because this is from
             * the initial position.
             */
            store_hash_value(next_variation,(const char *)NULL);
            free_move_list(next_variation);
            /* We need to know globally that positional variations
             * are of interest.
             */
            GlobalState.positional_variations = TRUE;
        }
    }
}
Esempio n. 9
0
/* Returns sx|sy|dx|dy in an integer byte-by-byte from least to most
 * significant, indicating which move should be made next.
 *
 * We seperate the initial iteration of negamax out like this to track the
 * actual move associated with the best score. Doing so during the
 * deeper iterations is a waste of time. */
unsigned int calculate_move(struct chessboard *c, int color, int depth)
{
	struct move_list *l;
	int n, fbsx = -1, fbsy = -1, fbdx = -1, fbdy = -1;
	int val, best_val = INT_MIN, alpha = INT_MIN, beta = INT_MAX;
	struct raw_move m;
	struct timespec *t;

	expanded_moves = 0;
	evaluated_moves = 0;

	t = start_timer();
	l = allocate_move_list();
	for (int i = 0; i < 16; i++) {
		n = enumerate_moves(c, (color << 4) | i, l);
		expanded_moves += n;

		for (int j = 0; j < n; j++) {
			get_move(l, j, &m.sx, &m.sy, &m.dx, &m.dy);
			execute_raw_move(c, &m);
			evaluated_moves++;

			val = -negamax_algo(c, !color, depth - 1, -beta, -alpha);

			alpha = max(alpha, val);
			if (val > best_val) {
				best_val = val;
				fbsx = m.sx;
				fbsy = m.sy;
				fbdx = m.dx;
				fbdy = m.dy;
			}

			debug("Move %d/%d for piece %d (%d,%d) => (%d,%d) has heuristic value %d\n", j + 1, n, (color << 4) | i, m.sx, m.sy, m.dx, m.dy, val);
			unwind_raw_move(c, &m);
		}
	}
	free_move_list(l);
	expanded_moves += n;
	debug("Evaluated %luM/%luM expanded moves in %lu seconds\n", evaluated_moves / 1000000, expanded_moves / 1000000, get_timer_and_free(t) / 1000);

	return (fbsx) | (fbsy << 8) | (fbdx << 16) | (fbdy << 24);
}
Esempio n. 10
0
void GameBoardSquare_ButtonClick(control* input)
{
	if ((curSettings->next_turn == curSettings->user_color || curSettings->game_mode == TWO_PLAYERS_GAME_MODE || isUpgrade) && gameOver == false){
		if (input == gameSelectedSquare_control)
		{
			switchOffAllButtons();
			gameSelectedSquare_control = NULL;
			free_move_list(posMovesFromCurPos);
			posMovesFromCurPos = NULL;
		}
		else if (gameSelectedSquare_control == NULL)
		{
			position chosenPos = GetPosOfSquare(input);

			if (is_piece_of_color(get_piece(board, chosenPos), curSettings->next_turn) == true){
				SwitchButtonHighlight(input);
				gameSelectedSquare_control = input;
				get_moves_from_pos(curMovesList, chosenPos, &posMovesFromCurPos);
				HightlightPosMoves(posMovesFromCurPos);
			}
		}
		else if (gameSelectedSquare_control != NULL)
		{
			position startPos = GetPosOfSquare(gameSelectedSquare_control);

			position endPos = GetPosOfSquare(input);

			chosenMove = (move*)(calloc(1, sizeof(move)));
			if (chosenMove == NULL)
			{
				guiQuit = -1;
				return;
			}
			chosenMove->start_pos = startPos;
			chosenMove->end_pos = endPos;
			chosenMove->new_disc = EMPTY;

			if (is_move_in_move_list(chosenMove, curMovesList) == true){
				if (isPawnUpgradePossible(chosenMove, board[(int)startPos.col][(int)startPos.row]) == true){
					if (-1 == DrawPiecesOnSidePanelFilterColor(tree->children[0], &upgradePieces_ButtonClick, curSettings->next_turn, &error_global))
					{
						free(chosenMove);
						chosenMove = NULL;
						guiQuit = -1;

					}
					isUpgrade = true;
				}
				else
				{
					make_move(board, chosenMove);
					SwitchButtonHighlight(gameSelectedSquare_control);
					gameSelectedSquare_control = NULL;
					curSettings->next_turn = get_opposite_color(curSettings->next_turn);
					free_move_list(curMovesList);
					curMovesList = NULL;
					free_move_list(posMovesFromCurPos);
					posMovesFromCurPos = NULL;
					free(chosenMove);
					chosenMove = NULL;
					Game();
					return;
				}
			}
		}

		// DrawTree
		if (-1 == FlipTree(&error_global))
		{
			guiQuit = -1;
			return;
		}
	}
}
Esempio n. 11
0
int HighlightBestMove(int blinknum, char** error)
{
	struct move_list* best_move_list = NULL;
	int number_of_boards_evaluated = 0;

	// Get the best next move
	int current_move_grade = get_best_moves(curSettings->minimax_depth, board, curSettings->next_turn, curMovesList, &best_move_list, &number_of_boards_evaluated);

	// Check for errors
	if (FAILED_ERROR == current_move_grade) {
		free_move_list(best_move_list);
		return -1;
	}

	move bestMove = best_move_list->mov;
	position startPos = bestMove.start_pos;
	position endPos = bestMove.end_pos;

	control* startSquare = buttonsBoard[(int)startPos.col][7 - (int)startPos.row];
	control* endSquare = buttonsBoard[(int)endPos.col][7 - (int)endPos.row];

	bool startHiglighted = startSquare->ishighlighted;
	bool endHiglighted = endSquare->ishighlighted;

	startSquare->ishighlighted = 1;
	endSquare->ishighlighted = 1;

	for (int i = 0; i < blinknum; i++){
		SwitchButtonHighlight(startSquare);
		SwitchButtonHighlight(endSquare);

		if (isPawnUpgradePossible(&bestMove, get_piece(board, startPos)))
		{
			char* fileName = ResolveFileNameFromLetter(bestMove.new_disc);
			char* name = ResolveNameFromLetter(bestMove.new_disc);

			if (fileName != NULL){
				control* chessPiece_control;
				if (-1 == Create_panel_from_bmp(
					fileName,
					name,
					(Sint16)(GAMEBOARDBACKGROUND_W - BUTTON_W - MARGIN),
					(Sint16)(0.5*BOARD_H - SQUARE_H - 0.5),
					(Uint16)SQUARE_W,
					(Uint16)SQUARE_H,
					&chessPiece_control, error))
				{
					return -1;
				}
				UINode* chessPiece_node;
				if (-1 == CreateAndAddNodeToTree(chessPiece_control, tree->children[0], &chessPiece_node, error))
				{
					FreeControl(chessPiece_control);
					return -1;
				}
			}
		}

		// DrawTree
		if (-1 == FlipTree(error))
		{
			return -1;
		}
		SDL_Delay(250);
	}



	startSquare->ishighlighted = startHiglighted;
	endSquare->ishighlighted = endHiglighted;

	free_move_list(best_move_list);
	return 0;
}
Esempio n. 12
0
int calculate_score_for_board_alpha(Disc board [BOARD_SIZE][BOARD_SIZE],int depth, int current_player, int alpha, int beta) {
    int is_max=0, temp = 0, current_depth = depth;
    Disc copy [BOARD_SIZE][BOARD_SIZE];
    int temp_score =0;
    Move* curr_suggested_move =NULL;
    MoveList* moves_for_all_discs_this_turn = NULL, *curr =NULL;
    is_max = (current_player == global_current_player) ? 1 :-1;
    
    if (depth >=curret_max_depth || (global_max_depth ==5 && count > max_board_count))
    {
        temp = get_discs_board_score_for_player(board, global_current_player);
 
        return temp;
    }
     
 
    update_all_legal_moves_for_player(board, current_player);
    
    moves_for_all_discs_this_turn = collect_all_moves_for_player(board, current_player);
   
    if (moves_for_all_discs_this_turn==NULL || moves_for_all_discs_this_turn->m ==NULL)
    {
        free_all_optional_moves_for_player(board, current_player);
        free_move_list(moves_for_all_discs_this_turn);
        moves_for_all_discs_this_turn = NULL;
        return (-600)*(is_max);
    }
    
    if (is_max ==1)
    { 
        curr = moves_for_all_discs_this_turn;
        
        while (curr  !=NULL)
        {
            if (global_max_depth ==5 && count > max_board_count)
            {
                free_all_optional_moves_for_player(board, current_player);
                free_move_list(moves_for_all_discs_this_turn);
                moves_for_all_discs_this_turn = NULL;
                return alpha;
            }
            count++;

            copy_board_from_copy(board, copy);
            curr_suggested_move = curr->m;
            make_turn_for_player(copy,curr_suggested_move,current_player);
             
 
            
            temp_score = calculate_score_for_board_alpha(copy, current_depth+1, (current_player)*(-1), alpha, beta);

            
            if (temp_score >= beta)
            {
                free_all_optional_moves_for_player(board, current_player);
                free_move_list(moves_for_all_discs_this_turn);
                moves_for_all_discs_this_turn = NULL;
                return beta;
            }
        
            if (temp_score > alpha)
            {
             alpha = temp_score;
            }
            curr = curr->next;
        }
        free_all_optional_moves_for_player(board, current_player);
        free_move_list(moves_for_all_discs_this_turn);
        moves_for_all_discs_this_turn = NULL;
        return alpha;
    }
    
    else
    { 
        curr = moves_for_all_discs_this_turn;
        
        while (curr  !=NULL)
        {
            if (global_max_depth ==5 && count > max_board_count)
            {
                free_all_optional_moves_for_player(board, current_player);
                free_move_list(moves_for_all_discs_this_turn);
                moves_for_all_discs_this_turn = NULL;
                return beta;
            }
            count++;
            copy_board_from_copy(board, copy);
            curr_suggested_move = curr->m;

            make_turn_for_player(copy,curr_suggested_move,current_player);
             
 
            
            temp_score = calculate_score_for_board_alpha(copy, current_depth+1, (current_player)*(-1), alpha, beta);
            if (temp_score <= alpha)
            {
                free_all_optional_moves_for_player(board, current_player);
                free_move_list(moves_for_all_discs_this_turn);
                moves_for_all_discs_this_turn = NULL;
                return alpha;
            }
            if (temp_score< beta)
            {
                beta = temp_score;
            }
            curr = curr->next;
            
        }
        free_all_optional_moves_for_player(board, current_player);
        free_move_list(moves_for_all_discs_this_turn);
        moves_for_all_discs_this_turn = NULL;
        return beta;
    }
    return 5000;
}
Esempio n. 13
0
Move* MaxMove (Disc board [BOARD_SIZE][BOARD_SIZE],int current_player) {
    
    Disc copy [BOARD_SIZE][BOARD_SIZE];
    int temp_score =0, alpha =-1000;
    Move* best_move =NULL;
    Move* curr_suggested_move =NULL;
    MoveList* moves_for_all_discs_this_turn = NULL, *curr =NULL;
	count =0;
    
    update_all_legal_moves_for_player(board, current_player);

    moves_for_all_discs_this_turn = collect_all_moves_for_player(board, current_player);

    if (global_max_depth == 5)
    {
        curret_max_depth = calculate_current_best_max_depth(board);
    }
    else
    {
        curret_max_depth = global_max_depth;
    }
    
    curr = moves_for_all_discs_this_turn;
    while (curr  !=NULL && curr->m !=NULL)
    {
        copy_board_from_copy(board, copy);
        curr_suggested_move = curr->m;
         
 

        make_turn_for_player(copy,curr_suggested_move,current_player);
        if (global_max_depth ==5 && count > max_board_count)
        {
            free_all_optional_moves_for_player(copy,current_player);
            free_move_list(moves_for_all_discs_this_turn);
            moves_for_all_discs_this_turn = NULL;
            printf ("%lu\n",count);
            return best_move;
        }
        count++;
         
 


        temp_score = calculate_score_for_board_alpha(copy, 0, current_player*-1, -1000, 1000);
        
        if (temp_score >= alpha)
        {
            if (best_move !=NULL)
            {
                free_move(&best_move);
                best_move = NULL;
            }
            best_move= init_move_from_int_arrs(curr_suggested_move->from, curr_suggested_move->to);
            alpha =temp_score;
        }
        curr = curr->next;
    }
    free_all_optional_moves_for_player(copy,current_player);
    free_move_list(moves_for_all_discs_this_turn);
    moves_for_all_discs_this_turn = NULL;
    curr= NULL;
    printf ("%lu\n",count);
    return best_move;
}
Esempio n. 14
0
int get_move_score_using_minimax(	int max_depth,
									char board[BOARD_SIZE][BOARD_SIZE],
									COLOR current_color,
									COLOR run_for_color,
									int current_depth,
									struct move_list* move_list,
									int alpha, int
									beta,
									int* number_of_boards_evaluated) {
	
	bool maximizingPlayer = current_depth % 2 == 0 ? true : false;

	int grade = 4000;
	if (maximizingPlayer) {
		grade *= -1;
	}

	struct move_list* current_move_node = move_list;
	do {
		// Temp board for current move
		char minimax_board[BOARD_SIZE][BOARD_SIZE];

		(*number_of_boards_evaluated)++;

		// Copies the board to a temp board
		copy_boards(board, minimax_board);

		// Make the move we want to check
		make_move(minimax_board, &current_move_node->mov);

		int score = get_board_score_for_color(minimax_board, run_for_color);

		int current_move_grade = FAILED_ERROR;

		// Stop condition - if we got to the max depth or there is a winner
		if (max_depth == current_depth + 1 || WIN_SCORE == score || LOSE_SCORE == score) {
			current_move_grade = score;
		}
		else {
			// Get the color of the next turn
			COLOR next_color = get_opposite_color(current_color);

			// Get the move list for the next turn
			struct move_list* minimax_move_list = NULL;

			if (-1 == get_moves_for_color(minimax_board, next_color, &minimax_move_list)) {
				// get_moves_for_color failed
				return FAILED_ERROR;
			}

			// Checks if there is no moves for the next turn
			if (NULL == minimax_move_list) {
				current_move_grade = score;
			}
			else {
				// Run minimax again with the new board and position
				current_move_grade = get_move_score_using_minimax(max_depth, minimax_board, next_color, run_for_color, current_depth + 1, minimax_move_list, alpha, beta, number_of_boards_evaluated);
				free_move_list(minimax_move_list);

				// If return value is FAILED_ERROR there was an error with a standard function
				if (FAILED_ERROR == current_move_grade) {
					return FAILED_ERROR;
				}
			}
		}

		if (maximizingPlayer) {
			grade = grade > current_move_grade ? grade : current_move_grade;
			alpha = alpha > grade ? alpha : grade;
		}
		else {
			grade = grade < current_move_grade ? grade : current_move_grade;
			beta = beta < grade ? beta : grade;
		}

		if (beta <= alpha) {
			break;
		}

	} while (NULL != (current_move_node = current_move_node->next));

	return grade;
}
Esempio n. 15
0
int get_best_moves(	int max_depth,
					char board[BOARD_SIZE][BOARD_SIZE],
					COLOR run_for_color,
					struct move_list* move_list,
					struct move_list** best_move_list,
					int* number_of_boards_evaluated) {
	int grade = -4000;
	int current_depth = 0;

	struct move_list* current_move_node = move_list;
	do {
		// Temp board for current move
		char minimax_board[BOARD_SIZE][BOARD_SIZE];

		(*number_of_boards_evaluated)++;

		// Copies the board to a temp board
		copy_boards(board, minimax_board);

		// Make the move we want to check
		make_move(minimax_board, &current_move_node->mov);

		int score = get_board_score_for_color(minimax_board, run_for_color);

		int current_move_grade = FAILED_ERROR;

		// Stop condition - if we got to the max depth or there is a winner
		if (max_depth == current_depth + 1 || WIN_SCORE == score || LOSE_SCORE == score) {
			current_move_grade = score;
		}
		else {
			// Get the color of the next turn
			COLOR next_color = get_opposite_color(run_for_color);

			// Get the move list for the next turn
			struct move_list* minimax_move_list = NULL;

			if (-1 == get_moves_for_color(minimax_board, next_color, &minimax_move_list)) {
				// get_moves_for_color failed
				return FAILED_ERROR;
			}

			// Checks if there is no moves for the next turn
			if (NULL == minimax_move_list) {
				current_move_grade = score;
			}
			else {
				// Run minimax again with the new board and position
				current_move_grade = get_move_score_using_minimax(max_depth, minimax_board, next_color, run_for_color, current_depth + 1, minimax_move_list, ALPHA_INIT, BETA_INIT, number_of_boards_evaluated);
				free_move_list(minimax_move_list);

				// If return value is FAILED_ERROR there was an error with a standard function
				if (FAILED_ERROR == current_move_grade) {
					return FAILED_ERROR;
				}
			}
		}

		// Update the grade if it the first move or take the max grade or the min grade according to the depth
		if (current_move_grade >= grade) {
			if (current_move_grade > grade) {
				free_move_list(*best_move_list);
				*best_move_list = NULL;
			}

			struct move_list* temp = add_new_move_node(*best_move_list, current_move_node->mov.start_pos, current_move_node->mov.end_pos, current_move_node->mov.new_disc);
			if (NULL == temp) {
				return FAILED_ERROR;
			}
			*best_move_list = temp;

			grade = current_move_grade;
		}
	} while (NULL != (current_move_node = current_move_node->next));

	return grade;
}