1

私はエラーIndexErrorを受け取り続けます:タプルが範囲外であり、皆さんが私のプログラムで私を助けてくれることを望んでいました

MIN_ROW = 0
MAX_ROW = 3
MIN_COLUMN = 0
MAX_COLUMN = 19

7行目で問題が解決しないようです

def display(theMap):
r = 0
c = 0
print("PLAYER MAP")
for r in range (0, (MAX_ROW + 1), 1):
    for c in range (0, (MAX_COLUMN + 1), 1):
        print(theMap[r][c])   #this line
    print()
print()

def loadMap():
theMap = []
for r in range(0,(MAX_ROW+1), 1):
    theMap.append([])
    for c in range(0,(MAX_COLUMN+1), 1):
        theMap[r].append(" ")
#           0    1    2    3    4    5    6    7    8    9   10   11    12   13   14   15   16    17   18   19 
map  [0] =   "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J"
map  [1] =   "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"
map  [2] =   "|r|","| |", "| |", "| |", "| |", "| |", "| |", "| |", "| |", "| |", "|" 
map  [3] =   "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"
return theMap

だから、私のタプルがどのように範囲外にあるのかわかりませんが、皆さんが指摘して私を助けてくれることを願っています

4

2 に答える 2

3

明示的なループで物事を書くと、デバッグが難しい問題が発生することがよくあります。そのため、Pythonは強制的にそうすることを強制せず、実際には次のことを行わないように勧めています。

def display(theMap):
    print("PLAYER MAP")
    for row in theMap:
        for col in row:
            print(col)
        print()
    print()

print(col)改行を出力するため、これはまだ実際には必要なものではありません。各セルを独自の行に配置するのではなく、セル間にスペースを配置し、各行を独自の行に配置する必要があります。それを取得するには、print(col, end=' ')代わりにする必要があります。

または、もっと簡単に:

def display(theMap):
    print("PLAYER MAP")
    for row in theMap:
        print(' '.join(row))
    print()

または、さらに簡潔に、しかしおそらくそれほど単純ではありません。

def display(theMap):
    print("PLAYER MAP")
    print('\n'.join(' '.join(row) for row in theMap))
    print()

同様に、空の行を作成してから置き換えるのではなく、1回のパスでマップを作成するだけでマップを改善できます。例えば:

def loadMap():
    return [
        ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J"),
        ("-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"),
        ("|r|","| |", "| |", "| |", "| |", "| |", "| |", "| |", "| |", "| |", "|"),
        ("-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-")]

一般に、for i in range(something)Pythonで記述していることに気付いたときはいつでも、デバッグするだけの不必要なことをしていることになります。

さて、このスタイルは「エラーをキャッチ」しないと主張することができます。ただし、明示的なループを使用して処理を行うと、ほんの一握りのエラーがキャッチされ、デバッグが非常に難しい方法でそれらがキャッチされます。前提条件を知っている場合は、通常、はるかに簡単かつ明確にそれらを書くことができます。

theMap = loadMap()
assert(all(len(row) == len(theMap[0]) for row in theMap))

また、テストケースの出力がどうあるべきかがわかっている場合は、出力を検証する単体テストを作成できます。

とにかく、これをすべて修正した後でも、まだいくつかの問題が発生します。たとえば、行2が他の行よりも数列短いという事実に加えて、その行の個々の列は他の行の列の3倍の大きさであるため、まったく整列しません。ただし、実行すると、視覚的なもののデバッグが簡単になります。

一歩下がると、明らかに「r」を行2まで進めます。実際、マップを表すために必要なのは、幅と現在の位置だけです。

def display(mapWidth, playerPosition):
    print('PLAYER MAP')
    # Display the first line. This is the header, with a label for each of the
    # mapWidth columsn, with a space between each label, and an extra space at
    # the start, like ' 0 1 2 3 4'. The ' '.join(s) creates a new string by 
    # putting a space between each element of s. The '012...XYZ'[:mapWidth] 
    # just takes the first mapWidth characters of the longer string. 
    print(' ' + ' '.join('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'[:mapWidth]))

    # Display the second line. This is just a '-' for each column, with a space
    # between each, and an extra space at the start, like ' - - - - -'. The join
    # works the same as above; the '-' * mapWidth creates a string with mapWidth
    # copies of '-'.
    print(' ' + ' '.join('-' * mapWidth))

    # Display the third line. This is the trickiest. This is cell for each column,
    # where the first playerPosition cells are '| |', the playerPositionth is 
    # '|r|', and the rest are again '| |', with no space between them. It seemed
    # simpler to treat this as a group of playerPosition+1 '|' characters with 
    # spaces between, an 'r' character, and a group of mapWidth-playerPosition
    # '|' characters with spaces between again, but there are various different 
    # ways of printing something equivalent. The only new thing here is the 
    # end='' keyword argument--without that, each print ends with a newline.
    print(' '.join('|' * (playerPosition + 1)), end='')
    print('r', end='')
    print(' '.join('|' * (mapWidth - playerPosition)))

    # Fourth line, same as the second.
    print(' ' + ' '.join('-' * mapWidth))
    print()

