游戏2048的python实现

前些日子被问了一下2048是如何实现,说实话当时没有想的特别清晰,所以回答的也比较混乱,后来仔细想想这个问题还是挺有趣的,简单的实现了一下

这个问题里面主要有两个问题,一个是移动时的计算,二是移动前对空的格的处理(就是0的格子)。

最初的想法是按行/列,向左移动就从左向右去读,做计算,遇0做处理,后来发现这样是行不通的,应该在移动开始前先把0的格子处理好,例如向左移,要先把为0的放到一行的末尾,然后再平移计算。

具体代码如下:

  1 #!/usr/bin/python
  2 # -*- coding:utf-8 -*-
  3 '''
  4 @author: lianying
  5 '''
  6 import random
  7 
  8 class Game:
  9     #init
 10     def __init__(self, size):
 11         self.size = size
 12         self.matrix = [[0]*self.size for i in range(self.size)]
 13     
 14     def start(self):
 15 
 16         #shallow copy  error
 17         #self.matrix = [[0]*self.size]*self.size
 18         self.add_random_num()
 19         self.display()
 20         while True:
 21             input=raw_input("Left(A/a),Right(D/d),Up(W/w),Down(D/d),Quit(S/s):")
 22             if input.lower() == 'a':
 23                 self.slip_left() 
 24             elif input.lower() == 'd':
 25                 self.slip_right() 
 26             elif input.lower() == 'w':
 27                 self.slip_up() 
 28             elif input.lower() == 's':
 29                 self.slip_down() 
 30             elif input.lower() == 'q':
 31                 break
 32             else:
 33                 print 'error input'
 34                 continue
 35             if self.add_random_num():          
 36                 self.display()
 37             else:
 38                 print 'no place to generate new num'
 39                 break
 40             #input=raw_input("Left(L/l),Right(R/d),Up(U/d),Down(D/d),Quit(Q/q):")
 41     
 42         print 'game over, the max num you get is %d' % self.get_max_num()
 43         
 44     #slip left 
 45     def slip_left(self):
 46         # move 0 to the tail
 47         for t_row in range(self.size):
 48             new_line = filter(lambda x:x != 0, self.matrix[t_row])
 49             new_line.extend([0] * (self.size - len(new_line)))
 50             self.matrix[t_row] = new_line
 51         #calculate
 52         for t_row in range(self.size):
 53             # list_b is a sign to the add action
 54             list_b = [0] * self.size
 55             for i in range(1, self.size):
 56                 if self.matrix[t_row][i - 1] == self.matrix[t_row][i] and list_b[i - 1] != 1:
 57                     self.matrix[t_row][i - 1] = self.matrix[t_row][i - 1] * 2
 58                     list_b[i - 1] = 1
 59                     # the first el to iter is i
 60                     for j in range(i + 1, self.size):
 61                         self.matrix[t_row][j - 1] = self.matrix[t_row][j]
 62                         list_b[j - 1] = list_b[j]
 63                     # the last one is set to 0
 64                     self.matrix[t_row][self.size - 1] = 0
 65                     list_b[self.size - 1] = 0
 66                 else:
 67                     pass
 68         return self.matrix
 69     #slip right 
 70     def slip_right(self):
 71         # move 0 to the front
 72         for t_row in range(self.size):
 73             new_line = filter(lambda x:x != 0, self.matrix[t_row])
 74             zero = [0] * (self.size - len(new_line))
 75             zero.extend(new_line)
 76             self.matrix[t_row] = zero
 77         #calculate
 78         for t_row in range(self.size):
 79             # list_b is a sign to the add action
 80             list_b = [0] * self.size
 81             for i in range(self.size - 1, 0, -1):
 82                 if self.matrix[t_row][i - 1] == self.matrix[t_row][i] and list_b[i] != 1:
 83                     self.matrix[t_row][i] = self.matrix[t_row][i ] * 2
 84                     list_b[i] = 1
 85                     # the first el to iter is i
 86                     for j in range(i - 1, 0, -1):
 87                         self.matrix[t_row][j] = self.matrix[t_row][j - 1]
 88                         list_b[j] = list_b[j - 1]
 89                     self.matrix[t_row][0] = 0
 90                     list_b[0] = 0
 91                 else:
 92                     pass
 93         return self.matrix
 94     #slip up 
 95     def slip_up(self):
 96         # move 0 to the bottom
 97         for t_col in range(self.size):
 98             col_line = [self.matrix[x][t_col] for x in range(self.size)]
 99             new_line = filter(lambda x:x != 0, col_line)
