国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 一步步教你用Python實現2048小游戲

一步步教你用Python實現2048小游戲

2020-09-18 10:36HustWolf Python

相信2048這個游戲對大家來說一定不陌生,下面這篇文章就主要給大家介紹了怎么用Python實現2048小游戲,文中通過注釋與示例代碼介紹的很詳細,相信對大家的理解和學習具有一定的參考借鑒價值,有需要的朋友們一起來看看吧。

前言

2048游戲規則:簡單的移動方向鍵讓數字疊加,并且獲得這些數字每次疊加后的得分,當出現2048這個數字時游戲勝利。同時每次移動方向鍵時,都會在這個4*4的方格矩陣的空白區域隨機產生一個數字2或者4,如果方格被數字填滿了,那么就GameOver了。

主邏輯圖

一步步教你用Python實現2048小游戲

邏輯圖解:黑色是邏輯層,藍色是外部方法,紅色是類內方法,稍后即可知道~

一步步教你用Python實現2048小游戲

下面容我逐行解釋主邏輯main()函數,并且在其中穿叉外部定義的函數與類。

主邏輯代碼解讀(完整代碼見文末)

主邏輯main如下,之后的是對主函數中的一些方法的解讀:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def main(stdscr):
 def init():
 #重置游戲棋盤
 game_field.reset()
 return 'Game'
 
 def not_game(state):
 #畫出 GameOver 或者 Win 的界面
 game_field.draw(stdscr)
 #讀取用戶輸入得到action,判斷是重啟游戲還是結束游戲
 action = get_user_action(stdscr)
 responses = defaultdict(lambda: state) #默認是當前狀態,沒有行為就會一直在當前界面循環
 responses['Restart'], responses['Exit'] = 'Init', 'Exit' #對應不同的行為轉換到不同的狀態
 return responses[action]
 
 def game():
 #畫出當前棋盤狀態
 game_field.draw(stdscr)
 #讀取用戶輸入得到action
 action = get_user_action(stdscr)
 
 if action == 'Restart':
  return 'Init'
 if action == 'Exit':
  return 'Exit'
 if game_field.move(action): # move successful
  if game_field.is_win():
  return 'Win'
  if game_field.is_gameover():
  return 'Gameover'
 return 'Game'
 
 
 state_actions = {
  'Init': init,
  'Win': lambda: not_game('Win'),
  'Gameover': lambda: not_game('Gameover'),
  'Game': game
 }
 
 curses.use_default_colors()
 game_field = GameField(win=32)
 
 state = 'Init'
 
 #狀態機開始循環
 while state != 'Exit':
 state = state_actions[state]()

逐條解讀(代碼框內會標注是來自外部,無標注則是來自內部):定義主函數

?
1
def main(stdscr):
?
1
2
3
def init():
#重置游戲棋盤
game_field.reset()

reset出自外部定義的類,game_field=GameField的一個方法reset:

  外部:

?
1
2
3
4
5
6
7
8
def reset(self):
 if self.score > self.highscore:
  self.highscore = self.score
 self.score = 0
 self.field = [[0 for i in range(self.width)] for j in range(self.height)]
 self.spawn()
 self.spawn()
#其中highscore為程序初始化過程中定義的一個變量。記錄你win游戲的最高分數記錄。
?
1
return 'Game'

返回一個游戲進行中的狀態。game_field=GameField狀態在后面有定義:

主函數底部定義:

?
1
2
3
4
5
6
state_actions = {
 'Init': init,
 'Win': lambda: not_game('Win'),
 'Gameover': lambda: not_game('Gameover'),
 'Game': game
}
?
1
2
3
def not_game(state):
#畫出 GameOver 或者 Win 的界面
game_field.draw(stdscr)

draw是導入的類game_field=GameField中的方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#來自外部類
 def draw(self, screen):
 help_string1 = '(W)Up (S)Down (A)Left (D)Right'
 help_string2 = ' (R)Restart (Q)Exit'
 gameover_string = '  GAME OVER'
 win_string = '  YOU WIN!'
#定義各個字符串
 def cast(string):
  screen.addstr(string + '\n')
 
 def draw_hor_separator():
  line = '+' + ('+------' * self.width + '+')[1:]
  separator = defaultdict(lambda: line)
  if not hasattr(draw_hor_separator, "counter"):
  draw_hor_separator.counter = 0
  cast(separator[draw_hor_separator.counter])
  draw_hor_separator.counter += 1
 
 def draw_row(row):
  cast(''.join('|{: ^5} '.format(num) if num > 0 else '| ' for num in row) + '|')
 
 screen.clear()
 cast('SCORE: ' + str(self.score))
 if 0 != self.highscore:
  cast('HGHSCORE: ' + str(self.highscore))
 for row in self.field:
  draw_hor_separator()
  draw_row(row)
 draw_hor_separator()
 if self.is_win():
  cast(win_string)
 else:
  if self.is_gameover():
  cast(gameover_string)
  else:
  cast(help_string1)
 cast(help_string2)
#這里面的draw方法的字函數我就不做多的解釋了,很簡單的一些概念。
#但是又運用到了很優秀的精簡代碼。
#有的地方建議去查一下python的一些高級概念,我就不做多的介紹了。

這里面的draw方法的字函數我就不做多的解釋了,很簡單的一些概念。

但是又運用到了很優秀的精簡代碼。

有的地方建議去查一下python的一些高級概念,我就不做多的介紹了。

?
1
2
#讀取用戶輸入得到action,判斷是重啟游戲還是結束游戲
action = get_user_action(stdscr)

讀取用戶行為,函數來自于代碼初始的定義

?
1
2
3
4
5
6
#來自外部定義的函數
def get_user_action(keyboard):
 char = "N"
 while char not in actions_dict:
 char = keyboard.getch()
 return actions_dict[char]

在結尾處,也即是主函數執行的第三步,定義了state = state_actions[state]()這一實例:

?
1
2
3
4
5
6
#主函數底部:
 state = 'Init'
 
 #狀態機開始循環
 while state != 'Exit':
 state = state_actions[state]()
?
1
2
3
responses = defaultdict(lambda: state) #默認是當前狀態,沒有行為就會一直在當前界面循環
responses['Restart'], responses['Exit'] = 'Init', 'Exit' #對應不同的行為轉換到不同的狀態
return responses[action]
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def game():
 #畫出當前棋盤狀態
 game_field.draw(stdscr)
 #讀取用戶輸入得到action
 action = get_user_action(stdscr)
 
 if action == 'Restart':
  return 'Init'
 if action == 'Exit':
  return 'Exit'
 if game_field.move(action): # move successful
  if game_field.is_win():
  return 'Win'
  if game_field.is_gameover():
  return 'Gameover'
 return 'Game'
#game()函數的定義類似于上面已經講過的not_game(),只是game()有了內部循環
#即如果不是Restart/Exit或者對move之后的狀態進行判斷,如果不是結束游戲,就一直在game()內部循環。

game()函數的定義類似于上面已經講過的not_game() ,只是game()有了內部循環,即如果不是Restart/Exit或者對move之后的狀態進行判斷,如果不是結束游戲,就一直在game()內部循環。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
state_actions = {
  'Init': init,
  'Win': lambda: not_game('Win'),
  'Gameover': lambda: not_game('Gameover'),
  'Game': game
   }
 
 curses.use_default_colors()
 game_field = GameField(win=32)
 
 
 state = 'Init'
 
 #狀態機開始循環
 while state != 'Exit':
 state = state_actions[state]()
#此處的意思是:state=state_actions[state] 可以看做是:
#state=init()或者state=not_game(‘Win')或者是另外的not_game(‘Gameover')/game()

此處的意思是:state=state_actions[state] 可以看做是:state=init()或者state=not_game(‘Win')或者是另外的not_game(‘Gameover')/game()

廢話不多說,上一個我的成功的圖,另外,可以通過設置最后幾行中的win=32來決定你最終獲勝的條件!

一步步教你用Python實現2048小游戲

完整代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#-*- coding:utf-8 -*-
import curses
from random import randrange, choice # generate and place new tile
from collections import defaultdict
letter_codes = [ord(ch) for ch in 'WASDRQwasdrq']
actions = ['Up', 'Left', 'Down', 'Right', 'Restart', 'Exit']
actions_dict = dict(zip(letter_codes, actions * 2))
def transpose(field):
 return [list(row) for row in zip(*field)]
 
def invert(field):
 return [row[::-1] for row in field]
 
