牛牛博弈编程算法(python)

2024-04-20 01:30:47 发布

您现在位置:Python中文网/ 问答频道 /正文

这是游戏的模拟Cows and Bulls有三位数字

我想把牛和公牛的数量介于两个数字之间。其中一个由计算机生成,另一个由用户猜测。我已经解析了两个数字,现在我有两个列表,每个列表有三个元素,每个元素都是数字中的一个数字。所以:

237将给出列表[2,3,7]。我确保相关的索引被维护,一般的模式是:(hundreds, tens, units)

这两个列表存储在两个列表中:machineperson

算法1

所以,我写了以下代码,最直观的算法:

在循环开始之前,cowsbulls被初始化为0。

for x in person:
    if x in machine:
        if machine.index(x) == person.index(x):
            bulls += 1
            print x,' in correct place'
        else:
            print x,' in wrong place'
            cows += 1

我开始用电脑猜出的不同类型的数字来测试这个。

很随机,我决定277。我猜是447。在这里,我首先得到了这个算法可能行不通的线索。我有1头牛和0头公牛。我应该有一头牛和一头牛。

这是第一个算法的输出表:

Guess        Output            Expected Output

447     0 bull, 1 cow          1 bull, 0 cow 
477     2 bulls, 0 cows        2 bulls, 0 cows
777     0 bulls, 3 cows        2 bulls, 0 cows

所以很明显,当计算机随机选择的数字中有重复的数字时,这个算法不起作用。

我试图理解为什么会发生这些错误,但我不能。我试了很多次,但是我看不出算法有什么错误(可能是因为我写的!)

算法2

想了几天之后,我试着说:

在循环开始之前,cowsbulls初始化为0。

for x in range(3):
    for y in range(3):
            if x == y and machine[x] == person[y]:
                bulls += 1
            if not (x == y) and machine[x] == person[y]:                   
                cows += 1

我对这个更有希望。但是当我测试这个的时候,我得到了:

Guess        Output            Expected Output

447     1 bull, 1 cow          1 bull, 0 cow 
477     2 bulls, 2 cows        2 bulls, 0 cows
777     2 bulls, 4 cows        2 bulls, 0 cows

我犯的错误在这里很清楚,我知道这些数字被一次又一次地计算。

即:277对477

当你数公牛的时候,2只公牛出现了,没关系。但当你数牛的时候:

  1. 单位处的7/277与十处的7/477相匹配,从而产生一头牛。
  2. 十位数的7/277与单位位数的7/477相匹配,就产生了一头牛

这里的匹配是完全正确的,因为我已经写了代码。但这不是我想要的。我也不知道接下来该怎么办。

而且

我想强调的是,如果计算机选择的数字中没有重复的数字,这两种算法都能很好地工作。


Tags: andin算法列表outputif计算机数字
3条回答
def digits(number):
    return [int(d) for d in str(number)]

def bulls_and_cows(guess, target):
    guess, target = digits(guess), digits(target)
    bulls = [d1 == d2 for d1, d2 in zip(guess, target)].count(True)
    bovine = 0
    for digit in set(guess):
      bovine += min(guess.count(digit), target.count(digit))
    return bulls, bovine - bulls

注意bulls_and_cows(277, 447)将返回1头公牛和0头奶牛。这就是我个人所期望的:为什么277年的前7只会算作母牛,因为已经有了一头447年7只的公牛了?

Here is an algorithm which compares digits and positions.
I use it in a program for finding the target in a 4-digit 
version of the game when the target can begin with "0". 
It works with or without repeating digits equally well.
In the table below are shown all 9 results/values of variable 
ED (Equal Digits) when comparing digits in each position of  
the guess 447 with each digit of the target 447, for the 
special case when the guess G$(3) equals the target T$(3)*.
For any other case the table is different and the values for 
B and C will change accordingly. 
It's a fact that for us, humans it's easier to count 
Bulls and Cows without repeating digits. 
With repeating digits I need to see the table below.
        !!!Important!!! 
Do not judge the values for B and C. Just use them. 

    4  4  7       3 Bulls      3 Cows
   --------        (I=J)       (I<>J)
 4| 1  1  0       1  .  .      .  1  .   
  |                    
 4| 1  1  1       .  1  .      1  .  1
  |                      
 7| 0  0  1       .  .  1      .  .  .



Here is the algorithm in Liberty BASIC:
'-------------------------------------
[calculate_Bulls_and_Cows]
B = 0: C = 0
        FOR I=1 TO 3
            FOR J=1 TO 3
                ED=(T$(I)=G$(J)) 'finding Equal Digits makes ED=1
                B = B+ED*(I=J)   'Bulls increment when ED*(I=J)=1
                C = C+ED*(I<>J)  'Cows increment when ED*(I<>J)=1
            NEXT J
        NEXT I
return
'------------------------------------
_________

*In this case I decided Digits to be considered 
text variables because of some benefits when 
it wasn't restricted the target to begin with "0".

.index()返回给定输入的第一个匹配项的索引:

>>> [1, 5, 5].index(5)
1

您应该使用^{}来获取所有可能的索引:

>>> for i, j in enumerate([1, 5, 5]):
...     if j == 5:
...             print i
... 
1
2

不过,这似乎可以通过zip()完成,除非我搞错了:

for x, y in enumerate(zip(player,computer)):
    if y[0] in computer and not y[0] == y[1]:
        print y[0], "is in the number"
        cows += 1
    elif y[0] == y[1]:
        print y[0], "in the correct place"
        bulls += 1
    else:
        print y[0], "is not in the number"

对于player = [4, 4, 7]

4 is not in the number
4 is not in the number
7 in the correct place
>>> cows
0
>>> bulls
1

使用player = [4, 7, 7]

4 is not in the number
7 in the correct place
7 in the correct place
>>> cows
0
>>> bulls
2

相关问题 更多 >