簡體   English   中英

如何修復我的 Python 3.6 戰艦代碼?

[英]How to fix my Python 3.6 battleship code?

基本上,當我單擊鼠標左鍵並且單元格的坐標匹配時,我想將參數 self.shot 永遠更改為 True(它檢查一個單元格之前是否被拍攝過,如果一個單元格被拍攝過,它會繪制一個點或一個尖角)。 問題是該參數僅在按下鼠標按鈕時更改,並在按鈕向上時更改回其標准值。 在這一點上,我真的不知道如何重建這段代碼才能正常工作。

這是代碼:

import pygame, random, time, math

pygame.init()

clock = pygame.time.Clock()

yours = 0
enemys = 1
exitPossible = False
gameStart = False
tour = random.randint(yours,enemys)

white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)

one = 32
two = 63
three = 94
four = 125
five = 156
six = 187
seven = 218
eight = 249
nine = 280
ten = 301

a = 32
b = 63
c = 94
d = 125
e = 156
f = 187
g = 218
h = 249
i = 280
j = 311

#lista

m = 0
n = 0
o = 0
p = 0
playerWins = 10
botWins = 0


window = pygame.display.set_mode((760, 410))
pygame.display.set_caption("Battleship")
font = pygame.font.SysFont("Arial", 30)

class crate:

    def __init__(self, sizex, sizey, shot, shiphere):

        self.sizex, self.sizey = sizex, sizey
        self.shot = shot
        self.shiphere = shiphere




    def crateShot(self):

        if not exitPossible:
            if not self.shot:
                if event.type == pygame.MOUSEBUTTONDOWN and self.sizex + 30 > mx > self.sizex and self.sizey + 30 > my > self.sizey:
                    self.shot = True


            if self.shot:
                if self.shiphere:
                    pygame.draw.line(window, white, (self.sizex, self.sizey), (self.sizex + 30, self.sizey + 30), 3)
                    pygame.draw.line(window, white, (self.sizex + 29, self.sizey), (self.sizex, self.sizey + 29), 3)
                else:
                    pygame.draw.circle(window, white, (self.sizex + 15, self.sizey + 15), 6, 5)




allCrates = ()

def crates(allCrates):
    a1 = crate(a, a, True, False)
    a1.crateShot()


    a2 = crate(b, a, True, True)
    a2.crateShot()


    a3 = crate(c, a, False, False)
    a3.crateShot()


    a4 = crate(d, a, False, True)
    a4.crateShot()



#slownik how to
ololollololol = {
    "" : 123
}

class ship:
    def __init__(self, size, amount):
        self.size = size
        self.amount = amount

    #def drawShip(self):


def ships():
    carrier = ship(4, 1)
    battleship = ship(3, 2)
    cruiser = ship(2, 3)
    destroyer = ship(1, 4)


def playerWindow(m, n):
    if not exitPossible:
        window.fill(black)
        for i in range(11):
            pygame.draw.line(window, white, (31 + m, 0), (31 + m, 341))
            m += 31
        for i in range(11):
            pygame.draw.line(window, white, (0, 31 + n), (341, 31 + n))
            n += 31


        a = font.render("A", True, white)
        window.blit(a, (4, 30))

        b = font.render("B", True, white)
        window.blit(b, (5, 61))

        c = font.render("C", True, white)
        window.blit(c, (4, 92))

        d = font.render("D", True, white)
        window.blit(d, (4, 123))

        e = font.render("E", True, white)
        window.blit(e, (5, 154))

        f = font.render("F", True, white)
        window.blit(f, (6, 185))

        g = font.render("G", False, white)
        window.blit(g, (3, 216))

        h = font.render("H", True, white)
        window.blit(h, (4, 247))

        i = font.render("I", True, white)
        window.blit(i, (12, 278))

        j = font.render("J", True, white)
        window.blit(j, (7, 309))

        a = font.render("1", True, white)
        window.blit(a, (39, -2))

        b = font.render("2", True, white)
        window.blit(b, (70, -2))

        c = font.render("3", True, white)
        window.blit(c, (101, -2))

        d = font.render("4", True, white)
        window.blit(d, (132, -2))

        e = font.render("5", True, white)
        window.blit(e, (163, -2))

        f = font.render("6", True, white)
        window.blit(f, (194, -2))

        g = font.render("7", True, white)
        window.blit(g, (225, -2))

        h = font.render("8", True, white)
        window.blit(h, (256, -2))

        i = font.render("9", True, white)
        window.blit(i, (287, -2))

        j = font.render("10", True, white)
        window.blit(j, (308, -2))


