如何用python写一个关机程序,如何用python写一个软件
2048游戏规则:只需移动方向键使数字重叠,这些数字每次重叠后得到分数。当数字2048出现时,游戏获胜。同时,每移动一次方向键,这个4*4的网格矩阵的空白区域就会随机产生一个数字2或者4。如果格子里填满了数字,那么游戏就结束了。
逐步分析:
(1)生成44棋盘,数据结构为嵌套列表
field=[[0 forjinrange(4)]foriinrange(4)](2)创建函数random_create在棋盘上的随机位置插入一个数字2或4,其中2的概率较高。
随机输入
defrandom_create():
i=random.choice(范围(4))
j=random.choice(范围(4))
值=random.choice([2,2,2,4])
Field[i][j]=value(3)如果随机插入数字的位置已经有内容,如何解决覆盖原数字的问题?
defrandom_creat():
whileTrue:
i=random.choice(范围(4))
j=random.choice(范围(4))
ifli[i][j]==0:
li[i][j]=4ifrandom.randint(1,100)80else2
破裂
random_creat()
Random_creat()(4) (4)通过图像绘制生成的数据。
defdraw_sep():
打印(- *4 )
defdraw_num(row):
打印()。join({:^5}.format(num)ifnum!=0elsefornuminrow) )
forrowinli:
draw_sep()
draw_num(行)
draw_sep()(5)矩阵的求逆
定义垂直(字段):
rowinfield的return[row[33603360-1](6)矩阵的变换秩
极好的
transpose(field):
return[list(row)forrowinzip(*field)](7)判断棋盘是否可移动
defis_row_change(row):(8)判断这个棋盘是否可左右上下移动#row
#判断一行内容是否可以移动
defis_change(i):
#判断每两个元素之间是否可以移动
ifrow[i]==0androw[i+1]!=0:
returnTrue
ifrow[i]!=0androw[i+1]==row[i]:
returnTrue
else:
returnFalse
returnany([is_change(index)forindexinrange(len(row)-1)])
defis_move_left(field):棋盘的移动,相加returnany([is_row_change(row)forrowinfield])
defis_move_right(field):
#对于列表元素进行反转
field=invert(field)
print(field)
returnis_move_left(field)
defis_move_up(field):
#对于列表元素进行转置
field=transpose(field)
returnis_move_left(field)
defis_move_down(field):
#反转+转置
field=transpose(field)
returnis_move_right(field)
deftight(row):#[2,0,2,0]棋盘左右上下移动相加#最快的方式,通过排序实现...........
returnsorted(row,key=lambdax:ifx==0)
score=0
#相加
defmerge(row):#[2,2,0,0]
#[0,1,2]
foriinrange(len(row)-1):
#如果两个值相等,前一个元素*2,后一个元素改为0。
ifrow[i]==row[i+1]:
row[i]*=2
row[i+1]=0
#如果覆盖成功,就给得分
globalscore
score+=row[i]
returnrow
defmove_row_left(self,row):(9)判断游戏的胜利与结束returnself.tight(self.merge(self.tight(row)))
defmove_left(self,field):
return[self.move_row_left(row)forrowinfield]
defmove_right(self,field):
field=self.invert(field)
returnself.invert([self.move_row_left(row)forrowinfield])
defmove_up(self,field):
returnself.transpose([self.move_row_left(row)forrowinself.transpose(field)])
defmove_down(self,field):
returnself.invert(self.transpose([self.move_row_left(row)
forrowinself.invert(self.transpose(field))]))
#判断游戏何时胜利:当棋盘中出现2048时,就代表着游戏胜利这样程序的各个部分就写好了,将各个部分封装到一个类里面,再导入curses模块来控制游戏,就可以了。defvictory(field):
li=[yforrowinliforyinrow]
ifmax(li)>=2048:
print('Victory')
defgame_over(filed):
ifall((is_move_left(filed),is_move_right(filed),is_move_up(filed),is_move_down(filed)))==False:
print('GameOver')
相关推荐:《Python教程》
下面是完整的代码:
importcurses实现双人版的2048游戏fromitertoolsimportchain
fromrandomimportchoice
classGameField(object):
#初始化信息
def__init__(self,width=4,height=4,win_value=8):
self.width=width
self.height=height
self.win_value=win_value
self.score=0#当前得分
self.highscore=0#最高分
self.moves={}
self.moves['Left']=self.is_move_left
self.moves['Right']=self.is_move_right
self.moves['Down']=self.is_move_down
self.moves['Up']=self.is_move_up
self.movesDict={}
self.movesDict['Left']=self.move_left
self.movesDict['Right']=self.move_right
self.movesDict['Down']=self.move_down
self.movesDict['Up']=self.move_up
defreset(self):#重置棋盘
ifself.score>self.highscore:
self.highscore=self.score#更新最高分
self.score=0
#需求1:生成4*4的棋盘,其中数据结构选择列表嵌套列表;
self.field=[[0forjinrange(self.width)]
foriinrange(self.height)]
#在棋盘的一个随机位置插入一个数字2或者4
self.random_create()
self.random_create()
defrandom_create(self):
#在棋盘的一个随机位置插入一个数字2或者4
#field[0][3]=2
whileTrue:
i,j=choice(range(self.height)),choice(range(self.width))
ifself.field[i][j]==0:
self.field[i][j]=choice([2,2,2,4])
break
defdraw(self,stdscr):
defdraw_sep():
stdscr.addstr('+'+"-----+"*self.width+'\n')
defdraw_one_row(row):
stdscr.addstr("".join('{:^5}'.format(num)ifnum!=0else""fornuminrow)+''+'\n')
#清屏
stdscr.clear()
stdscr.addstr("2048".center(50,'-')+'\n')
stdscr.addstr("当前分数:"+str(self.score)+'\n')
ifself.highscore!=0:
stdscr.addstr("最高分:"+str(self.highscore)+'\n')
forrowinself.field:
draw_sep()
draw_one_row(row)
draw_sep()
#判断是否赢或者输
ifself.is_win():
stdscr.addstr("胜利!!!!"+'\n')
ifself.is_gameover():
stdscr.addstr("游戏结束!!!!"+'\n')
stdscr.addstr("游戏帮助:上下左右键(R)RestartQ(Quit)")
defis_win(self):
returnmax(chain(*self.field))>=self.win_value
defis_gameover(self):
#任何方向都不能移动的时候,游戏结束
returnnotany([self.move_is_possible(direction)
fordirectioninself.moves])
@staticmethod
definvert(field):
#矩阵进行反转
return[row[::-1]forrowinfield]
#print(invert(li))
@staticmethod
#矩阵的转置
deftranspose(field):
return[list(row)forrowinzip(*field)]
@staticmethod
defis_row_change(row):
#row
#需求3.判断一行内容是否可移动。
defis_change(i):#0
#判断每两个元素之间是否可移动
ifrow[i]==0androw[i+1]!=0:
returnTrue
ifrow[i]!=0androw[i]==row[i+1]:
returnTrue
returnFalse
returnany([is_change(index)forindexinrange(len(row)-1)])
#判断这个棋盘是否可向左移动
defis_move_left(self,field):
returnany([self.is_row_change(row)forrowinfield])
defis_move_right(self,field):
#对于列表元素进行反转
field=self.invert(field)
print(field)
returnself.is_move_left(field)
defis_move_up(self,field):
#对于列表元素进行转置
field=self.transpose(field)
returnself.is_move_left(field)
defis_move_down(self,field):
#反转+转置
field=self.transpose(field)
returnself.is_move_right(field)
defmove_is_possible(self,direction):#'left'
#判断用户选择的方向是否可移动
ifdirectioninself.moves:
returnself.moves[direction](self.field)
else:
returnFalse
#将棋盘每一行的非0数向前移动,0向后移动;
@staticmethod
deftight(row):#[2,0,2,0]
#最快的方式,通过排序实现...........
returnsorted(row,key=lambdax:1ifx==0else0)
defmerge(self,row):#[2,2,0,0]
#[0,1,2]
foriinrange(len(row)-1):
#如果两个值相等,前一个元素*2,后一个元素改为0。
ifrow[i]==row[i+1]:
row[i]*=2
row[i+1]=0
#如果覆盖成功,就给得分
self.score+=row[i]
returnrow#[4,0,0,0]
defmove_row_left(self,row):
returnself.tight(self.merge(self.tight(row)))
defmove_left(self,field):
return[self.move_row_left(row)forrowinfield]
defmove_right(self,field):
field=self.invert(field)
returnself.invert([self.move_row_left(row)forrowinfield])
defmove_up(self,field):
returnself.transpose([self.move_row_left(row)forrowinself.transpose(field)])
defmove_down(self,field):
returnself.invert(self.transpose([self.move_row_left(row)
forrowinself.invert(self.transpose(field))]))
defmove(self,direction):#'left'
#判断用户选择的方向是否可移动
ifdirectioninself.movesDict:
#判断是否可移动
ifself.move_is_possible(direction):
self.field=self.movesDict[direction](self.field)
self.random_create()
returnTrue
else:
returnFalse
defget_user_action(stdscr):
action=stdscr.getch()
ifaction==curses.KEY_UP:
return'Up'
ifaction==curses.KEY_DOWN:
return'Down'
ifaction==curses.KEY_LEFT:
return'Left'
ifaction==curses.KEY_RIGHT:
return'Right'
ifaction==ord('r'):
return'Restart'
ifaction==ord('q'):
return'Exit'
defmain(stdscr):
action=stdscr.getch()
definit():
#初始化棋盘的操作
game_field.reset()
game_field.draw(stdscr)
return'Game'
defgame():
game_field.draw(stdscr)
action=get_user_action(stdscr)
ifaction=='Restart':
return'Init'
ifaction=='Exit':
return'Exit'
ifgame_field.move(action):
ifgame_field.is_win():
return'Win'
ifgame_field.is_gameover():
return'GameOver'
return'Game'
defnot_game():
game_field.draw(stdscr)
whileTrue:
action=get_user_action(stdscr)
ifaction=='Restart':
return'Init'
ifaction=='Exit':
return'Exit'
state_actions={
'Init':init,
'Game':game,
'Win':not_game,
'GameOver':not_game,
}
game_field=GameField()
state='Init'
#如果当前状态不是退出,那么一直执行
whilestate!='Exit':
#执行当前状态需要操作的内容,并返回,下一次的状态为什么.
state=state_actions[state]()
curses.wrapper(main)
importcursesimportrandom
fromitertoolsimportchain
classGameField(object):
def__init__(self,width=4,height=4,win_value=2048):
self.width=width
self.height=height
self.win_value=win_value
self.score1=0
self.score2=0
self.highscore=0
self.moves={}
self.moves['Left1']=self.is_left_move
self.moves['Right1']=self.is_right_move
self.moves['Up1']=self.is_up_move
self.moves['Down1']=self.is_down_move
self.moves['Left2']=self.is_left_move
self.moves['Right2']=self.is_right_move
self.moves['Up2']=self.is_up_move
self.moves['Down2']=self.is_down_move
self.movesDict1={}
self.movesDict2={}
self.movesDict1['Left1']=self.left_move
self.movesDict1['Right1']=self.right_move
self.movesDict1['Up1']=self.up_move
self.movesDict1['Down1']=self.down_move
self.movesDict2['Left2']=self.left_move
self.movesDict2['Right2']=self.right_move
self.movesDict2['Up2']=self.up_move
self.movesDict2['Down2']=self.down_move
defrandom_create1(self):
whileTrue:
i,j=random.randint(0,self.height-1),random.randint(0,self.width-1)
ifself.field1[i][j]==0:
self.field1[i][j]=random.choice([2,2,2,4])
break
defrandom_create2(self):
whileTrue:
i,j=random.randint(0,self.height-1),random.randint(0,self.width-1)
ifself.field2[i][j]==0:
self.field2[i][j]=random.choice([2,2,2,4])
break
defreset(self):
self.field1=[[0forjinrange(self.width)]foriinrange(self.height)]
self.score1=0
self.field2=[[0forjinrange(self.width)]foriinrange(self.height)]
self.score2=0
self.random_create1()
self.random_create1()
self.random_create2()
self.random_create2()
defdraw(self,stdscr):
stdscr.clear()
self.score1=sum(chain(*self.field1))
self.score2=sum(chain(*self.field2))
ifmax(self.score1,self.score2)>self.highscore:
self.highscore=max(self.score1,self.score2)
stdscr.addstr('最高分:'+str(self.highscore)+'')
stdscr.addstr('玩家1分数:'+str(self.score1)+'')
stdscr.addstr('玩家2分数:'+str(self.score2)+'\n')
forrowinself.field1:
stdscr.addstr('+'+'-----+'*self.width+'\n')
stdscr.addstr("".join('{:^5}'.format(num)ifnum!=0else""fornuminrow)+''+'\n')
stdscr.addstr('+'+'-----+'*self.width+'\n')
ifself.is_win1():
stdscr.addstr('胜利\n')
ifself.is_gameover1():
stdscr.addstr('游戏结束\n')
forrowinself.field2:
stdscr.addstr('+'+'-----+'*self.width+'\n')
stdscr.addstr("".join('{:^5}'.format(num)ifnum!=0else""fornuminrow)+''+'\n')
stdscr.addstr('+'+'-----+'*self.width+'\n')
ifself.is_win2():
stdscr.addstr('胜利\n')
ifself.is_gameover2():
stdscr.addstr('游戏结束\n')
stdscr.addstr("玩家1:上下左右键玩家2:wasd键(R)重置(Q)退出")
defis_win1(self):
returnmax(chain(*self.field1))>=self.win_value
defis_win2(self):
returnmax(chain(*self.field2))>=self.win_value
defis_gameover1(self):
returnnotany([self.is_move_possible1(direction)fordirectioninself.moves])
defis_gameover2(self):
returnnotany([self.is_move_possible2(direction)fordirectioninself.moves])
@staticmethod
definvert(field):
return[row[::-1]forrowinfield]
@staticmethod
deftranspose(field):
return[list(row)forrowinzip(*field)]
@staticmethod
defis_row_change(row):
foriinrange(len(row)-1):
ifrow[i]==0androw[i+1]!=0:
returnTrue
elifrow[i]!=0androw[i]==row[i+1]:
returnTrue
else:
returnFalse
defis_left_move(self,field):
returnany([self.is_row_change(i)foriinfield])
defis_right_move(self,field):
returnany([self.is_row_change(i)foriinself.invert(field)])
defis_up_move(self,field):
returnany([self.is_row_change(i)foriinself.transpose(field)])
defis_down_move(self,field):
returnany([self.is_row_change(i)foriinself.invert(self.transpose(field))])
defis_move_possible1(self,direction):
ifdirectioninself.moves:
returnself.moves[direction](self.field1)
else:
returnFalse
defis_move_possible2(self,direction):
ifdirectioninself.moves:
returnself.moves[direction](self.field2)
else:
returnFalse
@staticmethod
defrow_move(row):
row=sorted(row,key=lambdax:1ifx==0else0)
foriinrange(len(row)-1):
ifrow[i]==row[i+1]:
row[i]*=2
row[i+1]=0
returnsorted(row,key=lambdax:1ifx==0else0)
defleft_move(self,field):
return[self.row_move(i)foriinfield]
defright_move(self,field):
returnself.invert([self.row_move(i)foriinself.invert(field)])
defup_move(self,field):
returnself.transpose([self.row_move(i)foriinself.transpose(field)])
defdown_move(self,field):
returnself.transpose(self.invert([self.row_move(i)foriinself.invert(self.transpose(field))]))
defmove1(self,direction):
ifdirectioninself.movesDict1andself.is_move_possible1(direction):
self.field1=self.movesDict1[direction](self.field1)
self.random_create1()
returnTrue
else:
returnFalse
defmove2(self,direction):
ifdirectioninself.movesDict2andself.is_move_possible2(direction):
self.field2=self.movesDict2[direction](self.field2)
self.random_create2()
returnTrue
else:
returnFalse
defget_user_action(stdscr):
action=stdscr.getch()
ifaction==curses.KEY_UP:
return'Up1'
elifaction==curses.KEY_DOWN:
return'Down1'
elifaction==curses.KEY_LEFT:
return'Left1'
elifaction==curses.KEY_RIGHT:
return'Right1'
elifaction==ord('r'):
return'Restart'
elifaction==ord('q'):
return'Exit'
elifaction==ord('w'):
return'Up2'
elifaction==ord('s'):
return'Down2'
elifaction==ord('a'):
return'Left2'
elifaction==ord('d'):
return'Right2'
defmain(stdscr):
definit():
game_field.reset()
game_field.draw(stdscr)
return'Game'
defgame():
game_field.draw(stdscr)
action=get_user_action(stdscr)
ifaction=='Restart':
return'Init'
ifaction=='Exit':
return'Exit'
ifactionin('Up1','Down1','Left1','Right1'):
ifgame_field.move1(action):
ifgame_field.is_win1():
return'Win'
ifgame_field.is_gameover1():
return'GameOver'
ifactionin('Up2','Down2','Left2','Right2'):
ifgame_field.move2(action):
ifgame_field.is_win2():
return'Win'
ifgame_field.is_gameover2():
return'GameOver'
return'Game'
defnot_game():
game_field.draw(stdscr)
whileTrue:
action=get_user_action(stdscr)
ifaction=='Restart':
return'Init'
ifaction=='Exit':
return'Exit'
game_field=GameField()
state='Init'
state_actions={
'Init':init,
'Game':game,
'Win':not_game,
'GameOver':not_game
}
whilestate!='Exit':
state=state_actions[state]()
curses.wrapper(main)
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。