2013-07-30 94 views
5

我最近開始學習python,並決定嘗試做我的第一個項目。我正在嘗試製作一個戰艦遊戲,隨機在棋盤上放置兩塊3塊長的船。但它並不正確。我爲船2做了一段時間循環,應該檢查它旁邊的兩個空格是否空閒,然後在那裏建立它自己。但有時它只是在#1號船的頂端放上了自己的力量。有人可以幫我嗎?簡單的Python戰艦遊戲

下面的代碼的第一部分:

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

http://www.SSCCE.org – Stephan

+1

它看起來不像make_it_different在做任何事情。在函數結尾處拋出一個返回值,然後嘗試使用'row_2,col_2 = make_it_different(row_2,col_2)'。當你在一個函數中設置一個變量時,你並沒有在全局範圍內設置它(除非你想在函數中使用全局的row_2和col_2變量,我不建議這樣做) – scohe001

+0

我建議選擇方向該船在其位置之前。 –

回答

4

我建議您允許您的代碼在沒有if語句的情況下運行,它會更乾淨。然後,最後,您可以檢查是否有任何部分重疊,以及是否重置。

根據你最終決定存儲單個船隻的位置,可能是一個元組列表。你可以這樣做

的地方船方法可以返回的元組(點)名單

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),然後在你的網格內隨機生成許多點

+0

如果placeShip()在剛剛完成循環時產生了錯誤的位置,會發生什麼情況? – scohe001

+0

@Josh它不應該 – Stephan

+1

對不起,它看起來並不像你的編輯前會遞歸。這看起來更好,+1 – scohe001

1

分配到row_2col_2make_it_different不分配通過這些名字到全局變量。 Python用於確定函數局部變量的規則是函數在沒有聲明global的情況下分配的任何東西都是本地的;分配給row_2col_2將創建新的局部變量,而不是更改全局變量。你可以通過聲明row_col_2global來解決這個問題,但它可能會更好地將新值傳遞給調用者並讓調用者分配它們。

(爲什麼make_it_different採取row_2col_2在所有的初始值?爲什麼不只是有它產生的座標,如果發現直到一些工作?)

+0

你在最後一部分失去了我。你是什​​麼意思讓它產生座標,是不是它所做的?如果沒有這兩個值,我會怎麼做?你能舉個例子嗎? – Nathan

+0

@ user2631796:如果它們不工作,它實際上並不需要採取初始值並使它們不同;它只能生成值,直到它獲得可用的值。 – user2357112

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 

現在您可以爲每艘船隻生成點並直接檢查相同的點。代碼少得多,方式更可重用。