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

使用Racket制作BlackJack扑克牌组遇到的两类技术问题

解决Racket中制作BlackJack扑克牌组的问题

问题1:代码输出异常的原因

你的代码输出出现#<void>是因为pair-items函数的逻辑错误:

  • displayln函数的返回值是#<void>,你在cons里直接嵌套调用pair-items x (cdr y),会把递归调用的返回值(也就是displayln的#<void>)拼接到列表里,导致输出出现. #<void>。
  • 函数的递归分支没有正确返回构建好的牌组列表,反而依赖displayln打印,同时终止条件的返回值也没有和递归部分衔接。

你的原代码:

;This function creates a list of all the card faces.
(define faces '(2 3 4 5 6 7 8 9 10 J Q K A))
;This function creates a list of all card suits.
(define suits '(Clubs Diamonds Hearts Spades))

;make-deck: Creates a new (unshuffled) 52 card deck
;     Returns: The deck (a list of cards)
;     Parameters: none

(define make-deck
  (letrec ([pair-items (lambda (x y)
                         (cond
                           [(null? x) '()]
                           [(null? y) '()]
                           [(displayln (cons (car x) (cons (car y) (pair-items x (cdr y)))))]
                           ))])                 
    (pair-items faces suits))
  )

问题2:实现所有牌面与花色的配对

要让每个牌面和所有花色配对,本质是求两个列表的笛卡尔积,不需要手动“重置迭代器”,用递归或者Racket的高阶循环函数都能轻松实现:

方法1:用for*/list(最简洁)

for*/list会自动嵌套遍历两个列表,生成所有组合:

(define faces '(2 3 4 5 6 7 8 9 10 J Q K A))
(define suits '(Clubs Diamonds Hearts Spades))

(define (make-deck)
  (for*/list ([face faces]
              [suit suits])
    (list face suit)))

调用(make-deck)会返回完整的52张牌的列表,每张牌是(face suit)的形式。

方法2:递归实现

如果想用纯递归逻辑,可以写嵌套的递归函数:

(define faces '(2 3 4 5 6 7 8 9 10 J Q K A))
(define suits '(Clubs Diamonds Hearts Spades))

(define (make-deck)
  (letrec ([pair-face-with-all-suits (lambda (face suits)
                                       (if (null? suits)
                                           '()
                                           (cons (list face (car suits))
                                                 (pair-face-with-all-suits face (cdr suits)))))
           [pair-all-faces (lambda (faces suits)
                             (if (null? faces)
                                 '()
                                 (append (pair-face-with-all-suits (car faces) suits)
                                         (pair-all-faces (cdr faces) suits))))])
    (pair-all-faces faces suits)))

这个逻辑里,pair-face-with-all-suits负责把单个牌面和所有花色配对,pair-all-faces遍历所有牌面,把每个牌面的配对结果拼接起来,最终得到完整牌组。

修正你原代码的问题

如果要保留你原有的递归结构,需要让函数返回列表而不是依赖displayln,比如:

(define faces '(2 3 4 5 6 7 8 9 10 J Q K A))
(define suits '(Clubs Diamonds Hearts Spades))

(define make-deck
  (letrec ([pair-items (lambda (x y)
                         (cond
                           [(null? x) '()]
                           [(null? y) (pair-items (cdr x) suits)] ; 花色遍历完,切换到下一个牌面
                           [else (cons (list (car x) (car y))
                                       (pair-items x (cdr y)))]))])
    (pair-items faces suits)))

这里修改了递归逻辑:当花色列表为空时,递归处理下一个牌面(重置为完整的suits列表),否则构建当前牌的列表并继续遍历剩余花色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 00:47:37