Click here to Skip to main content
15,394,479 members
Articles / Programming Languages / XML
Article
Posted 4 Jun 2022

Tagged as

Stats

23.6K views
263 downloads
15 bookmarked

Schafkopf Starter Kit 2.7

Rate me:
Please Sign up or sign in to vote.
3.30/5 (13 votes)
19 Jul 2022CPOL7 min read
This article and the demo are about getting started using my Schafkopf Starter Kit project.
There are many CodeProject articles about other card games, but nothing with Schafkopf. So I started to create this document. I will not describe and explain every detail of the complete demo project, but how to use it and play the game.

Download Schafkopf.zip

Introduction

This article and the demo are about getting started using my SchafkopfStarterKit VB.NET project.

Version 2.6 or higher includes source code for C# in CSchafkopfStarterKit project. 

Background

There are many CodeProject articles about other card games, but nothing with Schafkopf. So I started to create this document.

I will not describe and explain every detail of the complete demo project but how to use it and play the game.

Using the Code

Here is a Quick Overview

MainWindow Concept and Code

When you start the program, the main window shows a complete deck of cards as a card fan and renders it in a circular panel (based on the above mentioned CodeProject article, Power of Templates in Control Development Within Windows Presentation Foundation including this credit: „I took this panel from the color swatch sample that ships with Microsoft Expression Blend“).

On top of the window, there are some menu items – click on 1. New Game please, then you should see something like that:

Image 1

MainWindow has the following controls:

  • A Grid with
    • a StackPanel called MyPanel
    • a WrapPanel (on top) with the menu items
  • HistoryTextBox for Trick History
  • Panels for the cards within the StackPanel called MyPanel
    • DockPanel Panel0 on top for player0 = North
    • DockPanel Panel2 on bottom for player2 = South
    • WrapPanel Panel1 on right side for player1 = East
    • WrapPanel Panel3 on left side for player3 = West
    • DockPanel CenterPanel

Card Resources and Definitions

The files in folder Resources are taken from [2].

I have changed some things as follows:

  • Jacks         => Unter => Under (or Sergeant)
  • Queens     => Ober => Over (or Officer)
  • Diamonds => Shells or Ring
  • Clubs        => Acorn

To keep things easy, I left Spades (which could become „Grass“) as it was.

Class Bridge is taken from [1].

I have changed the cards deck from 52 to 32 and adjusted the card values and colors as described above.

Putting Things Together - WPF Concept and Code

Shuffle and Distribute Cards

Function ShuffleArray and Function RandomNumber are taken from Reference [4].

Classes PlayingCard and CircularPanel are taken from Reference [2].

I have added the following properties:

  • Public Property CardSymbol As String
  • Public Property CardShortName As String
  • Public Property IsCallAce As Boolean
  • Public Property IsAlreadyPlayed As Boolean
  • Private Shared CardOwnerProperty As DependencyProperty = DependencyProperty.Register("CardOwner", GetType(CardOwner), GetType(PlayingCard), New PropertyMetadata(CardOwner.North))

. . .

When you click on 1. New Game, the ShuffleArray method is started.

After that, the shuffled cards are distributed to the four CardPanels.

