0

这是一个模拟三位数的牛和公牛游戏

我试图得到两个数字之间的奶牛和公牛的数量。其中一个由计算机生成,另一个由用户猜测。我已经解析了我拥有的两个数字,所以现在我有两个列表,每个列表包含三个元素,每个元素都是数字中的一个数字。所以:

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 头公牛。而我应该得到 1 头公牛和 1 头母牛。

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

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. 个位的 277 中的 7 与十位的 477 中的 7 匹配,因此生成了一头牛。
  2. 十位的 277 中的 7 与单位位的 477 中的 7 匹配,因此生成了一头牛。

这里的匹配是完全正确的,因为我已经按照它编写了代码。但这不是我想要的。而且我不知道在此之后该怎么做。

此外...

我想强调的是,如果计算机选择的数字中没有重复的数字,这两种算法都可以完美运行。

4

6 回答 6

5
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 头奶牛。这就是我个人所期望的:既然 447 的 7 已经有公牛,为什么 277 中的前 7 算作一头牛?

于 2013-06-26T10:18:48.083 回答
1
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".
于 2013-11-23T05:09:07.420 回答
1

.index()返回给定输入的第一次出现的索引:

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

您应该改为使用enumerate()来获取所有可能的索引:

>>> 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
于 2013-06-26T09:45:28.357 回答
0
def game(a,b,c,d):
    from random import randint
    m=randint(0,9)
    n=randint(0,9)
    o=randint(0,9)
    p=randint(0,9)
    cow=bull=0
    A={a:m,b:n,c:o,d:p}
    k=A.keys()
    v=A.values()
    bull=cow=0
    for i in k:
        if i==A[i]:
            bull+=1
        elif i in v:
            cow+=1
    if (cow>0 or bull>0):
        print(bull,"Bull and ",cow,"Cow")
    print("Correct No. :       ",m,n,o,p)
    print("You've Entered : ",a,b,c,d)
于 2014-11-27T14:33:56.040 回答
-1

公牛和奶牛(代码有点初学者,刚开始从 youtube 学习)

import random

def num_checker(guess_num,answer):
    guess_num=list(str(guess_num))
    ans=list(str(answer))
    cow=0
    bull=0
    for a in range(0,4):
        if guess_num[a]==ans[a]:
            bull+=1
            ans[a]=10#changed values to counter reccuring digits
            guess_num[a]=20#changed values to counter reccuring digits

    for a in range(0,4):
        for b in range (0,4):
            if guess_num[a]==ans[b]:
                cow+=1
                ans[b]=30#changed values to counter reccuring digits
                break

    final=[bull,cow]
    return final

#..................................................
ans=random.randrange(1000,10000)
print("this is the program to gues a four digit number")

#......................................................#continue asking until you get it right
while True:
    print("just for reference answer is:",ans)
    num_typed=int(input("please guess a four digit the number?\n "))
    reply=num_checker(num_typed,ans)
    if reply==[4,0]:
        print("correct")
        print(reply[0],"bull",reply[1],"cows and the ans is",ans)
        break
    else:
        print(reply[0],"bulls",reply[1],"cows")
于 2015-01-25T23:18:15.317 回答
-1

嘿,制作牛牛程序的最佳方法是使用字符和字符串而不是数字。这样你就不必为几百或十个地方烦恼了。您可以按照我关于 Python 中 4 位牛牛游戏的教程:http: //funpythonprojects.blogspot.in/2013/07/cow-bull-game-aka-guess-number-in-python.html

于 2013-07-10T18:09:52.557 回答