def botWindow(o, p):
    if not exitPossible:
        for i in range(11):
            pygame.draw.line(window, white, (419 + o, 0), (419 + o, 341))
            o += 31
        for i in range(11):
            pygame.draw.line(window, white, (419, 31 + p), (760, 31 + p))
            p += 31


        a = font.render("A", True, white)
        window.blit(a, (425, 30))

        b = font.render("B", True, white)
        window.blit(b, (425, 61))

        c = font.render("C", True, white)
        window.blit(c, (424, 92))

        d = font.render("D", True, white)
        window.blit(d, (424, 123))

        e = font.render("E", True, white)
        window.blit(e, (425, 154))

        f = font.render("F", True, white)
        window.blit(f, (426, 185))

        g = font.render("G", True, white)
        window.blit(g, (423, 216))

        h = font.render("H", True, white)
        window.blit(h, (424, 247))

        i = font.render("I", True, white)
        window.blit(i, (432, 278))

        j = font.render("J", True, white)
        window.blit(j, (427, 309))

        a = font.render("1", True, white)
        window.blit(a, (458, -2))

        b = font.render("2", True, white)
        window.blit(b, (489, -2))

        c = font.render("3", True, white)
        window.blit(c, (520, -2))

        d = font.render("4", True, white)
        window.blit(d, (551, -2))

        e = font.render("5", True, white)
        window.blit(e, (582, -2))

        f = font.render("6", True, white)
        window.blit(f, (613, -2))

        g = font.render("7", True, white)
        window.blit(g, (644, -2))

        h = font.render("8", True, white)
        window.blit(h, (675, -2))

        i = font.render("9", True, white)
        window.blit(i, (706, -2))

        j = font.render("10", True, white)
        window.blit(j, (727, -2))


def gameWindow(playerWins, botWins):
    if not exitPossible:
        score = font.render("SCORE:", True, white)
        window.blit(score, (325, 345))
        wins = font.render(str(playerWins) + " - " + str(botWins), True, white)
        window.blit(wins, (325, 375))
        auto = font.render("AUTO", True, white)
        window.blit(auto, (13, 359))
        pygame.draw.rect(window, white, (10, 361, 89, 30), 1)


while True:
    mx, my = pygame.mouse.get_pos()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()



        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            exitPossible = True

    if exitPossible:
        window.fill(black)
        uSure = font.render("ARE YOU SURE YOU WANT TO EXIT?", True, white)
        window.blit(uSure, (115, 145))
        YES = font.render("YES", True, white)
        window.blit(YES, (335, 195))
        NO = font.render("NO", True, white)
        window.blit(NO, (342, 230))

        if event.type == pygame.MOUSEBUTTONDOWN:
            if 390 >= mx >= 335 and 223 >= my >= 200:
                quit()
            elif 387 >= mx >= 342 and 256 >= my >= 235:
                exitPossible = False
                window.fill(black)


    playerWindow(m, n)
    botWindow(o, p)
    gameWindow(playerWins, botWins)
    crates(allCrates)
    pygame.display.flip()
    clock.tick(60)

目前代碼需要一個新特性:

檢測鼠標點擊,確定它發生在哪個單元格“板條箱”(如果有)

然而,所有現有代碼都使用一種“蠻力”方法,使用大量單個變量作為位置。 這使得如果不做 100 次就很難檢查所有位置,每個箱子一次。

我認為,如果稍微更改一下以使用玩家網格的矩形列表,代碼的向前推進會更容易。 請考慮代碼:

# Create the click-grid for the player
GRID_SIZE   = 31
player_grid = []
for y_cell in [ a,b,c,d,e,f,g,h,i,j ]:
    for x_cell in [ one, two, three, four, five, six, seven, eight, nine, ten ]:
        player_grid.append( [ x_cell, y_cell, GRID_SIZE, GRID_SIZE ] )

