''' Purpose: simulate a digital version of a 15 puzzle Email id: Email id: Pledge: All effort for this assignment has been done as team and when both the driver and navigator are present and working together ''' from PIL import Image import random # globals def initialize_globals( img ) : ''' Initializes the global variables to appropriate values based on image img ''' global LINE_THICKNESS, GRID_COLOR, TILE_DIMENSIONS, BOARD, BLACK_TILE, BLACK_TILE_SPOT LINE_THICKNESS = 4 GRID_COLOR = 'SteelBlue' tw = img.width // 4 th = img.height // 4 TILE_DIMENSIONS = ( tw, th ) bw = 4 * tw + 5 * LINE_THICKNESS bh = 4 * th + 5 * LINE_THICKNESS BOARD = Image.new( 'RGB', ( bw, bh ), GRID_COLOR ) BLACK_TILE = Image.new( 'RGB', ( tw, th ), 'BLACK' ) BLACK_TILE_SPOT = ( 3, 3 ) def cleanup( img ) : ''' Returns a version of image img where the bottom right corner is replaced by a black tile ''' global TILE_DIMENSIONS, BLACK_TILE tw, th = TILE_DIMENSIONS nw, nh = 4 * tw, 4 * th box = ( 0, 0, nw, nh ) new_image = img.crop( box ) ( x, y ) = translate_spot_into_image_coordinate( ( 3, 3 ) ) new_image.paste( BLACK_TILE, (x, y ) ) new_image = new_image.convert( "RGB" ) return new_image def initialize_board( img ): ''' Initializes the board using image an already cleaned-up image img ''' for r in range( 0, 4 ) : for c in range( 0, 4 ) : g_spot = ( r, c ) tile = get_image_tile(img, g_spot ) overlay(tile, g_spot) def scramble_board( img ) : ''' Assigns the tiles of img to random grid locations on the board ''' initialize_board( img ) canonical_ordering = [ (0, 0), (1, 0), (2, 0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1), (0, 2), (1, 2), (2, 2), (3, 2), (0, 3), (1, 3), (2, 3) ] ordering = canonical_ordering[ : ] random.shuffle(ordering) random_ordering = ordering for i in range( 0, 15 ) : g_spot = canonical_ordering[ i ] r_spot = random_ordering[ i ] tile = get_image_tile( img, r_spot ) overlay(tile, g_spot) def get_image_tile( img, g_spot ) : ''' Returns a copy of the img tile at grid location g_spt ''' global TILE_DIMENSIONS tw, th = TILE_DIMENSIONS tile = Image.new( "RGB", ( tw, th ) ) ulc = translate_spot_into_image_coordinate( g_spot ) x1, y1 = ulc x2, y2 = x1 + tw, y1 + th box = ( x1, y1, x2, y2 ) tile = img.crop( box ) return tile def get_board_tile( g_spot ) : ''' Returns a copy of the board tile at grid location g_spot ''' global TILE_DIMENSIONS, BOARD tw, th = TILE_DIMENSIONS ulc = translate_spot_into_board_coordinate(g_spot) x1, y1 = ulc x2, y2 = x1 + tw, y1 + th box = ( x1, y1, x2, y2 ) tile = BOARD.crop( box ) return tile def overlay( tile, g_spot ) : ''' Copies tile onto board starting at grid location g_spot ''' global BOARD ( x, y ) = translate_spot_into_board_coordinate( g_spot ) BOARD.paste( tile, ( x, y ) ) def translate_spot_into_board_coordinate( g_spot ) : ''' Returns the board coordinate of the upper-left-hand corner of the tile at grid location g_spot ''' global LINE_THICKNESS, TILE_DIMENSIONS r, c = g_spot tw, th = TILE_DIMENSIONS x = r * tw + ( r + 1 ) * LINE_THICKNESS y = c * th + ( c + 1 ) * LINE_THICKNESS return ( x, y ) def translate_spot_into_image_coordinate( g_spot ) : ''' Returns the img coordinate of the upper-left-hand corner of the tile at grid location g_spot ''' global TILE_DIMENSIONS r, c = g_spot tw, th = TILE_DIMENSIONS x = r * tw y = c * th return ( x, y ) def setup( img ) : ''' Sets up the global variables. Gets a cleaned-up version of img (that is, an image whose lower-right-hand tile area is black. Initializes the board to a canonical ordering. And, returns the cleaned-up image ''' initialize_globals( img ) img = cleanup( img ) initialize_board( img ) return img def inbounds( spot ) : ''' Determines whether spot is a valid grid location for the 15 puzzle ''' pass def slide_left() : ''' If legal, simulates sliding rightward the tile on BOARD that is to the left of the black tile spot: the tile is overlaid on the black tile spot; the black tile is overlaid on the now available spot; > the location of the black tile is updated ''' global BLACK_TILE_SPOT, BLACK_TILE pass def slide_right() : ''' If legal, simulates sliding leftward the tile on BOARD that is to the right of the black tile spot. ''' global BLACK_TILE_SPOT, BLACK_TILE pass def slide_down() : ''' If legal, simulates sliding downward the tile on BOARD that is above the black tile spot ''' global BLACK_TILE_SPOT, BLACK_TILE pass def slide_up() : ''' If legal, simulates sliding upward the tile on BOARD that is below the black tile spot ''' global BLACK_TILE_SPOT, BLACK_TILE pass if ( __name__ == "__main__" ) : global BOARD import url random.seed( 1112 ) mandrill = 'http://www.cs.virginia.edu/~cs1112/images/mandrill/full.png' img = url.get_image( mandrill ) img = setup( img ) BOARD.show() scramble_board( img ) BOARD.show()