VB.NET
Public Sub NewGame()

            Me.Deck.Children.Clear()

            handCards0.Clear()
            handCards1.Clear()
            handCards2.Clear()
            handCards3.Clear()

            Panel0.Children.Clear()
            Panel2.Children.Clear()
            Panel1.Children.Clear()
            Panel3.Children.Clear()

            CenterPanel.Children.Clear()
            cards.Clear()

            iTeamDeclarer = 0
            iTeamOpponent = 0

            HistoryTextBox.Text = "Trick History: " & Environment.NewLine

            RufAs.CardOwner = -1
            bh.iCoSpieler = -1
            bh.iGeber = bh.iGeber + 1
            If bh.iGeber = 4 Then bh.iGeber = 0
            nextMove = bh.iGeber
            bh.leadPlayer = bh.iGeber

            GameStatus = 2
            cbxDeclarer.SelectedIndex = 4
            cbxContractSuit.SelectedIndex = 8
            PlayCard.IsEnabled = False

            labelTrumpLead.Content = "        "
            labelTrumpcard.Content = "Display for Game Type"

            For Each type As CardType In [Enum].GetValues(GetType(CardType))
                For Each value As CardValue In [Enum].GetValues(GetType(CardValue))

                    Dim card As PlayingCard = New PlayingCard()

                    card.CardType = type
                    card.CardValue = value
                    card.Height = 135
                    card.Width = 85

                    If card.CardType = 0 Then card.CardSymbol = "Ꚛ"
                    If card.CardType = 1 Then card.CardSymbol = "♥"
                    If card.CardType = 2 Then card.CardSymbol = "♠"
                    If card.CardType = 3 Then card.CardSymbol = "Ⴖ"

                    card.CardShortName = card.CardValue
                    If card.CardValue = 2 Then card.CardShortName = "U"
                    If card.CardValue = 3 Then card.CardShortName = "O"
                    If card.CardValue = 4 Then card.CardShortName = "K"
                    If card.CardValue = 11 Then card.CardShortName = "A"
                    cards.Add(card)
                Next
            Next

            cards = ShuffleArray(cards)

            Dim cardShuffled As PlayingCard = New PlayingCard()
            Dim i As Integer = 0

            For Each cardShuffled In cards

                AddHandler cardShuffled.Click, AddressOf card_Click

                If i = 0 Or i = 4 Or i = 8 Or i = 12 Or i = 16 Or i = 20 Or i = 24 Or 
                   i = 28 Then

                    If handCards0.Count > 0 Then
                        For n = 0 To handCards0.Count - 1
                            If handCards0.Contains(cardShuffled) = False AndAlso 
                               cardShuffled.CardType < handCards0.Item(n).CardType Then

                                cardShuffled.CardOwner = CardOwner.North
                                If handCards0.Contains(cardShuffled) = False Then 
                                   handCards0.Insert(n, cardShuffled)

                                Exit For
                            End If
                        Next

                        If handCards0.Contains(cardShuffled) = False Then 
                           cardShuffled.CardOwner = CardOwner.North

                        If handCards0.Contains(cardShuffled) = False Then 
                           handCards0.Add(cardShuffled)

                    Else

                        If handCards0.Contains(cardShuffled) = False Then 
                           cardShuffled.CardOwner = CardOwner.North
                        If handCards0.Contains(cardShuffled) = False Then 
                           handCards0.Add(cardShuffled)

                    End If

                End If

                If i = 1 Or i = 5 Or i = 9 Or i = 13 Or i = 17 Or i = 21 Or i = 25 Or 
                   i = 29 Then

                    'Panel2.Children.Add(cardShuffled)
                    If handCards2.Count > 0 Then
                        For n = 0 To handCards2.Count - 1
                            If handCards2.Contains(cardShuffled) = False AndAlso 
                               cardShuffled.CardType < handCards2.Item(n).CardType Then

                                If handCards2.Contains(cardShuffled) = False Then
                                    cardShuffled.CardOwner = CardOwner.South
                                    handCards2.Insert(n, cardShuffled)
                                End If
                                Exit For
                            End If
                        Next

                        If handCards2.Contains(cardShuffled) = False Then
                            cardShuffled.CardOwner = CardOwner.South
                            handCards2.Add(cardShuffled)
                        End If
                    Else
                        If handCards2.Contains(cardShuffled) = False Then
                            cardShuffled.CardOwner = CardOwner.South
                            handCards2.Add(cardShuffled)
                        End If
                    End If
                End If

                If i = 2 Or i = 6 Or i = 10 Or i = 14 Or i = 18 Or i = 22 Or i = 26 Or 
                   i = 30 Then

                    'Panel1.Children.Add(cardShuffled)
                    If handCards1.Count > 0 Then
                        For n = 0 To handCards1.Count - 1
                            If handCards1.Contains(cardShuffled) = False AndAlso 
                               cardShuffled.CardType < handCards1.Item(n).CardType Then

                                If handCards1.Contains(cardShuffled) = False Then 
                                   cardShuffled.CardOwner = CardOwner.East

                                If handCards1.Contains(cardShuffled) = False Then 
                                   handCards1.Insert(n, cardShuffled)

                                Exit For
                            End If
                        Next

                        If handCards1.Contains(cardShuffled) = False Then 
                           cardShuffled.CardOwner = CardOwner.East

                        If handCards1.Contains(cardShuffled) = False Then 
                           handCards1.Add(cardShuffled)

                    Else

                        If handCards1.Contains(cardShuffled) = False Then 
                           cardShuffled.CardOwner = CardOwner.East

                        If handCards1.Contains(cardShuffled) = False Then 
                           handCards1.Add(cardShuffled)

                    End If
                End If

                If i = 3 Or i = 7 Or i = 11 Or i = 15 Or i = 19 Or i = 23 Or i = 27 Or 
                   i = 31 Then

                    'Panel3.Children.Add(cardShuffled)

                    If handCards3.Count > 0 Then
                        For n = 0 To handCards3.Count - 1
                            If handCards3.Contains(cardShuffled) = False AndAlso 
                               cardShuffled.CardType < handCards3.Item(n).CardType Then

                                If handCards3.Contains(cardShuffled) = False Then 
                                   cardShuffled.CardOwner = CardOwner.West

                                If handCards3.Contains(cardShuffled) = False Then 
                                   handCards3.Insert(n, cardShuffled)

                                Exit For
                            End If
                        Next

                        If handCards3.Contains(cardShuffled) = False Then 
                           cardShuffled.CardOwner = CardOwner.West

                        If handCards3.Contains(cardShuffled) = False Then 
                           handCards3.Add(cardShuffled)

                    Else

                        If handCards3.Contains(cardShuffled) = False Then 
                           cardShuffled.CardOwner = CardOwner.West

                        If handCards3.Contains(cardShuffled) = False Then 
                           handCards3.Add(cardShuffled)

                    End If
                End If
                i += 1
            Next

            For Each cardShuffled0 In handCards0
                Panel0.Children.Add(cardShuffled0)
            Next

            For Each cardShuffled2 In handCards2
                Panel2.Children.Add(cardShuffled2)
            Next

            For Each cardShuffled1 In handCards1
                Panel1.Children.Add(cardShuffled1)
            Next

            For Each cardShuffled3 In handCards3
                Panel3.Children.Add(cardShuffled3)
            Next

            Panel0 = SortHandCards(Panel0)
            Panel1 = SortHandCards(Panel1)
            Panel2 = SortHandCards(Panel2)
            Panel3 = SortHandCards(Panel3)

            Me.Deck.AddHandler(ToggleButton.CheckedEvent, _
                    New RoutedEventHandler(AddressOf OnCardSelected))

        End Sub

