找回密码
 会员注册
查看: 13|回复: 0

python小游戏2048字符版非图形界面

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-7 17:03:33 | 显示全部楼层 |阅读模式
参考链接: 闲谈2048小游戏和数组的旋转及翻转和转置目录2048 一、方阵类二、随机插入1或2三、合并和递增四、判断和移动五、键盘控制完整源代码玩法过程2048 上回说到2048小游戏中数组的各种旋转、翻转的方法,就是为代码编程作准备的;有了这些再就加上二维数组各行列上元素的合并、能否被合并的判断、成功失败的判断等等;以及再加上键盘按键的控制,小游戏就基本完成了。一、方阵类方阵就是高宽相同的矩阵,2048用方阵就行了,写代码也省事一点,方阵的类如下:>>>fromrandomimportsample>>>classMatrix:...  def__init__(self,order=4):...    self.order=order...    self.matrix=self.new()...  def__repr__(self):...    m,n=[],len(str(2**max(sum(self.matrix,[]))))...    formatinself.matrix:...      m.append(','.join(f'{2**xifxelse0:>{n}}'forxinmat))...    return'],\n['.join(m).join(['[[',']]'])...  defnew(self):...    n=self.order...    m=sample([0]*(n*n-2)+sample([0,1,1],2),n*n)...    return [m[i*n:i*n+n]foriinrange(n)]... ...   >>>Matrix()[[0,0,2,0], [0,0,0,0], [0,0,2,0], [0,0,0,0]]>>>Matrix()[[0,0,0,0], [0,0,0,0], [0,0,2,0], [0,0,0,0]]在方阵中随机产生1~2个1,sample([0,1,1],2)生成的1个还是2个,比例为2:1;在__repr__方法中显示时,这些1作为2的指数,所以显示为2^1=2。二、随机插入数字  definsert(self):    n=self.order    m=[ifori,ninenumerate(sum(self.matrix,[]))ifnotn]    ifm:      i=sample(m,1)[0]      self.matrix[i//n][i%n]=sum(sample([1,1,1,2],1))或者:  definsert(self):    n=self.order    m=[(i,j)forjinrange(n)foriinrange(n)ifnotself.matrix[i][j]]    ifm:      i,j=sample(m,1)[0]      self.matrix[i][j]=sum(sample([1,1,1,2],1))为加快数字的拼合速度,从5队开始,除了只插入1和2,可以考虑加入更大的数字:self.matrix[i][j]=sum(sample([1,1,1,2]*3+([1,2,3,3]+[iforiinrange(n+4,n,-1)]ifn>4else[]),1))如n=5时,拟插入的各数字比例为:>>>n=5>>>t=[1,1,1,2]*3+[1,2,3,3]+[iforiinrange(n+4,n,-1)]>>>foriinset(t):...  print([i,t.count(i)/20])... ...   [1,0.5][2,0.2][3,0.1][6,0.05][7,0.05][8,0.05][9,0.05] 三、合并和递增  ......     fori,arrayinenumerate(self.matrix):      self.matrix[i]=Matrix.update(array)  ......  defupdate(array):    split=lambdaa:[_for_inaif_]+[_for_inaifnot_]    array=split(array)    fori,ainenumerate(array):      ifiandaanda==array[i-1]:        array[i-1]+=1        array[i]=0    returnsplit(array)四、判断和移动略……写得有点复杂,可以到完整代码中阅读。五、键盘控制引入keyboard库控制键盘,示例如下:importkeyboarddefkeys0():print("Leftkeypressed")defkeys1():print("Rightkeypressed")defkeys2():print("Upkeypressed")defkeys3():print("Downkeypressed")defrestart():print("Enterkeypressed")#添加热键keyboard.add_hotkey('left',keys0)keyboard.add_hotkey('right',keys1)keyboard.add_hotkey('up',keys2)keyboard.add_hotkey('down',keys3)keyboard.add_hotkey('enter',restart)#等待用户按下esc键print("WaitingforESCtoexit...")keyboard.wait('esc')#在这里移除所有热键print("Removingallhotkeys...")keyboard.unhook_all_hotkeys()WaitingforESCtoexit...LeftkeypressedRightkeypressedUpkeypressedDownkeypressedEnterkeypressedRemovingallhotkeys...>>> 注:最后一行代码keyboard.unhook_all_hotkeys()很关键,一定都有否则即使按了ESC键退出程序,热键还是驻留在内存里,键盘还会响应keyboard.add_hotkey()添加的热键。完整源代码importkeyboardfromrandomimportsampleclassMatrix:def__init__(self,order=4):self.over=Falseself.order=orderself.matrix=self.new()self.victory=Falsedef__repr__(self):m,n=[],len(str(2**max(sum(self.matrix,[]))))formatinself.matrix:m.append(','.join(f'{2**xifxelse0:>{n}}'forxinmat))return'],\n['.join(m).join(['[[',']]'])defnew(self):n=self.orderm=sample([0]*(n*n-2)+sample([0,1,1],2),n*n)return[m[i*n:i*n+n]foriinrange(n)]defshow(self):ifself.overorself.victory:print('Entertorestart...')else:print(self)print()definsert(self):n=self.orderm=[(i,j)forjinrange(n)foriinrange(n)ifnotself.matrix[i][j]]ifm:i,j=sample(m,1)[0]self.matrix[i][j]=sum(sample([1,1,1,2],1))deffull(self):returnall(sum(self.matrix,[]))defmove(self,direction=0):ifself.overorself.victory:returndirection%=4ifdirection==0:#leftifself.cannotmove(0):returnelifdirection==1:#rightifself.cannotmove(1):returnself.matrix=self.flipH()elifdirection==2:#upifself.cannotmove(2):returnself.matrix=self.rotL()elifdirection==3:#downifself.cannotmove(3):returnself.matrix=self.rotR()fori,arrayinenumerate(self.matrix):self.matrix[i]=Matrix.update(array)ifdirection==1:self.matrix=self.flipH()elifdirection==2:self.matrix=self.rotR()elifdirection==3:self.matrix=self.rotL()indexmax=max(sum(self.matrix,[]))ifself.order==2andindexmax==4orself.order==3andindexmax==7orindexmax==self.order+7:self.victory=Trueprint(self)print('Win!Entertorestart...')returnself.insert()self.over=self.cannotmove()ifself.over:print(self)print('Gaveover!')defcannotmove(self,direction=4):m,n=self.matrix,self.rotR()p,q=self.rotL(),self.flipH()ifdirection==0:returnall(n[0])andMatrix.cannotupdate(m)elifdirection==1:returnall(n[-1])andMatrix.cannotupdate(q)elifdirection==2:returnall(m[0])andMatrix.cannotupdate(n)elifdirection==3:returnall(m[-1])andMatrix.cannotupdate(p)else:return(self.full()andself.cannotmove(0)andself.cannotmove(1)andself.cannotmove(2)andself.cannotmove(3))defcannotupdate(matrix):returnall([m==Matrix.update(m)forminmatrix])defupdate(array):split=lambdaa:[_for_inaif_]+[_for_inaifnot_]array=split(array)fori,ainenumerate(array):ifiandaanda==array[i-1]:array[i-1]+=1array[i]=0returnsplit(array)defflipH(self):m,n=self.matrix,self.orderreturn[[m[i][n-j-1]forjinrange(n)]foriinrange(n)]defflipV(self):m,n=self.matrix,self.orderreturn[[m[n-j-1][i]foriinrange(n)]forjinrange(n)]defrotL(self):m,n=self.matrix,self.orderreturn[[m[j][n-i-1]forjinrange(n)]foriinrange(n)]defrotR(self):m,n=self.matrix,self.orderreturn[[m[n-j-1][i]forjinrange(n)]foriinrange(n)]defmove(i):mat.move(i)mat.show()defkeys0():move(0)defkeys1():move(1)defkeys2():move(2)defkeys3():move(3)defrestart():globalmatifmat.victory:mat.order+=1mat=Matrix(mat.order)mat.show()ifmat.over:ifmat.order>3:mat.order-=1mat=Matrix(mat.order)mat.show()if__name__=='__main__':print("《2048小游戏》")print("上下左右前头控制方向,按ESC退出...")mat=Matrix(2)mat.show()keyboard.add_hotkey('left',keys0)keyboard.add_hotkey('right',keys1)keyboard.add_hotkey('up',keys2)keyboard.add_hotkey('down',keys3)keyboard.add_hotkey('enter',restart)keyboard.wait('esc')#等待用户按下esc键退出print('bye!')keyboard.unhook_all_hotkeys()#退出后移除所有热键玩法过程《2048小游戏》上下左右前头控制方向,按ESC退出...[[0,0], [0,2]][[0,0], [2,2]][[0,4], [0,4]][[0,2], [0,8]][[2,2], [8,0]][[4,2], [8,0]][[4,4], [8,2]][[8,2], [8,2]][[0, 0], [16, 4]]Win!Entertorestart...Entertorestart...[[0,2,0], [0,0,2], [0,0,0]][[0,0,0], [2,0,0], [0,2,2]][[4,0,0], [0,0,2], [0,0,4]][[0,2,0], [0,0,2], [4,0,4]][[0,0,2], [0,0,2], [4,0,8]][[0,0,2], [0,2,2], [0,4,8]][[0,0,0], [0,2,4], [2,4,8]][[2,0,0], [2,4,0], [2,4,8]][[2,0,0], [2,0,0], [4,8,8]][[0, 2, 2], [0, 0, 2], [0, 4,16]][[0, 0, 0], [2, 2, 4], [0, 4,16]][[0, 0, 0], [0, 4, 4], [4, 4,16]][[2, 0, 0], [0, 0, 4], [4, 8,16]][[2, 0, 0], [2, 0, 4], [4, 8,16]][[2, 0, 0], [4, 0, 4], [4, 8,16]][[0, 4, 0], [2, 0, 4], [8, 8,16]][[0, 2, 4], [0, 2, 4], [0,16,16]][[2, 2, 4], [0, 2, 4], [0, 0,32]][[0, 0, 0], [2, 0, 8], [2, 4,32]][[0, 0, 0], [2, 0, 8], [4, 4,32]][[0, 0, 2], [0, 2, 8], [0, 8,32]][[0, 0, 2], [0, 2, 8], [2, 8,32]][[2, 0, 4], [2, 8, 0], [2, 8,32]][[0, 0, 2], [2, 0, 4], [4,16,32]][[2, 0, 2], [2, 4, 0], [4,16,32]][[0, 0, 4], [4, 4, 2], [4,16,32]][[2, 0, 4], [0, 4, 2], [8,16,32]][[2, 2, 4], [0, 4, 2], [8,16,32]][[0, 4, 4], [2, 4, 2], [8,16,32]][[2, 0, 4], [2, 8, 2], [8,16,32]][[0, 2, 4], [4, 8, 2], [8,16,32]][[2, 4, 2], [4, 8, 2], [8,16,32]][[2, 4, 2], [4, 8, 4], [8,16,32]]Gaveover!Entertorestart...注:二阶方阵玩出16就过关,三阶方阵玩出128就过关,四阶就要到2048才能过关,五阶则要到4096才过关,六阶以上类推。演示时玩到三阶方阵就over了,如果三阶方阵过关会自动升级到四阶方阵,以此类推。本文完
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-11 06:08 , Processed in 0.514381 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表