Building a Simple Card Game in Golang

 



In this guide, we will walk through building a simple card game using Golang. The game will feature basic mechanics, such as a deck of cards, dealing cards to players, and simple gameplay logic. We’ll focus on structuring the game and modeling the core elements (cards, deck, players) using Go's features like structs and slices. While the card game we’re building here will be basic, it can serve as a foundation to add more complexity and features, such as scoring, AI, or multiplayer.


1. Game Design and Overview

Before we begin coding, let's outline the game mechanics and design.

Simple Card Game Rules:

  • A standard deck of 52 cards (13 ranks and 4 suits).
  • The deck is shuffled, and two players (or more) receive an equal number of cards.
  • Each player takes turns drawing a card from their hand.
  • The player with the highest card wins that round.
  • The game continues until all cards are drawn, and the player with the most rounds won is the overall winner.

2. Step-by-Step Implementation

Step 1: Defining the Card Structure

The first step is to create the basic structures that represent the Card, Deck, and Player.

We will define:

  • Card: Contains the suit and rank of the card.
  • Deck: Contains a collection of cards and provides methods for shuffling and dealing.
  • Player: Represents each player in the game and holds their hand of cards.

Code Example: Defining Structures

package main import ( "fmt" "math/rand" "time" ) // Define the structure for a card type Card struct { Rank string Suit string } // Define the structure for a deck of cards type Deck struct { Cards []Card } // Define the structure for a player type Player struct { Name string Hand []Card }

Here, we've defined the following:

  • Card has two fields: Rank and Suit to describe a single card.
  • Deck has a slice of Card to hold all the cards in the deck.
  • Player has a Name and a slice of Card to represent the cards they hold.

Step 2: Creating a Deck of Cards

Next, we need to create a deck of cards, shuffle them, and deal them to players.

Code Example: Deck Creation and Shuffling

// Function to create a new deck of cards func NewDeck() Deck { suits := []string{"Hearts", "Diamonds", "Clubs", "Spades"} ranks := []string{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"} var cards []Card for _, suit := range suits { for _, rank := range ranks { cards = append(cards, Card{Rank: rank, Suit: suit}) } } return Deck{Cards: cards} } // Function to shuffle the deck of cards func (d *Deck) Shuffle() { rand.Seed(time.Now().UnixNano()) // Initialize random seed for i := len(d.Cards) - 1; i > 0; i-- { j := rand.Intn(i + 1) d.Cards[i], d.Cards[j] = d.Cards[j], d.Cards[i] // Swap cards } } // Function to deal cards to players func (d *Deck) Deal(players []Player, numCards int) { for i := 0; i < numCards; i++ { for j := 0; j < len(players); j++ { card := d.Cards[len(d.Cards)-1] // Get the last card d.Cards = d.Cards[:len(d.Cards)-1] // Remove the card from deck players[j].Hand = append(players[j].Hand, card) // Add card to player hand } } }

Explanation:

  1. NewDeck creates a deck of 52 cards by combining each suit with each rank.
  2. Shuffle uses the rand package to shuffle the cards randomly.
  3. Deal distributes the cards to players. It loops through the deck and gives one card to each player until each player has the desired number of cards.

Step 3: Comparing Cards and Determining the Winner

Each round, players draw a card, and the player with the highest card wins. We’ll create a function that compares the rank of two cards.

Code Example: Comparing Cards


// Function to convert rank into a numeric value for comparison func rankValue(rank string) int { rankValues := map[string]int{ "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10, "J": 11, "Q": 12, "K": 13, "A": 14, } return rankValues[rank] } // Function to compare two cards and return the winner func CompareCards(card1, card2 Card) string { if rankValue(card1.Rank) > rankValue(card2.Rank) { return "Player 1" } else if rankValue(card1.Rank) < rankValue(card2.Rank) { return "Player 2" } else { return "Draw" } }

Explanation:

  • rankValue converts card ranks (e.g., "2", "J", "A") into numeric values so that cards can be compared.
  • CompareCards compares two cards and returns the winner based on their rank.

Step 4: Running the Game

Now we can bring everything together and implement the main game loop. We'll initialize the deck, shuffle it, deal the cards to players, and then simulate rounds of the game.

Code Example: Running the Game

func main() { // Create two players player1 := Player{Name: "Player 1"} player2 := Player{Name: "Player 2"} players := []Player{player1, player2} // Create and shuffle the deck deck := NewDeck() deck.Shuffle() // Deal 5 cards to each player deck.Deal(players, 5) // Simulate the rounds of the game player1Score := 0 player2Score := 0 for i := 0; i < 5; i++ { // Each player draws a card (take the first card in hand) card1 := players[0].Hand[i] card2 := players[1].Hand[i] fmt.Printf("Round %d:\n", i+1) fmt.Printf("%s draws: %s of %s\n", players[0].Name, card1.Rank, card1.Suit) fmt.Printf("%s draws: %s of %s\n", players[1].Name, card2.Rank, card2.Suit) // Compare the cards winner := CompareCards(card1, card2) if winner == "Player 1" { player1Score++ fmt.Println("Player 1 wins this round!") } else if winner == "Player 2" { player2Score++ fmt.Println("Player 2 wins this round!") } else { fmt.Println("It's a draw!") } fmt.Println() } // Final score fmt.Println("Final Scores:") fmt.Printf("%s: %d\n", players[0].Name, player1Score) fmt.Printf("%s: %d\n", players[1].Name, player2Score) if player1Score > player2Score { fmt.Println("Player 1 wins the game!") } else if player1Score < player2Score { fmt.Println("Player 2 wins the game!") } else { fmt.Println("The game is a draw!") } }

Explanation:

  1. We create two players and a deck of cards.
  2. The deck is shuffled, and 5 cards are dealt to each player.
  3. For each round, each player draws a card, and the winner is determined by comparing the ranks of their cards.
  4. After all rounds are played, the player with the most round wins is declared the overall winner.

3. Running the Game

To run the game, simply save the code into a file (e.g., main.go), and use the go run command:


go run main.go

Sample Output:


Round 1: Player 1 draws: 8 of Hearts Player 2 draws: 5 of Diamonds Player 1 wins this round! Round 2: Player 1 draws: 3 of Spades Player 2 draws: 6 of Hearts Player 2 wins this round! Round 3: Player 1 draws: K of Clubs Player 2 draws: 10 of Spades Player 1 wins this round! Round 4: Player 1 draws: A of Diamonds Player 2 draws: Q of Hearts Player 1 wins this round! Round 5: Player 1 draws: 7 of Diamonds Player 2 draws: J of Clubs Player 2 wins this round! Final Scores: Player 1: 3 Player 2: 2 Player 1 wins the game!

Conclusion

In this guide, we built a simple card game using Golang. We defined the core structures (cards, deck, players), implemented a game loop, shuffled and dealt cards, and compared cards to determine the winner. This game provides a foundation that you can expand upon to add more complexity, such as supporting more players, introducing more rules, or implementing a graphical user interface (GUI).

Go's simplicity, strong support for concurrency (which you could use for a multiplayer version), and efficient handling of slices and maps make it a great choice for building card games and other interactive applications.

Post a Comment

Cookie Consent
Zupitek's serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.