Selection of the Declarer and the Game Type

The selection of the declarer and the game type are also human controlled (by the user).

You have to follow the steps as shown in the menu on top.

1. New Game

A click on that menu item starts the ShuffleArray method.

After that, the shuffled cards are distributed to the four CardPanels.

2. Select Declarer

From the combobox on the right of this label, you can select the declarer of the game (who plays a solo or calls an ace).

3. Select GameType

From the combobox on the right of this label, you can select which game type the declarer of the game wants to play – select which solo he wants to play or which ace he wants to call.

Menu item 4. Ready to Play is only active after steps 2. And 3. are completed.

After you clicked it, the Auto Play feature moves a card to the CenterPanel or - if it is the human player's turn – nothing happens until the human player clicked on one of his cards.

The label „Waiting for Card from Player:“ shows whose turn is next.

Place a Card on the CenterPanel

If it is the human player's turn, he can play one of them by clicking on one of his cards.

The clicked card is then automatically moved to the DockPanel CenterPanel.

VB.NET
Private Sub card_Click (ByVal sender As Object, ByVal e As System.EventArgs)

      Dim ACP As New AutoCardPlay

           If CenterPanel.Children.Count = 4 Then
               CenterPanel.Children.Clear()
               HistoryTextBox.AppendText(Environment.NewLine & _
                                         "-----------------------" &
                  Environment.NewLine)
           End If

           sender.Parent.Children.Remove(sender)

           Dim cardColor As String
           Dim cardValue As String
           Dim cardOwner As String

           If sender.CardType = 0 Then cardColor = "Ꚛ"
           If sender.CardType = 1 Then cardColor = "♥"
           If sender.CardType = 2 Then cardColor = "♠"
           If sender.CardType = 3 Then cardColor = "Ⴖ"

           cardValue = sender.CardValue

           If sender.CardValue = 2 Then cardValue = "U"
           If sender.CardValue = 3 Then cardValue = "O"
           If sender.CardValue = 4 Then cardValue = "K"
           If sender.CardValue = 11 Then cardValue = "A"

           If sender.CardOwner = 0 Then cardOwner = "North"
           If sender.CardOwner = 1 Then cardOwner = "East   "
           If sender.CardOwner = 2 Then cardOwner = "South"
           If sender.CardOwner = 3 Then cardOwner = "West  "

           If sender.CardType = RufAs.CardType AndAlso sender.CardShortName = _
                                "A " Then
               RufAs.IsAlreadyPlayed = True
           End If

           HistoryTextBox.AppendText(Environment.NewLine & cardOwner & ": " _
                                     & cardColor &
              " " & cardValue)

           CenterPanel.Children.Add(CType(sender, UIElement))
           System.Threading.Thread.Sleep(250)

           If totalMove Mod 4 = 0 Then Trick_Content.PrevCard1 = Trick_Content.Card1
           If totalMove Mod 4 = 0 Then Trick_Content.PrevCard2 = Trick_Content.Card2
           If totalMove Mod 4 = 0 Then Trick_Content.PrevCard3 = Trick_Content.Card3
           If totalMove Mod 4 = 0 Then
               If Trick_Content.Card4 IsNot Nothing Then Trick_Content.PrevCard4 =
                  Trick_Content.Card4
           End If

           If totalMove Mod 4 = 1 Then
               Trick_Content.Card1 = cardValue.ToString & " " & cardColor
               Trick_Content.Card2 = Nothing
               Trick_Content.Card3 = Nothing
               Trick_Content.Card4 = Nothing
               Trick_Content.PlayerIdCard2 = -1
               Trick_Content.PlayerIdCard3 = -1
               Trick_Content.PlayerIdCard3 = -1
           End If

           If totalMove Mod 4 = 2 Then Trick_Content.Card2 = cardValue.ToString &
              " " & cardColor

           If totalMove Mod 4 = 3 Then Trick_Content.Card3 = cardValue.ToString &
              " " & cardColor

           If totalMove Mod 4 = 0 Then Trick_Content.Card4 = cardValue.ToString &
              " " & cardColor

           If totalMove Mod 4 = 1 Then Trick_Content.CountCardsInTrick = 1
           If totalMove Mod 4 = 2 Then Trick_Content.CountCardsInTrick = 2
           If totalMove Mod 4 = 3 Then Trick_Content.CountCardsInTrick = 3
           If totalMove Mod 4 = 0 Then Trick_Content.CountCardsInTrick = 4

           If totalMove Mod 4 = 1 Then Trick_Content.PlayerIdCard1 = nextMove
           If totalMove Mod 4 = 2 Then Trick_Content.PlayerIdCard2 = nextMove
           If totalMove Mod 4 = 3 Then Trick_Content.PlayerIdCard3 = nextMove
           If totalMove Mod 4 = 0 Then Trick_Content.PlayerIdCard4 = nextMove

           If totalMove Mod 4 = 1 Then
               tc = Trick_Content.Card1
               Trick_Content.CurrentTrickWinner = nextMove ' totalMove Mod 4
           End If

           If totalMove Mod 4 = 2 Then
               tc = Trick_Content.Card2
               Trick_Content.CurrentTrickWinner = GetCurrentTrickWinner(Me,
                  totalMove Mod 4)
           End If

           If totalMove Mod 4 = 3 Then
               tc = Trick_Content.Card3
               Trick_Content.CurrentTrickWinner = GetCurrentTrickWinner(Me,
                  totalMove Mod 4)
           End If

           If totalMove Mod 4 = 0 Or totalMove Mod 4 = 4 Then
               tc = Trick_Content.Card4
               Trick_Content.CurrentTrickWinner = GetCurrentTrickWinner(Me,
                  totalMove Mod 4)
           End If

           If totalMove Mod 4 = 1 Then
               sWenz = ""
               sOber = ""

               If sender.CardValue = 2 Or sender.CardValue = 3 Then
                   If totalMove Mod 4 = 1 Then bh.leadSuit = bh.trumpCard
               Else
                   bh.leadSuit = sender.CardType
               End If

               labelTrumpLead.Content = "Trump or Lead: " & bh.suitRows(bh.leadSuit)

           End If

           nextMove = (nextMove + 1) Mod 4
           updateTurnToMoveMessage(nextMove)

           If totalMove Mod 4 = 0 Then
               tally()
               GameStatus = GameState.FirstCardInTrick
               System.Threading.Thread.Sleep(500)
           Else
               GameStatus = GameState.AnotherCardInTrick
           End If

           totalMove += 1

           Trick_Content.PossibleWinnerPlayerID =
              TrickWinnerID(Trick_Content.CurrentTrickWinner)

           Dim cardsPanel As Object = {Panel0, Panel1, Panel2, Panel3}

           For i = 0 To 3

               If GameStatus.ToString = "SpielAus" Then Exit Sub

               If nextMove = 2 Then
                   If nextMove = 2 Then Exit Sub
               Else
                   If nextMove = i Then ACP.SelectCard(Nothing, nextMove, bh.declarer,
                      GameStatus, cardsPanel(nextMove), _
                      bh.trumpCard, Nothing, Me, bh.leadSuit)
                   If nextMove = i Then If i > 0 Then GameStatus = _
                                                 GameState.AnotherCardInTrick
               End If
           Next
       End Sub

