python

超轻量级php框架startmvc

200行python代码实现2048游戏

更新时间:2020-07-15 20:48:01 作者:startmvc
Python实战系列用于记录实战项目中的思路,代码实现,出现的问题与解决方案以及可行的改

Python实战系列用于记录实战项目中的思路,代码实现,出现的问题与解决方案以及可行的改进方向

本文为第2篇–200行Python代码实现2048

一、分析与函数设计

1.1 游戏玩法

2048这款游戏的玩法很简单,每次可以选择上下左右滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。(介绍来自百度百科)

1.2 函数设计

  • _init _() 初始化4*4游戏地图,分数等游戏基本数据
  • is_gameover() 判断是否结束游戏
  • rannumber() 玩家每次移动时在地图上随机生成2、4
  • show() 在控制台打印出4*4游戏地图
  • print_score() 在控制台打印出当前分数
  • up(), upmove() 上移
  • down(), downmove() 下移
  • left(), leftmove() 左移
  • right(), rightmove() 右移
  • nextstep() 读取玩家按键

二、代码实现

注:IDE为Spyder,Python版本为3.6


# -*- coding: utf-8 -*-
"""
Created on Sat Sep 29 16:29:04 2018

@author: PastoralDog
"""
import random

class game2048(object):
 def __init__(self):
 self.score=0
 self.number=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
 self.move=0
 seed=random.randint(0,15)
 line=int(seed/4)
 row=seed%4
 self.number[line][row]=2 
 
 def is_gameover(self):
 numbersum=0
 for i in range(4):
 for j in range(4):
 if (self.number[i][j]!=0):
 numbersum+=1
 if(numbersum!=16): return False
 for i in range(4):
 for j in range(3):
 if(self.number[i][j+1]==self.number[i][j]): return False
 for i in range(3):
 for j in range(4):
 if(self.number[i+1][j]==self.number[i][j]): return False
 print("游戏结束")
 print("您的得分为:"+str(self.score))
 self.__init__()
 return True
 
 def rannumber(self):
 rannumber=random.randint(1,10) 
 if(rannumber<=8): rannumber=2
 else: rannumber=4
 done=0
 count=0
 for i in range(4):
 for j in range(4):
 if(self.number[i][j]==0):
 count+=1
 while(done==0 and count!=0):
 ranplace=random.randint(0,15)
 line=int(ranplace/4)
 row=ranplace%4
 if(self.number[line][row]==0):
 done=1
 self.number[line][row]=rannumber 
 
 def show(self):
 print(self.number[0])
 print(self.number[1])
 print(self.number[2])
 print(self.number[3])
 
 def print_score(self):
 print("得分:"+str(self.score))
 
 def upmove(self):
 for i in range(1,4):
 for j in range(4):
 temp=i
 while(temp>=1 and self.number[temp-1][j]==0):
 box=self.number[temp-1][j]
 self.number[temp-1][j]=self.number[temp][j]
 self.number[temp][j]=box
 if(self.number[temp][j]!=0):self.move=1
 temp-=1
 
 def up(self):
 self.upmove()
 for i in range(1,4):
 for j in range(4):
 if(self.number[i-1][j]==self.number[i][j]):
 if(self.number[i-1][j]!=2048):
 self.score+=self.number[i][j]
 self.number[i][j]=0
 self.number[i-1][j]=2*self.number[i-1][j] 
 self.upmove() 
 if(self.move!=0):self.rannumber()
 self.move=0
 self.show()
 self.is_gameover()
 self.print_score()
 
 def downmove(self):
 for i in range(2,-1,-1):
 for j in range(4):
 temp=i
 while(temp<=2 and self.number[temp+1][j]==0 ):
 box=self.number[temp+1][j]
 self.number[temp+1][j]=self.number[temp][j]
 self.number[temp][j]=box
 if(self.number[temp+1][j]!=0):self.move=1
 temp+=1
 
 def down(self):
 self.downmove()
 for i in range(2,-1,-1):
 for j in range(4):
 if(self.number[i+1][j]==self.number[i][j]):
 if(self.number[i+1][j]!=2048):
 self.score+=self.number[i][j]
 self.number[i][j]=0
 self.number[i+1][j]=2*self.number[i+1][j] 
 self.downmove()
 if(self.move!=0):self.rannumber()
 self.move=0
 self.show()
 self.is_gameover()
 self.print_score()
 
 def leftmove(self):
 for i in range(4):
 for j in range(1,4): 
 temp=j
 while(temp>=1 and self.number[i][temp-1]==0 ):
 box=self.number[i][temp-1]
 self.number[i][temp-1]=self.number[i][temp]
 self.number[i][temp]=box
 if(self.number[i][temp-1]!=0):self.move=1
 temp-=1
 
 def left(self):
 self.leftmove()
 for i in range(4):
 for j in range(0,3):
 if(self.number[i][j+1]==self.number[i][j]):
 if(self.number[i][j+1]!=2048):
 self.score+=self.number[i][j]
 self.number[i][j+1]=0
 self.number[i][j]=2*self.number[i][j] 
 self.leftmove()
 if(self.move!=0):self.rannumber()
 self.move=0
 self.show()
 self.is_gameover()
 self.print_score()
 
 def rightmove(self):
 for i in range(4):
 for j in range(2,-1,-1): 
 temp=j
 while(temp<=2 and self.number[i][temp+1]==0 ):
 box=self.number[i][temp+1]
 self.number[i][temp+1]=self.number[i][temp]
 self.number[i][temp]=box
 self.move=1
 temp+=1
 
 def right(self):
 self.rightmove()
 for i in range(4):
 for j in range(2,-1,-1):
 if(self.number[i][j+1]==self.number[i][j]):
 if(self.number[i][j+1]!=2048):
 self.score+=self.number[i][j]
 self.number[i][j]=0
 self.number[i][j+1]=2*self.number[i][j+1] 
 self.rightmove()
 if(self.move!=0):self.rannumber()
 self.move=0
 self.show()
 self.is_gameover()
 self.print_score()
 
 def nextstep(self,step):
 if(step=='w'): self.up()
 elif(step=='s'): self.down()
 elif(step=='a'): self.left() 
 elif(step=='d'): self.right()
 else: pass
 
if __name__ == '__main__':
 game=game2048()
 game.show()
 while(True):
 step=input()
 if(step=='b'):break
 game.nextstep(step)

三、问题与解决方案

1.地图的储存与表示:目前没有界面设计,因此就用二维数组直接储存与表示

2.数组越界:调试代码中遇到过五六次,除了牢记要边缘检测外, and 语句左右条件顺序也要有讲究。

例:while(temp<=2 and self.number[temp+1][j]==0 ) 注:self.number为4*4的二维数组 当temp=3时,语句在temp<=2 被阻塞,不会执行self.number[temp+1][j]==0,此时没有问题; 若语句改为while(self.number[temp+1][j]==0 and temp<=2), 先执行self.number[temp+1][j]==0,此时编译器报错数组越界

四、可行的改进方向

1.添加可视化界面,可考虑Tkinter,QT等

2.拓展游戏地图大小为N x N

本人水平有限,欢迎大家提出问题与建议。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

python 2048游戏