Exemple #1
0
/*  NW | NE
 *  -------
 *  SW | SE
 *
 *
 */
void rotate_blank(cardinal_direction starting_reference, int number_movements, bool clockwise)
{
    if (number_movements == 0)
        return;
        
    switch (starting_reference)
    {
        case NE:
            move_blank(clockwise ? down : left);
            rotate_blank(clockwise ? SE : NW, number_movements - 1, clockwise);
            return;
        case SE:
            move_blank(clockwise ? left : up);
            rotate_blank(clockwise ? SW : NE, number_movements - 1, clockwise);
            return;
        case SW:
            move_blank(clockwise ? up : right);
            rotate_blank(clockwise ? NW : SE, number_movements - 1, clockwise);
            return;
        case NW:
            move_blank(clockwise ? right : down);
            rotate_blank(clockwise ? NE : SW, number_movements - 1, clockwise);
            return;
        default:
            return;      
    }
}
Exemple #2
0
int main(int argc, char *argv[])
{	int **s_board;
	int n, i, ch;
	tile blank;

	if(argc != 2)
	{	printf("Usage: %s <shuffle board order>\n", argv[0]);
		exit(1);
	}
	n = atoi(argv[1]);
	
	s_board = (int **)calloc(n, sizeof(int *));
	for(i = 0;i < n; ++i)
		s_board[i] = (int *)calloc(n, sizeof(int));
	init_board(s_board, n, &blank);
	initscr();
	keypad(stdscr, TRUE);
	cbreak();
	shuffle_board(s_board, n);
	while((ch = getch()) != KEY_F(1))
	{	switch(ch)
		{	case KEY_LEFT:
				move_blank(RIGHT, s_board, n, &blank);
				break;
			case KEY_RIGHT:
				move_blank(LEFT, s_board, n, &blank);
				break;
			case KEY_UP:
				move_blank(DOWN, s_board, n, &blank);
				break;
			case KEY_DOWN:
				move_blank(UP, s_board, n, &blank);
				break;
		}
		shuffle_board(s_board, n);
		if(check_win(s_board, n, &blank) == TRUE)
		{	mvprintw(24, 0, "You Win !!!\n");
			refresh();
			break;
		}
	}
	endwin();
	return 0;	
}
Exemple #3
0
/* TODO Attempt to reduce this function's complexity
 *
 * Move blank tile to the right of the target tile
 *
 * tile_row - target tile's row
 * tile_col - target tile's collumn
 *
 */
