Saturday, July 27, 2024

Euchre (card game) Strategy Brainstorming

What's a more Michiganian card game than Euchre?

Euchre is a card game using all 9-A cards (24 total). 20 cards are dealt, 5 to each player (4 players), and I have played it by dealing 2, then 3, then 2, then 3, and 3, 2, 3, 2 to get 5. In this project, I am just going to simplify and deal 1 card each. In person, the 3/2 approach speeds it up. Does it matter on computers? The distribution of cards is different, so I will tackle that later. But first, strategy and this will be a to do list of things to add to what I have done so far.


Intro to the game

Player 1 is next to the dealer (player 4) and the first to tell dealer to pick up (aka "calling it", the trump suit) the card turned over (21st card) or pass to player 2. The dealer then discards one of their cards. Player 1 works with player 3 to get three tricks. This earns players 1 and 3 one point. If they get all five, they get two points, and you can "shoot the moon". This means your partner sits out and you play alone. There is also an optional rule where the dealer can shoot the moon which overrides the first person to call it. In either case, 5 points can be given (online I am seeing some weird point variations). I won't be including this, so the first player to tell dealer to pick up determines trump. If 3 tricks are not won by the team calling it, the other team gets two points. In this case, the team that called it and didn't get three tricks is referred to as being "euchred". I think a new rule could be instead to lose 2 points if you want the game to last longer. I might add that later.

Strategy and evaluation are very similar. The difference is how far the human can calculate in a limited time frame. Evaluation before playing? In the chess world, we call that preparation. So, in a way I am doing both strategy and evaluation here, but I am going to stick to simplicity.

The first factor is whether or not you are the dealer and what card is being picked up.

The second is a guideline, where the player calling it tries to get two tricks and relies on their partner to get one.

The third involves a second round of bidding. If no one calls it in the first round, the remaining three suits can be called in the second round. Also, in the second round if players 1-3 don't call it, the dealer has to. This is referred to as "stick the dealer". I will add this, but it will have zero effect on strategy. It won't be used so the opposing team can try to euchre and get two points. Instead, losing two points will probably be put in. This forces both teams to earn the points and not just get points based on a bad deal. If you truly are the better team, you can get those two points back.

Right and left bower (what makes Euchre Euchre). Jack of the suit called is called the right bower. This makes it the highest card, and jack of the other suit of the same color is the left bower, second highest before ace, king, queen, 10, and 9. Jacks of opposite color are treated normally, higher than 10, lower than queen.

Lead with high non-trump cards (in the beginning)/Getting rid of low non-trump cards. This means after trump has been determined, the highest probability players will have a 9 or 10 where you have the ace will be in the beginning. Also, if you don't have an ace, playing a 9 or 10 trump card where you partner called it will allow them to lead and get rid of four trumps or show who doesn't have trump.


Levels

This will be a work in progress, but a few examples should provide a yardstick for comparison.

♠ is trump and J♠ is the card the dealer turned over.
The dealer has been dealt: J♦ Q♥ A♠ 10♠ J♣

This is a guaranteed point for players 2 and 4(dealer), and since the dealer doesn't have a non-trump 9 or 10 they could go alone and shoot the moon. Another way of thinking is that player 2 has high diamonds (Q, K, and A) and high hearts (K and A). This could give two points in case players 1 and 3 also have them. At this stage, I will use a 9/10 approach. If the dealer doesn't have non-trump 9 or 10 cards then shoot the moon. If they have 2, maybe 1 (flip a coin?), then don't shoot the moon. Another factor is the score. If it is near the end of the game and you are down, shooting the moon might be worth it since you won't lose or give points. I won't program this in and just focus on each round independently.

In this next example Player 1 has good reason to call it.

The card the dealer turned over was 9♣.

 Player 1 has:  J♣ Q♦ 9♦ A♣ 10♣
 Player 2 has:  9♥ Q♥ K♦ K♠ A♠
 Player 3 has:  K♥ Q♠ A♦ 10♦ J♥
 Dealer has:  K♣ Q♣ 10♠ 9♠ J♠

Player 1 has two of the top three cards and can rely on their partner for the third trick. Plus, they have an extra trump in case hearts are played which they don't have. The dealer would only get a low 9 for trump. However, they do have left bower and two trump cards.

Game play could go: J♣, 9♥, 10♦, 9♣ (1-0) / 9♦, K♦, A♦, Q♣ (1-1) / J♠, 10♣, K♠, J♥ (1-2) / 10♠, A♣, Q♥, Q♠ (2-2) / Q♦, A♠, K♥, K♣ (2-3) Euchred!!

The 9♦ is to see if their partner has the ace or trump and use it up with 2 more trump in hand to get the point. The irony is if A♣ was played instead, Player 4 (dealer) could take it with left bower and then rely on their partner who has K♠ and A♠ to get the third trick.

Game play with 9♦ first: 9♦, K♦, A♦, 9♣ (0-1) / Q♣, J♣, 9♥, J♥ (1-1) also leads to being euchred.

9♦, K♦, A♦, 9♣ (0-1) / 10♠, 10♣, K♠, J♥ (1-1) / Q♦, 9♥, 10♦, Q♣ (1-2) Not Euchred

If I am correct here, then it all boils down to the fact Player 4 (dealer) had more trump to outnumber Player 1. In chess, this is similar to more knights and bishops (maybe queen) in a position. If players 2 and 3 had trump, player 1 would be able to get at least a point.

In cases like this, I will program it with a flip of the coin. In the beginning, non-trump could be played, but later (3rd trick?) it would play the trump. If that shows human play winning more, another level could be set to calculate it out more by counting cards. I am going to stick to least calculating at first.


