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 snake = new List(); 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 } } }