You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中含Unicode扑克牌字符的字符串如何实现随机抽n张牌

问题分析与修复方案

核心错误点

  • 牌堆生成逻辑错误:deckGenerator函数中误用strconv.Itoa将扑克牌Unicode码点转为了数字字符串,而非直接转为字符。比如红桃A的码点127153被转成了字符串"127153",最终牌堆里存的全是数字字符,和后续判断的扑克牌rune完全不匹配,自然找不到对应牌导致死循环。
  • 抽卡返回值未正确赋值:drawCard函数找到匹配卡牌后,没有给返回值cardPulledOut、deck2赋值,返回的始终是空值。
  • 剩余牌堆未同步更新:drawCards函数中每次抽卡后,没有将返回的剩余牌堆覆盖原有牌堆,每次抽卡都用初始完整牌堆,很快就会抽到已经被移除的卡牌触发死循环。

修复后完整代码

package main

import (
    "fmt"
    "math/rand"
    "strings"
    "time"
)

func main() {
    var n int
    var deck string

    rand.Seed(int64(time.Now().Nanosecond()))

    n = readNumber()
    deck = deckGenerator()
    drawCards(deck, n)

}

func readNumber() (n int) {
    for n <= 0 || n >= 10 {
        fmt.Print("输入1到9之间的数字: ")
        fmt.Scan(&n)
    }
    return n
}

func deckGenerator() (deck string) {
    for i := 0; i < 10; i++ {
        // 直接将码点转为Unicode字符,而非转成数字字符串
        deck += string(rune('\U0001F0B1' + i))
    }
    return deck
}

func drawCards(deck string, n int) {
    for i := 0; i < n; i++ {
        cardPulledOut, deck2 := drawCard(deck)
        // 更新剩余牌堆
        deck = deck2
        fmt.Println("抽到的牌是", string(cardPulledOut), "- 剩余牌数:", len(deck)/4) // 每个扑克牌Unicode占4字节,除以4得剩余牌数
    }
}

func drawCard(deck string) (cardPulledOut rune, deck2 string) {
    for {
        card := rune('\U0001F0B1' + rand.Intn(10))
        for _, v := range deck {
            if v == card {
                newDeck := strings.Replace(deck, string(card), "", 1)
                // 直接返回匹配到的卡牌和新牌堆
                return card, newDeck
            }
        }
    }
}

改动说明

  1. 修复牌堆生成逻辑,直接将扑克牌码点转为Unicode字符存入字符串,保证牌堆存储的是正确的卡牌字符。
  2. 抽卡匹配到对应卡牌后直接返回正确的卡牌和剩余牌堆,避免返回空值。
  3. 抽卡循环中每次都更新剩余牌堆,保证后续抽卡基于更新后的牌堆操作。
  4. 打印输出时将rune转为string,可直接显示扑克牌符号,剩余牌数通过字节长度计算得到。

内容的提问来源于stack exchange,提问作者Dario Sansone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 23:24:01