From f7342093af02e586d7cce75f0ec125f20c025856 Mon Sep 17 00:00:00 2001 From: DIvan2000 <divan2000@noreply.localhost> Date: Sun, 22 Dec 2024 11:40:58 +0400 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=D0=B0=20=D1=83=D0=B3=D0=B0=D0=B4=D0=B0=D0=B9=D0=BA?= =?UTF-8?q?=D0=B0,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B7=D0=BC=D0=B5=D0=B9=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Program.cs | 16 +- GUI/{ExitDialog.cs => Dialogs.cs} | 8 +- GUI/GuessForm.cs | 22 +- GUI/MathGameForm.cs | 6 +- GUI/MenuForm.cs | 4 +- GUI/SnakeForm.Designer.cs | 39 +++ GUI/SnakeForm.cs | 194 +++++++++++++++ GUI/SnakeForm.resx | 120 ++++++++++ ProgLab1.csproj | 2 +- Subprograms/SnakeGame.cs | 380 ------------------------------ 10 files changed, 385 insertions(+), 406 deletions(-) rename GUI/{ExitDialog.cs => Dialogs.cs} (68%) create mode 100644 GUI/SnakeForm.Designer.cs create mode 100644 GUI/SnakeForm.cs create mode 100644 GUI/SnakeForm.resx delete mode 100644 Subprograms/SnakeGame.cs diff --git a/Core/Program.cs b/Core/Program.cs index 778781b..7ada5da 100644 --- a/Core/Program.cs +++ b/Core/Program.cs @@ -10,6 +10,7 @@ class Program static MenuForm snakeSizeMenuForm; static AboutMeForm aboutMeForm; static MathGameForm mathGameForm; + static SnakeForm snakeForm; [STAThread] // Требуется для Windows Forms static void Main() @@ -19,7 +20,7 @@ class Program int sizex = 20; int sizey = 20; - SnakeGame.Level difficulty = 0; + SnakeForm.Level difficulty = 0; Menu sizeMenu = new Menu("Select world size"); sizeMenu.AddOption("Small size (10x10)", () => { sizex = 10; sizey = 10; }); @@ -27,9 +28,9 @@ class Program sizeMenu.AddOption("Big size (40x20)", () => { sizex = 40; sizey = 20; }); Menu difficultyMenu = new Menu("Select difficulty"); - difficultyMenu.AddOption("Easy", () => { difficulty = SnakeGame.Level.Low; }); - difficultyMenu.AddOption("Medium", () => { difficulty = SnakeGame.Level.Medium; }); - difficultyMenu.AddOption("Hard", () => { difficulty = SnakeGame.Level.High; }); + difficultyMenu.AddOption("Easy", () => { difficulty = SnakeForm.Level.Low; }); + difficultyMenu.AddOption("Medium", () => { difficulty = SnakeForm.Level.Medium; }); + difficultyMenu.AddOption("Hard", () => { difficulty = SnakeForm.Level.High; }); Menu mainMenu = new Menu("Select option"); mainMenu.AddOption("Guess answer math game", () => mainMenuForm.SwitchToForm(mathGameForm)); @@ -50,9 +51,8 @@ class Program snakeSizeMenuForm = new MenuForm(sizeMenu, () => { snakeSizeMenuForm.Hide(); - SnakeGame game = new SnakeGame(difficulty, sizex, sizey); - game.start(); - snakeSizeMenuForm.SwitchToForm(mainMenuForm); + snakeForm = new SnakeForm(difficulty, sizex, sizey, mainMenuForm); + snakeForm.Show(); }); aboutMeForm = new AboutMeForm(mainMenuForm); @@ -71,7 +71,7 @@ Website: divan2000.su"; } private static void Exit() { - ExitDialog.Exit(); + Dialogs.Exit(); } private static bool ExitMenu() { diff --git a/GUI/ExitDialog.cs b/GUI/Dialogs.cs similarity index 68% rename from GUI/ExitDialog.cs rename to GUI/Dialogs.cs index 61d1b94..6e98eb8 100644 --- a/GUI/ExitDialog.cs +++ b/GUI/Dialogs.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace ProgLab1.GUI { - public static class ExitDialog + public static class Dialogs { public static bool Exit() { @@ -18,5 +18,11 @@ namespace ProgLab1.GUI } return false; } + + public static bool GameOver(string message) + { + DialogResult result = MessageBox.Show(message, "Игра окончена", MessageBoxButtons.OK); + return result == DialogResult.OK; + } } } diff --git a/GUI/GuessForm.cs b/GUI/GuessForm.cs index bacf220..5c81e74 100644 --- a/GUI/GuessForm.cs +++ b/GUI/GuessForm.cs @@ -1,4 +1,5 @@ -using System; +using laba3.Subprograms; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; @@ -79,23 +80,22 @@ namespace ProgLab1.GUI { input.BackColor = SystemColors.Window; double inputNum = double.Parse(input.Text); - Console.WriteLine(Math.Abs(answer - inputNum)); - if (Math.Abs(answer - inputNum) < 0.1) + if (Math.Abs(answer - inputNum) < 0.01) { - + Dialogs.GameOver("Победа!\nВы угадали значение функции!"); + this.Close(); } else { tryes--; - } - - if(tryes <= 0) - { - this.Close(); + tryCount.Text = $"Количество попыток: {tryes}"; + if (tryes <= 0) + { + Dialogs.GameOver($"Попытки кончились :(\nВерный ответ был {answer:F2}"); + this.Close(); + } } } - - tryCount.Text = $"Количество попыток: {tryes}"; } } } diff --git a/GUI/MathGameForm.cs b/GUI/MathGameForm.cs index ea63205..e3d6c26 100644 --- a/GUI/MathGameForm.cs +++ b/GUI/MathGameForm.cs @@ -131,21 +131,21 @@ namespace ProgLab1.GUI game.setArgs(a, b); bool funcValid = game.CheckArgs(); - + if (!funcValid) { error.Text = "Функция не определена при этих аргументах"; } - else { error.Text = ""; + game.ComputeResult(); guessForm.SetAnswer(game.GetResult()); this.Hide(); guessForm.Show(); } } - if (!(isAValid && isBValid)) + else { // Если есть ошибка, подсвечиваем поля if (!isAValid) textBoxA.BackColor = Color.Red; diff --git a/GUI/MenuForm.cs b/GUI/MenuForm.cs index 7f88a38..d190945 100644 --- a/GUI/MenuForm.cs +++ b/GUI/MenuForm.cs @@ -22,7 +22,7 @@ namespace ProgLab1.GUI this.Width = 800; this.Height = 600; AddMenu(consoleMenu); - this.FormClosing += new FormClosingEventHandler((object sender, FormClosingEventArgs e) => { e.Cancel = !ExitDialog.Exit(); }); + this.FormClosing += new FormClosingEventHandler((object sender, FormClosingEventArgs e) => { e.Cancel = !Dialogs.Exit(); }); } public MenuForm(Menu consoleMenu, Action onAny) @@ -32,7 +32,7 @@ namespace ProgLab1.GUI this.Width = 800; this.Height = 600; AddMenu(consoleMenu, onAny); - this.FormClosing += new FormClosingEventHandler((object sender, FormClosingEventArgs e) => { e.Cancel = !ExitDialog.Exit(); }); + this.FormClosing += new FormClosingEventHandler((object sender, FormClosingEventArgs e) => { e.Cancel = !Dialogs.Exit(); }); } public void SwitchToForm(Form form) diff --git a/GUI/SnakeForm.Designer.cs b/GUI/SnakeForm.Designer.cs new file mode 100644 index 0000000..7434fea --- /dev/null +++ b/GUI/SnakeForm.Designer.cs @@ -0,0 +1,39 @@ +namespace ProgLab1.GUI +{ + partial class SnakeForm + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "SnakeGUI"; + } + + #endregion + } +} \ No newline at end of file diff --git a/GUI/SnakeForm.cs b/GUI/SnakeForm.cs new file mode 100644 index 0000000..31a0737 --- /dev/null +++ b/GUI/SnakeForm.cs @@ -0,0 +1,194 @@ +using laba3.Subprograms; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static System.Formats.Asn1.AsnWriter; + +namespace ProgLab1.GUI +{ + public partial class SnakeForm : Form + { + private System.Windows.Forms.Timer gameTimer = new System.Windows.Forms.Timer(); + private List<Point> snake = new List<Point>(); + private Point food = Point.Empty; + private int tileSize = 20; + private string direction = "Right"; + private string nextDirection = "Right"; + private bool isGameOver = false; + private int score = 0; + + private Level level; + private int sizex; + private int sizey; + + private Random rand = new Random(); + + public SnakeForm(Level level, int sizex, int sizey, Form onCloseForm) + { + this.level = level; + this.sizex = sizex; + this.sizey = sizey; + InitializeComponent(); + InitializeGame(); + + this.FormClosing += new FormClosingEventHandler((object sender, FormClosingEventArgs e) => {onCloseForm.Show();}); + } + + private void InitializeGame() + { + this.Text = "Snake Game"; + this.ClientSize = new Size(sizex*tileSize, sizey*tileSize); + this.DoubleBuffered = true; + this.KeyDown += OnKeyDown; + this.Paint += OnPaint; + + gameTimer.Interval = level switch + { + Level.Low => 250, + Level.Medium => 125, + Level.High => 50, + _ => 500, + }; ; + gameTimer.Tick += OnGameTick; + gameTimer.Start(); + + ResetGame(); + } + + private void ResetGame() + { + snake.Clear(); + snake.Add(new Point(2, sizey/2)); // Initial snake head + snake.Add(new Point(1, sizey/2)); // Initial snake body + snake.Add(new Point(0, sizey/2)); // Initial snake tail + direction = "Right"; + nextDirection = "Right"; + isGameOver = false; + SpawnFood(); + } + + private void SpawnFood() + { + int maxX = sizex; + int maxY = sizey; + do + { + food = new Point(rand.Next(0, maxX), rand.Next(0, maxY)); + } while (snake.Contains(food)); + } + + private void OnGameTick(object sender, EventArgs e) + { + if (isGameOver) return; + + // Update direction + direction = nextDirection; + + // Calculate new head position + Point newHead = snake[0]; + switch (direction) + { + case "Up": newHead.Y--; break; + case "Down": newHead.Y++; break; + case "Left": newHead.X--; break; + case "Right": newHead.X++; break; + } + + // Check collisions + if (newHead.X < 0 || newHead.Y < 0 || + newHead.X >= sizex || + newHead.Y >= sizey || + snake.Contains(newHead)) + { + isGameOver = true; + gameTimer.Stop(); + Dialogs.GameOver($"Счёт: {score}"); + this.Close(); + return; + } + + // Move snake + snake.Insert(0, newHead); + if (newHead == food) + { + SpawnFood(); + addScore(); + } + else + { + snake.RemoveAt(snake.Count - 1); // Remove tail + } + + this.Invalidate(); // Redraw + } + + private void OnPaint(object sender, PaintEventArgs e) + { + Graphics g = e.Graphics; + + // Draw snake + foreach (Point p in snake) + { + DrawTile(g, p.X, p.Y, Brushes.Green); + } + + // Draw food + DrawTile(g, food.X, food.Y, Brushes.Red); + + // Draw grid (optional) + for (int x = 0; x < this.ClientSize.Width; x += tileSize) + { + for (int y = 0; y < this.ClientSize.Height; y += tileSize) + { + g.DrawRectangle(Pens.Gray, x, y, tileSize, tileSize); + } + } + } + + private void DrawTile(Graphics g, int x, int y, Brush brush) + { + g.FillRectangle(brush, x * tileSize, y * tileSize, tileSize, tileSize); + } + + private void OnKeyDown(object sender, KeyEventArgs e) + { + if (isGameOver && e.KeyCode == Keys.R) + { + ResetGame(); + gameTimer.Start(); + return; + } + + switch (e.KeyCode) + { + case Keys.Up: if (direction != "Down") nextDirection = "Up"; break; + case Keys.Down: if (direction != "Up") nextDirection = "Down"; break; + case Keys.Left: if (direction != "Right") nextDirection = "Left"; break; + case Keys.Right: if (direction != "Left") nextDirection = "Right"; break; + } + } + + private void addScore() + { + score += level switch + { + Level.Low => 50, + Level.Medium => 100, + Level.High => 250, + _ => 1, + }; + } + public enum Level + { + Low, + Medium, + High + } + } +} diff --git a/GUI/SnakeForm.resx b/GUI/SnakeForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/GUI/SnakeForm.resx @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root> \ No newline at end of file diff --git a/ProgLab1.csproj b/ProgLab1.csproj index d4b3787..2cfef70 100644 --- a/ProgLab1.csproj +++ b/ProgLab1.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <OutputType>Exe</OutputType> + <OutputType>WinExe</OutputType> <TargetFramework>net8.0-windows10.0.17763.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> diff --git a/Subprograms/SnakeGame.cs b/Subprograms/SnakeGame.cs deleted file mode 100644 index e118773..0000000 --- a/Subprograms/SnakeGame.cs +++ /dev/null @@ -1,380 +0,0 @@ -using System.Diagnostics; - -namespace laba3.Subprograms -{ - /// <summary> - /// TUI classic game "Snake"; - /// The player controls the snake. - /// The player has to eat apples to increase the length of the snake - /// and try not to crash into the wall or themselves; - /// </summary> - internal class SnakeGame - { - int size_x; - int size_y; - int score; - int size_xy; - Level difficulty; - Tiles[,] world; - Snake snake; - Random rnd; - - private bool gameover; - /// <summary> - /// Game world constructor; - /// </summary> - /// <param name="difficulty">Game speed</param> - /// <param name="size_x">Game world size dim x</param> - /// <param name="size_y">Game world size dim y</param> - public SnakeGame(Level difficulty, int size_x, int size_y) - { - this.size_x = size_x; - this.size_y = size_y; - this.difficulty = difficulty; - world = new Tiles[size_x, size_y]; - rnd = new Random(); - score = 0; - size_xy = size_x * size_y; - } - /// <summary> - /// Start game; - /// Console will be clean!; - /// </summary> - public void start() - { - int msPerTick = difficulty switch - { - Level.Low => 500, - Level.Medium => 250, - Level.High => 100, - _ => 500, - }; - gameover = false; - - Console.Clear(); - Console.CursorVisible = false; - snake = new Snake(new Point(size_x / 2, size_y / 2, this), 1, Direction.Right, this); - - GenerateFood(); - - DrawBackground(); - DrawWorld(); - - Stopwatch tickTimer = new Stopwatch(); - while (!gameover) - { - tickTimer.Restart(); - if (Console.KeyAvailable) - { - ConsoleKeyInfo key = Console.ReadKey(false); - snake.HandleKey(key.Key); - while (Console.KeyAvailable) - Console.ReadKey(false); - } - snake.Move(); - long delta = tickTimer.ElapsedMilliseconds; - - Console.SetCursorPosition(1, 0); - if (delta > msPerTick) - Console.ForegroundColor = ConsoleColor.Red; - Console.Write(delta); - - Thread.Sleep((int)Math.Max(0, msPerTick - delta)); - } - onStop(); - } - - /// <summary> - /// Stop game; - /// </summary> - public void stop() - { - gameover = true; - } - - private void onStop() - { - string gameOverTitle = -@" - ### ## -# ## #### # # # # # # ## -# ## # # # # # ### # # # # ### # -# # # # # # # # # # # # # - ### ## # # # ## ## # ## # -"; - Console.Clear(); - printArt(gameOverTitle, (Console.WindowWidth - 36) / 2, 4, ConsoleColor.DarkYellow, ConsoleColor.DarkGray); - - Console.ResetColor(); - - string scoreString = $"Score: {score}"; - Console.SetCursorPosition((Console.WindowWidth - scoreString.Length) / 2, 11); - Console.Write(scoreString); - Console.SetCursorPosition((Console.WindowWidth - "Press Enter to continue".Length) / 2, 14); - Console.CursorVisible = true; - } - - private void printArt(string art, int x, int y, ConsoleColor primaryColor, ConsoleColor shadowColor) - { - int row = 0; - Console.SetCursorPosition(x, y); - char shadow = ' '; - foreach (char ch in art) - { - if (ch == '\n') - { - if (shadow == '#') - { - Console.BackgroundColor = shadowColor; - Console.Write(' '); - } - Console.SetCursorPosition(x, y++ + row); - Thread.Sleep(25); - shadow = ch; - } - else if (ch == ' ') - { - if (shadow == '#') - { - Console.BackgroundColor = shadowColor; - Console.Write(' '); - } - else - Console.CursorLeft++; - shadow = ch; - } - else if (ch == '#') - { - Console.BackgroundColor = primaryColor; - Console.Write(' '); - shadow = ch; - } - - } - } - - private void addScore() - { - score += difficulty switch - { - Level.Low => 10, - Level.Medium => 50, - Level.High => 100, - _ => 1, - }; - } - - - /// <summary> - /// Generate food in random place; - /// </summary> - public void GenerateFood() - { - int x; - int y; - do - { - x = rnd.Next(size_x); - y = rnd.Next(size_y); - } while (world[x, y] != Tiles.Void); - world[x, y] = Tiles.Food; - DrawTile(x, y); - } - - private void DrawBackground() - { - for (int x = 1; x < (size_x + 1) * 2 + 1; x++) - { - Console.SetCursorPosition(x, 1); - Console.Write('#'); - Console.SetCursorPosition(x, size_y + 2); - Console.Write('#'); - } - for (int y = 1; y < size_y + 2; y++) - { - Console.SetCursorPosition(1, y); - Console.Write('#'); - - Console.SetCursorPosition(size_x * 2 + 1, y); - Console.Write('#'); - } - } - - private void DrawTile(int x, int y) - { - char symbol; - switch (world[x, y]) - { - case Tiles.Void: - symbol = ' '; - break; - case Tiles.Snake: - symbol = '*'; - Console.ForegroundColor = ConsoleColor.DarkRed; - break; - case Tiles.Food: - symbol = '@'; - Console.ForegroundColor = ConsoleColor.Red; - break; - default: - symbol = '?'; - break; - }; - //Console.BackgroundColor = ConsoleColor.DarkGreen; - Console.SetCursorPosition((x + 1) * 2, y + 2); - Console.Write(symbol); - - Console.BackgroundColor = ConsoleColor.Black; - Console.ForegroundColor = ConsoleColor.White; - } - private void DrawWorld() - { - for (int x = 0; x < size_x; x++) - { - for (int y = 0; y < size_y; y++) - { - DrawTile(x, y); - } - } - } - private enum Tiles - { - Void, - Snake, - Food - } - public enum Level - { - Low, - Medium, - High - } - private class Snake - { - private SnakeGame game; - private List<Point> body; - private Direction direction; - - public Snake(Point tail, int length, Direction initialDirection, SnakeGame game) - { - this.game = game; - body = new List<Point>(); - direction = initialDirection; - - for (int i = 0; i < length; i++) - { - Point p = new Point(tail.X, tail.Y, game); - body.Add(p); - } - } - - public void Move() - { - Point head = GetNextPoint(); - Point tail = body.First(); - - if (head.X < 0 || head.Y < 0 || head.X >= game.size_x || head.Y >= game.size_y) - { - game.stop(); - return; - } - - if (game.world[head.X, head.Y] == Tiles.Snake) - { - game.stop(); - return; - } - - - body.Add(head); - if (game.world[head.X, head.Y] != Tiles.Food) - { - body.Remove(tail); - tail.UpdateWorld(Tiles.Void); - } - else - { - game.addScore(); - game.GenerateFood(); - if (body.Count >= game.size_xy) game.stop(); - } - head.UpdateWorld(Tiles.Snake); - } - - public Point GetNextPoint() - { - Point head = body.Last(); - Point nextPoint = new Point(head.X, head.Y, game); - - switch (direction) - { - case Direction.Right: - nextPoint.X++; - break; - case Direction.Left: - nextPoint.X--; - break; - case Direction.Up: - nextPoint.Y--; - break; - case Direction.Down: - nextPoint.Y++; - break; - } - - return nextPoint; - } - - public void HandleKey(ConsoleKey key) - { - switch (key) - { - case ConsoleKey.LeftArrow: - if (direction != Direction.Right) - direction = Direction.Left; - break; - case ConsoleKey.RightArrow: - if (direction != Direction.Left) - direction = Direction.Right; - break; - case ConsoleKey.UpArrow: - if (direction != Direction.Down) - direction = Direction.Up; - break; - case ConsoleKey.DownArrow: - if (direction != Direction.Up) - direction = Direction.Down; - break; - } - } - } - - enum Direction - { - Left, - Right, - Up, - Down - } - - private class Point - { - private SnakeGame game { get; set; } - public int X { get; set; } - public int Y { get; set; } - - public Point(int x, int y, SnakeGame game) - { - this.game = game; - X = x; - Y = y; - } - - public void UpdateWorld(Tiles tile) - { - game.world[X, Y] = tile; - game.DrawTile(X, Y); - } - } - } -}