Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1
    Private snakeLength As Integer = 1
    Private snakePositions As New List(Of Point)
    Private snakeDirection As Direction = Direction.Right
    Private snakeSpeed As Integer = 200 ' milliseconds
    Private gameTimer As New Timer()
    Private currentWord As String = ""
    Private targetLetter As Char = "A"c
    Private score As Integer = 0
    Private gameActive As Boolean = False

    Private letters As New List(Of Char)()
    Private letterButtons As New List(Of Button)()

    Private Enum Direction
        Up
        Down
        Left
        Right
    End Enum

    Public Sub New()
        InitializeComponent2()
        InitializeGame()
        SetupLetters()
    End Sub

    Private Sub InitializeComponent2()
        Me.Text = "Word Snake Game"
        Me.Size = New Size(850, 600)
        Me.StartPosition = FormStartPosition.CenterScreen
        Me.BackColor = Color.LightGray
        Me.KeyPreview = True

        ' Create start button dynamically
        Dim btnStart As New Button()
        btnStart.Text = "Start Game"
        btnStart.Size = New Size(100, 40)
        btnStart.Location = New Point(50, 250)
        btnStart.BackColor = Color.LimeGreen
        btnStart.ForeColor = Color.White
        AddHandler btnStart.Click, AddressOf StartGame
        Me.Controls.Add(btnStart)

        ' Create restart button
        Dim btnRestart As New Button()
        btnRestart.Text = "Restart"
        btnRestart.Size = New Size(100, 40)
        btnRestart.Location = New Point(50, 300)
        btnRestart.BackColor = Color.Orange
        btnRestart.ForeColor = Color.White
        AddHandler btnRestart.Click, AddressOf RestartGame
        Me.Controls.Add(btnRestart)

        ' Create game panel
        Dim gamePanel As New Panel()
        gamePanel.BackColor = Color.Black
        gamePanel.Size = New Size(400, 400)
        gamePanel.Location = New Point(200, 50)
        gamePanel.BorderStyle = BorderStyle.FixedSingle
        ''Me.Controls.Add(gamePanel)

        ' Create score label
        Dim lblScore As New Label()
        lblScore.Text = "Score: 0"
        lblScore.Font = New Font("Arial", 14, FontStyle.Bold)
        lblScore.ForeColor = Color.Blue
        lblScore.Size = New Size(150, 30)
        lblScore.Location = New Point(620, 50)
        Me.Controls.Add(lblScore)
        lblScore.Name = "lblScore"

        ' Create word display label
        Dim lblWord As New Label()
        lblWord.Text = "Word: "
        lblWord.Font = New Font("Arial", 12)
        lblWord.Size = New Size(300, 30)
        lblWord.Location = New Point(620, 100)
        Me.Controls.Add(lblWord)
        lblWord.Name = "lblWord"

        ' Create target letter label
        Dim lblTarget As New Label()
        lblTarget.Text = "Target: A"
        lblTarget.Font = New Font("Arial", 12, FontStyle.Bold)
        lblTarget.ForeColor = Color.Red
        lblTarget.Size = New Size(150, 30)
        lblTarget.Location = New Point(620, 150)
        Me.Controls.Add(lblTarget)
        lblTarget.Name = "lblTarget"

        ' Create instructions label
        Dim lblInstructions As New Label()
        lblInstructions.Text = "Use Arrow Keys to control the snake." & vbCrLf &
                             "Collect letters in alphabetical order!" & vbCrLf &
                             "Press Space to pause/resume."
        lblInstructions.Font = New Font("Arial", 10)
        lblInstructions.Size = New Size(200, 100)
        lblInstructions.Location = New Point(620, 200)
        Me.Controls.Add(lblInstructions)

        ' Setup game timer
        gameTimer.Interval = snakeSpeed
        AddHandler gameTimer.Tick, AddressOf GameLoop
    End Sub

    Private Sub InitializeGame()
        snakePositions.Clear()

        ' Initialize snake in the middle of the panel
        Dim startX As Integer = 200 + 200 ' Center of game panel
        Dim startY As Integer = 50 + 200

        For i As Integer = 0 To snakeLength - 1
            snakePositions.Add(New Point(startX - i * 20, startY))
        Next

        currentWord = ""
        targetLetter = "A"c
        score = 0

        UpdateScoreDisplay()
        UpdateWordDisplay()
        UpdateTargetDisplay()
    End Sub

    Private Sub SetupLetters()
        ' Create alphabet letters
        For i As Integer = 0 To 25
            letters.Add(Chr(Asc("A"c) + i))
        Next

        ' Randomly place letters on the form
        Dim random As New Random()

        For Each letter As Char In letters
            Dim btn As New Button()
            btn.Text = letter.ToString()
            btn.Tag = letter
            btn.Size = New Size(30, 30)
            btn.BackColor = Color.Yellow
            btn.ForeColor = Color.Black
            btn.Font = New Font("Arial", 10, FontStyle.Bold)

            ' Random position within game area
            Dim x As Integer = random.Next(200, 600)
            Dim y As Integer = random.Next(50, 450)
            btn.Location = New Point(x, y)

            AddHandler btn.Click, AddressOf LetterClicked
            Me.Controls.Add(btn)
            letterButtons.Add(btn)
        Next
    End Sub

    Private Sub StartGame(sender As Object, e As EventArgs)
        If Not gameActive Then
            gameActive = True
            gameTimer.Start()

            Focus()

            InitializeGame()
            CType(sender, Button).Enabled = False
            CType(sender, Button).Text = "Game Running"
        End If
    End Sub

    Private Sub RestartGame(sender As Object, e As EventArgs)
        gameActive = False
        gameTimer.Stop()

        ' Remove existing letter buttons
        For Each btn As Button In letterButtons
            Me.Controls.Remove(btn)
        Next
        letterButtons.Clear()

        ' Reinitialize
        InitializeGame()
        SetupLetters()

        ' Enable start button
        For Each ctrl As Control In Me.Controls
            If TypeOf ctrl Is Button AndAlso ctrl.Text = "Game Running" Then
                ctrl.Text = "Start Game"
                ctrl.Enabled = True
            End If
        Next
    End Sub

    Private Sub GameLoop(sender As Object, e As EventArgs)
        If Not gameActive Then Return

        ' Move snake
        MoveSnake()

        ' Check for collision with letters
        CheckLetterCollision()

        ' Check for game over conditions
        CheckGameOver()

        ' Redraw
        Me.Invalidate()
    End Sub

    Private Sub MoveSnake()
        ' Get head position
        Dim head As Point = snakePositions(0)

        ' Calculate new head position based on direction
        Select Case snakeDirection
            Case Direction.Up
                head.Y -= 20
            Case Direction.Down
                head.Y += 20
            Case Direction.Left
                head.X -= 20
            Case Direction.Right
                head.X += 20
        End Select

        ' Add new head
        snakePositions.Insert(0, head)

        ' Remove tail
        If snakePositions.Count > snakeLength Then
            snakePositions.RemoveAt(snakePositions.Count - 1)
        End If
    End Sub

    Private Sub CheckLetterCollision()
        Dim head As Point = snakePositions(0)

        For Each btn As Button In letterButtons
            If btn.Visible AndAlso head.X >= btn.Location.X AndAlso head.X <= btn.Location.X + btn.Width AndAlso
               head.Y >= btn.Location.Y AndAlso head.Y <= btn.Location.Y + btn.Height Then

                Dim letter As Char = CChar(btn.Tag)

                If letter = targetLetter Then
                    ' Correct letter collected
                    currentWord += letter
                    score += 10
                    snakeLength += 1 ' Grow snake

                    ' Move to next letter
                    If targetLetter < "Z"c Then
                        targetLetter = Chr(Asc(targetLetter) + 1)
                    Else
                        targetLetter = "A"c ' Reset to A
                    End If

                    btn.Visible = False

                    UpdateScoreDisplay()
                    UpdateWordDisplay()
                    UpdateTargetDisplay()

                    ' Increase speed every 5 letters
                    If score Mod 50 = 0 Then
                        snakeSpeed = Math.Max(50, snakeSpeed - 20)
                        gameTimer.Interval = snakeSpeed
                    End If
                Else
                    ' Wrong letter - game over
                    gameActive = False
                    gameTimer.Stop()
                    MessageBox.Show($"Game Over! Wrong letter: {letter}. Expected: {targetLetter}")
                End If

                Exit For
            End If
        Next
    End Sub

    Private Sub CheckGameOver()
        Dim head As Point = snakePositions(0)

        ' Check wall collision
        If head.X < 200 OrElse head.X > 600 OrElse head.Y < 50 OrElse head.Y > 450 Then
            gameActive = False
            gameTimer.Stop()
            MessageBox.Show("Game Over! Hit the wall!")
        End If

        ' Check self collision
        For i As Integer = 1 To snakePositions.Count - 1
            If head.Equals(snakePositions(i)) Then
                gameActive = False
                gameTimer.Stop()
                MessageBox.Show("Game Over! Snake collided with itself!")
            End If
        Next
    End Sub

    Private Sub LetterClicked(sender As Object, e As EventArgs)
        If Not gameActive Then Return

        Dim btn As Button = CType(sender, Button)
        Dim letter As Char = CChar(btn.Tag)

        ' Manual collection (alternative to snake movement)
        If letter = targetLetter Then
            currentWord += letter
            score += 5 ' Less points for manual collection
            If targetLetter < "Z"c Then
                targetLetter = Chr(Asc(targetLetter) + 1)
            Else
                targetLetter = "A"c
            End If

            btn.Visible = False

            UpdateScoreDisplay()
            UpdateWordDisplay()
            UpdateTargetDisplay()
        End If
    End Sub

    Private Sub UpdateScoreDisplay()
        For Each ctrl As Control In Me.Controls
            If ctrl.Name = "lblScore" Then
                ctrl.Text = $"Score: {score}"
                Exit For
            End If
        Next
    End Sub

    Private Sub UpdateWordDisplay()
        For Each ctrl As Control In Me.Controls
            If ctrl.Name = "lblWord" Then
                ctrl.Text = $"Word: {currentWord}"
                Exit For
            End If
        Next
    End Sub

    Private Sub UpdateTargetDisplay()
        For Each ctrl As Control In Me.Controls
            If ctrl.Name = "lblTarget" Then
                ctrl.Text = $"Target: {targetLetter}"
                Exit For
            End If
        Next
    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)

        If Not gameActive Then Return

        ' Draw snake
        Dim snakeBrush As New SolidBrush(Color.Lime)
        Dim headBrush As New SolidBrush(Color.Red)

        For i As Integer = 0 To snakePositions.Count - 1
            Dim pos As Point = snakePositions(i)

            If i = 0 Then
                ' Draw head
                e.Graphics.FillEllipse(headBrush, pos.X, pos.Y, 20, 20)
            Else
                ' Draw body segment
                e.Graphics.FillEllipse(snakeBrush, pos.X, pos.Y, 20, 20)
            End If
        Next

        snakeBrush.Dispose()
        headBrush.Dispose()
    End Sub

    Protected Overrides Function ProcessCmdKey(
    ByRef msg As Message,
    keyData As Keys) As Boolean

        If gameActive Then
            Select Case keyData
                Case Keys.Up
                    If snakeDirection <> Direction.Down Then
                        snakeDirection = Direction.Up
                    End If
                    Return True

                Case Keys.Down
                    If snakeDirection <> Direction.Up Then
                        snakeDirection = Direction.Down
                    End If
                    Return True

                Case Keys.Left
                    If snakeDirection <> Direction.Right Then
                        snakeDirection = Direction.Left
                    End If
                    Return True

                Case Keys.Right
                    If snakeDirection <> Direction.Left Then
                        snakeDirection = Direction.Right
                    End If
                    Return True

                Case Keys.Space
                    gameActive = Not gameActive
                    If gameActive Then
                        gameTimer.Start()
                    Else
                        gameTimer.Stop()
                    End If
                    Return True
            End Select
        End If

        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

    Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
        MyBase.OnKeyDown(e)

        If Not gameActive Then Return

        Select Case e.KeyCode
            Case Keys.Up
                If snakeDirection <> Direction.Down Then
                    snakeDirection = Direction.Up
                End If
            Case Keys.Down
                If snakeDirection <> Direction.Up Then
                    snakeDirection = Direction.Down
                End If
            Case Keys.Left
                If snakeDirection <> Direction.Right Then
                    snakeDirection = Direction.Left
                End If
            Case Keys.Right
                If snakeDirection <> Direction.Left Then
                    snakeDirection = Direction.Right
                End If
            Case Keys.Space
                ' Pause/resume
                gameActive = Not gameActive
                If gameActive Then
                    gameTimer.Start()
                Else
                    gameTimer.Stop()
                End If
        End Select
    End Sub

    Protected Overrides Sub OnFormClosing(e As FormClosingEventArgs)
        gameTimer.Stop()
        gameTimer.Dispose()
        MyBase.OnFormClosing(e)
    End Sub

    <STAThread()>
    Sub Main()
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(New Form1())
    End Sub
End Class