If it is the auto player's turn, the Public Sub AutoPlaceCardOnTable method does something similar like the Sub card_Click.

At the end of this method:

VB.NET
ACP.SelectCard(Nothing, nextMove, bh.declarer, GameStatus, cardsPanel(nextMove), 
    bh.trumpCard, Nothing, Me, bh.leadSuit)

is called. ACP is a New AutoCardPlay object.

With nextMove, we control whose turn it is to play a card.

In Sub SelectCard, we make a difference between the first card of a trick and the other cards of a trick.

For the first card of a trick, the methods SelectBestFirstCard and WenzBestFirstCard are relevant.

For the other cards of a trick, the method SelectBestReturnCard is normally used.

All of these methods may call other Functions or Subs like:

  • OptimizeSelection
  • PlayTogether_WenzUsage
  • ContainsHandCardsStandardTrumps
  • GetLowOfHandCards
  • GetBestOfHandCards

Most used method is cardLessThan which is very important for comparing values of cards.

The original version is taken from [1]. I extended it because of the special value of „Overs“ and „Unders“ in the Schafkopf game.

At the end of the SelectCard method, we use the following code:

VB.NET
If CurrentCard IsNot Nothing Then

    CardsPanel.Children.Remove(CurrentCard)
    MyForm.AutoPlaceCardOnTable(CurrentCard, PlayerID)

