abbarnes

2048 game [codeskulptor]

Dec 12th, 2017
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.04 KB | None | 0 0
  1. """
  2. Clone of 2048 game.
  3. """
  4.  
  5. import poc_2048_gui
  6. import random
  7.  
  8. # Directions, DO NOT MODIFY
  9. UP = 1
  10. DOWN = 2
  11. LEFT = 3
  12. RIGHT = 4
  13.  
  14. # Offsets for computing tile indices in each direction.
  15. # DO NOT MODIFY this dictionary.
  16. OFFSETS = {UP: (1, 0),
  17.            DOWN: (-1, 0),
  18.            LEFT: (0, 1),
  19.            RIGHT: (0, -1)}
  20.  
  21. def move_places(line, places):
  22.     """
  23.    Helper function for merge.  
  24.    Moves elements of places to first and second non-zero, or to end
  25.    of line.  Can produce a zero if at end.
  26.    """
  27.    
  28.     while places[0] < len(line)-2 and line[places[0]] == 0:
  29.         places[0] += 1
  30.     places[1] = places[0] +1
  31.     while places[1] < len(line)-1 and line[places[1]] == 0:
  32.         places[1] += 1
  33.     return places
  34.  
  35. def merge(line):
  36.     """
  37.    Helper function that merges a single row or column in 2048
  38.    """
  39.     #copy input list
  40.     left_align = []
  41.     for dummy_index in range(len(line)):
  42.         left_align.append(line[dummy_index])
  43.     #list of two indexing parameters used to grab the next non-zero elements in list
  44.     places = [0,0]
  45.     #index value used to iterate through elements of list
  46.     index = 0
  47.     #bool used to check whether the places have reached end of list
  48.     #if true, need to account for special cases, i.e. non-zeros
  49.     end = False
  50.    
  51.     #iterate over list
  52.     while index < len(left_align)-1:
  53.        
  54.         #print "Iteration " + str(index)
  55.         #print "List: " + str(left_align)
  56.        
  57.         #places returned to index, index+1, then sent to find non-zeros
  58.         places[0] = index
  59.         places[1] = index
  60.         move_places(left_align, places)
  61.         #print "index:" + str(index) + "; P1:" + str(places[0]) + "; P2:" + str(places[1])
  62.        
  63.         #check if places
  64.         end = places[0] == len(left_align) - 2
  65.        
  66.         #check if selected elements in list are a match
  67.         if left_align[places[0]] == left_align[places[1]]:
  68.             #print "match"
  69.            
  70.             #place combined values into current index location & set prevous values to 0
  71.             left_align[index] = 2 * left_align[places[0]]
  72.             if index != places[0]:
  73.                 left_align[places[0]] = 0
  74.             left_align[places[1]] = 0
  75.            
  76.             #print result and return result if at end
  77.             #print left_align
  78.             if end:
  79.                 #print "at end"
  80.                 return left_align
  81.            
  82.         #logic for non-matching selected values
  83.         else:
  84.             #print "no match"
  85.            
  86.             #move first value to list[index] and delete from previous location
  87.             left_align[index] = left_align[places[0]]
  88.             if index != places[0]:
  89.                 left_align[places[0]] = 0
  90.                
  91.            
  92.             if end:
  93.                 #print "at end"
  94.                
  95.                 #cases: [I,P0 = 0,P1] or [I = P0 = 0,P1]  
  96.                 #excpetion:  index will become 0, so must move P1 to index
  97.                 if left_align[index] == 0:
  98.                     #print "places1 was zero.  Moving places2 to index"
  99.                     left_align[index] = left_align[places[1]]
  100.                     #delete P1. moved to index, so no need for conditional check
  101.                     left_align[places[1]] = 0
  102.                 #cases:  [I,P1,P2], [I,P1,0], [I/P1, P2], [I/P1, 0], [0,P2]
  103.                 #exception: whether P1 is 0 or not, move to index+1 before returning list
  104.                 else:
  105.                     left_align[index + 1] = left_align[places[1]]
  106.                     if (index + 1) != places[1]:
  107.                         left_align[places[1]] = 0
  108.                        
  109.                 return left_align
  110.             #print left_align
  111.            
  112.         #print "-------------------------------"
  113.         index += 1
  114.     return left_align
  115.  
  116. class TwentyFortyEight:
  117.     """
  118.    Class to run the game logic.
  119.    """
  120.  
  121.     def __init__(self, grid_height, grid_width):
  122.         self._rows = grid_height
  123.         self._columns = grid_width
  124.         self._grid = []
  125.         self._borders = {UP: [(0,col)for col in range(self._columns)] ,
  126.                    DOWN: [(self._rows-1,col)for col in range(self._columns)],
  127.                    LEFT: [(row,0)for row in range(self._rows)],
  128.                    RIGHT: [(row,self._columns-1)for row in range(self._rows)]}
  129.  
  130.         self.reset()
  131.  
  132.     def reset(self):
  133.         """
  134.        Reset the game so the grid is empty except for two
  135.        initial tiles.
  136.        """
  137.         #create grid of variable size filled with values of 0
  138.         self._grid = [[0 for dummy_w in range(self._columns)] for dummy_h in range(self._rows)]
  139.         #generate initial values for playing in GUI
  140.         self.new_tile()
  141.         self.new_tile()
  142.         self.new_tile()
  143.         self.new_tile()
  144.         self.new_tile()
  145.         self.new_tile()
  146.        
  147.     def __str__(self):
  148.         """
  149.        Return a string representation of the grid for debugging.
  150.        """
  151.         print "Rows of Grid:"
  152.         for row_num in range(self._rows):
  153.             print self._grid[row_num]
  154.         return str(self._grid)
  155.  
  156.     def get_grid_height(self):
  157.         """
  158.        Get the height of the board.
  159.        """
  160.         return self._rows
  161.  
  162.     def get_grid_width(self):
  163.         """
  164.        Get the width of the board.
  165.        """
  166.         return self._columns
  167.    
  168.     def get_merge_list(self, cell, direction, num_steps):
  169.         merged_list = []
  170.         for step in range(num_steps):
  171.             row = cell[0] + OFFSETS[direction][0] * step
  172.             col = cell[1] + OFFSETS[direction][1] * step
  173.             merged_list.append(self._grid[row][col])
  174.         return merged_list
  175.            
  176.     def store_values(self, cell, values, direction, num_steps):
  177.         for step in range(num_steps):
  178.             row = cell[0] + OFFSETS[direction][0] * step
  179.             col = cell[1] + OFFSETS[direction][1] * step
  180.             self._grid[row][col] = values.pop(0)
  181.    
  182.     def move(self, direction):
  183.         """
  184.        Move all tiles in the given direction and add
  185.        a new tile if any tiles moved.
  186.        """
  187.         moved = False
  188.         for tile in self._borders[direction]:
  189.             #gives either the #rows if up/down or #columns if right/left
  190.             steps = abs(OFFSETS[direction][0] * self._rows + OFFSETS[direction][1] * self._columns)
  191.             merge_list = self.get_merge_list(tile, direction, steps)
  192.             value_list = merge(merge_list)
  193.             if value_list != merge_list:
  194.                 moved = True
  195.             self.store_values(tile, value_list, direction, steps)
  196.         #only add new tile if the pieces moved (i.e. there were open spaces to slide tiles)
  197.         if moved:
  198.             self.new_tile()
  199.            
  200.     def new_tile(self):
  201.         """
  202.        Create a new tile in a randomly selected empty
  203.        square.  The tile should be 2 90% of the time and
  204.        4 10% of the time.
  205.        """
  206.         new_values = [2,2,2,2,2,2,2,2,2,4]
  207.         value_placed = False
  208.         full = False
  209.         full_row = 0
  210.         for row_check in self._grid:
  211.             if 0 not in row_check:
  212.                 full_row += 1
  213.         if full_row >= self._rows:
  214.             print "full"
  215.             full = True
  216.         while not value_placed and not full:
  217.             row = random.randint(0,self._rows -1)
  218.             col = random.randint(0,self._columns -1)
  219.             if self._grid[row][col] == 0:
  220.                 self._grid[row][col] = random.choice(new_values)
  221.                 value_placed = True
  222.                 #print "Placing " + str(self.grid[row][col]) + " in row " + str(row) + " column " + str(col)
  223.  
  224.     def set_tile(self, row, col, value):
  225.         """
  226.        Set the tile at position row, col to have the given value.
  227.        """
  228.         self._grid[row][col] = value
  229.  
  230.     def get_tile(self, row, col):
  231.         """
  232.        Return the value of the tile at position row, col.
  233.        """
  234.         # replace with your code
  235.         return self._grid[row][col]
  236.  
  237. poc_2048_gui.run_gui(TwentyFortyEight(4, 4))
Add Comment
Please, Sign In to add comment