2017-03-07 69 views
0

Python初學者 - 在一個類的Battleship項目上工作。我的程序將通過第一個玩家放置他們的船。網格成功打印板上的視覺船隻,但是一旦我到達玩家二,這些船隻與玩家之一重疊。 (還要注意有一些驗證工作仍需要完成)。使用類方法在Python遊戲中存儲用戶值

我認爲這個問題可能是我將兩個座標都存儲在同一個列表中。所以我的問題是我如何爲每個玩家存儲價值,以便我能讓董事會打印只適用於每個玩家的船舶?

這裏是我的課:

BOARD_SIZE = 10 

class Ship: 

    def __init__(self, ship_name, size, coords, player, direction): 
     self.ship_name = ship_name 
     self.size = size 
     self.player = player 
     self.coords = coords 
     self.direction = direction 


class Board: 
    def __init__(self): 
     self.board = [] 
     self.guesses = [] 

    board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)] 

    def add_ship(self, name, size, player, coords, direction): 
     for coord in coords: 
      # convert string like "a1" to x,y coordinates 
      y = ord(coord[0])-ord('a') 
      x = int(coord[1:])-1 
      # update the board at this position 
      self.board = board[x][y] 
     print(" " + " ".join([chr(c) for c in range(ord('A'), ord('A') + BOARD_SIZE)])) 
     row_num = 1 
     for row in board: 
      print(str(row_num).rjust(2) + " " + (" ".join(row))) 
      row_num += 1 
     self.board.append(Ship(coords,player,name,size,direction)) 

    def print_board_heading(self): 
     print(" " + " ".join([chr(c) for c in range(ord('A'), ord('A') + BOARD_SIZE)])) 

    def print_board(self): 
     board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)] 
     print_board_heading() 
     row_num = 1 
     for row in board: 
      print(str(row_num).rjust(2) + " " + (" ".join(row))) 
      row_num += 1 

    def print_updated_board(coords, direction, board, player): 
     for coord in coords: 
      # convert string like "a1" to x,y coordinates 
      y = ord(coord[0])-ord('a') 
      x = int(coord[1:])-1 
      # update the board at this position 
      board[x][y] = '|' if direction == 'v' else '-' 
     print(" " + " ".join([chr(c) for c in range(ord('A'), ord('A') + BOARD_SIZE)])) 
     row_num = 1 
     for row in board: 
      print(str(row_num).rjust(2) + " " + (" ".join(row))) 
      row_num += 1 


class Player(): 
    def __init__(self,name): 
     self.name = name 
     self.board = Board() 
     self.ships = [] 
     self.guesses = [] 

而戰艦遊戲文件:

from ship import Ship, Player, Board 

SHIP_INFO = [ 
    ("Aircraft Carrier", 5), 
    ("Battleship", 4), 
    ("Submarine", 3), 
    ("Cruiser", 3), 
    ("Patrol Boat", 2) 
] 

BOARD_SIZE = 10 

VERTICAL_SHIP = '|' 
HORIZONTAL_SHIP = '-' 
EMPTY = 'O' 
MISS = '.' 
HIT = '*' 
SUNK = '#' 

board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)] 

def print_board_heading(): 
    print(" " + " ".join([chr(c) for c in range(ord('A'), ord('A') + BOARD_SIZE)])) 


def print_board(): 
    board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)] 
    print_board_heading() 
    row_num = 1 
    for row in board: 
     print(str(row_num).rjust(2) + " " + (" ".join(row))) 
     row_num += 1 

def print_updated_board(coords, direction,board): 
    # create an empty board 
    # board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)] 
    # at each coordinate, draw a ship 

    for coord in coords: 
     # convert string like "a1" to x,y coordinates 
     y = ord(coord[0])-ord('a') 
     x = int(coord[1:])-1 
     # update the board at this position 
     board[x][y] = '|' if direction == 'v' else '-' 
    print_board_heading() 
    row_num = 1 
    for row in board: 
     print(str(row_num).rjust(2) + " " + (" ".join(row))) 
     row_num += 1 


def clear_screen(): 
    print("\033c", end="") 


def get_coordinates(ship): 
    while True: 
     print("\n") 
     coordinate = input("Where do you want the " + ship + "(example: A1)?: ") 
     coords_strip = coordinate.strip() 
     coords_lower = coords_strip.lower() 
     x = coords_lower[0] 
     y = coords_lower[1:] 

     if (len(x)+len(y)) in range(2,4): 
      if x not in 'abcdefghij' or y not in '1,2,3,4,5,6,7,8,9,10': 
       print("Oops! That was not a valid entry. Try again...") 
       continue 

      else: 
       return x, y 

     else: 
      if len(coords_lower) < 2 or len(coords_lower) > 3: 
       print("Oops! That's too not the right amount of characters. Please try again...") 
       continue 