End If

to remove the CurrentCard from the players CardsPanel and call the AutoPlaceCardOnTable method again to paste the CurrentCard to the CenterPanel and go on with Auto Play.

TrickContent is another important class which we need for using cardLessThan or other features.

VB.NET
Public Class TrickContent

    Public Property IdLeadSuit As Integer

    Public Property Card1 As String
    Public Property Card2 As String
    Public Property Card3 As String
    Public Property Card4 As String

    Public Property CurrentTrickWinner As Integer  
    Public Property PossibleWinnerPlayerID As Integer  
    Public Property PossibleWinnerCardString As String
    Public Property CountCardsInTrick As Integer

    Public Property GetSumOfCardValuesInTrick As Integer

    Public Property PlayerIdCard1 As Integer
    Public Property PlayerIdCard2 As Integer
    Public Property PlayerIdCard3 As Integer
    Public Property PlayerIdCard4 As Integer

    Public Property PrevCard1 As String
    Public Property PrevCard2 As String
    Public Property PrevCard3 As String
    Public Property PrevCard4 As String

End Class

Auto Play Feature

At the end of:

VB.NET
      Public Sub AutoPlaceCardOnTable

. . .

. . .

            Dim cardsPanel As Object = {Panel0, Panel1, Panel2, Panel3}
            For i = 0 To 3

                If GameStatus.ToString = "SpielAus" Then Exit Sub

                If nextMove = 2 Then
                    If nextMove = 2 Then Exit Sub
                Else
                    If nextMove = i Then ACP.SelectCard(Nothing, nextMove, bh.declarer, 
                       GameStatus, cardsPanel(nextMove), _
                                   bh.trumpCard, Nothing, Me, bh.leadSuit)
                    If nextMove = i Then If i > 0 _
                    Then GameStatus = GameState.AnotherCardInTrick
                End If

            Next

        End Sub

