2017-03-07 67 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

谢谢奥斯汀 - 这里有一些很好的建议,谢谢花时间向我解释。 –