IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

[List out of range] Test dans le démineur


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Par défaut [List out of range] Test dans le démineur
    j'ai le même problème sur une matrice mais je sais pas comment le resoudre: je vous met mon code pour comprendre le problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    def mineautour(size):
        global mat
        for i in range(5):
            for j in range(5):
                k=0;
                if (mat[i][j]=='B'):
                    break
                else:
                    if (mat[i-1][j]=='B'):
                        k=k+1;
                    if (mat[i-1][j+1]=='B'):
                        k=k+1;
                    if (mat[i][j+1]=='B'):
                        k=k+1;
                    if (mat[i+1][j+1]=='B'):
                        k=k+1;
                    if (mat[i+1][j]=='B'):
                        k=k+1;
                    if (mat[i+1][j-1]=='B'):
                        k=k+1;
                    if (mat[i][j-1]=='B'):
                        k=k+1;
                    if (mat[i-1][j-1]=='B'):
                        k=k+1;
                    if (mat[i-1][j]=='B'):
                        k=k+1;
                mat[i][j]=k;
    J'ai une matrice avec des bombes à l'interieur et pour chaque case, il faut que je cherche les bombes autour si quelqu'un peut m'aider...

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Citation Envoyé par mcalus Voir le message
    [...] il faut que je cherche les bombes autour si quelqu'un peut m'aider...
    Donc, par contraposition, si personne ne peut t'aider, tu n'as plus à chercher les bombes autour. Tu as donc intérêt à ce que personne ne puisse t'aider, c'est moins de travail pour toi.

    Bon sérieux, tu n'as vraiment pas une idée d'où ça peut venir ? Qu'est-ce qui se passe sur les bords de ta matrice. Quelle est la valeur minimum que va prendre i (ou j) ? Donc quand tu écris mat[i-1][j] ça donne quoi ?

  3. #3
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Par défaut
    Le truc sait que je sait....que je sors de la matrice et donc c'est pour sa qu'il comprend pas. J'aimerais donc trouver un (autre) moyen pour le faire....
    Quand je suis en (i,j), je regarde autour de cette valeur pour voir si ya B.Mais je trouve aucune autre manière de le dire que celle-ci....

  4. #4
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Par défaut
    je pense que l'idée est bonne mais il me marque liste index out of range....
    Parce qu'il teste des valeurs qui n'existe pas.
    Je cherche donc à parcourir chaque case de la matrice et à regarder autour voir si il y'a une bombe.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2008
    Messages : 76
    Par défaut
    Salut !

    Le problème se situe dans le test des positions autours de la case courante. Lorsque tu arrives près des bords du terrain, tu continues de vérifier les valeurs de cases qui n'existent pas. Par exemple, avec mat[i+1][j+1]=='B', si i est égal à 5 tu vas essayer de regarder la valeur de la case mat[6][6]... une case en dehors du tableau.

    Il y a le même soucis avec les valeurs négatives, ou presque. Au début de ta boucle, tes valeurs i et j valent toutes deux 0. Aussi, quand tu testes la valeur de mat[i-1][j]=='B' c'est équivalent à mat[-1][0] ce qui n'est pas le comportement recherché (si tu indiques -1 comme indice dans un tableau, tu consultes sa dernière valeur ^^).

    Pour éviter ça, je construis généralement une petite liste avec les différentes positions que je veux tester autour de la case centrale. Je parcours toutes les cases du tableau comme tu le fais mais quand je tombe sur un calcul impossible (x ou y < que 0 et x ou y plus grand que le tableau) je saute le test tout simplement et passe au prochain.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    # -*- coding: latin-1 -*-
    # Terrain de jeu. 0 pour les cases vides, 1 pour les cases contenant une bombe
    terrain = [
    [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
    [0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
    [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ]
     
    # Compte le nombre de mines autour d'une case
    ## Retourne une tableau du terrain avec, pour chaque case, le nombre de mines alentours
    def compterMines (terrain):
     
    	nbrMines = []
    	# Liste de positions à tester
    	casesATester = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]
     
    	# Parcourir le terrain
    	for y in range(len(terrain)-1):
     
    		nbrMines.append( [] )	# On ajoute une ligne dans le tableau que l'on va retourner
    		for x in range( len(terrain[0])-1 ):
     
    			nbr = 0	# Initialiser le compte des mines alentours
    			for c in casesATester:
     
    				# On passe au test suivant si la position testée est négative (x ou y < 0)
    				if x+c[0] < 0 or y+c[1] < 0:
    					continue
    				# Idem si la position testée est en dehors du terrain
    				if x+c[0] > len(terrain[0])-1 or y+c[1] > len(terrain)-1:
    					continue
     
    				# Si la case contient un 1, c'estune bombe, on incrémente le compteur (x ou y > que le tableau représentant le terrain)
    				if terrain[y+c[1]][x+c[0]] == 1:
    					nbr += 1
    			# On ajoute le nombre de mines dans le tableau
    			nbrMines[y].append(nbr)
     
    	return nbrMines
     
    # Compter les mines du terrain
    t = compterMines(terrain)
    # Affichage du résultat
    for y in t:
    	ligne = ""
    	for x in y:
    		ligne += str(x) + " "
    	print ligne

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Une façon classique de faire, qu'on ferait en C par exemple, c'est de rajouter deux lignes (une au début et une à la fin) et deux colonnes à ta matrice, qui resteraient toujours vide et ne seraient pas affichées; tes indices à parcourir vont de 1 à n et les indices 0 et n+1 sont donc valides mais contiennent une valeur "neutre". En Python, on peut se contenter de ne rajouter qu'une seule ligne et une seule colonne, la dernière, car l'indice -1 est valide et retourne le dernier élément du tableau. Tes indices continuent donc de varier de 0 à n-1 comme actuellement mais le tableau contient un élément de plus (d'indice n).

    Une autre solution serait de tester la validité de tes indices dans la boucle, mais c'est plus lent car le test doit être effectué pour chaque case.

  7. #7
    Expert confirmé
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Par défaut
    Le mieux pour éviter d'avoir des tests à effectuer pour savoir si on est en dehors du tableau est de construire ta matrice de 2 colonnes et 2 lignes de plus, les cases du bord ne pouvant bien entendu ne pas avoir de mines. Non seulement, au niveau de ton programme, cela sera plus concis mais en plus, cela sera plus rapide.

    C'est ce que je fais dans le jeu du Reversi

  8. #8
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Par défaut
    Bonjour...
    Encore un petit problème...

    J'ai choisi d'imposer une condition avant de tester (if i-1>-1....) le problème c'est que dés que le j rencontre une bombe, j s'implémente et donc le prog arréte de chercher dans la colonne.....

    Je vous mets le programme (un peu indigeste...)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    def mineautour(size):
        global mat
        for i in range(5):
            for j in range(5):
                k=0;
                if (mat[i][j]=='B'):
                    break
                if(i-1>-1):
                    if (mat[i-1][j]=='B'):
                        k=k+1;
                    if(j+1<5):
                        if (mat[i-1][j+1]=='B'):
                            k=k+1;
                if(j+1<5):
                    if (mat[i][j+1]=='B'):
                       k=k+1;
                    if(i+1<5):
                        if (mat[i+1][j+1]=='B'):
                            k=k+1;
                if(i+1<5):
                    if (mat[i+1][j]=='B'):
                        k=k+1;
                    if(j-1>-1):
                        if (mat[i+1][j-1]=='B'):
                            k=k+1;
                if(j-1>-1):
                    if (mat[i][j-1]=='B'):
                        k=k+1;
                    if(i-1>-1):
                        if (mat[i-1][j-1]=='B'):
                            k=k+1;
                if(i-1>-1):
                    if (mat[i-1][j]=='B'):
                        k=k+1;
     
                mat[i][j]=k;

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2008
    Messages : 76
    Par défaut
    Pfiou, effectivement c'est un peu indigeste... c'est le soucis quand on rajoute beaucoup de tests...

    Je ne comprends pas trop pourquoi tu testes si la case courante est une bombe puisque tu cherches à compter mines alentours. Si tu supprimes le test "if (mat[i][j]=='B'):" ta fonction ne devrait plus sauter les colonnes quand elle rencontre une bombe.

    Je t'encourage à suivre la méthode proposée par dividee et Guigui_ ou la mienne (que je préfère évidemment, car j'aime que mon terrain/tableau reflète ce que je vais afficher... question de sensibilité). Les deux me semblent plus claires et compréhensibles qu'une batterie de if imbriqués.

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut j'adore

    Donc, par contraposition, si personne ne peut t'aider, tu n'as plus à chercher les bombes autour. Tu as donc intérêt à ce que personne ne puisse t'aider, c'est moins de travail pour toi.

  11. #11
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    merci eyquem, je pensais que c'était passé inaperçu

    mcalus, "dérouler" ainsi tous les tests c'est effectivement indigeste et il est facile de se tromper. La preuve: dans ton code, le cas mat[i-1][j]=='B' se trouve deux fois!

    Voilà un exemple (en Python 3.0) avec la méthode que j'ai décrite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    mat =[list('         X'),
          list('    B   BX'),
          list('B        X'),
          list('   BB  B X'),
          list('  B      X'),
          list('  BB     X'),
          list('     BB  X'),
          list('  B      X'),
          list(' B   B   X'),
          list('XXXXXXXXXX')]
     
    WIDTH, HEIGHT = len(mat[0])-1, len(mat)-1
     
    for i in range(WIDTH):
        for j in range(HEIGHT):
            if mat[i][j] != 'B':
                mat[i][j] = sum(mat[i+k][j+l]=='B' for k in (-1,0,1) for l in (-1,0,1))
     
    for line in mat[:-1]:
        print(*line[:-1])
    Les calculs sont effectués en 4 lignes au lieu de 34 (bien que la vitesse d'exécution reste du même ordre). Les 'X' c'est juste pour indiquer la ligne et la colonne ajoutée; j'aurais pu mettre n'importe quoi sauf un 'B'.

    Résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    0 0 0 1 1 1 0 1 1
    1 1 0 1 B 1 0 1 B
    B 1 1 3 3 2 1 2 2
    1 2 2 B B 1 1 B 1
    0 2 B 5 3 1 1 1 1
    0 2 B B 2 2 2 1 0
    0 2 3 3 2 B B 1 0
    1 2 B 1 2 3 3 1 0
    1 B 2 1 1 B 1 0 0

  12. #12
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 23
    Par défaut
    merci à tous, on a résolu ce petit pb.....
    je ferme pas le sujet car d'autre risque d'arrive....

Discussions similaires

  1. Tache cron IndexError: list index out of range
    Par rene2200 dans le forum Général Python
    Réponses: 3
    Dernier message: 20/11/2009, 14h02
  2. un impossible "list index out of range" alors que si !
    Par guiguizekid dans le forum Général Python
    Réponses: 3
    Dernier message: 18/05/2008, 04h04
  3. test sur nom de sheet => "error 9 out of range"
    Par _debutant dans le forum Macros et VBA Excel
    Réponses: 19
    Dernier message: 09/12/2007, 15h54
  4. Test dans Liste déroulante
    Par gentoo dans le forum IHM
    Réponses: 1
    Dernier message: 29/01/2007, 15h19
  5. list index out of range
    Par watcha2020 dans le forum Général Python
    Réponses: 2
    Dernier message: 29/06/2006, 09h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo