Imports System.Drawing
Imports System.Collections.Generic

Public Class Form1
    ' Game state
    Private players As New List(Of Player)
    Private currentPlayerIndex As Integer = 0
    Private currentCards As New List(Of Card)
    Private deck2 As New Deck()
    Private gameStarted As Boolean = False

    ' UI Controls created at runtime
    Private WithEvents btnStartGame As Button
    Private WithEvents btnPlayCards As Button
    Private WithEvents btnPass As Button
    Private WithEvents lblStatus As Label
    Private WithEvents lblCurrentPlayer As Label
    Private WithEvents lblCurrentCards As Label
    Private WithEvents lstPlayers As ListBox
    Private WithEvents pnlPlayerHand As Panel
    Private cardCheckBoxes As New List(Of CheckBox)

    ' Player class
    Private Class Player
        Public Property Name As String
        Public Property Hand As List(Of Card)
        Public Property Rank As String
        Public Property IsHuman As Boolean

        Public Sub New(name As String, isHuman As Boolean)
            Me.Name = name
            Me.IsHuman = isHuman
            Me.Hand = New List(Of Card)()
            Me.Rank = "Citizen"
        End Sub

        Public Function HasCards() As Boolean
            Return Hand.Count > 0
        End Function
    End Class

    ' Card class
    Private Class Card
        Public Property Rank As String
        Public Property Suit As String
        Public Property Value As Integer

        Public Sub New(rank As String, suit As String, value As Integer)
            Me.Rank = rank
            Me.Suit = suit
            Me.Value = value
        End Sub

        Public Overrides Function ToString() As String
            Return $"{Rank} of {Suit}"
        End Function
    End Class

    ' Deck class
    Private Class Deck
        Private cards As New List(Of Card)()
        Private Shared ReadOnly ranks() As String = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"}
        Private Shared ReadOnly suits() As String = {"♠", "♥", "♦", "♣"}

        Public Sub New()
            InitializeDeck()
        End Sub

        Private Sub InitializeDeck()
            cards.Clear()

            ' Create standard 52-card deck
            For Each suit In suits
                For i As Integer = 0 To ranks.Length - 1
                    Dim value As Integer = i + 3 ' 3 is lowest value
                    cards.Add(New Card(ranks(i), suit, value))
                Next
            Next
        End Sub

        Public Sub Shuffle()
            Dim rng As New Random()
            Dim n As Integer = cards.Count

            While n > 1
                n -= 1
                Dim k As Integer = rng.Next(n + 1)
                Dim value = cards(k)
                cards(k) = cards(n)
                cards(n) = value
            End While
        End Sub

        Public Function DealCard() As Card
            If cards.Count = 0 Then
                Return Nothing
            End If

            Dim card = cards(0)
            cards.RemoveAt(0)
            Return card
        End Function

        Public ReadOnly Property Count As Integer
            Get
                Return cards.Count
            End Get
        End Property
    End Class

    Public Sub New()
        ' Initialize form
        Me.Text = "President Card Game"
        Me.Size = New Size(900, 700)
        Me.StartPosition = FormStartPosition.CenterScreen

        CreateControls()
    End Sub

    Private Sub CreateControls()
        ' Title label
        Dim lblTitle As New Label()
        lblTitle.Text = "PRESIDENT CARD GAME"
        lblTitle.Font = New Font("Arial", 16, FontStyle.Bold)
        lblTitle.ForeColor = Color.DarkBlue
        lblTitle.Size = New Size(300, 30)
        lblTitle.Location = New Point(300, 10)
        Me.Controls.Add(lblTitle)

        ' Start game button
        btnStartGame = New Button()
        btnStartGame.Text = "Start New Game"
        btnStartGame.Size = New Size(150, 40)
        btnStartGame.Location = New Point(50, 50)
        btnStartGame.Font = New Font("Arial", 10, FontStyle.Bold)
        btnStartGame.BackColor = Color.LightGreen
        Me.Controls.Add(btnStartGame)

        ' Play cards button
        btnPlayCards = New Button()
        btnPlayCards.Text = "Play Selected Cards"
        btnPlayCards.Size = New Size(150, 40)
        btnPlayCards.Location = New Point(220, 50)
        btnPlayCards.Font = New Font("Arial", 10)
        btnPlayCards.BackColor = Color.LightBlue
        btnPlayCards.Enabled = False
        Me.Controls.Add(btnPlayCards)

        ' Pass button
        btnPass = New Button()
        btnPass.Text = "Pass Turn"
        btnPass.Size = New Size(150, 40)
        btnPass.Location = New Point(390, 50)
        btnPass.Font = New Font("Arial", 10)
        btnPass.BackColor = Color.LightCoral
        btnPass.Enabled = False
        Me.Controls.Add(btnPass)

        ' Status label
        lblStatus = New Label()
        lblStatus.Text = "Game not started"
        lblStatus.Size = New Size(400, 30)
        lblStatus.Location = New Point(50, 100)
        lblStatus.Font = New Font("Arial", 10, FontStyle.Bold)
        lblStatus.ForeColor = Color.DarkRed
        Me.Controls.Add(lblStatus)

        ' Current player label
        lblCurrentPlayer = New Label()
        lblCurrentPlayer.Text = "Current Player: None"
        lblCurrentPlayer.Size = New Size(300, 30)
        lblCurrentPlayer.Location = New Point(50, 130)
        lblCurrentPlayer.Font = New Font("Arial", 10)
        Me.Controls.Add(lblCurrentPlayer)

        ' Current cards label
        lblCurrentCards = New Label()
        lblCurrentCards.Text = "Cards on table: None"
        lblCurrentCards.Size = New Size(300, 30)
        lblCurrentCards.Location = New Point(50, 160)
        lblCurrentCards.Font = New Font("Arial", 10)
        Me.Controls.Add(lblCurrentCards)

        ' Players list box
        lstPlayers = New ListBox()
        lstPlayers.Size = New Size(200, 300)
        lstPlayers.Location = New Point(50, 200)
        lstPlayers.Font = New Font("Arial", 10)
        Me.Controls.Add(lstPlayers)

        ' Player hand panel
        pnlPlayerHand = New Panel()
        pnlPlayerHand.Size = New Size(600, 200)
        pnlPlayerHand.Location = New Point(270, 200)
        pnlPlayerHand.BackColor = Color.WhiteSmoke
        pnlPlayerHand.AutoScroll = True
        pnlPlayerHand.BorderStyle = BorderStyle.FixedSingle
        Me.Controls.Add(pnlPlayerHand)

        ' Instructions label
        Dim lblInstructions As New Label()
        lblInstructions.Text = "Instructions:" & vbCrLf &
                              "1. Click Start Game to begin" & vbCrLf &
                              "2. Select cards from your hand" & vbCrLf &
                              "3. Play cards of same rank" & vbCrLf &
                              "4. Higher value beats lower value" & vbCrLf &
                              "5. 2 is the highest card"
        lblInstructions.Size = New Size(300, 120)
        lblInstructions.Location = New Point(50, 510)
        lblInstructions.Font = New Font("Arial", 9)
        lblInstructions.BackColor = Color.LightYellow
        lblInstructions.BorderStyle = BorderStyle.FixedSingle
        Me.Controls.Add(lblInstructions)
    End Sub

    Private Sub StartGame() Handles btnStartGame.Click
        ' Initialize players
        players.Clear()
        players.Add(New Player("You", True))
        players.Add(New Player("Computer 1", False))
        players.Add(New Player("Computer 2", False))
        players.Add(New Player("Computer 3", False))

        ' Create and shuffle deck
        deck2 = New Deck()
        deck2.Shuffle()

        ' Deal cards
        While deck2.Count > 0
            For Each player In players
                If deck2.Count > 0 Then
                    player.Hand.Add(deck2.DealCard())
                End If
            Next
        End While

        ' Sort each player's hand
        For Each player In players
            player.Hand.Sort(Function(c1, c2) c1.Value.CompareTo(c2.Value))
        Next

        ' Reset game state
        currentPlayerIndex = 0
        currentCards.Clear()
        gameStarted = True

        ' Update UI
        UpdatePlayerList()
        UpdatePlayerHand()
        UpdateStatus("Game started! You go first.")
        UpdateCurrentPlayer()

        btnStartGame.Enabled = False
        btnPlayCards.Enabled = True
        btnPass.Enabled = True

        ' If first player is computer, make computer move
        If Not players(currentPlayerIndex).IsHuman Then
            ComputerTurn()
        End If
    End Sub

    Private Sub UpdatePlayerList()
        lstPlayers.Items.Clear()
        For Each player In players
            lstPlayers.Items.Add($"{player.Name}: {player.Hand.Count} cards - {player.Rank}")
        Next
    End Sub

    Private Sub UpdatePlayerHand()
        pnlPlayerHand.Controls.Clear()
        cardCheckBoxes.Clear()

        Dim player As Player = players(0) ' Human player is always first

        If player Is Nothing OrElse player.Hand.Count = 0 Then
            Return
        End If

        Dim xPos As Integer = 10
        Dim yPos As Integer = 10
        Dim cardWidth As Integer = 80
        Dim cardHeight As Integer = 120

        For i As Integer = 0 To player.Hand.Count - 1
            Dim card = player.Hand(i)

            ' Create card panel
            Dim cardPanel As New Panel()
            cardPanel.Size = New Size(cardWidth, cardHeight)
            cardPanel.Location = New Point(xPos, yPos)
            cardPanel.BackColor = If(card.Suit = "♥" Or card.Suit = "♦", Color.LightPink, Color.White)
            cardPanel.BorderStyle = BorderStyle.FixedSingle

            ' Card rank label
            Dim lblRank As New Label()
            lblRank.Text = card.Rank
            lblRank.Font = New Font("Arial", 14, FontStyle.Bold)
            lblRank.ForeColor = If(card.Suit = "♥" Or card.Suit = "♦", Color.Red, Color.Black)
            lblRank.Location = New Point(5, 5)
            lblRank.Size = New Size(30, 20)
            cardPanel.Controls.Add(lblRank)

            ' Card suit label
            Dim lblSuit As New Label()
            lblSuit.Text = card.Suit
            lblSuit.Font = New Font("Arial", 24)
            lblSuit.ForeColor = If(card.Suit = "♥" Or card.Suit = "♦", Color.Red, Color.Black)
            lblSuit.Location = New Point(25, 40)
            lblSuit.Size = New Size(40, 40)
            cardPanel.Controls.Add(lblSuit)

            ' Card value label (hidden)
            Dim lblValue As New Label()
            lblValue.Text = card.Value.ToString()
            lblValue.Visible = False
            cardPanel.Controls.Add(lblValue)

            ' Checkbox for selection
            Dim chkSelect As New CheckBox()
            chkSelect.Text = ""
            chkSelect.Size = New Size(20, 20)
            chkSelect.Location = New Point(cardWidth - 25, 5)
            chkSelect.Tag = i
            cardCheckBoxes.Add(chkSelect)
            cardPanel.Controls.Add(chkSelect)

            pnlPlayerHand.Controls.Add(cardPanel)

            xPos += cardWidth + 10

            ' Move to next row if needed
            If xPos + cardWidth > pnlPlayerHand.Width - 20 Then
                xPos = 10
                yPos += cardHeight + 10
            End If
        Next
    End Sub

    Private Sub UpdateStatus(message As String)
        lblStatus.Text = message
    End Sub

    Private Sub UpdateCurrentPlayer()
        If currentPlayerIndex >= 0 AndAlso currentPlayerIndex < players.Count Then
            Dim player = players(currentPlayerIndex)
            lblCurrentPlayer.Text = $"Current Player: {player.Name}"
            lblCurrentPlayer.ForeColor = If(player.IsHuman, Color.DarkGreen, Color.DarkBlue)
        End If
    End Sub

    Private Sub UpdateCurrentCards()
        If currentCards.Count = 0 Then
            lblCurrentCards.Text = "Cards on table: None"
        Else
            Dim cardsText As String = ""
            For Each card In currentCards
                cardsText &= card.ToString() & ", "
            Next
            lblCurrentCards.Text = "Cards on table: " & cardsText.TrimEnd(", ".ToCharArray())
        End If
    End Sub

    Private Sub PlayCards() Handles btnPlayCards.Click
        If Not gameStarted Then Return

        Dim humanPlayer = players(0)
        If Not humanPlayer.IsHuman Then Return

        ' Get selected cards
        Dim selectedIndices As New List(Of Integer)()
        For Each chk In cardCheckBoxes
            If chk.Checked Then
                selectedIndices.Add(CInt(chk.Tag))
            End If
        Next

        If selectedIndices.Count = 0 Then
            UpdateStatus("Please select at least one card to play!")
            Return
        End If

        ' Validate selection (all cards must have same rank)
        Dim selectedCards As New List(Of Card)()
        For Each index In selectedIndices
            selectedCards.Add(humanPlayer.Hand(index))
        Next

        Dim firstRank = selectedCards(0).Rank
        For Each card In selectedCards
            If card.Rank <> firstRank Then
                UpdateStatus("All selected cards must be of the same rank!")
                Return
            End If
        Next

        ' Validate play against current cards
        If currentCards.Count > 0 Then
            ' Must play same number of cards
            If selectedCards.Count <> currentCards.Count Then
                UpdateStatus($"You must play {currentCards.Count} card(s) to beat the current play!")
                Return
            End If

            ' Must play higher value
            If selectedCards(0).Value <= currentCards(0).Value Then
                UpdateStatus("Your cards must have higher value than the current cards!")
                Return
            End If
        End If

        ' Remove cards from hand
        selectedIndices.Sort()
        selectedIndices.Reverse()

        For Each index In selectedIndices
            currentCards.Add(humanPlayer.Hand(index))
            humanPlayer.Hand.RemoveAt(index)
        Next

        ' Update current cards display
        UpdateCurrentCards()

        ' Check if player won
        If humanPlayer.Hand.Count = 0 Then
            UpdateStatus("Congratulations! You won this round!")
            humanPlayer.Rank = GetNextRank()
            EndTurn()
            Return
        End If

        ' Update hand display
        UpdatePlayerHand()
        UpdatePlayerList()

        ' Move to next player
        NextPlayer()

        If players(currentPlayerIndex).IsHuman Then
            UpdateStatus("Your turn! Select cards to play.")
        Else
            UpdateStatus("Computer's turn...")
            ComputerTurn()
        End If
    End Sub

    Private Sub PassTurn() Handles btnPass.Click
        If Not gameStarted Then Return

        Dim currentPlayer = players(currentPlayerIndex)
        If Not currentPlayer.IsHuman Then Return

        ' Clear current cards if everyone passed
        Dim passedCount As Integer = 0
        For Each player In players
            If Not player.HasCards() Then passedCount += 1
        Next

        If passedCount = players.Count - 1 Then
            currentCards.Clear()
            UpdateCurrentCards()
            UpdateStatus("Round cleared! New round starts.")
        End If

        NextPlayer()

        If players(currentPlayerIndex).IsHuman Then
            UpdateStatus("Your turn! Select cards to play.")
        Else
            UpdateStatus("Computer's turn...")
            ComputerTurn()
        End If
    End Sub

    Private Sub ComputerTurn()
        If Not gameStarted Then Return

        Dim computer = players(currentPlayerIndex)
        If computer.IsHuman Then Return

        ' Simple AI logic
        Dim playableCards As New List(Of Card)()

        If currentCards.Count = 0 Then
            ' Play lowest single card or pair
            If computer.Hand.Count >= 1 Then
                playableCards.Add(computer.Hand(0))
            End If
        Else
            ' Try to beat current cards
            Dim requiredValue = currentCards(0).Value + 1
            Dim requiredCount = currentCards.Count

            For Each card In computer.Hand
                If card.Value >= requiredValue Then
                    ' Count how many of this rank we have
                    Dim count As Integer = 0
                    For Each c In computer.Hand
                        If c.Rank = card.Rank Then count += 1
                    Next

                    If count >= requiredCount Then
                        For i As Integer = 0 To requiredCount - 1
                            For Each c In computer.Hand
                                If c.Rank = card.Rank Then
                                    playableCards.Add(c)
                                    Exit For
                                End If
                            Next
                        Next
                        Exit For
                    End If
                End If
            Next
        End If

        If playableCards.Count > 0 Then
            ' Play the cards
            For Each card In playableCards
                computer.Hand.Remove(card)
                currentCards.Add(card)
            Next

            UpdateCurrentCards()
            UpdateStatus($"{computer.Name} played {playableCards.Count} card(s)")

            ' Check if computer won
            If computer.Hand.Count = 0 Then
                UpdateStatus($"{computer.Name} won this round!")
                computer.Rank = GetNextRank()
                EndTurn()
                Return
            End If
        Else
            ' Computer passes
            UpdateStatus($"{computer.Name} passed.")
        End If

        UpdatePlayerList()

        ' Move to next player
        NextPlayer()

        If players(currentPlayerIndex).IsHuman Then
            UpdateStatus("Your turn! Select cards to play.")
        Else
            ComputerTurn()
        End If
    End Sub

    Private Sub NextPlayer()
        If players.Count = 0 Then Return

        Do
            currentPlayerIndex = (currentPlayerIndex + 1) Mod players.Count

            ' Skip players who have finished all cards
            If players(currentPlayerIndex).HasCards() Then
                Exit Do
            End If
        Loop

        UpdateCurrentPlayer()
    End Sub

    Private Function GetNextRank() As String
        Dim assignedRanks As New List(Of String)

        For Each p In players
            If p.Rank <> "Citizen" Then
                assignedRanks.Add(p.Rank)
            End If
        Next

        Select Case assignedRanks.Count
            Case 0
                Return "President"
            Case 1
                Return "Vice President"
            Case 2
                Return "Vice Asshole"
            Case Else
                Return "Asshole"
        End Select
    End Function

    Private Sub EndTurn()
        UpdatePlayerList()

        ' Count players who still have cards
        Dim activePlayers As Integer = 0

        For Each player In players
            If player.Hand.Count > 0 Then
                activePlayers += 1
            End If
        Next

        ' Only one player left = game over
        If activePlayers <= 1 Then
            FinishGame()
            Return
        End If

        NextPlayer()

        If players(currentPlayerIndex).IsHuman Then
            UpdateStatus("Your turn!")
        Else
            ComputerTurn()
        End If
    End Sub

    Private Sub FinishGame()
        ' Assign last remaining rank
        For Each player In players
            If player.Hand.Count > 0 AndAlso player.Rank = "Citizen" Then
                player.Rank = "Asshole"
            End If
        Next

        UpdatePlayerList()

        Dim results As String = "Game Over!" & vbCrLf & vbCrLf

        For Each player In players
            results &= $"{player.Name}: {player.Rank}" & vbCrLf
        Next

        MessageBox.Show(results, "Final Rankings")

        gameStarted = False

        btnStartGame.Enabled = True
        btnPlayCards.Enabled = False
        btnPass.Enabled = False

        UpdateStatus("Game finished. Click Start New Game to play again.")
    End Sub
End Class
