In addition to work, I wrote a simple snake program in C #, generally in the form of winform. This time I got a console version, because C # console is all input and output streams, this kind of program with front-end UI interface in the CMD window should not be suitable, but I think it should be possible to think of the previous DOS version system, so it took a few nights to get such a thing. First, the first one was:
The interface is relatively simple. In a cmd window, the other is the various shapes composed of characters. There are several important points to be aware of in this console:
1. Understand the console. It is a standard I/O input/output stream;
2. There are two terminologies in the console: the screen buffer and console window. We generally obtain the console size rather than the buffer size. Please refer to msdn;
3. There are several questions about the snake itself: how to make the snake move? How can I determine whether a snake has eaten food? How can I determine if a snake has touched a border? And so on.
First of all, I would like to say that no matter what programs or software are used, it is very important to design the data structure. After the data structure is well designed, the problem becomes simple!
According to the object-oriented requirements, the snake class is designed. Because all the console programs are in the form of characters, it is necessary to draw a snake class. points constitute a line. First, the point class is designed as follows:
1. Point. CS
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Snake{ /// <summary> /// Class Point /// </summary> public class Point : IComparable<Point> { private int x = 0; /// <summary> /// Gets or sets the x /// </summary> public int X { get { return x; } set { x = value; } } private int y = 0; /// <summary> /// Gets or sets the y /// </summary> public int Y { get { return y; } set { y = value; } } /// <summary> /// Compare the two point /// </summary> /// <param name="other">Other point</param> /// <returns>-1 if x < other.X && y < other.Y , 0 if x == other.X && y == other.Y , otherwise 1</returns> public int CompareTo(Point other) { if (x < other.X && y < other.Y) { return -1; } else if (x == other.X && y == other.Y) { return 0; } else { return 1; } } }}
This point inherits the icomparable interface to compare and determine whether the snake has touched other objects or itself. Now we can design the snake. CS class.
2. Snake. CS
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Snake{ /// <summary> /// Class Snake /// </summary> public class Snake { private Point head = null; /// <summary> /// Gets or sets the snake's head /// </summary> public Point Head { get { return head; } set { head = value; } } private Point[] body = null; /// <summary> /// Gets or sets the snake's body /// </summary> public Point[] Body { get { return body; } set { body = value; } } private Point tail = null; /// <summary> /// Gets or sets the snake's tail /// </summary> public Point Tail { get { return tail; } set { tail = value; } } }}
Why should we have a snake head, a snake body, and a snake tail? To put it simply, you will think of the object-oriented method. The complicated method depends on the logic processing of the code. I will not talk about it here, but I will understand it myself. The next step is food. CS.
3. Food. CS
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Snake{ /// <summary> /// Class Food /// </summary> public class Food { private Point position = null; /// <summary> /// Gets or sets the food's position /// </summary> public Point Position { get { return position; } set { position = value; } } }}
Food is a point in one position, and there is no other attribute. In this way, the basic data structure is constructed, and the rest is how to link these structures to construct the logic of the game. First, go to the game, you must press the arrow key to control the movement of the Snake. The console provides the following methods and attributes for judging the keyboard input:
ConsoleKey key = Console.ReadKey(true).Key;
The consolekey class has attributes to determine which key is pressed on the keyboard. For details, refer to msdn. After the eaglekey is completed, let's take a look at how to draw the game interface. This is not too complicated. The console class has the following method:
Console.SetCursorPosition(i, j);
Set the position of the cursor so that the writing character can be used. If this method is not used, we need to redraw the entire interface every time the snake moves, this will lead to a problem: the console window screen will always flash, because we are drawing the entire console. With this method, we only need to refresh the local area, for example, we only need to update the position of the snake. Finally, let's talk about how to deal with the snake's food and border. When the snake hits the food, we can use the food as the current snake's head, and the previous snake's head as the first node of the snake's body, in this way, the length of the snake body is increased by 1, and the snake tail is still the original snake tail. When the snake head hits the border, the game ends. Also, when the snake moves and does not touch the food or border, the snake's head becomes the current point of the snake's movement, the first point of the snake body becomes the point of the previous Snake Head, and so on, the snake moves a position like before.
Well, there's probably so much. The final part is to draw the interface. The Code is as follows:
/// <summary> /// Draw console ui /// </summary> private void DrawConsoleUI() { Console.Clear(); Point tempPoint = null; Console.SetCursorPosition(0, 0); Console.WriteLine("Name : " + name); Console.SetCursorPosition(0, 1); Console.WriteLine("Score : " + score); Console.SetCursorPosition(0, 2); Console.WriteLine("Press R to restart game after you losed the game, press E to exit game"); for (int i = 0; i < uiWidth; i += 2) { Console.SetCursorPosition(i, 3); Console.Write("."); } for (int i = 2; i < uiHeight; i++) { for (int j = 0; j < uiWidth; j++) { tempPoint = new Point(); tempPoint.X = j; tempPoint.Y = i; if (tempPoint.CompareTo(currentFood.Position) == 0) { Console.SetCursorPosition(j, i); Console.Write(GetFoodElement()); } else if (tempPoint.CompareTo(currentSnake.Head) == 0) { Console.SetCursorPosition(j, i); Console.Write(GetHeadElement()); } else if (IsSnakeBodyCoverPoint(currentSnake.Body, tempPoint)) { Console.SetCursorPosition(j, i); Console.Write(GetBodyElement()); } else if (tempPoint.CompareTo(currentSnake.Tail) == 0) { Console.SetCursorPosition(j, i); Console.Write(GetTailElement()); } } } }
Some of these methods will know what the name means. This implementation is relatively simple, and the code will not be available here...
Source code download