一个简单的洗牌算法实现 Python

  • Post author:
  • Post category:python


为一副去掉大小王的52张扑克设计洗牌算法,思想如下:


1.


cut牌

:随机选取一个cut点,位于cut点下方的牌保持顺序不变全部移到cut点上方牌的上部,此时cut点位于牌的末尾。

2.

叠插牌

: 将扑克牌分为相等的两堆,选取其中一堆,保持顺序依次插入到另一堆的两牌之间

import random
#返回一个拥有52张扑克的列表
def newPack():
    return list(range(1,53))

#cut牌,本质上就是列表左移
def MirrorP(p,start,end):
    while start < end:
        tmp = p[start]
        p[start] = p[end]
        p[end] = tmp
        
        start += 1
        end -= 1
def cutPack(p):
    length = len(p)
    cutPoint = random.randint(1,length)   #select any card
    if cutPoint > 1:
        MirrorP(p,0,cutPoint-2)
        MirrorP(p,cutPoint-1,length-1)
        MirrorP(p,0,length-1)
    return p

#叠插牌
#method1 
def shufflePack(p):
    length = len(p)
    i = 1
    
    if length % 2 == 0:
        j = length//2
    else:
        j = length//2+1
        
    while j < length:
        t = p[j]
        k = j
        while k >= i:
            p[k] = p[k-1]
            k -= 1
        p[i] = t
        j += 1
        i += 2
#method2
def shufflePack(p):
    length = len(p)
    i = 1
    
    if length % 2 == 0:
        j = length//2
    else:
        j = length//2+1
        
    t = p[j:]
    p[::2] = p[:j]
    p[1::2] = t

#结合多种方法随机打乱牌的顺序
def randomShuffle(p):
    times = random.randint(1,16)
    for i in range(times):
        cutPack(p)
        shufflePack(p)

#数字和牌花色的映射
#S、H、D、C 代表四个花色
def card(i):
    #calculate suit
    suit_dict = {0:'S',1:'H',2:'D',3:'C'}
    result = [suit_dict[(i-1)//13]]
    
    if (i+2) % 13 == 0:
        result.insert(0,"J")
    elif (i+1) % 13 == 0:
        result.insert(0,"Q")
    elif i % 13 == 0:
        result.insert(0,"K")
    elif i % 13 == 1:
        result.insert(0,"A")
    else:
        result.insert(0,str(i%13))
        
    return "".join(result)


cards = newPack()
randomShuffle(cards)
for item in cards:
    print(card(item),end = " ")



版权声明:本文为qq_33768643原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。