We take a break If nextMove = 2 (this means Human Player needs to place a card) or run ACP.SelectCard again if nextMove <> 2.

We stop the game If GameStatus.ToString = "SpielAus".

Implementing Schafkopf Rules

After some time, my coding resulted in many, many loops when checking a players cards and endless "rules" which are done with "If, Then, ElseIf ..." statements. But it seems to work very well now.

The main problem is how to find possible issues within those code parts.

The new Version 2.6 or higher reaches an improved playing level, like medium playing level.
 

VB.NET
Private Function SelectBestFirstCard(ByVal CardsPanel As Object, PlayerID As Integer, 
   DeclarerID As Integer, GameStatus As Object, sHandCards As Object, _
                                                TrumpCardID As Integer, 
   CorrectCards As Object, MyForm As MainWindow, LeadSuitID As Integer) As PlayingCard 

            Dim MyBridge As New Bridge
            'Dim sCard As String
            'Dim sCardColor As String
            'Dim sCardValue As String
            Dim CurrentCard As PlayingCard
            Dim bTeamDeclarer As Boolean
            Dim bTeamOpponent As Boolean

            If MyForm.GameOver = True Then Exit Function
            If GameStatus.ToString = "SpielAus" Then MyForm.GameOver = True
            If GameStatus.ToString = "SpielAus" Then Exit Function

            If PlayerID <> DeclarerID And PlayerID <> MyForm.iCoSpieler Then 
               bTeamOpponent = True
            If PlayerID = DeclarerID Or PlayerID = MyForm.iCoSpieler Then 
               bTeamDeclarer = True

            With CardsPanel.Children

                'PlayerID = DeclarerID Or PlayerID = MyForm.iCoSpieler
                If .Count > 0 AndAlso bTeamDeclarer = True Then
                    For n = 0 To .Count - 1
                        If .Item(n).CardType = TrumpCardID Then
                            If sHandCards.ToString.Contains("A") = True AndAlso 
                               DeclarerID = PlayerID Then
                                If MyForm.iTricks = 5 Or MyForm.iTricks = 6 Or 
                                   MyForm.iTricks = 7 Then
                                    If SearchInCardsPanel(11, CardsPanel).CardType <> 
                                        TrumpCardID Then
                                        CurrentCard = SearchInCardsPanel(11, CardsPanel)
                                    End If
                                End If
                            Else
                                Dim s As String = .Item(n).CardShortName
                                If s.Contains(GetBestOfHandCards_
                                     (CardsPanel, PlayerID, DeclarerID, 
                                   GameStatus, sHandCards, TrumpCardID, "RufAs", MyForm, 
                                   LeadSuitID)) Then
                                    CurrentCard = CardsPanel.Children.Item(n)
                                End If
                            End If

                        End If
                    Next
                End If

                If .Count > 0 AndAlso bTeamDeclarer = True Then
                    For n = 0 To .Count - 1
                        If .Item(n).CardType <> TrumpCardID Then
                            Dim sO As String
                            If TrumpCardID = 4 Then sO = "X"
                            If TrumpCardID <> 4 Then sO = "O"
                            If .Item(n).CardShortName.Contains(sO) Or 
                               .Item(n).CardShortName.Contains("U") Then
                                CurrentCard = .Item(n)
                                LeadSuitID = TrumpCardID
                                MyBridge.leadSuit = TrumpCardID
                            End If
                        End If
                    Next
                End If

                ' RufAs Suchen (wenn nicht CoSpieler)
                If bTeamOpponent = True Then

                    If .Count > 0 Then
                        For n = 0 To .Count - 1
                            If .Item(n).CardType = LeadSuitID Then
                                'If .Item(n).CardType <> TrumpCardID Then
                                Dim sO As String
                                If TrumpCardID = 4 Then sO = "X"
                                If TrumpCardID <> 4 Then sO = "O"
                                If .Item(n).CardShortName.Contains(sO) = False AndAlso
                                    .Item(n).CardShortName.Contains("U") = False Then
                                    CurrentCard = .Item(n)
                                End If
                                'End If
                            End If
                        Next
                    End If

                    If .Count > 0 AndAlso MyForm.RufAs.IsAlreadyPlayed = False AndAlso 
                       MyForm.iCoSpieler > -1 Then
                        For n = 0 To .Count - 1
                            If .Item(n).CardType <> TrumpCardID AndAlso 
                               .Item(n).CardType = MyForm.RufAs.CardType Then
                                Dim sO As String
                                If TrumpCardID = 4 Then sO = "X"
                                If TrumpCardID <> 4 Then sO = "O"
                                If .Item(n).CardShortName.Contains(sO) = False AndAlso
                                    .Item(n).CardShortName.Contains("U") = False Then
                                    CurrentCard = .Item(n)
                                    MyForm.RufAs.IsAlreadyPlayed = True
                                End If
                            End If
                        Next
                    End If

                End If

                ' CurrentCard Is Nothing 

                If .Count > 0 AndAlso CurrentCard Is Nothing Then
                    For n = 0 To .Count - 1
                        CurrentCard = .Item(n)
                    Next
                End If

            End With

            Return CurrentCard

        End Function

