Use python to implement an unbounded 2048, python interface 2048

In the past, when the game was on fire for 2048, I was writing one program in other languages. Now I learned python and decided to use python to write a 2048 program. Since I have never learned Interface Programming in python, so I wrote an extremely simple non-interface 2048. The Principle and Implementation of game 2048 are not difficult. You can just use it to train your hands. If you don't know about the game, you can check it online or download it to your mobile phone, I will not talk about its principles. I know that if you don't want to show a picture, you will have no interest at all. Next, let's first put a game picture, and then let's talk about how to implement it step by step with the most basic knowledge.

1. Generate a 4*4 Matrix

The first step of the game is to generate a 4*4 matrix. As the main interface of our game, it is actually relatively simple. Here we use the most primitive method, print it directly with print. First, we need to generate a 4*4 two-dimensional list of all 0, and then use a list similar to 'zookeeper, Zookeeper, Zookeeper │, ──, principal, refer to the Code Implementation below.

Matix = [[0 for I in range (4)] for I in range (4)] # Use List derivation to generate a 4*4 list, the function 0 # notzero indicates that all list elements are displayed when the game interface is non-zero. If the function is 0, leave it blank. def notzero (s ): return s if s! = 0 else ''# Return itself if it is not zero; otherwise, return ''def display (): # display the interface function. Use the functions provided by ┌ ├, ┤, ┘ │,-, ┬, border, print ("\ r \ ── ┬ ── ┐ \ n \ │ % 4s │ % 4s │ % 4s │ % 4s │ % 4s │ \ n \ ├ ── ┬ ── ┤ \ n \ │ % 4s │ % 4s │ % 4s │ % 4s │ \ n \ ── ┬ ── ┤ \ n \ │ % 4s │ % 4s │ % 4s │ % 4s │ \ n \ ── ┬ ── ┤ \ n \ │ % 4s │ % 4s │ % 4s │ % 4s │ \ n \ ── ┴ ┘ "\ % (notzero (matix [0] [0]), notzero (matix [0] [1]), notzero (matix [0] [2]), notzero (matix [0] [3]), \ notzero (matix [1] [0]), notzero (matix [1] [1]), notzero (matix [1] [2]), notzero (matix [1] [3]), \ notzero (matix [2] [0]), notzero (matix [2] [1]), notzero (matix [2] [2]), notzero (matix [2] [3]), \ notzero (matix [3] [0]), notzero (matix [3] [1]), notzero (matix [3] [2]), notzero (matix [3] [3]),) display ()

Let's take a look at the effect of the code above. Does it feel like a game framework is ready? Because the matrix elements are all zero during initialization, the following figure does not show 0. Is it very simple, we have built a game interface, but we have never learned the interface, so don't complain about how ugly the interface is.

Ii. generate random numbers during initialization

At the beginning of each game, two random numbers 2 or 4 are randomly generated in the previous matrix, so how can we implement the random number 2 or 4 generated at a random position in the matrix above? Of course, the random module we learned earlier and divmod () are used (), next we will look at how to use the random module to implement a function.

Def init (): # initialization matrix initNumFlag = 0 while 1: k = 2 if random. randrange (0, 10)> 1 else 4 # k = 2 when the random number is generated greater than 1; otherwise k = 4 generates 2 and 4 with a probability of s = divmod (random. randrange (0, 16), 4) # generate the subscript for Matrix initialization, for example, divmod (), s is) it can be used as the matrix subscript if matix [s [0] [s [1] = 0: # It is assigned only when its value is not 0, avoid duplicate matix [s [0] [s [1] = k initNumFlag + = 1 if initNumFlag = 2: # When initNumFlag = 2, the two random numbers in the matrix are generated, and the loop breakinit () display () is exited ()

Let's take a look at the effect of the above Code. Have two numbers already been generated at two random locations? If you have time to try it, you can see that each execution is, the positions on the matrix are different, and the numbers displayed each time are different. Because I set the probability of to, 2 is usually displayed, which is also the need of the game. Now, the matrix can be moved, and the game's functionality is half done.

Iii. Game logic implementation

