Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1
    Inherits Form

    ' Game components
    Private WithEvents btnNewGame As Button
    Private WithEvents btnDeal As Button
    Private WithEvents btnSpit As Button

    Private lblPlayer1 As Label
    Private lblPlayer2 As Label
    Private lblCenterPiles As Label
    Private lblStatus As Label

    ' Panels for card display
    Private pnlPlayer1 As Panel
    Private pnlPlayer2 As Panel
    Private pnlCenter As Panel

    ' Game logic
    Private deck As List(Of Integer)
    Private player1Hand As List(Of Integer)
    Private player2Hand As List(Of Integer)
    Private centerPiles As List(Of Integer)()
    Private currentPlayer As Integer
    Private gameActive As Boolean

    ' Card dimensions
    Private Const CARD_WIDTH As Integer = 60
    Private Const CARD_HEIGHT As Integer = 90
    Private Const CARD_SPACING As Integer = 5

    Public Sub New()
        InitializeForm()
        InitializeGame()
    End Sub

    Private Sub InitializeForm()
        ' Form properties
        Me.Text = "Spit Card Game"
        Me.Size = New Size(1000, 700)
        Me.StartPosition = FormStartPosition.CenterScreen
        Me.BackColor = Color.DarkGreen

        ' Create controls dynamically
        CreateControls()
        ArrangeControls()
    End Sub

    Private Sub CreateControls()
        ' Status label
        lblStatus = New Label()
        lblStatus.Text = "Click 'New Game' to start"
        lblStatus.ForeColor = Color.White
        lblStatus.Font = New Font("Arial", 12, FontStyle.Bold)
        lblStatus.TextAlign = ContentAlignment.MiddleCenter

        ' Player labels
        lblPlayer1 = New Label()
        lblPlayer1.Text = "Player 1 (Bottom)"
        lblPlayer1.ForeColor = Color.White
        lblPlayer1.Font = New Font("Arial", 10, FontStyle.Bold)

        lblPlayer2 = New Label()
        lblPlayer2.Text = "Player 2 (Top)"
        lblPlayer2.ForeColor = Color.White
        lblPlayer2.Font = New Font("Arial", 10, FontStyle.Bold)

        lblCenterPiles = New Label()
        lblCenterPiles.Text = "Center Piles"
        lblCenterPiles.ForeColor = Color.White
        lblCenterPiles.Font = New Font("Arial", 10, FontStyle.Bold)

        ' Panels for card display
        pnlPlayer1 = New Panel()
        pnlPlayer1.BackColor = Color.FromArgb(0, 100, 0)
        pnlPlayer1.BorderStyle = BorderStyle.FixedSingle

        pnlPlayer2 = New Panel()
        pnlPlayer2.BackColor = Color.FromArgb(0, 100, 0)
        pnlPlayer2.BorderStyle = BorderStyle.FixedSingle

        pnlCenter = New Panel()
        pnlCenter.BackColor = Color.FromArgb(0, 100, 0)
        pnlCenter.BorderStyle = BorderStyle.FixedSingle

        ' Buttons
        btnNewGame = New Button()
        btnNewGame.Text = "New Game"
        btnNewGame.BackColor = Color.SteelBlue
        btnNewGame.ForeColor = Color.White
        btnNewGame.Font = New Font("Arial", 10, FontStyle.Bold)

        btnDeal = New Button()
        btnDeal.Text = "Deal Cards"
        btnDeal.BackColor = Color.SteelBlue
        btnDeal.ForeColor = Color.White
        btnDeal.Font = New Font("Arial", 10, FontStyle.Bold)
        btnDeal.Enabled = False

        btnSpit = New Button()
        btnSpit.Text = "Spit!"
        btnSpit.BackColor = Color.Crimson
        btnSpit.ForeColor = Color.White
        btnSpit.Font = New Font("Arial", 10, FontStyle.Bold)
        btnSpit.Enabled = False

        ' Add controls to form
        Me.Controls.AddRange({
            lblStatus, lblPlayer1, lblPlayer2, lblCenterPiles,
            pnlPlayer1, pnlPlayer2, pnlCenter,
            btnNewGame, btnDeal, btnSpit
        })
    End Sub

    Private Sub ArrangeControls()
        ' Status label at top
        lblStatus.Size = New Size(Me.ClientSize.Width - 20, 40)
        lblStatus.Location = New Point(10, 10)

        ' Center panel
        pnlCenter.Size = New Size(Me.ClientSize.Width - 40, 150)
        pnlCenter.Location = New Point(20, 60)

        lblCenterPiles.Size = New Size(150, 20)
        lblCenterPiles.Location = New Point(pnlCenter.Left, pnlCenter.Top - 25)

        ' Player 2 panel (top)
        pnlPlayer2.Size = New Size(Me.ClientSize.Width - 40, 150)
        pnlPlayer2.Location = New Point(20, 220)

        lblPlayer2.Size = New Size(150, 20)
        lblPlayer2.Location = New Point(pnlPlayer2.Left, pnlPlayer2.Top - 25)

        ' Player 1 panel (bottom)
        pnlPlayer1.Size = New Size(Me.ClientSize.Width - 40, 150)
        pnlPlayer1.Location = New Point(20, 380)

        lblPlayer1.Size = New Size(150, 20)
        lblPlayer1.Location = New Point(pnlPlayer1.Left, pnlPlayer1.Top - 25)

        ' Buttons at bottom
        Dim buttonWidth As Integer = 120
        Dim buttonHeight As Integer = 40
        Dim buttonY As Integer = Me.ClientSize.Height - 70

        btnNewGame.Size = New Size(buttonWidth, buttonHeight)
        btnNewGame.Location = New Point(50, buttonY)

        btnDeal.Size = New Size(buttonWidth, buttonHeight)
        btnDeal.Location = New Point(200, buttonY)

        btnSpit.Size = New Size(buttonWidth, buttonHeight)
        btnSpit.Location = New Point(350, buttonY)
    End Sub

    Private Sub InitializeGame()
        deck = New List(Of Integer)()
        player1Hand = New List(Of Integer)()
        player2Hand = New List(Of Integer)()
        centerPiles = {New List(Of Integer)(), New List(Of Integer)()}
        currentPlayer = 1
        gameActive = False
    End Sub

    Private Sub CreateDeck()
        deck.Clear()
        ' Create a standard 52-card deck (1-52 representing cards)
        For i As Integer = 1 To 52
            deck.Add(i)
        Next

        ' Shuffle the deck
        Dim rnd As New Random()
        deck = deck.OrderBy(Function(x) rnd.Next()).ToList()
    End Sub

    Private Sub DealCards()
        player1Hand.Clear()
        player2Hand.Clear()

        ' Deal 26 cards to each player
        For i As Integer = 0 To 25
            player1Hand.Add(deck(i))
            player2Hand.Add(deck(i + 26))
        Next

        ' Sort player hands
        player1Hand.Sort()
        player2Hand.Sort()
    End Sub

    Private Sub DisplayCards()
        ' Clear panels
        pnlPlayer1.Controls.Clear()
        pnlPlayer2.Controls.Clear()
        pnlCenter.Controls.Clear()

        ' Display Player 1 cards
        DisplayCardList(pnlPlayer1, player1Hand, False)

        ' Display Player 2 cards
        DisplayCardList(pnlPlayer2, player2Hand, True)

        ' Display center piles
        DisplayCenterPiles()
    End Sub

    Private Sub DisplayCardList(panel As Panel, cards As List(Of Integer), showFaceDown As Boolean)
        Dim xPos As Integer = CARD_SPACING

        For Each cardValue As Integer In cards
            Dim cardPanel As New Panel()
            cardPanel.Size = New Size(CARD_WIDTH, CARD_HEIGHT)
            cardPanel.Location = New Point(xPos, (panel.Height - CARD_HEIGHT) \ 2)
            cardPanel.BackColor = Color.White
            cardPanel.BorderStyle = BorderStyle.FixedSingle

            If showFaceDown Then
                ' Show card back
                cardPanel.BackColor = Color.Blue
                AddHandler cardPanel.Click, AddressOf Card_Click
                cardPanel.Tag = cardValue
            Else
                ' Show card face
                Dim cardLabel As New Label()
                cardLabel.Text = GetCardDisplay(cardValue)
                cardLabel.Font = New Font("Arial", 10, FontStyle.Bold)
                cardLabel.ForeColor = GetCardColor(cardValue)
                cardLabel.Dock = DockStyle.Fill
                cardLabel.TextAlign = ContentAlignment.MiddleCenter
                cardPanel.Controls.Add(cardLabel)
            End If

            panel.Controls.Add(cardPanel)
            xPos += CARD_WIDTH + CARD_SPACING
        Next
    End Sub

    Private Sub DisplayCenterPiles()
        Dim centerWidth As Integer = pnlCenter.Width
        Dim pileWidth As Integer = CARD_WIDTH * 2
        Dim startX As Integer = (centerWidth - (pileWidth * 2 + CARD_SPACING)) \ 2

        For pileIndex As Integer = 0 To 1
            Dim pilePanel As New Panel()
            pilePanel.Size = New Size(pileWidth, CARD_HEIGHT)
            pilePanel.Location = New Point(startX + pileIndex * (pileWidth + CARD_SPACING),
                                          (pnlCenter.Height - CARD_HEIGHT) \ 2)
            pilePanel.BackColor = Color.DarkGray
            pilePanel.BorderStyle = BorderStyle.Fixed3D

            If centerPiles(pileIndex).Count > 0 Then
                ' Show top card of pile
                Dim topCard As Integer = centerPiles(pileIndex).Last()
                Dim cardLabel As New Label()
                cardLabel.Text = GetCardDisplay(topCard)
                cardLabel.Font = New Font("Arial", 12, FontStyle.Bold)
                cardLabel.ForeColor = GetCardColor(topCard)
                cardLabel.Dock = DockStyle.Fill
                cardLabel.TextAlign = ContentAlignment.MiddleCenter
                pilePanel.Controls.Add(cardLabel)

                ' Add pile label
                Dim pileLabel As New Label()
                pileLabel.Text = $"Pile {pileIndex + 1}"
                pileLabel.Font = New Font("Arial", 8)
                pileLabel.ForeColor = Color.White
                pileLabel.Location = New Point(5, 5)
                pilePanel.Controls.Add(pileLabel)
            End If

            pnlCenter.Controls.Add(pilePanel)
        Next
    End Sub

    Private Function GetCardDisplay(cardValue As Integer) As String
        Dim suit As String = ""
        Dim rank As Integer = (cardValue - 1) Mod 13 + 1

        Select Case Math.Ceiling(cardValue / 13.0)
            Case 1 : suit = "♠"
            Case 2 : suit = "♥"
            Case 3 : suit = "♦"
            Case 4 : suit = "♣"
        End Select

        Dim rankStr As String = rank.ToString()
        Select Case rank
            Case 1 : rankStr = "A"
            Case 11 : rankStr = "J"
            Case 12 : rankStr = "Q"
            Case 13 : rankStr = "K"
        End Select

        Return $"{rankStr}{suit}"
    End Function

    Private Function GetCardColor(cardValue As Integer) As Color
        Dim suit As Integer = Math.Ceiling(cardValue / 13.0)
        Return If(suit = 2 OrElse suit = 3, Color.Red, Color.Black)
    End Function

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

        Dim clickedCard As Panel = DirectCast(sender, Panel)
        Dim cardValue As Integer = CInt(clickedCard.Tag)

        ' Check if player can play this card
        If currentPlayer = 1 AndAlso player1Hand.Contains(cardValue) Then
            PlayCard(1, cardValue)
        ElseIf currentPlayer = 2 AndAlso player2Hand.Contains(cardValue) Then
            PlayCard(2, cardValue)
        End If
    End Sub

    Private Sub PlayCard(player As Integer, cardValue As Integer)
        ' Find a valid pile to play on
        For pileIndex As Integer = 0 To 1
            If centerPiles(pileIndex).Count = 0 Then
                ' Can play any card on empty pile
                centerPiles(pileIndex).Add(cardValue)
                RemoveFromHand(player, cardValue)
                SwitchPlayer()
                UpdateGame()
                Return
            Else
                Dim topCard As Integer = centerPiles(pileIndex).Last()
                If IsValidPlay(topCard, cardValue) Then
                    centerPiles(pileIndex).Add(cardValue)
                    RemoveFromHand(player, cardValue)
                    SwitchPlayer()
                    UpdateGame()
                    Return
                End If
            End If
        Next

        lblStatus.Text = "Invalid move! Try another card."
    End Sub

    Private Function IsValidPlay(topCard As Integer, newCard As Integer) As Boolean
        ' Cards can be played if they are one higher or one lower
        Dim topRank As Integer = (topCard - 1) Mod 13 + 1
        Dim newRank As Integer = (newCard - 1) Mod 13 + 1

        ' Handle Ace (1) and King (13) wrap-around
        If topRank = 1 AndAlso newRank = 13 Then Return True
        If topRank = 13 AndAlso newRank = 1 Then Return True

        Return Math.Abs(topRank - newRank) = 1
    End Function

    Private Sub RemoveFromHand(player As Integer, cardValue As Integer)
        If player = 1 Then
            player1Hand.Remove(cardValue)
        Else
            player2Hand.Remove(cardValue)
        End If
    End Sub

    Private Sub SwitchPlayer()
        currentPlayer = If(currentPlayer = 1, 2, 1)
    End Sub

    Private Sub UpdateGame()
        DisplayCards()
        lblStatus.Text = $"Player {currentPlayer}'s turn. Cards: P1={player1Hand.Count}, P2={player2Hand.Count}"

        ' Check for win conditions
        If player1Hand.Count = 0 Then
            lblStatus.Text = "Player 1 wins!"
            gameActive = False
            btnSpit.Enabled = False
        ElseIf player2Hand.Count = 0 Then
            lblStatus.Text = "Player 2 wins!"
            gameActive = False
            btnSpit.Enabled = False
        End If
    End Sub

    ' Event Handlers
    Private Sub btnNewGame_Click(sender As Object, e As EventArgs) Handles btnNewGame.Click
        InitializeGame()
        CreateDeck()
        DealCards()
        DisplayCards()

        btnDeal.Enabled = True
        btnSpit.Enabled = False
        lblStatus.Text = "Cards dealt. Click 'Spit!' to start game."
    End Sub

    Private Sub btnDeal_Click(sender As Object, e As EventArgs) Handles btnDeal.Click
        ' Reset center piles
        centerPiles(0).Clear()
        centerPiles(1).Clear()

        DisplayCards()
        btnDeal.Enabled = False
        btnSpit.Enabled = True
        lblStatus.Text = "Ready to spit! Click 'Spit!' to begin."
    End Sub

    Private Sub btnSpit_Click(sender As Object, e As EventArgs) Handles btnSpit.Click
        ' Each player places a card in the center piles
        If player1Hand.Count > 0 AndAlso player2Hand.Count > 0 Then
            centerPiles(0).Add(player1Hand(0))
            player1Hand.RemoveAt(0)

            centerPiles(1).Add(player2Hand(0))
            player2Hand.RemoveAt(0)

            gameActive = True
            currentPlayer = 1
            UpdateGame()
            btnSpit.Enabled = False
        End If
    End Sub

    Protected Overrides Sub OnResize(e As EventArgs)
        MyBase.OnResize(e)
        If lblStatus IsNot Nothing Then
            ArrangeControls()
            DisplayCards()
        End If
    End Sub
End Class

' Program entry point
Module Program
    Sub Main()
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(New Form1())
    End Sub
End Module
