python代码实现21点小游戏(入门级别哈)
第一次写这个博客,也是想分享一下自己的代码,有点菜,感觉面向对象学得不是很好,语句都改了很多遍,大佬们多指点哈
21点是什么?
21点, (有些又叫24点)就是从扑克牌中随机抽取4张牌,每张牌只能用一次,用加减乘除将这四张牌凑成21(24点就是凑成24)
创作历程
-
第一次就是想将所有组合的模板写出来,感觉自己太智障了,写了好几个小时也没列举完,自己已然忘记列举规律。
-
放弃第一种思路,想出第二种方法:从四个数里面先选两个数做运算得到结果 “r1”,再从剩下两个数里面选一个与 r1 做运算得到 r2 ,r2再与最后的数做运算。在这个过程里,运算都是加减乘除都算一边,然后选择一个结果进行下一个运算。这其实与我玩21点的思路十分相似。
具体解释下思路:
- 先发牌,随机生成四种花色与四个1~13的数字
- 随机抽取牌(这一步是为了改变牌的顺序)
- 算得结果r1,有8种运算的原因是第一个数字的符号是正是负是有关系的,如果默认是正的话算不到所有情况(比如我有两个数m1=2和m2=8,正确答案要求的过程是8-2,但是这样就算不出来6,有些同学可能会问:“下一次选择到m1=8,m2=2不就行了?”,但是我们这里是随机生成的顺序,概率很小,而且如果要求的答案是-6呢?我这里是希望用这一组顺序算出所有结果,所以会有8种运算。)
- r1,r2,r3都算出来了,如果r3等于21的话就是我们需要的答案了,这时就需要记录每个数字之间的符号了。我定义了一个符号列表(’+’,’-’,’*’,’/’),引用通过i,j,k与所需符号在列表中的序数之间的关系:仔细看哦,每一层运算有八个结果,前四个是正的加减乘除,后面是负的加减乘除,我先通过四舍五入确定是前四个还是后四个,这里就会输出结果0和1,刚好就是‘+’和‘-’的序数;后面是通过对4取余数确定是加减乘除之间的哪个符号。
- 生成1000组数的顺序,每组顺序组合成的所有答案都算一遍,算到21就停止。(顺序应该只有4 * 3 * 2 * 1种,但是反正计算机算的快,多算几千次无所谓哈!)
给代码了(大佬们多指点)
class Twentyone(object):
def __init__(self, num=0, color='', b='', c=''):
self.num = num
self.color = color
self.b = b
self.c = c
def sent(self):
import random as rand
self.b = []
self.c = []
for i in range(4):
self.num = int(rand.randint(1, 13))
self.color = rand.choice(('♠', '♥', '♣', '♦'))
self.b.append('%s%d' % (self.color, self.num))
self.c.append('%d' % self.num)
return self.b
def find(self):
import random as rand
f = ('+', '-', '*', '/')
c = self.c
rand.shuffle(c)
m1 = float(c[0])
m2 = float(c[1])
m3 = float(c[2])
m4 = float(c[3])
for i in range(1, 8):
r1a = m1 + m2
r1b = m1 - m2
r1c = m1 * m2
r1d = m1 / m2
r1e = -m1 + m2
r1f = -m1 - m2
r1g = -m1*m2
r1h = -m1/m2
R1 = (r1a, r1b, r1c, r1d, r1e, r1f, r1g, r1h)
r1 = float(R1[i-1])
for j in range(1, 5):
r2a = r1 + m3
r2b = r1 - m3
r2c = r1*m3
r2d = r1/m3
r2e = - r1 + m3
r2f = - r1 - m3
r2g = - r1 * m3
r2h = - r1 / m3
R2 = (r2a, r2b, r2c, r2d, r2e, r2f, r2g, r2h)
r2 = float(R2[j-1])
for k in range(1, 8):
r3a = r2 + m4
r3b = r2 - m4
r3c = r2 * m4
r3d = r2 / m4
r3e = -r2 + m4
r3f = -r2 - m4
r3g = -r2 * m4
r3h = -r2 / m4
R3 = (r3a, r3b, r3c, r3d, r3e, r3f, r3g, r3h)
r3 = float(R3[k - 1])
if r3 == 21:
print('found it!')
print('%s[%s(%s %d %s %d) %s %d] %s %d' % (f[round(k/9)], f[round(j/9)], f[round(i/9)], m1, \
f[i % 4-1], m2, f[j % 4-1], m3, f[k % 4 -1], m4))
return r3
def main():
m = Twentyone()
print(m.sent())
p = input('press h for help, p for pass')
i = 0
while p == 'h' and i < 1000:
r3 = m.find()
if r3 == 21:
break
i += 1
if i == 1000:
print('not found')
main()