目录
一、游戏简介
二、思路
三、思路分解成代码
1.我们可以把它看成4*4的二维矩阵+我们可以把二维矩阵初始化全为0+而为了确定是否发生滑动,也就是格子前后是否有变化,我们需要对前后进行比较
2.再随机挑选两个格子的0随机变成2或者4。
3.滑动+当滑动时,如果有相同的数字相撞,会进行相加。
1.左移
2.右移
3.上移
4.下移
4.我们可以通过按键控制上下左右方向+我们可以理解为当发生滑动时,会随机把一个为0的格子随机成2或者4。
四、整体代码
一、游戏简介
有16个格子,分布为4*4.初始时会有两个格子上安放了两个数字2或者4,每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方随即出现一个数字方块2或者4,相同数字的方块在靠拢、相撞时会相加。
二、思路
我们把游戏简介进行分开解读。
1.有16个格子,分布为4*4:我们可以把它看成4*4的二维矩阵。
2.初始时会有两个格子上安放了两个数字2或者4:我们可以把二维矩阵初始化全为0,再随机挑选两个格子的0随机变成2或者4。
3.每次可以选择上下左右其中一个方向去滑动:我们可以通过按键控制上下左右方向
4.每滑动一次,所有的数字方块都会往滑动的方向靠拢外:滑动。
5.系统也会在空白的地方随即出现一个数字方块2或者4:我们可以理解为当发生滑动时,会随机把一个为0的格子随机成2或者4。而为了确定是否发生滑动,也就是格子前后是否有变化,我们需要对前后进行比较。
6.相同数字的方块在靠拢、相撞时会相加:当滑动时,如果有相同的数字相撞,会进行相加。
三、思路分解成代码
根据思路中带颜色的文字进行代码分析。
1.我们可以把它看成4*4的二维矩阵+我们可以把二维矩阵初始化全为0+而为了确定是否发生滑动,也就是格子前后是否有变化,我们需要对前后进行比较
这三句话一起看可知,我们需要两个矩阵。因为前后进行比较,一个矩阵记录滑动后的矩阵(这个矩阵是变化后的矩阵,也就是我们在界面上看到的矩阵),另一个矩阵记录滑动前的矩阵(这个矩阵是变化前的矩阵,也就是我们没有看见的矩阵)。并且这两个矩阵初始化都是0,于是有了如下代码
before_matrix=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] after_matrix=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
def compare_matrix(): if before_matrix != after_matrix: random_location()
random_location()函数在第2点
2.再随机挑选两个格子的0随机变成2或者4。
因为随机挑选的两个格子只能变成2或者4,我们需要一个元组保存2和4,再从中随机取值。
random_tuple=(2,4)
因为从这个元组中随机取值,所以我们需要获取这个元组的长度(假设为random_tuple_len),再通过元组下标随机取值。于是有random.randint(0,random_tuple_len-1)获取元组随机下标。
比如说,当前元组长度为2,也就是random_tuple_len=2。再通过
random.randint(0,random_tuple_len-1)随机取到0到1.
再结合元组,于是有了random_tuple[random.randint(0,random_tuple_len-1)],这样就能随机取到元组的值。
再在一个随机位置上把矩阵的0变成这个元组的随机值。有如下代码
def random_location(): random_tuple_len=len(random_tuple) while True: x = random.randint(0,3) y = random.randint(0, 3) if after_matrix[x][y]==0: after_matrix[x][y]=random_tuple[random.randint(0,random_tuple_len-1)] break
其中after_matrix是我们看到的矩阵.但是一次只能随机变化一个位置的矩阵值,所以需要循环两次,并打印出来。
def init(): for i in range(2): random_location() print_matrix()
def print_matrix(): for i in after_matrix: print(i)
打印函数把二维数组的每行取出来,打印后换行。
3.滑动+当滑动时,如果有相同的数字相撞,会进行相加。
接下来讲解滑动操作,为了解释更清晰,我们举例说明。
1.左移
我们首先取出二维矩阵的一行(可以看作是一个列表),可以分为以下四种情况
0,0,0,2 0,0,2,2 2,0,0,0
都按照左移进行分析,这几种情况,左移后
2,0,0,0 4,0,0,0 2,0,0,0
先看第3种情况,我们发现它没有发生变化也就是没有发生滑动,也就不需要改变
再看第1种情况,我们发现非0数字往左移。我们可以从右往左检查,如果为0则删除,并且往这个列表后面补0。于是有
def zero_to_end(list_data): for i in range(3,-1,-1): if list_data[i]==0: del list_data[i] list_data.append(0)
其中参数list_data是二维矩阵的每一行。
再看第2种情况,我们发现经过第一步0往后移,它变成2,2,0,0。要变成4,0,0,0则发生碰撞。我们可以从左往右检查列表,如果前一位=后一位,则前一位*2,删除后一位,再往列表后面补0,但是为了防止0,0,0,0这种情况,我们可以进行判断这一行是否都为0
def merge_list(list_data): zero_to_end(list_data) for i in range(3): if list_data[i]==0: break if list_data[i]==list_data[i+1]: list_data[i]*=2 del list_data[i+1] list_data.append(0)
因为需要把矩阵每行传过去,所以需要
def merge(): for i in range(4): merge_list(after_matrix[i])
def left(): merge()
这样左移就完成了。
2.右移
同样举例,
0,2,0,0 0,2,4,0
看第1种情况,左移为2,0,0,0,右移为0,0,0,2。只需要把列表左移后再进行逆转
但是看第2种情况,左移为2,4,0,0,右移应该为0,0,2,4。但是把列表左移后再进行逆转,发现成为0,0,4,2。所以需要在左移前进行一次逆转。如下
0,2,4,0——0,4,2,0——4,2,0,0——0,0,2,4
def reverse(): for i in range(4): after_matrix[i].reverse()
def right(): reverse() merge() reverse()
3.上移
对于把水平方向改为垂直方向,只需要把矩阵置换成水平方向,左移后,再转置回去
def transposition(): for x in range(4): for y in range(x,4): after_matrix[x][y],after_matrix[y][x]=after_matrix[y][x],after_matrix[x][y]
def up(): transposition() merge() transposition()
4.下移
def down(): transposition() reverse() merge() reverse() transposition()
需要先置换,再逆转,左移,再逆转,再置换。根据以上可以自行理解。
4.我们可以通过按键控制上下左右方向+我们可以理解为当发生滑动时,会随机把一个为0的格子随机成2或者4。
可以在主代码中实现。
def main(): init() while True: try: global before_matrix before_matrix=copy.deepcopy(after_matrix) key=input("输入:") if key=='a':left() if key == 'd': right() if key == 'w': up() if key == 's': down() compare_matrix() print_matrix() except KeyboardInterrupt: break
global:全局变量
copy.deepcopy():深拷贝
浅拷贝:只复制地址,不复制对象。也就是新旧对象共享一个地址。如果after_matrix对象改变,before_matrix也会改变
深拷贝:会创造一个一模一样的对象,新旧对象不共享一个地址,修改after_matrix,不会改变before_matrix
最后调用主函数完成。
if __name__ == '__main__': main()
四、整体代码
import copy import random before_matrix=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] after_matrix=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] random_tuple=(2,4) def compare_matrix(): if before_matrix != after_matrix: random_location() def random_location(): random_tuple_len=len(random_tuple) while True: x = random.randint(0,3) y = random.randint(0, 3) if after_matrix[x][y]==0: after_matrix[x][y]=random_tuple[random.randint(0,random_tuple_len-1)] break def init(): for i in range(2): random_location() print_matrix() def print_matrix(): for i in after_matrix: print(i) def zero_to_end(list_data): for i in range(3,-1,-1): if list_data[i]==0: del list_data[i] list_data.append(0) def merge_list(list_data): zero_to_end(list_data) for i in range(3): if list_data[i]==0: break if list_data[i]==list_data[i+1]: list_data[i]*=2 del list_data[i+1] list_data.append(0) def merge(): for i in range(4): merge_list(after_matrix[i]) def left(): merge() def reverse(): for i in range(4): after_matrix[i].reverse() def right(): reverse() merge() reverse() def transposition(): for x in range(4): for y in range(x,4): after_matrix[x][y],after_matrix[y][x]=after_matrix[y][x],after_matrix[x][y] def up(): transposition() merge() transposition() def down(): transposition() reverse() merge() reverse() transposition() def main(): init() while True: try: global before_matrix before_matrix=copy.deepcopy(after_matrix) key=input("输入:") if key=='a':left() if key == 'd': right() if key == 'w': up() if key == 's': down() compare_matrix() print_matrix() except KeyboardInterrupt: break if __name__ == '__main__': main()