This is my second post to Qiita. Thank you.
This time, we implemented that game "Numer0n", which once dominated the world, in Python.
Each player uses 3 out of 10 cards with numbers from 0-9 to create a 3-digit number. Since there is no duplication of cards, you cannot make numbers that use two or more of the same numbers such as "550" and "377". The first player infers the opponent's number and calls. The other party compares the called number with his own number and announces how well the called number matches. If the numbers and digits match, it will be "EAT", and if the numbers match but the digits do not match, it will be "BITE". For example, if the other party's number is "765" and the called number is "746", "7" out of the three digits is EAT because the digit positions match, and "6" is the number itself. BITE because it matches but the position of the digit is different. Since there is one EAT and one BITE, it becomes "1EAT-1 BITE". This is repeated by the first attack and the second attack, and the player who hits the opponent's number completely first (if it is 3 digits, let the opponent announce 3EAT) wins.
This time, I implemented a program that can specify the number of digits (even for those who are not satisfied with 3 digits).
Numer0n_Basic.py
#Numer0n_Basic
import random
#The number to be the subject is decided
proper = 0
while proper == 0:
print("Digit?")
#Determine the number of digits
D = int(input())
N = []
#The number of digits must be from 1 to 10 digits
if 1 <= D <= 10:
while len(N) < D:
n = random.randint(0,9)
if n in N:
pass
else:
N.append(n)
proper += 1
else:
print("Improper.")
#Number guessing game started
count = 1
eat = 0
bite = 0
while eat < D:
print("Call " + str(count) )
call = input()
#Make a decision when the call is correct
if len(call) == D and len(set(call)) == len(call):
eat = 0
bite = 0
for i in range(D):
for j in range(D):
if str(N[i]) == call[j]:
if i == j:
eat += 1
else:
bite += 1
if eat == D:
print(str(D) + " EAT")
#A special effect will be added only when ONE CALL is achieved.
if count == 1:
print("ONE CALL")
else:
print("Numer0n in " + str(count) + " Calls")
else:
print(str(eat) + " EAT " + str(bite) + " BITE")
count += 1
#Correspondence in case of Miss Call
else:
print("Again!")
By changing the number of digits D
, you can challenge the game of guessing numbers of 5 digits or more in addition to the 3 digits and 4 digits that appeared in the original family.
Basically, it is a game that you only attack, so by displaying the number of calls such as "how many times you were hit", a score attack element is added. Aim for ONE CALL!
In this program, the original number N
is of type ʻint and the entered number
callis of type string, and in the comparison part,
N` is converted to type string and the judgment is made. I will. The reason why I am doing such a troublesome thing is because of the ** "item" ** that I will implement later.
What sets Numer0n apart from Hit and Blow is the presence of ** items **.
In Numer0n, there are various items that can help you attack and defend. This time, we will implement three of them, attack items.
3.1 HIGH & LOW
You can know either "HIGH (5-9)" or "LOW (0-4)" for all the digits of the other party. The other party is made to declare in order from the left digit (example: if "809", "HIGH (8), LOW (0), HIGH (9)"). You can narrow down the numbers to some extent in the early stages, and it can be useful for fixing the numbers in the final stages. (Wikipedia)
A powerful item that can narrow down all digits. For 3 digits, you can use HIGH & LOW first to narrow down the candidates from 720 to 100 at worst, and hopefully 60.
If you implement this item in Python, it will look like this.
high_and_low.py
#HIGH and LOW
N = [int(input()) for _ in range(3)]
HL = ""
for i in range(len(N)):
if N[i] <= 4:
HL += 'L '
else:
HL += 'H '
print(HL)
Entering a number for each digit returns the number HIGH / LOW.
input
5 2 9
output
H L H
It's easy because you just compare the size with 4.
3.2 SLASH
You can ask for the "slash number", which is the maximum number used by the other party minus the minimum number. For example, if it is "634", the maximum number "6" -the minimum number "3" = the slash number "3". If the slash number is "9", there is only a possibility that the maximum number is "9" and the minimum number is "0", so the use of 0 and 9 is confirmed. Also, if it is "2", it is inevitably understood that it is composed of three consecutive numbers such as "012" and "123". Depending on how you use it, you can see a lot of people, and you can use it as a deterrent to "use 9 and 0" or "use consecutive numbers" just by holding it without using it. It was named because it can "throw away" the possible usage patterns of numbers. (Wikipedia)
This is also an item that allows you to narrow down the numbers of the other party at once. It's more difficult to use than HIGH & LOW, but if you use it in this situation, you can determine the number you are using at once. In particular, as you can see in the quoted part, the effect is outstanding for specific arrangements such as "combination of 9 and 0".
If you implement this item in Python, it will look like this.
slash.py
#SLASH
N = [int(input()) for _ in range(3)]
SN = max(N) - min(N)
print(SN)
If you enter a number for each digit, the slash number of that number is returned.
input
5 2 9
output
7
This isn't that big of a deal either. max function is the best! By the way, the slash number of 7 is narrowed down to the patterns of "7,0 and the number between", "8,1 and the number between", and "9,2 and the number between". Depending on the result of the Call so far, you can eliminate the possibility from here.
3.3 TARGET
You can specify one of 10 different numbers to ask the other person. If the number is included in the other party's combination, it is also known which digit it is in. In particular, if you specify "a number in the BITE state that you can see that it is included but you do not know which digit it is," you can know exactly where the digit is. On the contrary, if the number you asked is not included, you can narrow down by using other numbers. (Wikipedia)
This item is used from the middle to the end of the game. It is effective for narrowing down from the possibility that there is little remaining.
If you implement this item in Python, it will look like this.
target.py
#TARGET
N = [int(input()) for _ in range(3)]
TN = int(input())
judge = 0
for i in range(len(N)):
if N[i] == TN:
print("Place " + str(i+1))
judge = 1
if judge == 0:
print("Nothing.")
Enter a number, and then enter one TN
(this is an abbreviation for TARGET NUMBER) from 10 types of numbers, and if it is included, its position (what number from the left), if it is not included, Nothing. Returns.
input
5 2 9
Target number 1
2
Output 1
Place 2
Target number 2
7
Output 2
Nothing.
You can use break, but it's okay because you only have to turn the loop 10 times at most.
Here is the Numer0n program that incorporates the above three items.
As a rule
Numer0n_Item.py
#Numer0n_Item
import random
#Decide the number to be the subject
proper = 0
while proper == 0:
print("Digit?")
#The number of digits is decided
D = int(input())
N = []
#The number of digits must be from 1 to 10 digits
if 1 <= D <= 10:
while len(N) < D:
n = random.randint(0,9)
if n in N:
pass
else:
N.append(n)
proper += 1
else:
print("Improper.")
#Number guessing game started
count = 1
eat = 0
bite = 0
#Items can only be used once in total
item = 1
while eat < D:
print("Call " + str(count) )
call = input()
#Make a decision when the call is correct
if len(call) == D and len(set(call)) == len(call):
eat = 0
bite = 0
for i in range(D):
for j in range(D):
if str(N[i]) == call[j]:
if i == j:
eat += 1
else:
bite += 1
if eat == D:
print(str(D) + " EAT")
#A special effect will be added only when ONE CALL is achieved.
if count == 1:
print("ONE CALL")
else:
print("Numer0n in " + str(count) + " Calls")
else:
print(str(eat) + " EAT " + str(bite) + " BITE")
count += 1
#HIGH AND LOW
elif call == "HIGH AND LOW":
if item == 1:
HL = ""
for i in range(len(N)):
if N[i] <= 4:
HL += 'L '
else:
HL += 'H '
print(HL)
item = 0
else:
print("Already used.")
#SLASH
elif call == "SLASH":
if item == 1:
SN = max(N) - min(N)
print(SN)
item = 0
else:
print("Already used.")
#TARGET
elif call == "TARGET":
if item == 1:
print("TARGET Number?")
TN = int(input())
judge = 0
for i in range(len(N)):
if N[i] == TN:
print("Place " + str(i+1))
judge = 1
if judge == 0:
print("Nothing.")
item = 0
else:
print("Already used.")
#Correspondence in case of Miss Call
else:
print("Again!")
The main reason I received the call
as a string was because I wanted to declare the name of the item so that it could be used.
It is not possible to deal with notational fluctuations such as TARGET
and Target
, target
, but forgive it.
There were many people who implemented Numer0n in Python in the Qiita article, but I didn't implement the item, so I tried it myself. I'm glad that it went well.
It sounds interesting even in a person-to-person game. Then, it seems that the significance of existence of DOUBLE, SHUFFLE, and CHANGE, which were not implemented this time, will grow. The problem is that it seems to be annoying, and it would be a problem if the other party could see the output, so it would be difficult to implement it.
The game that the CPU also attacks seems to be tough with my ability, so if anyone is interested, please do it.
We welcome comments such as impressions of playing and pointing out improvements.
Well then.
Recommended Posts