100             zero = [0] * (self.size - len(new_line))
101             new_line.extend(zero)
102             for x in range(self.size):
103                 self.matrix[x][t_col] = new_line[x]
104             
105         for t_col in range(self.size):
106             # list_b is a sign to the add action
107             list_b = [0] * self.size
108             for i in range(1, self.size):
109                 if self.matrix[i - 1][t_col] == self.matrix[i][t_col] and list_b[i] != 1:
110                     self.matrix[i - 1][t_col] = self.matrix[i - 1][t_col] * 2
111                     list_b[i - 1] = 1
112                     # the first el to iter is i
113                     for j in range(i + 1, self.size):
114                         self.matrix[j - 1][t_col] = self.matrix[j][t_col]
115                         list_b[j - 1] = list_b[j]
116                     # the last one is set to 0
117                     self.matrix[self.size - 1][t_col] = 0
118                     list_b[self.size - 1] = 0
119                 else:
120                     pass
121         return self.matrix
122     #slip down
123     def slip_down(self):
124         # move 0 to the top
125         for t_col in range(self.size):
126             col_line = [self.matrix[x][t_col] for x in range(self.size)]
127             new_line = filter(lambda x:x != 0, col_line)
128             zero = [0] * (self.size - len(new_line))
129             zero.extend(new_line)
130             for x in range(self.size):
131                 self.matrix[x][t_col] = zero[x]
132                 
133         for t_col in range(self.size):
134             list_b = [0] * self.size
135             for i in range(self.size - 1, 0, -1):
136                 if self.matrix[i -1][t_col] == self.matrix[i][t_col] and list_b[i] != 1:
137                     self.matrix[i][t_col] = self.matrix[i][t_col] * 2
138                     list_b[i] = 1
139                     for j in range(i - 1, 0, -1):
140                         self.matrix[j][t_col] = self.matrix[j - 1][t_col]
141                         list_b[j] = list_b[j - 1]
142                     self.matrix[0][t_col] = 0
143                     list_b[0] = 0
144                 else:
145                     pass
146         return self.matrix
147     #add a new num in matrix where is 0   
148     def add_random_num(self):
149         zero_list = []
150         for i in range(self.size):
151             for j in range(self.size):
152                 if self.matrix[i][j] == 0:
153                     zero_list.append(i*self.size +j)         
154         if len(zero_list) > 0:
155             #get a random position--->random.choice(iterable)
156             pos = random.choice(zero_list)
157             num = random.choice([2,2,2,4])
158             self.matrix[pos / self.size][pos % self.size] = num 
159             return True
160         else:
161             return False
162     #display the chess
163     def display(self):
164         print "The Chess is:
"
165         for i in range(self.size):
166             for j in range(self.size):
167                 print '%4d' % self.matrix[i][j],
168             print '
',
169     #get the max num in the chess
170     def get_max_num(self): 
171         return max([max(self.matrix[i]) for i in range(self.size)]) 
172 def main():
173     print 'Welcome to the 2048 game:'
174     while True:
175         try:
176             size = int(raw_input('choose the size you want:'))
177             if size > 2:
178                 game = Game(size)
179                 game.start()
180                 break
181             else:
182                 print 'the num should greater than 2'
183         except:
184             print 'wrong input!'
185 
186       
187 if __name__ == '__main__':
188     main()
189     

然后,自己竟然无聊的玩了一会儿,哈哈哈

原文地址:https://www.cnblogs.com/sparkling-ly/p/5591575.html