joinメソッドやprint関数などに精通している場合は、これを少し読みやすくすることができます。

def display(mapWidth, playerPosition):
    print('PLAYER MAP')
    print(' ' + ' '.join('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'[:mapWidth]))
    print(' -' * mapWidth)
    print(' '.join('|' * (playerPosition + 1)) +
          'r' +
          ' '.join('|' * (mapWidth - playerPosition)))
    print(' -' * mapWidth)
    print()

' ' + ' '.join('-' * 8)たとえば、がと同じである理由を検討する価値があり' -' * 8ます。

トリッキーな3行目を行うさらに別の方法は次のとおりです。

   # Print mapWidth '|' characters, each followed by a ' ', except for the one
   # at the player position, which is followed by an 'r'. Then we still need one
   # more '|' at the end.
   print(''.join('|' + (' ' if i != playerPosition else 'r') 
                 for i in range(mapWidth) + '|')

これは英語で説明するのが最も簡単な方法だと思いますが、Pythonに変換するには、ジェネレーター式と3項式のif式が必要です。どちらもまだ学習したくないと思われます。最終的には、Pythonの経験にさえなります。開発者はおそらく読みたくないでしょう。

もちろん、疑わしい場合は、いつでも物事を別々の行に、または別々の関数に引き出して、読みやすくすることができます。

    cellsBeforePlayer = '| ' * playerPosition
    cellsWithPlayer = cellsBeforePlayer + '|r|'
    cellsToEnd = cellsWithPlayer + '| ' * (mapWidth - playerPosition)
    print(cellsToEnd)

とにかく、これらはすべて同じことをします:

>>> display(MAX_COLUMN - MIN_COLUMN + 1, 3)
PLAYER MAP
 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J
 - - - - - - - - - - - - - - - - - - - -
| | | |r| | | | | | | | | | | | | | | | |
 - - - - - - - - - - - - - - - - - - - -

MIN_COLUMNそれらと値が要件の一部でない限り、代わりにMAX_COLUMN単一のCOLUMNS=20変数を使用します。これも、別の一般的な1つずつのエラー(+ 1必要なときに含めるのを忘れがちな関数呼び出しでのエラー)を回避します。不要なときに誤って追加する)。

または、マップの幅が固定されている場合は、さらに簡単です。

def display(playerPosition):
    print('PLAYER MAP')
    print(' ' + ' '.join('0123456789ABCDEFGHIJ'))
    print(' -' * 20)
    print(' '.join('|' * (playerPosition + 1)) +
          'r' +
          ' '.join('|' * (20 - playerPosition)))
    print(' -' * 20)
    print()

いずれにせよ、これの利点は、単純さを超えておりdisplay、まったく必要ありませんloadMap。これの代わりに、プレーヤーを動かすことができます。

theMap[2][playerPosition] = '| |'
playerPosition += stepsMoved
theMap[2][playerPosition] = '|r|'
display(theMap)

あなたはこれをするだけです:

playerPosition += stepsMoved
display(playerPosition)

ゲーム全体の状態は、リストの複雑なリストから単一の整数に削減されます。

于 2012-11-21T01:33:09.050 に答える
1

map[2]他の行とはフォーマットが異なるようです。これは、反復する要素が20個ないことを意味します。それはあなたが見ているエラーを引き起こすでしょう。

また、map()は組み込み関数なので、混乱を避けるために別の名前を選択することをお勧めします。

この場合、インデックスを使用してマップを反復処理することは避け、とにかくタプルを反復処理する必要があります。

def display(the_map):
    print("PLAYER MAP")
    for row in the_map:
        for cell in row:
            print(cell)
        print()
    print()

多分

def display(the_map):
    print("PLAYER MAP")
    for row in the_map:
        print(''.join(row))
    print()

編集:より多くの情報があります、ここにあなたの地図を実装するためのより簡単で非常に明確な方法があります

def display(the_map):
    print(the_map[0].replace("", " "))
    print(the_map[1].replace("", " "))
    print(the_map[2].replace("", "|"))
    print(the_map[3].replace("", " "))

the_map = ["0123456789ABCDEFGHIJ",
           "--------------------",
           "r                   ",
           "--------------------"]
display(the_map)
于 2012-11-21T01:03:53.813 に答える