Skip to content

Instantly share code, notes, and snippets.

@bitoffdev
Last active August 29, 2015 14:01
Show Gist options
  • Save bitoffdev/de770c5757a04f5bccf3 to your computer and use it in GitHub Desktop.
Save bitoffdev/de770c5757a04f5bccf3 to your computer and use it in GitHub Desktop.
from random import randint, choice
RIGHT,LEFT,UP,DOWN = 'right','left','up','down'
DIRECTIONS = {
'r': RIGHT,
'l': LEFT,
'u': UP,
'd': DOWN
}
class GridSizeError(Exception):
pass
class Grid(dict):
def __init__(self,height,width):
self._height = height
self._width = width
def setHeight(self,height):
self._height = height
def setWidth(self,width):
self._width = width
def getHeight(self):
return self._height
def getWidth(self):
return self._width
def __getitem__(self,key):
return self.get(key,0)
def __setitem__(self,key,value):
if type(key) != type((1,1)):
raise TypeError
if key[0] > self._height:
raise GridSizeError
if key[1] > self._width:
raise GridSizeError
super(Grid, self).__setitem__(key, value)
def __str__(self):
output = ''
for i in range(self._height):
for j in range(self._width):
output += " %s " % self[i,j]
output += "\n"
return output
def slide(self, d):
height, width = self.getHeight(), self.getWidth()
iter1 = range(height if d == 'left' or d == 'right' else width)
iter2 = range(width if d == 'left' or d == 'right' else height)
for i in iter1:
if d == 'left' or d == 'right':
new_list = [self[i, j] for j in range(width) if self[i, j]!=0]
else:
new_list = [self[j, i] for j in range(height) if self[j, i]!=0]
if d=='down' or d=='right': new_list.reverse()
for c in iter2:
if c >= len(new_list):
new_list.append(0)
elif c+1 < len(new_list):
if new_list[c] == new_list[c+1]:
new_list[c] *= 2
new_list.pop(c+1)
if d=='down' or d=='right': new_list.reverse()
for j in iter2:
if d=='up' or d=='down': self[j, i] = new_list[j]
else: self[i,j] = new_list[j]
def addNum(self):
i,j = randint(0,3),randint(0,3)
while self[i,j] != 0: i,j = randint(0,3),randint(0,3)
self[i,j] = choice([2,4])
def isFull(self):
return any(i!=0 for i in self.itervalues())
def noMoves(self):
return True
def test():
# start test
grid = Grid(4,4)
grid[0,0] = 2
grid[0,1] = 2
grid[1,2] = 4
print grid
# test slide down
grid.slide(DOWN)
print grid
# test slide right
grid.slide(RIGHT)
print grid
# test slide left
grid.slide(LEFT)
print grid
#Define a gameOver() function that returns True if the board is full and there are no possible moves
def gameOver(g):
return g.isFull() and g.noMoves()
#Define a function called playGame() to play 2048
def playGame():
#Create an instance of the class Grid and assign it to "grid"
grid = Grid(4,4)
#Add two numbers to the empty grid using the addNum() method of Grid
for i in range(2): grid.addNum()
#Loop while the game is not over
while not gameOver(grid):
#print the grid using the Grid's __str__ method
print grid
#assign value None to the variable "move"
move = None
#Loop until the variable "move" has a value (other than None, undefined, 0, False, etc)
while not move:
#Try to get a valid move
try:
move = DIRECTIONS[raw_input('Move - r, l, u, d ? ').lower()[0]]
#If the attempted move was not in the dictionary "DIRECTIONS" then except pass and move on to the next iteration so that the player can try to move again
except:
pass
#Call the slide method of "grid" and pass it the argument "move"
grid.slide(move)
#Call the addNum() method of "grid" in order to add another number to the grid
grid.addNum()
# Prompt the player to see if they want to play again and return True if yes
return raw_input("Try Again? ").lower()[0] == 'y'
# Run this code if this program is called from command line (not imported)
if __name__ == "__main__":
# Assign True to the variable "playagain"
playagain = True
# Loop while "playagain" is True
while playagain:
#call function playgame and assign its return value to "playagain"
playagain = playGame()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment