使用类方法在Python游戏中存储用户值

时间:2017-03-07 02:15:57

标签: python

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)

1 个答案:

答案 0 :(得分:1)

IIRC,在战舰上有四个板。一个是由每个玩家管理,他们向敌人射击,另一个是玩家自己的船只以及来自敌人的射击。

&#34;拍摄&#34;进程是通知敌人射击的地方之一,敌人用&#34;命中&#34;或&#34; miss&#34;,并将结果记录在本地玩家的出局板上。

&#34;通知&#34;进程是接收敌人射击的位置,在本地船上查找结果,返回&#34;命中&#34;或者&#34;想念&#34;,并更新当地的船只板以表明敌人射击。

所以你有一个玩家,有一对董事会。你可能还有一个Game类来嫁给这两个玩家。

输入船只将在很大程度上取决于您的实际用户界面。你用鼠标做图形吗?你用鼠标做文字吗?带有箭头键的文字curses或其他一些?简单的坐标输入?

如果你正在做坐标,你可能想要一些简单的东西,比如x,y,{up,down,left,right},以消除必须定位船的每个块。

同样,这里有一个Board方法 - 放置一艘船。董事会可以执行有关放置的任何规则(例如:两艘船可以直接相邻吗?或者两者之间是否必须存在一个空格?)并拒绝不适当的尝试。

如果你把所有的智慧放在你的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?")之类的事情。这应该被推入玩家类。

尝试从上到下设计:游戏,玩家,棋盘。并尝试遵守规则,&#34;告诉,不要问。&#34;也就是说,如果需要做某些事情,你告诉一个类去做,而不是要求类的数据并自己做。

而不是:

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

这样做:

player1.make_move()

向下推动逻辑。最终,你到了知识所在的地方&#34;。玩家&#34;应该&#34;做出动作。董事会&#34;应该&#34;知道什么是有效的举动。并且每种方法都应该&#34;获得足够的数据来完成它的工作。 ; - )