If you have played this game, you will know that every time the game moves up and down, for example, when moving down, all the numbers will move down and hit the same number, A new number is generated, for example, 4 is generated when 2 and 2 are met, and a 2 or 4 is randomly generated at other positions, similarly, if 4 and 4 match, 8 will be generated until the 2048 Game is merged, and the number in the Matrix cannot be moved, that is, Game Over. Of course, if we play games on our mobile phones, we can slide all the numbers in one direction. But there is no interface, and the conditions are hard, therefore, you can only read the letters entered by the user from the console, and then read them one by one to determine where to move them. Therefore, we need to write four functions to process the user's upper, lower, and left movements respectively, let the next function process how to add a random number after a user moves each time. Next, write a pseudo code to explain the process.

Def addRandomNum (): # A number pass def moveDown () is generated randomly in the matrix after each move: # The Processing Function pass to move up

AddRandomNum () # After the mobile processing is completed, a number def moveLeft () is randomly generated: # The processing function to move to the left pass addRandomNum () def moveUp (): # The Processing Function pass addRandomNum () def moveRight (): # The Processing Function pass addRandomNum () def main (): while flag: # defines an endless loop, read user input continuously, and then make judgments to see where to move d = input ('(rows: w) (rows: s) (rows: a) (→: d), q (uit): ") if d = 'A': moveLeft () elif d = 's': moveDown () elif d = 'W ': moveUp () elif d = 'D': moveRight () elif d = 'q': break else: pass

The above is a piece of pseudo code for understanding. Let's take a look at how to implement a mobile processing function. Here is the most difficult part of the game, the entire game is basically implemented. Here I use the downward movement processing function as an example. Everything else is the same. When the user inputs the downward movement, all the numbers move downward, if the same number is matched, the square with a number moves toward the square without a number. Here we need to implement it in a loop. There are four columns, so there are four loops in the outermost layer, and each column needs to be processed cyclically. Let's take a look at how to implement it,

Def addRandomNum (): # It is the same as the random number generated during initialization. However, only a random number while 1: k = 2 if random is generated here. randrange (0, 10)> 1 else 4 s = divmod (random. randrange (0, 16), 4) if matix [s [0] [s [1] = 0: matix [s [0] [s [1] = k break display () # After the random number is added, the display function is called directly to display the game interface def moveDown (): # function for processing downward movement in range (4): # the outer layer processes four cycles, and the inner layer processes two and three loops, for j in range (3, 0,-1): for k in range (j-1,-1,-1 ): if matix [k] [I]> 0: # process two adjacent numbers starting from the lowest number. if matix [j] [I] = 0: matix [j] [I] = matix [k] [I] # If the number below is null, if the number above is not blank, move the number above to the number below matix [k] [I] = 0 elif matix [j] [I] = matix [k] [I]: # If the two adjacent numbers are equal, they are connected to and set the input value to zero, the number below is doubled. matix [j] [I] * = 2 matix [k] [I] = 0 break addRandomNum () # a random number is generated after the movement is completed.

After writing down the processing function, the moving function in other directions will also be the same. Just write it, and the most difficult part of the game will be completed here, it can be said that victory is just in sight. Well, before that, we still need to deal with other problems, that is, we need to check whether the Game is Over after every move, another is to define a variable to record scores. These implementations are relatively simple.

4. Record game scores and check whether the game is over

The ending sign of the game is that all numbers in the matrix are not 0, and all adjacent numbers cannot be merged. Based on this, we can write a function to determine whether the game is GG, as for the score record, we only need to define a variable and add a certain score each time when there is a sum. Let's take a look at the implementation of the function.

Def check (): for I in range (4): # loop 4 times in each row for j in range (3): # If 0 exists in the matrix, or if there is an adjacent number, the game can continue to work, otherwise, GG if matix [I] [j] = 0 or matix [I] [j] = matix [I] [j + 1] or matix [j] [I] = matix [j + 1] [I]: return True else: return False

V. Complete game source code

After completing the above part, the entire game process is implemented. The source code of the entire game is attached below. There are still many imperfections in the game. For example, if the game shows 2048, it means the player wins and the game ends, but I have not done anything here, so this game can play until 4096 .... it's not over. Unless you have GG in the game, it's easy to process. You can also store the matrix in a file to complete the game archiving function. If you are interested, implement it.