這個操作之后我們得到的是一個python 列表列表,所以player_grid[0][ one, a, 31, 31 ] ,然后是[ two, a, 31, 31 ]等。 player_grid列表中的所有元素只是 position 和大小的記錄,並不復雜。 go 的所有這些麻煩制作列表的原因是因為它允許代碼簡單地循環檢查它們內部的所有矩形。

在示例中,我使用了代碼現有abc , ...變量,因為它們已經在問題的代碼中定義。 但這很容易是range( 0, 10 )和一些窗口大小的因素。

所以現在在player_grid我們有 100 個矩形。 如果我們可以用同樣的方式制作一個crate object,讓這個crate “知道”它的 position,那會更好。 這允許板條箱 object(給定 x,y)告訴我們它是否被點擊。 因此,讓我們對crate做一些小的修改 - 將__init__()更改為采用xy ,並將PyGame Rect作為成員變量存儲:

class crate:
    def __init__(self, x, y, sizex, sizey, shot, shiphere):
        self.x        = x
        self.y        = y
        self.sizex    = sizex
        self.sizey    = sizey
        self.rect     = pygame.Rect( x, y, sizex, sizey )
        self.shot     = shot
        self.shiphere = shiphere

現在,在類似於之前的循環中創建一個crate列表:

# Create the click-grid for the player
GRID_SIZE   = 31
all_crates  = []
for y_cell in [ a,b,c,d,e,f,g,h,i,j ]:
    for x_cell in [ one, two, three, four, five, six, seven, eight, nine, ten ]:
        all_crates.append( crate( x_cell, y_cell, GRID_SIZE, GRID_SIZE, False, False ) )

在這個操作之后,我們得到的是一個pythoncrate對象列表,每個對象都包含一個PyGame Rect 這種意義上的 Rect 只是一個 position 和大小,它並不太復雜。 但它確實允許一些更容易的檢查,因為在 PyGame Rect 中有一堆方便的碰撞函數

回到問題——用戶點擊了屏幕,我們需要看看它是否在 100 個crate之一中。 現在每個板條箱都知道它是矩形 position,很容易遍歷它們,依次檢查:

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        elif event.type == pygame.MOUSEBUTTONUP:  # User released mouse button
            mx, my = pygame.mouse.get_pos()       # Position of the click

            # Loop through all crate objects, seeing if any where clicked
            for c in all_crates:
                if c.rect.collidepoint( mx, my ) == True:
                    # User clicked inside a crate
                    c.crateShot( mx, my )         # Test for hit
                    break                         # No further checks needed

就個人而言,我會在crate中創建一個成員 function ,並使用它而不是直接從 object 外部引用crate.rect

def wasClicked( self, mouse_x, mouse_y ):
    return self.rect.collidepoint( mouse_x, mouse_y )

雖然在這種情況下微不足道,但它允許將任何未來的額外處理和檢查添加到crate object 中,而不是“污染”主循環的簡單性。

注意:我嘗試盡可能少地更改代碼,同時保留樣式和現有代碼。 但是我認為重寫屏幕網格邏輯以使用 window 大小的因子並動態構建網格而不是手動調整坐標列表是一個很好的學習練習。 盡管最初需要更多的努力,但像繪制網格字母標題列表這樣的事情可能會變成一個簡單的 5 行循環。

例如,類似:

WINDOW_WIDTH  = 1000
WINDOW_HEIGHT = 500
CELL_COUNT    = 10
GRID_SIZE     = WINDOW_HEIGHT // (CELL_COUNT * 0.7)  # cells cover 70% of the window-height
GRID_OFFSET   = GRID_SIZE * 2                        # Leave room for headings, etc.

# Define the player grid
player_grid = []
for y in range( 0, CELL_COUNT ):
    for x in range( 0, CELL_COUNT ):
        pos_x = x + GRID_OFFSET  # move the grid away from the edge
        pos_y = y + GRID_OFFSET 
        player_grid.append( pygame.Rect( pos_x, pos_y, GRID_SIZE, GRID_SIZE ) )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM