1. Introduction2048 this period of time is not good, and everyone has made a series of copies, "a hundred schools of contention", so there are various technical versions: apart from the mobile phone version, there are also C, Qt, Web, java, C #, and so on. I just got in touch with Python, so I got a Python version-2048 of the console, just familiar with the Python syntax, the program running effect is as follows:
Figure 1 Python version console 2048 running
There are about 150 lines of comments added to the program code. Some Python built-in data types are used to save a lot of code. Next, let's talk about my writing ideas. At last, we will provide the source code.
2. 2048 Implementation ideas
2.1 game rulesThis game is very playable. The simple move arrow keys overlay the numbers and get the scores after each superposition of these numbers. When the number 2048 is displayed, the game wins. At the same time, a number 2 or 4 will be randomly generated in the blank area of the 4*4 square matrix each time you move the direction key. If the square is filled with numbers, then GameOver will be generated.
2.2 Implementation ideasAll the operations of this game are centered around a 4*4 matrix. Each time a user's operations (that is, moving direction) are obtained from the user interface ), then re-calculate the status of the 4*4 matrix, and refresh the user interface to display the latest status of the 4*4 matrix. This process continues until 2048 or no blank blocks appear, the following is a process:
I wrote A console program without A UI. Therefore, the character (W/S/A/D) is used to represent the arrow key input, and the number 0 represents the blank square. Next is the computing part. Taking moving to the left as an example, after receiving the instruction to move to the left, the 4*4 matrix should overlay the numbers in each row to the left, defines a row overlay operation as the function handle (list, direction). The first parameter is used to store a row (column) in the 4*4 matrix ), the second parameter indicates the moving direction (up, down, and left ).
In this way, when you move the arrow keys left and right, you can calculate the matrix as follows: traverse each row of the matrix and overlay the numbers of each row along the left or right. For row in matrix: handle (row, direction)
When the arrow keys are moved up and down, because the matrix is stored by row, you cannot directly process columns in the Matrix. You can use the preceding function handle () as a work und (). For each column in The Matrix, copy it to a list, and then call the handle () function to overlay the list, finally, copy the new overlay list back to the column in the original matrix, which is logically equivalent to the following code operations. For col in matrix: handle (col, direction)
The handle (row, direction) function overlays numbers in a row in the specified direction. See the following examples:
Direction of movement |
Before moving |
After moving |
Handle (x, 'left ') |
X = [0, 2, 2, 2] |
X = [4, 2, 0, 0] |
Handle (x, 'left ') |
X = [2, 4, 2, 2] |
X = [2, 8, 0, 0] |
Handle (x, 'right ') |
X = [2, 4, 2, 2] |
X = [0, 0, 2, 8] |
Implement the handle (row, direction) Function
According to the above introduction, implementing the handle function is the key. The process of superposition is composed of two sub-processes: (1)
Align (row, direction)Align the numbers in the row in the list along the direction, for example, after x = [0, 4, 0, 2] align (x, 'left') x = [4, 2, 0, 0] After align (x, 'right') x = [0, 0, 4, 2]
(2)
AddSame (row, direction)Search
Same and adjacent. If one of them is found, double and the other is set to 0 (if the direction is 'left', double the left and 0 on the right. If the direction is 'right', double the right, 0 on the left), and returns True; otherwise, False. For example, after x = [2, 2, 2] addSame (x, 'left') and x = [4, 0, 2, 2] returns True and then addSame (x, after 'left') x = [4, 0, 4, 0] returns True and then addSame (x, 'left') after x = [4, 0, 4, 0] False
With the above two subfunctions, it is not difficult to implement them. With these two subfunctions, the handle () function is well implemented, as follows: handle (row, direction): align (row, direction) result = addSame (row, direction) while result = True: align (row, direction) result = addSame (row, direction)
Next, let's take a look at the processing process of the handle function based on an actual example: x = [2, 4, 2, 2] calls handle (x, 'right'), and variable x changes: align (x, 'right')-> [2, 4, 2, 2] addSame (x, 'right')-> [2, 4, 0, 4]-> return Truealign (x, 'right')-> [0, 2, 4, 4] addSame (x, 'right')-> [0, 2, 0, 8]-> return Truealign (x, 'right')-> [0, 0, 2, 8] addSame (x, 'right')-> [0, 0, 2, 8]-> return False the final result is x = [0, 0, 2, 8]. The most important part has been completed. I will post the code below, because there are not many codes, paste them directly.
3. Code
These are all the code and can be run in a single file. The runtime environment is Python3.0 +
#-*-Coding: UTF-8 -*-#! /Usr/bin/python3import randomv = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0], [0, 0, 0, 0] def display (v, score ): '''display interface ''' print }'. format (v [0] [0], v [0] [1], v [0] [2], v [0] [3]) print }'. format (v [1] [0], v [1] [1], v [1] [2], v [1] [3]) print }'. format (v [2] [0], v [2] [1], v [2] [2], v [2] [3]) print }'. format (v [3] [0], V [3] [1], v [3] [2], v [3] [3]), 'total score: ', score) def init (v ): '''randomly distributed grid value' ''for I in range (4): v [I] = [random. choice ([0, 0, 0, 2, 2, 4]) for x in v [I] def align (vList, direction ): ''' alignment a non-zero number ction = 'left': Align to the left. For example, [,] After the left alignment, [,] direction = 'right ': right alignment, for example, [,] After right alignment [,] ''' # Remove 0 for I in range (vList. count (0): vList. remove (0) #0 zeros = [0 for x in range (4-len (VList)] # Add 0 if ction = 'left' to the side of a non-0 Number: vList. extend (zeros) else: vList [: 0] = zeros def addSame (vList, direction): ''' Add the same and adjacent numbers in the list, returns True if the condition is met. Otherwise, returns False. Also, returns the added score direction = 'left': right-to-left lookup to find the same and adjacent two numbers, double the number on the left, and set 0 ction = 'right' to the right. Search for the two numbers that are the same and adjacent to the right, and double the number on the right, 0 ''' score = 0 if direction = 'left': for I in [0, 1, 2]: if vList [I] = vList [I + 1]! = 0: vList [I] * = 2 vList [I + 1] = 0 score + = vList [I] return {'bool ': True, 'score ': score} else: for I in [3, 2, 1]: if vList [I] = vList [I-1]! = 0: vList [I-1] * = 2 vList [I] = 0 score + = vList [I-1] return {'bool ': True, 'score ': score} return {'bool ': False, 'score': score} def handle (vList, direction): ''' processes data in a row (column, obtain the numeric status value of the final row (column), and return the score vList: List structure, which stores the data direction in a row (column): moving direction, use 'left' in both the upward and left directions, and 'right' in both the right and downward directions. ''totalscore = 0 align (vList, direction) result = addSame (vList, direction) while result ['bool '] = True: totalScore + = result ['sco Re '] align (vList, direction) result = addSame (vList, direction) return totalScore def operation (v): ''' recalculates the matrix state value based on the moving direction, and record the score ''' totalScore = 0 gameOver = False ction = 'left' op = input ('operator: ') if op in ['A', 'a']: # Move ction = 'left' for row in range (4): totalScore + = handle (v [row], direction) elif op in ['D ', 'D']: # Move ction = 'right' for row in range (4): totalScore + = han Dle (v [row], direction) elif op in ['w', 'w']: # Move up direction = 'left' for col in range (4 ): # copy a column in the Matrix to a list. After that, vList = [v [row] [col] for row in range (4)] totalScore + = handle (vList, direction) # overwrite the value in the original matrix for row in range (4) from the number in the processed list ): v [row] [col] = vList [row] elif op in ['s ','s']: # Move down direction = 'right' for col in range (4): # Same as vList = [v [row] [col] for row in range (4)] totalScore + = hand Le (vList, direction) for row in range (4): v [row] [col] = vList [row] else: print ('invalid input, please enter a charactor in [W, S, A, D] or the lower ') return {'gameover': gameOver, 'score ': totalScore} # count the number of blank areas N = 0 for q in v: N + = q. count (0) # if the remaining blank area does not exist, the game ends if N = 0: gameOver = True return {'gameover': gameOver, 'score ': totalScore} # the probability of occurrence of 2 and 4 is 3/1 to generate random numbers 2 and 4 num = random. choice ([2, 2, 2, 4]) # Generate a random number k. The 2 or 4 generated in the previous step will be filled in the k blank area k = random. randrange (1, N + 1) n = 0 for I in range (4): for j in range (4): if v [I] [j] = 0: n + = 1 if n = k: v [I] [j] = num break return {'gameover': gameOver, 'score ': totalScore} init (v) score = 0 print ('input: W (Up) S (Down) A (Left) D (Right), press <CR>. ') while True: display (v, score) result = operation (v) if result ['gameover'] = True: print ('game Over, You failed! ') Print ('your total score:', score) else: score + = result ['score '] if score> = 2048: print ('game Over, you Win !!! ') Print ('your total score:', score)