class GameField(object):
 def __init__(self, height=4, width=4, win=2048):
 self.height = height
 self.width = width
 self.win_value = win
 self.score = 0
 self.highscore = 0
 self.reset()
 
 def reset(self):
 if self.score > self.highscore:
  self.highscore = self.score
 self.score = 0
 self.field = [[0 for i in range(self.width)] for j in range(self.height)]
 self.spawn()
 self.spawn()
 
 def move(self, direction):
 def move_row_left(row):
  def tighten(row): # squeese non-zero elements together
  new_row = [i for i in row if i != 0]
  new_row += [0 for i in range(len(row) - len(new_row))]
  return new_row
 
  def merge(row):
  pair = False
  new_row = []
  for i in range(len(row)):
   if pair:
   new_row.append(2 * row[i])
   self.score += 2 * row[i]
   pair = False
   else:
   if i + 1 < len(row) and row[i] == row[i + 1]:
    pair = True
    new_row.append(0)
   else:
    new_row.append(row[i])
  assert len(new_row) == len(row)
  return new_row
  return tighten(merge(tighten(row)))
 
 moves = {}
 moves['Left'] = lambda field:    \
  [move_row_left(row) for row in field]
 moves['Right'] = lambda field:    \
  invert(moves['Left'](invert(field)))
 moves['Up'] = lambda field:    \
  transpose(moves['Left'](transpose(field)))
 moves['Down'] = lambda field:    \
  transpose(moves['Right'](transpose(field)))
 
 if direction in moves:
  if self.move_is_possible(direction):
  self.field = moves[direction](self.field)
  self.spawn()
  return True
  else:
  return False
 
 def is_win(self):
 return any(any(i >= self.win_value for i in row) for row in self.field)
 
 def is_gameover(self):
 return not any(self.move_is_possible(move) for move in actions)
 
 def draw(self, screen):
 help_string1 = '(W)Up (S)Down (A)Left (D)Right'
 help_string2 = ' (R)Restart (Q)Exit'
 gameover_string = '  GAME OVER'
 win_string = '  YOU WIN!'
 def cast(string):
  screen.addstr(string + '\n')
 
 def draw_hor_separator():
  line = '+' + ('+------' * self.width + '+')[1:]
  separator = defaultdict(lambda: line)
  if not hasattr(draw_hor_separator, "counter"):
  draw_hor_separator.counter = 0
  cast(separator[draw_hor_separator.counter])
  draw_hor_separator.counter += 1
 
 def draw_row(row):
  cast(''.join('|{: ^5} '.format(num) if num > 0 else '| ' for num in row) + '|')
 
 screen.clear()
 cast('SCORE: ' + str(self.score))
 if 0 != self.highscore:
  cast('HGHSCORE: ' + str(self.highscore))
 for row in self.field:
  draw_hor_separator()
  draw_row(row)
 draw_hor_separator()
 if self.is_win():
  cast(win_string)
 else:
  if self.is_gameover():
  cast(gameover_string)
  else:
  cast(help_string1)
 cast(help_string2)
 
 def spawn(self):
 new_element = 4 if randrange(100) > 89 else 2
 (i,j) = choice([(i,j) for i in range(self.width) for j in range(self.height) if self.field[i][j] == 0])
 self.field[i][j] = new_element
 
 def move_is_possible(self, direction):
 def row_is_left_movable(row):
  def change(i): # true if there'll be change in i-th tile
  if row[i] == 0 and row[i + 1] != 0: # Move
   return True
  if row[i] != 0 and row[i + 1] == row[i]: # Merge
   return True
  return False
  return any(change(i) for i in range(len(row) - 1))
 
 check = {}
 check['Left'] = lambda field:    \
  any(row_is_left_movable(row) for row in field)
 
 check['Right'] = lambda field:    \
   check['Left'](invert(field))
 
 check['Up'] = lambda field:    \
  check['Left'](transpose(field))
 
 check['Down'] = lambda field:    \
  check['Right'](transpose(field))
 
 if direction in check:
  return check[direction](self.field)
 else:
  return False
def main(stdscr):
 def init():
 #重置游戲棋盤
 game_field.reset()
 return 'Game'
 def not_game(state):
 #畫出 GameOver 或者 Win 的界面
 game_field.draw(stdscr)
 #讀取用戶輸入得到action,判斷是重啟游戲還是結束游戲
 action = get_user_action(stdscr)
 responses = defaultdict(lambda: state) #默認是當前狀態,沒有行為就會一直在當前界面循環
 responses['Restart'], responses['Exit'] = 'Init', 'Exit' #對應不同的行為轉換到不同的狀態
 return responses[action]
 
 def game():
 #畫出當前棋盤狀態
 game_field.draw(stdscr)
 #讀取用戶輸入得到action
 action = get_user_action(stdscr)
 
 if action == 'Restart':
  return 'Init'
 if action == 'Exit':
  return 'Exit'
 if game_field.move(action): # move successful
  if game_field.is_win():
  return 'Win'
  if game_field.is_gameover():
  return 'Gameover'
 return 'Game'
 
 
 state_actions = {
  'Init': init,
  'Win': lambda: not_game('Win'),
  'Gameover': lambda: not_game('Gameover'),
  'Game': game
 }
 curses.use_default_colors()
 game_field = GameField(win=32)
 state = 'Init'
 #狀態機開始循環
 while state != 'Exit':
 state = state_actions[state]()
curses.wrapper(main)

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

原文鏈接:http://www.jianshu.com/p/7a3a7545d2fb

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 黄色网页大全 | 午夜久久久 | 欧美国产日韩精品 | 国产一区二区三区免费观看 | 日韩在线观看第一页 | 国产欧美日韩在线 | 国产精品免费在线 | 亚洲毛片网站 | 综合视频一区 | 免费观看黄色 | 国产91亚洲精品 | 日韩一区在线播放 | 一区二区不卡视频 | 久久99精品久久久久婷婷暖91 | 国产精品对白一区二区三区 | 91免费看网站 | 一级黄色片看看 | 亚洲 自拍 另类 欧美 丝袜 | 天堂一区二区三区 | 免费的av电影| 国产片性视频免费播放 | 国内免费自拍视频 | 亚洲国产精品久久久久 | 夜夜夜操 | 久在线视频 | 日本久久久久久 | 蜜臀网| 久久精品国语 | 成人一区二区在线 | 欧美一级在线观看 | 亚洲免费视频一区二区 | 欧美视频一区二区三区 | 久久精品亚洲 | 亚洲骚片 | 精品一区二区久久 | 91亚洲国产精品 | 一级做a爰片性色毛片2021 | 亚洲精品一区二区三区樱花 | 国产精品久久久久国产a级 成人a在线视频 | 免费看黄在线网站 | 欧美成人免费在线 |