About Version 2.6 or higher

This version includes all improvements from v1.5 to 2.3

And it includes a converted version of the project to C# what caused some trouble but finally it seems to work now. For unknown reasons, the C# 2.0 version had a worse playing level than the VB.NET one. 

With version 2.6 or higher, both - VB.NET and C# - projects are at a comparable level. 

Conclusion

This is only a demo – it is not production ready.

But I think it will allow you to play Schafkopf with / against your computer and have a lot of fun.

Final Note

I am very interested in feedback of any kind - problems, suggestions and other.

Credits / Reference

History

  • 19th July, 2022 - VB and C# Version 2.7 include bug fixes and improved Team Playing. 
  • 11th July, 2022 - replaced dead link, VB and C# Version 2.6 with an improved playing level
  • 7th July, 2022 - VB and C# Version 2.5 with an improved playing level
  • 1st July, 2022 - VB and C# Version 2.3 come along with some improvements
  • 25th June, 2022 - VB and C# Version 2.2 come along with some improvements
  • 21st June, 2022 - C# Version 2.1 with an improved playing level
  • 19th June, 2022 - Version 2.0 reaches almost medium playing level. NEW: C# Version of this project.
  • 15th June, 2022 - Version 1.8 reaches an improved playing level, almost like medium playing level and fixes some bugs
  • 12th June, 2022 - Version 1.7 reaches an improved playing level, almost like medium playing level and includes some bug fixes as well
  • 10th June, 2022 - Version 1.6 improves Auto Playing Level and includes some bug fixes as well
  • 7th June, 2022 - Version 1.5 allows an improved Auto Playing Level and includes some bug fixes as well
  • 4th June, 2022 - Initial submission

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Jo_vb.net
Engineer
Germany Germany
Retired

Comments and Discussions

 
NewsHere is the link to Part 2 of this project: Pin
Jo_vb.net22-Jul-22 11:45
MemberJo_vb.net22-Jul-22 11:45 
QuestionSome architectual improvements Pin
KarstenK19-Jul-22 4:25
mveKarstenK19-Jul-22 4:25 
SuggestionSimplification Pin
Tony Hill12-Jun-22 4:37
mveTony Hill12-Jun-22 4:37 
GeneralRe: Simplification Pin
Jo_vb.net12-Jun-22 5:12
MemberJo_vb.net12-Jun-22 5:12 
GeneralRe: Simplification Pin
f_tom22-Jun-22 5:07
Memberf_tom22-Jun-22 5:07 
GeneralRe: Simplification Pin
Graeme_Grant11-Jul-22 2:45
professionalGraeme_Grant11-Jul-22 2:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.