Last example:

The card the dealer turned over was 9♠.

 Player 1 has:  K♣ K♠ 9♥ A♥ J♣
 Player 2 has:  9♣ 10♠ 9♦ Q♣ J♠
 Player 3 has:  K♥ Q♦ A♠ Q♠ 10♥
 Dealer has:  K♦ Q♥ A♣ 10♣ J♥

This one is unclear and possibly a "stick the dealer" scenario. With dealer passing, and it coming back, ♥ would probably be called.

Game play could be: K♠, 10♠, Q♠, Q♥ (0-1) / J♥, 9♥, 9♣, 10♥ (0-2) / A♣, A♥, 9♦, Q♦ (1-2) / K♣, Q♣, A♠, 10♣ (2-2) /  J♣, J♠, K♥, K♦ (3-2) Euchred!!

With Players 1 and 3 winning, did 2 and 4 have a better option? Player 2 could have left bower for clubs and player 4 (dealer) has the ace.

Game play could then be: A♥, 9♣, 10♥, J♥ (0-1) / J♠, Q♠, 10♣, J♣ (1-1) / K♠, 10♠, A♠, A♣ (1-2) / K♦, K♣, 9♦, Q♦ (2-2) / 9♥, Q♣, K♥, Q♥ (2-3) Not Euchred

So, how do you know Player 2 has potential? J♣, A♣, and K♣ were not in Player 2's hand. The only thing I can see is Player 2 could get two of three tricks. This seems to be a good factor to put in for initial strategy. Well, off to programming all this and see what breaks.  

Thursday, July 18, 2024

Card Shuffling

In this one, the user sets the number of players and cards per player. Then, it shuffles and lists cards dealt, as well as which cards each player is dealt. In the Clue program, it was suggested I use "random.variable" to simplify things, but I don't see how to isolate the position of each card drawn in the array. So, instead of removing from a set list, I created the array and then listed. I would like to try this again, where each card dealt out is removed from the 52 card list, and instead of listing based on position, it is more real with place holders. To do this, I need to find out how to deal with an indeterminate number of players so I can assign a list/array to each player. Then, it is not needed to base things on position.

Can be tested at https://www.programiz.com/python-programming/online-compiler/ (Remove the 3 lines of "stuff" on the left on their site, or it might not run properly. Also, the site seems to time out, but it's the only one I see that can run this one.)

import random

a=0
card_progress_num = 51
cards = ["Ace of Clubs", "Ace of Diamonds", "Ace of Hearts", "Ace of Spades", "2 of Clubs", "2 of Diamonds", "2 of Hearts", "2 of Spades", "3 of Clubs", "3 of Diamonds", "3 of Hearts", "3 of Spades", "4 of Clubs", "4 of Diamonds", "4 of Hearts", "4 of Spades", "5 of Clubs", "5 of Diamonds", "5 of Hearts", "5 of Spades", "6 of Clubs", "6 of Diamonds", "6 of Hearts", "6 of Spades", "7 of Clubs", "7 of Diamonds", "7 of Hearts", "7 of Spades", "8 of Clubs", "8 of Diamonds", "8 of Hearts", "8 of Spades", "9 of Clubs", "9 of Diamonds", "9 of Hearts", "9 of Spades", "10 of Clubs", "10 of Diamonds", "10 of Hearts", "10 of Spades","Jack of Clubs", "Jack of Diamonds", "Jack of Hearts", "Jack of Spades", "Queen of Clubs", "Queen of Diamonds", "Queen of Hearts", "Queen of Spades", "King of Clubs", "King of Diamonds", "King of Hearts", "King of Spades"]   
player_num = int(input("How many players? "))
card_num = int(input("How many cards per player? "))
cards_dealt_num = player_num * card_num
cards_dealt = []
print ("\n")


while a < (cards_dealt_num):

#random.choice HOW DO YOU ISOLATE THE POSITION OF THE CARD TO REMOVE IT?
#cards = random.choice (("Ace of Clubs", "Ace of Diamonds", "Ace of Hearts", "Ace of Spades", "2 of Clubs", "2 of Diamonds", "2 of Hearts", "2 of Spades", "3 of Clubs", "3 of Diamonds", "3 of Hearts", "3 of Spades", "4 of Clubs", "4 of Diamonds", "4 of Hearts", "4 of Spades", "5 of Clubs", "5 of Diamonds", "5 of Hearts", "5 of Spades", "6 of Clubs", "6 of Diamonds", "6 of Hearts", "6 of Spades", "7 of Clubs", "7 of Diamonds", "7 of Hearts", "7 of Spades", "8 of Clubs", "8 of Diamonds", "8 of Hearts", "8 of Spades", "9 of Clubs", "9 of Diamonds", "9 of Hearts", "9 of Spades", "10 of Clubs", "10 of Diamonds", "10 of Hearts", "10 of Spades","Jack of Clubs", "Jack of Diamonds", "Jack of Hearts", "Jack of Spades", "Queen of Clubs", "Queen of Diamonds", "Queen of Hearts", "Queen of Spades", "King of Clubs", "King of Diamonds", "King of Hearts", "King of Spades"))
#print(cards)
#a = a+1
    card_selection = (random.randint(0,card_progress_num))
    cards_dealt.append(cards[card_selection])
    print (card_selection, " - ", cards[card_selection])
    cards.pop(card_selection)
    card_progress_num = card_progress_num - 1
    a=a+1

print ("\n")

for x in range(player_num):     
    print ("Player ", x+1, "has:")
    for y in range(card_num):
        print (cards_dealt[(x)])
        x=x+player_num
    print ("\n")