6

我最近开始学习 python 并决定尝试制作我的第一个项目。我正在尝试制作一个战舰游戏,将两艘 3 格长的船随机放置在板上。但它并不完全正确。我为 2 号船做了一个 while 循环,它应该检查它旁边的两个空间是否空闲,然后在那里构建自己。但有时它只是把自己拍在 1 号船已经在的地方。有人可以帮我吗?

这是代码的第一部分:

from random import randint

###board:

board = []

for x in range(7):
    board.append(["O"] * 7)

def print_board(board):
    for row in board:
        print " ".join(row)

###ships' positions:
#ship 1
def random_row(board):
    return randint(0, len(board) - 1)
def random_col(board):
    return randint(0, len(board[0]) - 1)
row_1 = random_row(board)
col_1 = random_col(board)

#ship 2
row_2 = random_row(board)
col_2 = random_col(board)
def make_it_different(r,c):
    while r == row_1 and c == col_1:
        r = random_row(board)
        c = random_col(board)
        row_2 = r
        col_2 = c
make_it_different(row_2,col_2)


### Makes the next two blocks of the ships:
def random_dir():
    n = randint(1,4)
    if n == 1:
        return "up"
    elif n == 2:
        return "right"
    elif n == 3:
        return "down"
    elif n == 4:
        return "left"
#ship one:
while True:
    d = random_dir() #reset direction
    if d == "up":
        if row_1 >= 2:
            #building...
            row_1_2 = row_1 - 1
            col_1_2 = col_1
            row_1_3 = row_1 - 2
            col_1_3 = col_1
            break
    if d == "right":
        if col_1 <= len(board[0])-3:
            #building...
            row_1_2 = row_1
            col_1_2 = col_1 + 1
            row_1_3 = row_1
            col_1_3 = col_1 + 2
            break
    if d == "down":
        if row_1 <= len(board)-3:
            #building...
            row_1_2 = row_1 + 1
            col_1_2 = col_1
            row_1_3 = row_1 + 2
            col_1_3 = col_1
            break
    if d == "left":
        if col_1 >= 2:
            #building...
            row_1_2 = row_1
            col_1_2 = col_1 - 1
            row_1_3 = row_1
            col_1_3 = col_1 - 2
            break
ship_1 = [(row_1,col_1),(row_1_2,col_1_2),(row_1_3,col_1_3)]

这是船 2 部分的位置:

#ship two:
while True:
    d = random_dir() #reset direction
    if d == "up":
        if row_2 >= 2:
            if (row_2 - 1,col_2) not in ship_1 and (row_2 - 2,col_2) not in ship_1:
                #building...
                row_2_2 = row_2 - 1
                col_2_2 = col_2
                row_2_3 = row_2 - 2
                col_2_3 = col_2
                break
    if d == "right":
        if col_2 <= len(board[0])-3:
             if (row_2 ,col_2 + 1) not in ship_1 and (row_2,col_2 + 2) not in ship_1:
                #building...
                row_2_2 = row_2
                col_2_2 = col_2 + 1
                row_2_3 = row_2
                col_2_3 = col_2 + 2
                break
    if d == "down":
        if row_2 <= len(board)-3:
            if (row_2 + 1 ,col_2) not in ship_1 and (row_2 + 2,col_2) not in ship_1:
                #building...
                row_2_2 = row_2 + 1
                col_2_2 = col_2
                row_2_3 = row_2 + 2
                col_2_3 = col_2
                break
    if d == "left":
        if col_2 >= 2:
            if (row_2 ,col_2 - 1) not in ship_1 and (row_2,col_2 - 2) not in ship_1:
                #building...
                row_2_2 = row_2
                col_2_2 = col_2 - 1
                row_2_3 = row_2
                col_2_3 = col_2 - 2
                break

###test
board[row_1][col_1] = "X"
board[row_1_2][col_1_2] = "X"
board[row_1_3][col_1_3] = "X"
board[row_2][col_2] = "Y"
board[row_2_2][col_2_2] = "Y"
board[row_2_3][col_2_3] = "Y"
#Ship1 = X's and Ship2 = Y's
print_board(board)
4

3 回答 3

4

我建议让您的放置代码简单地运行并且没有 if 语句,它会更干净。然后,最后,您可以检查是否有任何部分重叠,以及它们是否会重置。

取决于您最终决定存储各个船只所在的点的方式,可能是元组列表。你可以这样做

place ship 方法可以返回元组(点)列表

def placeShip():
    points = []

    # put random point generation here

    for point in points:
        if point in otherShipPoints:
            return placeShip()         # overlap detected, redo ship placement

    return points

将您的放置代码放在一个函数中,以便可以以这种方式简单地调用它。您的代码开始变得混乱,我建议采用这样的方法来避免遇到意大利面条代码问题。

您还可以为placeShip()要添加的船舶大小提供一个参数,然后此方法可能是您的一体化船舶放置器。只要让你的函数看起来像这样placeShip(size),然后在你的网格中随机生成那么多点

于 2013-07-30T17:02:33.353 回答
2

分配给row_2col_2inmake_it_different不会通过这些名称分配给全局变量。Python 确定函数的局部变量的规则是,函数分配给没有global声明的任何东西都是局部的;分配row_2col_2创建新的局部变量而不是更改全局变量。您可以通过声明row_and来解决此问题col_2 global,但最好将新值传递给调用者并让调用者分配它们。

(为什么要取and的make_it_different初始值?为什么不让它生成坐标,直到找到一些可行的方法?)row_2col_2

于 2013-07-30T16:56:52.347 回答
2

您为此编写了很多代码,也许另一种方法会更好。尝试编写一个类似的函数

def ship_points(rowcol = (3,3), shiplength = 4, direction = (1,0), boardsize=(7,7)):
    points = []
    for i in xrange(shiplength):
        points.append((rowcol[0]+i*direction[0], rowcol[1]+i*direction[1]))
        if points[i][0] >= boardsize[0] or points[i][1] >= boardsize[1]:
            return None
    return points

现在您可以为每艘船生成分数并直接检查相同的分数。更少的代码,更可重用。

于 2013-07-30T17:01:49.150 回答