0

現在、私は戦艦ボードゲームを練習として作成しようとしています。ほとんどの場合、いくつかのその他のスタンドアロン関数でクラスを使用しています。以下はすべてスタンドアロンです。これは、リストの最後から最初の順に船を攻撃するとうまくいきますが、他の順序で行くと、リストのインデックスが存在しないと言って壊れます。助けてください。

基本的に私のシステムは、船が「ヒット」するたびに(移動はshipListの位置と同じ位置にあります)、hitListを追加します。これらの関数は、船の既知の位置に対して hitList 内の項目のいずれかがチェックされているかどうかを確認します...船オブジェクトが作成されるときに別のリストに作成されます。私はこれを2日間機能させようとしています

def checkForSunk(shipList, hitList):

    #Lists is something like this [[0,1],[0,2],[0,3]]
    #ShipList[0] is list, [1] is name of ship
    #ShipList is ALL ships.

    print 'SHIPLIST : %s' % (shipList)
    #[[[[0,1],[0,2],[0,3],[0,4],[0,5],[],[]], 'Destroyer'], [[[0,1],[0,2],[0,3],[0,4],[0,5],[],[]], 'Destroyer'], [[[0,1],[0,2],[0,3],[0,4],[0,5],[],[]], 'Destroyer']]

    #[[[0,1],[0,2],[0,3],[0,4],[0,5],[],[]], 'Destroyer']
    #   0                                       1
    print 'HITLIST : %s ' % (hitList)
    for j in range(len(shipList)):
        for i in shipList[j][0]:
            if i in hitList:
                print 'True in ship # %s' % (shipList[j][1])
                del shipList[j][0][shipList[j][0].index(i)] #Delete that part of the ship from the list.
    #Check if there's any empty ships, and delete the ship if there are.
    for j in range(len(shipList)):
        print shipList[j] #Problem around here!!!!!!!!!!!!
        if listIsEmpty(shipList[j][0]):
            print '%s has been sunk!' % (shipList[j][1])
            del shipList[j]


def isGameOver(shiplist):
    if shiplist == []:
        return True
    else:
        return False

def listIsEmpty(list):
    for i in range(len(list)):
        if list[i] != []: #If it finds anything thats not empty, return False. Else true
            return False
        else:
            return True

私はそれについてすべて間違っていますか?リストを物理的に削除する必要がありますか?

ありがとう

4

4 に答える 4

1

答えは、 for-loop を使用してリスト内の項目を削除する問題と同じです。

逆方向に繰り返す:

for j in range(len(shipList) - 1, -1, -1):
于 2012-08-01T11:54:46.287 に答える
0

私がよく理解している場合、あなたhitlistにはすべてのヒットが含まれています(つまり、各移動でチェックしません):そうであれば、geccoは症状に合っています:反復中にリスト内の要素を削除できません(インデックスを無効にします)。ただし、リストを逆にしても、船を最初から最後まで沈めると同じ問題が発生するため、これは修正されません。

コードをあまり変更したくない場合は、(リスト要素を削除しないため、反復は有効なままです)に置き換えdel shipList[j]てからshipList[j][0] = None、 function を再定義しますisGameOver

def isGameOver(shiplist):
    ret = True
    for ship in shiplist:
        if shiplist[0] is not None:
            ret = False
            break
    return ret
于 2012-08-01T12:11:56.863 に答える
0

あなたが遭遇したバグは @gecco answer で説明されています。

ネストされたループを使用しないようにすると、コードが理解しやすくなります。

たとえば、次の関数は、リストの最初の要素のみをチェックするため、間違っています。

def listIsEmpty(list):
    for i in range(len(list)):
        if list[i] != []: #If it finds anything thats not empty, return False. Else true
            return False
        else:
            return True

それは次のように書くことができます

def listIsEmpty(alist):
    return not any(alist)

および checkForSunk 関数

#Check if there's any empty ships, and delete the ship if there are.
for j in range(len(shipList)):
    print shipList[j] #Problem around here!!!!!!!!!!!!
    if listIsEmpty(shipList[j][0]):
        print '%s has been sunk!' % (shipList[j][1])
        del shipList[j]

次のように書くことができます

# sometimes use filter can make thing easier.
shipList = [k for k in shipList if not listIsEmpty(k[0])]
于 2012-08-01T12:52:26.520 に答える
-1

申し訳ありませんが、修正するのに十分な情報またはコードが提供されていないため、解決策のコードを提供できません。しかし、リストを理解するのに役立つコード例を提供しました。

#a list with 10 object
mylist = [1,2,3,4,5,6,7,8,9,10]
print mylist
>>> 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#if i print the 6th object:
print mylist[5]
>>> 
6
#if i delete an object from the end:
del mylist[9]
print mylist
>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9]
#as you can see, the item is gone, and the list only has 9 objects.

#if i print the 6th object:
print mylist[5]
>>> 
6

#but if i delete an item from the middle
del mylist[4]
print mylist
>>>
[1, 2, 3, 4, 6, 7, 8, 9]
#i now have 8 objects as expected, but the objects location in the list has changed.

#if i print the 6th object:
print mylist[5]
>>> 
7

これが役立つことを願っています

于 2012-08-01T11:45:27.683 に答える