2017-06-29 11 views
1

私はPythonで戦艦ゲームを構築しています。私はリストを持っており、私はリストの10x10の範囲外にあるユーザ入力をキャッチするためにPythonでバリデーションツールを構築しようとしています。ここPythonの検証関数がIndexErrorを生成します:リスト割り当てインデックスが範囲外です

コードである:

from random import randint 

player = "User" 
board = [] 
board_size = 10 

ships = {"Aircraft Carrier":5, 
      "Battleship":4, 
      "Submarine":3, 
      "Destroyer":3, 
      "Patrol Boat":2} 

def print_board(player, board): # to print joined board 
    print("Here is " + player + "'s board") 
    for row in board: 
     print(" ".join(row)) 

def switch_user(player): # to switch users 
    if player == "User": 
     player = "Computer" 
    elif player == "Computer": 
     player = "User" 
    else: 
     print("Error with user switching") 

for x in range(0, board_size): # to create a board 
    board.append(["O"] * board_size) 

print_board(player,board) 

def random_row(board): # generate random row 
    return randint(0, len(board) - 1) 

def random_col(board): # generate random column 
    return randint(0, len(board[0]) - 1) 

def user_places_ships(board, ships): # user choses to place its ships by providing starting co-ordinate and direction. 
    for ship in ships: 
     valid = False 
     while(not valid): 
      user_input_coordinates = input("Please enter row & column number for your " + str(ship) + ", which is " + str(ships[ship]) + "-cells long (row, column).") 
      ship_row, ship_col = user_input_coordinates.split(",") 
      ship_row = int(ship_row) 
      ship_col = int(ship_col) 
      user_input_dir = input("Please enter direction for your " + str(ship) + ", which is " + str(ships[ship]) + "-cells long (h for horizontal or v for vertical).") 
      valid = validate_coordinates(board, ships[ship], ship_row, ship_col, user_input_dir) 
      if not valid: 
       print("The ship coordinates either outside of" , board_size, "X" , board_size, "range, overlap with or too close to another ship.") 
     place_ship(board, ships[ship], ship_row, ship_col, user_input_dir) 
    print("You have finished placing all your ships.") 

def validate_coordinates(board, ship_len, row, col, dir): # validates if the co-ordinates entered by a player are within the board and don't overlap with other ships 
    if dir == "h" or dir == "H": 
     for x in range(ship_len): 
      if row-1 > board_size or col-1+x > board_size: 
       return False 
      elif row-1 < 0 or col-1+x < 0: 
       return False 
      elif board[row-1][col-1+x] == "S": 
       return False 
    elif dir == "v" or dir == "V": 
     for x in range(ship_len): 
      if row-1+x > board_size or col-1 > board_size: 
       return False 
      elif row-1+x < 0 or col-1 < 0: 
       return False 
      elif board[row-1+x][col-1] == "S": 
       return False 
    return True 

def place_ship(board, ship_len, row, col, dir): # to actually place ships and mark them as "S" 
    if dir == "h" or dir == "H": 
     for x in range(ship_len): 
      board[row-1][col-1+x] = "S" 
    elif dir == "v" or dir == "V": 
     for x in range(ship_len): 
      board[row-1+x][col-1] = "S" 
    else: 
     print("Error with direction.") 
    print_board(player,board) 

user_places_ships(board,ships) 

ユーザが船の座標と水平方向のための "H" は、 "10,10" を入力した場合、その後、Pythonは、次のエラーメッセージを生成:

Traceback (most recent call last): File "C:/Users/Elchin's PC/Downloads/battleships game.py", line 85, in <module> 
    user_places_ships(board,ships) File "C:/Users/Elchin's PC/Downloads/battleships game.py", line 49, in user_places_ships 
    valid = validate_coordinates(board, ships[ship], ship_row, ship_col, user_input_dir) File "C:/Users/Elchin's PC/Downloads/battleships game.py", line 62, in validate_coordinates 
    elif board[row-1][col-1+x] == "S": IndexError: list index out of range 

私はエラーがこの行であることを知っている:

elif board[row-1][col-1+x] == "S": 
    return False 

しかし、私はそれを修正する方法がわかりません。あなたは解決策を理解するのを助けてくれますか?

+4

チェックは '行-1 + X> = board_sizeする必要がありますまたはcol-1> = board_size':より大きいか等しい*。 –

+0

エラーは、無効な位置にアクセスしようとしていることを意味します。アクセスしようとしている位置がボードのサイズよりも小さいことを確認してください。有効な位置は '0 <= pos KelvinS

答えて

1

リストの長さはn個を持っている場合は、(包括的両方の)0からのn-1にインデックスにアクセスすることができます。

あなたifステートメントは、しかしチェック:我々は最後elifの部分に達した場合

if row-1+x > board_size or col-1 > board_size: # greater than n 
    return False 
elif row-1+x < 0 or col-1 < 0:     # less than 0 
    return False 
elif board[row-1+x][col-1] == "S": 
    return False 

をその結果、我々はインデックスが0 < i <= nであることを保証しています。しかし、これらは0 < i < nでなければなりません。

だから、あなたが最初のif文を変更する必要があります。あなたが書くことでコードをよりエレガントにすることができます

if row-1+x >= board_size or col-1 >= board_size: # greater than or equal n 
    return False 
elif row-1+x < 0 or col-1 < 0:     # less than 0 
    return False 
elif board[row-1+x][col-1] == "S": 
    return False 

if not (0 < row-1+x < board_size and 0 < col-1 < board_size) or \ 
     board[row-1+x][col-1] == "S": 
    return False 
関連する問題