void move_blank_2_position(int tile_row, int tile_col)
{
    if (tile_col == empty_col)
    {
        if (tile_col < d - 1)
        {
            move_blank(right);
            
            while (empty_row < tile_row)
                move_blank(down);
                
            while (empty_row > tile_row)
                move_blank(up);
        }
        else
        {
            move_blank(down); // Verify this condition
            
            move_blank(left);
            
            while (empty_row < tile_row)
                move_blank(down);
                
            while (empty_row > tile_row)
                move_blank(up);
                
            move_blank(right);    
        }
        
        return;
    }
    else
    {
        if (tile_col < d - 1)
        {
            if (empty_row == tile_row)
            {
                while (empty_col < tile_col)
                    move_blank(right);
            }
            else
            {
                while (empty_col < tile_col + 1)
                    move_blank(right);
            }
            
            
            while (empty_row < tile_row)
                move_blank(down);   
                
            while (empty_row > tile_row)
                move_blank(up);
            
            while (empty_col > tile_col + 1)
                move_blank(left);
        }
        else
        {
            while (empty_row < tile_row)
                move_blank(down);
                
            while (empty_col < tile_col - 1)
                move_blank(right);
                
            while (empty_row > tile_row)
                move_blank(up);
                   
            move_blank(right);
        }
    }
    
    
    return;
}
Exemple #4
0
void fix_bottom_corner(int iteration)
{
    int larger_tile = d * (d  - 1) + iteration + 1;
    int smaller_tile = larger_tile - d;
    
    int tile_row, tile_col;
    int target_row, target_col;
    
    look_4_tile(larger_tile, &tile_row, &tile_col);
    move_blank_2_position(tile_row, tile_col);
    
    // Move larger tile to position [d - 2][iteration + 1]
    target_row = d - 2;
    target_col = iteration + 1;
    #if DEBUG
    sprintf(str, "Moving tile %d to position [d - 2][iteration + 1]\n",larger_tile);
    god_mode_debug(str);
    #endif
    move_tile_2_position(target_row, target_col);
    
    // If smaller_tile is in position [d - 2][iteration], reorder tiles
    if (board[d - 2][iteration] == smaller_tile)
    {
        #if DEBUG
        sprintf(str, "Tile %d in position [d - 2][iteration]\n",smaller_tile);
        god_mode_debug(str);
        
        sprintf(str, "Reordering tiles\n");
        god_mode_debug(str);
        #endif
        
        // Reorder tiles
        move_blank(left);
        rotate_blank(NE, 3, true);
        move_blank(right);
        move_blank(right);
        rotate_blank(NE, 2, true);
        move_blank(left);
        rotate_blank(SW, 3, true);
        rotate_blank(SW, 2, false);
        #if DEBUG
        sprintf(str, "Reordering complete\n");
        god_mode_debug(str);
        #endif
    }
    else    // Else move larger tile to position [d - 2][iteration]
    {
        #if DEBUG
        sprintf(str, "Moving tile %d to position [d - 2][iteration]\n",larger_tile);
        god_mode_debug(str);
        #endif
    
        // Move larger tile to position [d - 2][iteration]
        move_tile(left);
        #if DEBUG
        sprintf(str, "Moving tile %d to position [d - 2][iteration + 1]\n",smaller_tile);
        god_mode_debug(str);
        #endif
        
        // Move smaller tile to position [d - 2][iteration + 1]
        look_4_tile(smaller_tile, &tile_row, &tile_col);
        move_blank_2_position(tile_row, tile_col);
    
        target_col = iteration + 1;
    
        move_tile_2_position(target_row, target_col);
    }
    #if DEBUG
    sprintf(str, "Rotating corner tiles\n");
    god_mode_debug(str);
    #endif
    
    // Rotate tiles to fix corner
    rotate_blank(NE, 2, true);
    rotate_blank(SE, 3, true);
}
Exemple #5
0
void god_mode()
{
    for (int i = 0; i < d - 3; i++)
    {
        #if DEBUG
        sprintf(str, "Filling %dth top row\n",i);
        god_mode_debug(str);
        #endif
        // Fix top row
        fix_top_row(i);
        
        #if DEBUG
        sprintf(str, "Fix top corner\n");
        god_mode_debug(str);
        #endif
        // Fix top corner
        fix_top_corner(i);
        
        // Fix left collumn
        fix_left_collumn(i);
        
        #if DEBUG
        sprintf(str, "Fix bottom corner\n");
        god_mode_debug(str);
        #endif
        
        // Fix bottom corner
        fix_bottom_corner(i);
    }
    
    #if DEBUG
    // Solve 3 x 3 puzzle
    god_mode_debug("Solving 3 x 3 puzzle\n");
    #endif
    
    search_node head_node;
    
    head_node.previous = NULL;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            head_node.board[i][j] = board[i + d - 3][j + d - 3];
        }
    }
    head_node.g = 0;
    
    lifo * solution = NULL;
    
    #if DEBUG
    god_mode_debug("Calling a_star_search\n");
    #endif
    a_star_search(&head_node, &solution);
    if (solution == NULL)
        printf("solution is NULL\n");
    #if DEBUG
    god_mode_debug("Solution for 3 x 3 puzzle retrieved, begginning tiles movements\n");
    #endif
    lifo_entry * entry = solution->head;
    lifo_entry * aux;
    
    while (solution->total_entries > 0)
    {
        switch(entry->node->move)
        {
            case up:
                move_blank(up);
                break;
            case down:
                move_blank(down);
                break;
            case left:
                move_blank(left);
                break;
            case right:
                move_blank(right);
                break;
        }
        aux = entry->next;
        free(entry);
        entry = aux;
        solution->head = entry;
        solution->total_entries--;
    }
    #if DEBUG
    god_mode_debug("3 x 3 puzzle solved\n");
    #endif
    return;
}