Import randomscore = 0 # record the game's score matix = [[0 for I in range (4)] for I in range (4)] # initialize and generate a 4*4 List def notzero (s): return s if s! = 0 else ''def display (): print ("\ r \ ── ┬ ┐ \ n \ │ % 4s │ % 4s │ % 4s │ % 4s │ \ n \ ── ┬ ── ── ┤ \ n \ │ % 4s │ % 4s │ % 4s │ % 4s │ \ n \ ── ┬ ┤ \ n \ │ % 4s │ % 4s │ % 4s │ % 4s │ \ n \ ── ┬ ── ┤ \ n \ │ % 4s │ % 4s │ % 4s │ % 4s │ \ n \ ── ── ┴ ┘ "\ % (notzero (matix [0] [0]), notzero (matix [0] [1]), notzero (matix [0] [2]), notzero (matix [0] [3]), \ notzero (matix [1] [0]), notzero (matix [1] [1]), notzero (matix [1] [2]), notzero (matix [1] [3]), \ notzero (mati X [2] [0]), notzero (matix [2] [1]), notzero (matix [2] [2]), notzero (matix [2] [3]), \ notzero (matix [3] [0]), notzero (matix [3] [1]), notzero (matix [3] [2]), notzero (matix [3] [3]),) def init (): # initialization matrix initNumFlag = 0 while 1: k = 2 if random. randrange (0, 10)> 1 else 4 # randomly generate 2 or 4 s = divmod (random. randrange (0, 16), 4) # generate the subscript for Matrix initialization if matix [s [0] [s [1] = 0: # assign a value only when the value is not 0. Avoid the second value repeating matix [s [0] [s [1] = k ini TNumFlag + = 1 if initNumFlag = 2: break display () def addRandomNum (): # Add a random number after processing the movement while 1: k = 2 if random. randrange (0, 10)> 1 else 4 s = divmod (random. randrange (0, 16), 4) if matix [s [0] [s [1] = 0: matix [s [0] [s [1] = k break display () def check (): # check whether the game GG for I in range (4 ): for j in range (3 ): if matix [I] [j] = 0 or matix [I] [j] = matix [I] [j + 1] or matix [j] [I] = matix [j + 1] [I]: return True else: return Falsedef moveRight (): # global score for I in range (4): for j in range (3, 0,-1 ): for k in range (j-1,-1,-1): if matix [I] [k]> 0: if matix [I] [j] = 0: matix [I] [j] = matix [I] [k] matix [I] [k] = 0 elif matix [I] [j] = matix [I] [k ]: matix [I] [j] * = 2 score + = matix [I] [j] # Add the current number as the score plus matix [I] [k] = 0 break addRandomNum () def moveUp (): global score for I in range (4): for j in Range (3): for k in range (j + 1, 4): if matix [k] [I]> 0: if matix [j] [I] = 0: matix [j] [I] = matix [k] [I] matix [k] [I] = 0 elif matix [k] [I] = matix [j] [I ]: matix [j] [I] * = 2 score + = matix [j] [I] matix [k] [I] = 0 break addRandomNum () def moveDown (): global score for I in range (4): for j in range (3, 0,-1): for k in range (j-1,-1,-1 ): if matix [k] [I]> 0: if matix [j] [I] = 0: matix [j] [I] = matix [k] [I] ma Tix [k] [I] = 0 elif matix [j] [I] = matix [k] [I]: matix [j] [I] * = 2 score + = matix [j] [I] matix [k] [I] = 0 break addRandomNum () def moveLeft (): global score for I in range (4): for j in range (3): for k in range (1 + j, 4 ): if matix [I] [k]> 0: if matix [I] [j] = 0: matix [I] [j] = matix [I] [k] matix [I] [k] = 0 elif matix [I] [j] = matix [I] [k ]: matix [I] [j] * = 2 score + = matix [I] [j] matix [I] [k] = 0 break addRandomN Um () def main (): print ("\ 033 [33; 1 mWelcome to the Game of 2048! \ 033 [0 m ") flag = True init () while flag: # print ('\ 033 [33; 1 m You Score: % s \ 033 [0m' % (score) d = input ('\ 033 [33; 1 m (cost: w) (cost: s) (cost:) (→: d), q (uit): \ 033 [0m') # process user input continuously if d = 'A': moveLeft () if not check (): # check whether the game has GG print ('gg ') flag = False # directly exit elif d = 's': moveDown () if not check () if GG (): print ('gg ') flag = False elif d = 'W': moveUp () if not check (): print ('gg ') flag = False elif d = 'D': moveRight () if not check (): print ('gg ') flag = False elif d = 'q ': # exit break else: # Do not process other user input passif _ name _ = '_ main _': main ()

Finally, the end of the attached image is