我最近开始学习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)
答案 0 :(得分: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)
,然后在网格中随机生成那么多点
答案 1 :(得分: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
现在您可以为每艘船生成积分并直接检查相同的点。更少的代码,更可重用的方式。
答案 2 :(得分:1)
分配给row_2
中的col_2
和make_it_different
不会通过这些名称分配给全局变量。用于确定函数局部变量的Python规则是函数在没有global
声明的情况下分配的任何内容都是本地的;分配给row_2
和col_2
会创建新的局部变量,而不是更改全局变量。您可以通过声明row_
和col_2
global
来解决此问题,但最好将新值传递给调用者并让调用者分配它们。
(为什么make_it_different
取row_2
和col_2
的初始值?为什么不让它生成坐标,直到找到一些有用的?)