Objective
These two days on the internet to see a picture of the rise in posture, the picture shows the snake game, estimated that most people have played. But if it is just a snake game, then there is no place for people to pose. The crux of the problem is that the image of the snake is really greedy xd, it is the appearance of the rectangle in the food to eat it all over, and then gorgeous to fill the whole rectangle, it is really pleasing to see. As a cser, the first thing that comes to mind is that it's written in a program (because the average person can't do it.) Decisive is to get the program to dry) The second thought is, how to write a program, what algorithm? Now that you think about it, start doing it. Because talk is cheap, show me the code. (learned from Uncle Rat)
Before we begin, let's take a look at the one-man-pose snake: (You can right-click to view it if the following dynamic picture is not working well)
Snake_ai
Language selection
Life was short, use python! So, just don't think about it, go straight to Python.
Original version
Let your program run first.
First of all, the first thing we need to do is not to analyze the problem first. You can start by writing a snake game that works, and then think about the AI section. This should be very simple, c\c++ also hundred line code (if I remember correctly.) Without complicated interfaces, running directly under the console, Python is much simpler, removing comments and blank lines, and 5, 60 lines of code are done. And, most critical of all, this thing on the Internet must be excessive, you do not have to repeat the wheel, to get a copy to follow your wishes to change the line.
Simple version
I think it's not a good way to write the perfect version directly. Because perfect version often have to consider a lot of things, straight up to write this is generally a bug. So, at first, my goal was simply to get the program to control the snake movement and let it eat food, that's all. Now let us state the initial question:
In a rectangle, every moment there is a food, the snake will not bump into their own conditions,
Find a way (not necessarily optimal), then run along this road to enjoy its food
Let's not think of the fact that snakes will grow longer. The problem is basically to give you a starting point (a snake head) and an end point (food), to avoid obstacles (snakes), to find a feasible way to reach the end point from the beginning. The methods we can use are:
BFS
Dfs
A *
As long as there is a choice, we first choose the simplest solution, our goal now is to let the program run first, optimization is something. So, start with BFS. We initially put the snake head position in the queue, and then as long as the queue is not empty, the team head position out of the team, and then put it four areas of the 4 points in the queue, continue to cycle operations until the location of food. In this process, we need to note several points: 1. The visited point is no longer accessible. 2. Save the parent node of each point (that is, where each location comes to it so that we can find the feasible path). 3. The location of the snake body and the four walls are inaccessible.
After finding food through BFS, just let the snake move along the feasible path. Once this simple version is finished, the snake can run happily for a while. Look at the picture: (Not smooth feeling from the recording screen software @_@)
To keep it as simple as possible, I used the curses module to draw directly at the terminal. From the above dynamic picture can be seen, each time the use of BFS, and eventually one day, the snake will be because of this reckless short-sighted behavior into trouble. Moreover, even at that time, it will only BFS a strategy, resulting from the current sight of the target (food), think that their life is so, broken broken falls, eventually stop at a point in its life, no longer forward. (I love to talk philosophy xd)
Bfs+wander
The simple version of the previous section after running, we realized that it is not possible to teach only the snake a strategy. It's so stupid a snake, you don't teach it a little more, it will be dead in minutes. So, I wrote a wander function, as the name implies, when the snake into a difficult situation, don't let it again BFS, but let it casually walk around, distraction, think about life or something. This is like when you are confused and confused when you go to work, inefficient not to say, but also may hinder you out of trouble, on the contrary, if you put down the work, stop, go out and travel a trip or something. Come back, perhaps the enlightened, land groud, houses like.
Wander function How to write all right, but there must be good and bad points. I wrote two versions, one of which is a random step in a random direction, within a workable range. In other words, the direction of each movement of the snake is random, the total number of moving steps is also random. After wander, go to BFS again, see if you can eat food, if it is happy. If not, the time to think about life is not enough, and then wander a bit. This process continues to circulate. But just like random process random, you "randomly wander random". Snakes that can wander can do a lot more walking. But one day, it will be a random to the death of the road. Get into trouble can also wander, into a dead end, there is no rollback mechanism. So, the second version of the Wander function, I let the greedy snake greedy to the end. After the BFS has no solution, tell the snake to step step (randomly generated step), so that it moves in the white space in the S-shaped movement step. This time the direction of movement is not random, but organized and disciplined movement. Look at the picture first, and then say its question again:
Yes, and it ended up hanging out. The S-shape movement is also unable to let the snake avoid the fate of death. The snake can survive for a long time by the S-shaped movement, but because of its strategy is:
The problem was that the snake found its own path between itself and the food, and apart ran to eat food. It does not take into account that the situation (the body layout) that you have eaten after you eat the food, is completely likely to let you hang out. (such as entering a small, enclosed space in which the snake is surrounded)
So, in order to make snakes live longer, it has to be more visionary.
Visionary version
We now have a relatively low-end version and a little bit more insight into the problem. It is now possible to carry out some more rigorous and careful analysis. First, let's list some questions: (like brainstorming, write down what you think)
It is not advisable to have a path between the snake and the food to eat directly. What should I do then?
If the snake goes to eat food, the layout is safe, whether to eat directly? (Is this optimal?) )
How to define the layout is safe?
What if there is no path between the snake and the food?
is the shortest path optimal? (This is obviously not a)
So, if the layout is safe, is the shortest path optimal?
In addition to the shortest path, how can we go? S shape? The longest?
How to deal with the problem of the snake body getting longer?
Food is randomly present, is there any possibility of a solution-free layout?
Can the Violence Act (brute force) get the optimal sequence? (Allow the snake to eat as much food as possible)
As long as you think, there are a lot of problems. At this time let us take the process-oriented thinking, with the above questions, the idea of a rationale. At first, the snake was very short (the initialization length was 1), and it saw a food, using BFS to get the shortest path length for each position in the rectangle to reach the food. In the absence of a snake, it is the distance from Manhattan. Then, I have to judge first, whether the snake is safe to go. So I need a virtual snake, and it's always going to go to scout. If it's safe, let the real snake run. Of course, the virtual snake will not be drawn out, it is only responsible for simulating the pathfinder. So, how is it safe to define a layout? If you take a look at the snake's ecstasy in the animated picture at the beginning of the article, you will find that even the last snake has been a long time, it is still OK to walk out of the way generally. And it was followed by the tail of the snake! Well, this is not difficult to explain, the snake in the process of movement, the consumption of snake body, the tail of the snake is always constantly emerging new space. When the snake is short, it does not matter, when the snake long, you will find that to survive, the basic can only chase the tail of the snake run. In the process of chasing the tail of the snake, then consider whether it is safe to eat food. (is a certain time after the BFS, a layout, 0 for food, the number for the location to reach the food distance, + number for the snake head, * number represents the snake body,-the tail of the snake, #号代表空格, the outside of the ring # represents the fence)
Through the above analysis, we can define whether the layout is safe as the snake can follow the tail movement, that is, the snake after eating food, snake head and the tail of the snake there is a path, if there is, I think it is safe.
OK, go ahead. The real snake sent a virtual snake to find out after eating food layout is safe. Then the real snake went straight to the food. Wait, is this a good strategy? Not necessarily. Because the snake moves every step, the layout changes once. A change in layout means there may be a better solution. For example, because the tail of the consumption of the original need to take a detour to eat food, suddenly appeared in the eyes of the snake. So, the real snake after a step, a better approach is to re-do BFS. Then make the same security judgment as above and then go.
Let's consider what to do if there is no path between the snake and the food. In fact, the above has already mentioned the practice, followed by the tail of the snake walk. As long as there is no path between the snake and the food, the snake follows the tail of the snake. Similarly, because each step of the layout will change, so every step to re-do BFS to get the latest layout.
Okay, here's the problem again. What if there is no path between the snake and the food and there is no path between the snake and the snake tail? I have no way to do this, choose a feasible path to go. It is still a truth, one step at a time, update the layout, and then determine whether there is a safe path between the snake and food; no, there is no path between the serpent's head and the tail of the snake. No, pick one step to go.
Several of the questions listed above involve the snake's walking strategy, in general, we will let the snake take the shortest path every time. This is for the snake to eat food, but the snake in pursuit of their own tail when it can not be considered. We want the snake head to be as slow as possible while chasing the tail of the snake. So the snake head and the tail of the snake can make more space, more space to develop. So the snake's walking strategy is divided into two main types:
1. When the target is food, take the shortest path
2. When the target is the tail of the snake, take the longest path
What about the third situation? With the food and snake Tail no path exists, this time is only to pick a feasible step to walk, the shortest and longest relationship is not big. As for artificially letting the snake go the S-shaped, I don't think it's a good strategy, and the initial version has already analyzed its problem. (Unless, of course, you want to use the most invulnerable version, it's completely food-independent, let the snake go all the way, and then leave an aisle on the wall.) In this way, the snake can always perfectly eat all the food, and then fill the whole space, but it is very boring. without any meaning)
It also mentions a problem: Because food is randomly present, is there any possibility of a non-solvable situation? The answer is: yes. I ran the program, and then I output each layout to log, and I found that there was a situation like this:
Among them, the + number is the snake head,-is the tail of the snake, * is a snake body, 0 is food, #号代表空格, outside a circle # represents the wall. This layout, the food is already in front of the snake head, but it can eat it? No! Since it eats the food, the length adds 1, the snake head will fill the 0 position, the layout becomes:
At this time, because the length of the snake plus 1, the tail of the snake is not moving, and the snake head is surrounded by themselves, hung off. However, we still have a blank lattice # without padding. According to our strategy of teaching snakes, the snake head will only run after the tail of the snake, and whenever it and food have a path, it allows the virtual snake to run over and find that the new layout is unsafe, so it will not eat food, but choose to continue chasing the tail of the snake run. And then it just keeps running and running. Loop until you press the ESC key.
Since food is randomly occurring, it is possible to have this non-solvable layout above. Of course, you can also get a happy ending, the snake fills the whole rectangle.
The last question above, whether the violence law can get the optimal sequence. From the above analysis, it can be obtained, but there is no guarantee that it will be obtained.
Finally, let's see how the Visionary snakes run:
The size of the rectangle 10*20, except for the outer border, which is 8*18. Linux under the screen and then into the GIF format of the picture, the optimization of more than 40 m, really can't compare with Windows. When optimizing with the following command, there is a feeling that the system is optimizing with life:
Finally, you get the rinsed with AE, and use the image sequence to synthesize the dynamic picture (remember to select looping in the format options, otherwise the picture will not loop)
Last but not least
In addition, the snake program in this article uses the Curses module, UNIX-like systems are installed by default, the use of Windows children's shoes need to install this module. The above code can still be improved (now with less than 300 lines, optimize for less), you can also use Pygame or Pyglet library to make the interface more beautiful, enjoy!
How to write a snake ai in python