def get_direction(): 
    while True: 
     dir = input("[H]orizontal or [V]ertical?: ") 
     dir_strip = dir.strip() 
     direction = dir_strip.lower() 

     if direction not in 'hv': 
      print("Oops! That was not a valid entry. Try again...") 
      continue 

     else: 
      return direction 


def create_ship_coordinates(x, y, size, direction): 
    ship_col = ord(x) 
    ship_row = int(y) 
    if direction == 'v': 
     # ship runs vertically DOWN from coordinate 
     coords = [chr(ship_col) + str(r) for r in range(ship_row, ship_row + size)] 
     return coords 
    else: 
     # ship runs horizontally RIGHT from coordinate 
     coords = [chr(col) + str(ship_row) for col in range(ship_col, ship_col + size)] 
     return coords 


def place_user_ships(player): 
    ships = [] 
    print_board() 
    print("\n") 
    print("Let's go " + player + " !") 
    for ship, size in SHIP_INFO: 

     while True: 
      # ask for starting coordinate 
      x, y = get_coordinates(ship) 
      # ask for vertical or horizontal direction 
      direction = get_direction() 
      # create the coordinates for the ship placement 
      coords = create_ship_coordinates(x, y, size, direction) 
      # validate the 
      # new_ship = Board().add_ship(ship, size, coords, direction, player) 
      # update = Board.print_updated_board(coords,direction,board,player) 
      break 
     # create ship from data 
     # add the ship from above to a player list 
     # player = Player(board) 
     # place the ship on the game board 
     # print out the board to reflect the shp placement 
    clear_screen() 
    print("\n") 
    input("All ships placed for {}. Please hit ENTER to continue....".format(player)) 

player1 = input("What's Player 1's Name? ") 
player2 = input("What's Player 2's Name? ") 

# define player one's fleet 
place_user_ships(player1) 
place_user_ships(player2) 
+0

夠公平的是我有辦法讓它移動到那裏嗎? –

+0

再次查看您的問題後,我實際上並不認爲它是針對SO或代碼審覈的完整主題。對於SO,你應該只問**一個與特定編程問題有關的問題。你的要點中的問題要麼過於寬泛,要麼主要是基於意見的。對於代碼審查,您只應要求提供有關*完全工作計劃的反饋*,並避免有關最佳實踐的一般性問題。 – ekhumoro

+1

更改後的問題希望更易於理解。 –

回答

1

IIRC,在戰艦真的有四塊主板。一名球員由對方投籃,另一名球員爲自己的船隊和敵方投籃。

「拍攝」過程是通知敵人拍攝照片,敵人以「擊中」或「未命中」作爲迴應,並將結果記錄在本地玩家的出局板上。

「通知」的過程是接收其中一個敵人的射門被做了一個位置,查找在本地船隻板的結果之一,返回「打」或「小姐」,並更新本地船板來指示敵人射擊。

所以你有一個玩家,有一對棋盤。你也可能有一個遊戲課來和這兩個玩家結婚。

輸入船舶將取決於您的實際用戶界面。你用鼠標做圖形嗎?你在用鼠標做文本嗎?帶有箭頭鍵的文字通過curses還是其他一些?簡單的座標輸入?

如果你正在做座標,你可能想要一些簡單的東西,比如x,y,{上,下,左,右}以消除必須定位船的每個方塊。

再次,這裏有一個委員會的方法 - 放置一艘船。董事會可以強制執行任何有關放置的規則(例如:兩艘船可以直接相鄰嗎?還是必須在兩者之間存在一個空隙?),並拒絕不適當的嘗試。

如果你把所有的智慧都放在你的Board類中,那麼Player類可以很簡單,只需鏈接到板子。而本場比賽又可以管理球員:

def play(self): 
    p1 = self.player[0] 
    p2 = self.player[1] 

    try: 
     while True: 
      self.attack(p1, p2) 
      self.attack(p2, p1) 

    except Victory v: 
     print("The winner is", v.player.name) 

我注意到你做這樣的事情player1 = input("What is player 1's name?")。這是應該推入玩家類的東西。

嘗試從上往下設計:遊戲,玩家,董事會。並嘗試遵守規則,「告訴,不要問。」也就是說,如果需要完成的事情,你需要告訴一個類去做,而不是要求這個類的數據並自己做。

取而代之的是:

move = player1.get_move() 
if valid_move(move): 
    ... 

這樣做:

player1.make_move() 

,向下推的邏輯。最終,你會到達知識「應該」的地方。玩家「應該」做出動作。董事會「應該」知道什麼是有效的舉動。而且每種方法都應該有足夠的數據來完成它的工作。 ;-)

+0

謝謝奧斯汀 - 這裏有一些很好的建議,謝謝花時間向我解釋。 –