J'essaie d'améliorer un jeu de cuirassés. La version originale fonctionne correctement sans erreur. J'ai écrit du code pour aider à surmonter le fait que la première version place les navires au même endroit à chaque fois, donc j'ai commencé avec un navire (constitué de deux carrés). J'ai fait cela en créant deux fonctions: la première génère une coordonnée aléatoire ...
# Destroyer (2 squares)
def Deploy_Destroyer_1(Player):
Rand_col_1 = randint(0,11)
if Rand_col_1 <= 5:
Rand_row_1 = randint(0,11)
else:
Rand_row_1 = randint(6,11)
return Rand_col_1
return Rand_row_1
if Player[Rand_row_1][Rand_col_1] == 'X':
Deploy_Destroyer_1(Player)
else:
Deploy_Destroyer_2(Player)
et les deuxièmes essais correspondent aux conditions (s’il tient sur le tableau et quelle rotation il peut être placé).
def Deploy_Destroyer_2(Player):
if Rand_col_1 == 5 and Rand_row_1 == 6:
#can be 1, 2, 3 or 4... in that order below
Rand_position_1 = randint(1,4)
if Rand_position_1 == 1:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 + 1][Rand_col_1] = 2
if Rand_position_1 == 2:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 3:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 + 1] = 2
if Rand_position_1 == 4:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Elif Rand_col_1 in range(1,4) and Rand_row_1 in range(1,10):
#can be any 1, 2, 3 or 4... in that order below
Rand_position_1 = randint(1,4)
if Rand_position_1 == 1:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 + 1][Rand_col_1] = 2
if Rand_position_1 == 2:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 3:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 + 1] = 2
if Rand_position_1 == 4:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Elif Rand_col_1 in range(5,10) and Rand_row_1 in range(7,10):
#can be any 1, 2, 3 or 4... in that order below
Rand_position_1 = randint(1,4)
if Rand_position_1 == 1:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 + 1][Rand_col_1] = 2
if Rand_position_1 == 2:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 3:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 + 1] = 2
if Rand_position_1 == 4:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Elif Rand_col_1 == 0 and Rand_row_1 == 0:
#can be any 1, 2, 3 or 4... in that order below
Rand_position_1 = randint(1,4)
if Rand_position_1 == 1:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 + 1][Rand_col_1] = 2
if Rand_position_1 == 2:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 3:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 + 1] = 2
if Rand_position_1 == 4:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Elif (Rand_col_1 == 5 and Rand_row_1 == 0) or (Rand_col_1 == 11 and Rand_row_1 ==6):
#can be one or four
#check brackets and booleans here
Rand_position_1 = randint(1,2)
if Rand_position_1 == 1: #position 1
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 + 1][Rand_col_1] = 2
if Rand_position_1 == 2: #position 4
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Elif Rand_col_1 == 0 and Rand_row_1 == 11:
#can be 2 or 3
Rand_position_1 = randint(2,3)
if Rand_position_1 == 2: #position 2
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 3: #position 3
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 + 1] = 2
Elif Rand_col_1 == 11 and Rand_row_1 == 11:
#can be 2 or 4
Rand_position_1 = randint(1,2)
if Rand_position_1 == 1: #position 2
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 2: #position 4
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Elif (Rand_row_1 == 0 and Rand_col_1 in range(1,4)) or (Rand_row_1 == 6 and Rand_col_1 in range(6,10)):
#can be 1, 3 or 4
#check brackets and booleans here
Rand_position_1 = randint(1,3)
if Rand_position_1 == 1: #position 1
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 + 1][Rand_col_1] = 2
if Rand_position_1 == 2: #position 3
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 + 1] = 2
if Rand_position_1 == 3: #position 4
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Elif (Rand_col_1 == 5 and Rand_row_1 in range(1,5)) or (Rand_col_1 == 11 and Rand_row_1 in range(7,10)):
#can be 1, 2 or 4
#check brackets and booleans here
Rand_position_1 = randint(1,3)
if Rand_position_1 == 1: #position 1
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 + 1][Rand_col_1] = 2
if Rand_position_1 == 2: #position 2
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 3: #position 4
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Elif Rand_col_1 == 0 and Rand_row_1 in range(1,10):
#can be 1, 2 or 3... in that order below
Rand_position_1 = randint(1,3)
if Rand_position_1 == 1:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 + 1][Rand_col_1] = 2
if Rand_position_1 == 2:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 3:
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 + 1] = 2
Elif Rand_col_1 in range(1,10) and Rand_row_1 == 11:
#can be 2, 3 or 4
Rand_position_1 = randint(1,3)
if Rand_position_1 == 2: #position 2
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1 - 1][Rand_col_1] = 2
if Rand_position_1 == 3: #position 3
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 + 1] = 2
if Rand_position_1 == 4: #position 4
Player[Rand_row_1][Rand_col_1] = 2
Player[Rand_row_1][Rand_col_1 - 1] = 2
Après avoir appliqué mon code, j'obtiens cette erreur.
Traceback (most recent call last):
File "<stdin>", line 310, in <module>
File "<stdin>", line 15, in PrintBoards
TypeError: sequence item 0: expected string, NoneType found
et voici la fonction PrintBoards
def PrintBoards(Player,Opponent):
print ' '*10, 'PLAYER', ' '*30, 'OPPONENT'
letters = ['A','B','C','D','E','F','G','H','I','J','K','L']
for x in range(6):
print letters[x]," ".join(map(DisplayChar,Player[x]))," "*18,"| "," ".join(map(DisplayChar,Opponent[x]))
for x in range(6,12):
print letters[x]," ".join(map(DisplayChar,Player[x]))," | "," ".join(map(DisplayChar,Opponent[x]))
print " "," ".join(map(str,range(1,10)))," 10 11 12"," "," ".join(map(str,range(1,10)))," 10 11 12"
et voici la fonction DisplayChar
def DisplayChar(x):
if x==0:
return '?'
Elif x==1:
return ' '
Elif x==2:
return 'X'
Elif x==3:
return ' '
Elif x==4:
return '*'
J'ai essayé de modifier la fonction ci-dessus pour cela ...
def DisplayChar(x):
if x==0:
return '?'
Elif x==2:
return 'X'
Elif x==4:
return '*'
else:
return ' '
Cependant il m'a donné cette erreur à la place
Traceback (most recent call last):
File "<stdin>", line 309, in <module>
File "<stdin>", line 15, in PrintBoards
TypeError: argument 2 to map() must support iteration
J'ai également essayé d'imprimer les listes Player et Opponent après la fonction PrintBoards pour s'assurer qu'elles contenaient des 0 et des 1 (en référence à la fonction DisplayChar), ce qu'elles font (lorsqu'elles sont insérées dans l'original, pas lorsque je mets mon nouveau et très long code)
Ce bit suivant est une réponse à Michael
PLAYER OPPONENT
[[1, 1, 1, 1, 1, 1], [1, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1], [1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1], [1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
[0, 0, 0, 0, 0, 0]
A | ? ? ? ? ? ?
<function Deploy_Destroyer_1 at 0x1c2634>
[0, 0, 0, 0, 0, 0]
B
Traceback (most recent call last):
File "<stdin>", line 314, in <module>
File "<stdin>", line 17, in PrintBoards
TypeError: argument 2 to map() must support iteration
MODIFIER
Après que quelqu'un a gentiment fait remarquer que j'avais assigné la fonction au lieu de l'appeler, j'ai constaté qu'une autre erreur s'était produite (je ne pense pas que Python m'aime bien)
Traceback (most recent call last):
File "<stdin>", line 313, in <module>
File "<stdin>", line 17, in PrintBoards
TypeError: argument 2 to map() must support iteration
Ci-dessous, j'ai également indiqué où j'ai appelé la fonction au cas où je ferais une bêtise.
Player, Opponent = InitBoards()
Player = DeployFleet(Player), Deploy_Destroyer_1(Player)
PrintBoards(Player,Opponent)
EDIT 2
Je l'ai changé en ce que Micheal0x2a a dit et il s'est déroulé sans erreur, mais le navire que le code place a disparu: s
D'après ce que j'ai compris, la fonction PrintBoards
imprime le tableau pour la Player
en mappant les éléments de la liste à la fonction DisplayChar
(si 2 est un élément de la liste, il imprime X, etc.). Ainsi, mes connaissances de novice me disent que la fonction Deploy_Destroyer_1
doit être appelée dans Player =
dans la fonction Main
(incluse ci-dessus) pour garantir que l'élément de la liste est modifié. Le caractère imprimé doit donc être modifié.
Je suppose qu'il y a quelque chose qui ne va pas dans mon nouveau code (Deploy_Destroyer_1
) qui ne le fait pas correctement (soit ne change pas l'élément de la liste et n'imprime donc pas le caractère correct, ou quelque chose d'autre que je peux ». ne pense pas à).
Cependant, il y a aussi une grande chance que je me suis confus :)
Je n'ai appris le python que depuis quelques semaines, donc si quelqu'un a besoin de plus de détails pour m'aider, merci de demander
Si vous êtes arrivé ici parce que vous recherchiez la cause première de "TypeError: sequence item 0: expected string, NoneType found
", cela peut venir de faire quelque chose dans ce sens ...
','.join([None])
Votre fonction DisplayChar n'a pas de valeur par défaut. Cela ne ferait aucun mal si vous gérez tous les cas possibles pour x
, mais apparemment, vous ne l'êtes pas. Essayer
def DisplayChar(x):
if x == 0:
return '?'
Elif x == 2:
return 'X'
Elif x == 4:
return '*'
else:
return ' '
mais cela donnera probablement des chaînes vierges où vous ne les attendez pas.
En général, je vous recommande de commencer par un bon tutoriel sur Python. Tout votre code ci-dessus peut être grandement simplifié.
Le problème se situe probablement dans ces 4 lignes:
for x in range(6):
print letters[x]," ".join(map(DisplayChar,Player[x]))," "*18,"| "," ".join(map(DisplayChar,Opponent[x]))
for x in range(6,12):
print letters[x]," ".join(map(DisplayChar,Player[x]))," | "," ".join(map(DisplayChar,Opponent[x]))
Dans ces lignes, vous avez utilisé plusieurs fois une instruction join
. L'instruction join
requiert une liste de chaînes pour fonctionner. Toutefois, lorsque vous mappez DisplayChar
à Player[x]
, la fonction DisplayChar
renvoie la valeur None
au lieu d'une chaîne quelconque.
Si vous examinez la fonction DisplayChar
, elle ne traite que les valeurs de 0 à 4. Les listes que vous utilisez contiennent probablement des chiffres ou des caractères supplémentaires. Si x
se trouve être quelque chose comme 5
, DisplayChar
se terminera et renverra simplement la valeur None
. N'oubliez pas que les fonctions renvoient la valeur None
par défaut.
Vous devez soit gérer ces numéros supplémentaires dans DisplayChar
, soit modifier DisplayChar
pour contenir une instruction else
afin de renvoyer une chaîne vide, comme suit:
def DisplayChar(x):
if x==0:
return '?'
Elif x==1:
return ' '
Elif x==2:
return 'X'
Elif x==3:
return ' '
Elif x==4:
return '*'
else:
return ' '
Modifier:
Ok, je pense que je pourrais savoir ce qui se passe, compte tenu des nouvelles modifications.
Notez que lorsque vous imprimiez Player[x]
, il imprimait <function Deploy_Destroyer_1 at 0x1c2634>
la deuxième fois?
Cela signifie que quelque part, enfoui au plus profond de votre code, vous avez agi comme suit: Player[row] = Deploy_Destroyer_1
(remarquez la parenthèse manquante!). Au lieu d'appeler la fonction, vous avez assigné la fonction.
La recherche et l'ajout de parenthèses manquantes devraient probablement résoudre le problème.
Edit 2:
Je pense que votre problème est avec cette ligne: Player = DeployFleet(Player), Deploy_Destroyer_1(Player)
Si vous essayez de faire un print Player
immédiatement après, je pense que vous verrez probablement une grande liste de nombres, suivie de None
.
En effet, la fonction DeployFleet
renvoie la table (je pense?) Alors que la fonction Deploy_Destroyer_1
ne renvoie rien. Au lieu de cela, il ne fait que transformer la table Player
.
Pour résoudre ce problème, essayez ceci:
Player = DeployFleet(Player)
Deploy_Destroyer_1(Player)
... ou modifiez Deployer_Destroyer_1
pour qu'il renvoie Player
une fois terminé, afin que vous puissiez le faire:
Player = DeployFleet(Player)
Deploy_Destroyer_1(Player)