国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

手把手教你使用Python實(shí)現(xiàn)推箱子小游戲(附完整源碼)

這篇具有很好參考價(jià)值的文章主要介紹了手把手教你使用Python實(shí)現(xiàn)推箱子小游戲(附完整源碼)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

項(xiàng)目介紹

我們這個(gè)項(xiàng)目是一個(gè)基于Python實(shí)現(xiàn)的推箱子小游戲,名叫Sokoban:
python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言

這個(gè)游戲的目的是讓玩家,也就是大寫的P,推著箱子#,填充用小寫的o標(biāo)記的地面上的洞

項(xiàng)目規(guī)則

該版本的Sokoban的規(guī)則如下:

  • 游戲在矩形的二維網(wǎng)格上舉行,其原點(diǎn)(0,0)位于左上方
  • 網(wǎng)格上的每個(gè)單元格可以隨時(shí)包含以下內(nèi)容之一:
    • 由大寫字母P表示的玩家
    • 由空格字符' '表示的地磚
    • 由哈希字符#表示的箱子
    • 由星號(hào)字符*表示的墻
    • 由小寫字符o表示的洞
  • 每個(gè)回合,玩家角色可以在網(wǎng)格上向上、向下、向左或向右移動(dòng)一個(gè)單位
  • 玩家角色不能移動(dòng)到墻或洞中
  • 每一回合,玩家角色都可以將箱子向他們?cè)噲D移動(dòng)的方向推一個(gè)單位,前提是玩家試圖移動(dòng)方向的箱子的下一個(gè)單元格是地磚或者是洞。如果不滿足此條件,玩家和箱子都不會(huì)移動(dòng)
  • 如果玩家將箱子推入到洞中,洞和箱子都會(huì)消失,并留下一塊板磚。
  • 如果玩家試圖離開屏幕邊緣或?qū)⑾渥油齐x屏幕邊緣,如果其他規(guī)則允許,玩家或箱子應(yīng)該出現(xiàn)在屏幕的對(duì)側(cè),就像屏幕的兩側(cè)是連接的一樣

項(xiàng)目接口文檔

在這個(gè)項(xiàng)目中你需要去實(shí)現(xiàn)含有以下方法的Sokoban類;

  • __init__(self,board):使用給定的board創(chuàng)建Sokoban實(shí)例,參數(shù)board是一個(gè)二維嵌套列表,也就是我們的游戲地圖
  • find_player(self):返回玩家角色在棋盤上的位置。行和列從0開始,原點(diǎn)(0,0)位于網(wǎng)格的左上角,例如在我們項(xiàng)目介紹中玩家的位置為 (0,0)
  • is_complete(self):判斷游戲是否結(jié)束。如果地圖中沒有洞,則返回真,代表游戲結(jié)束,否則返回假
  • steps(self):返回玩家角色的移動(dòng)次數(shù)(也就是玩家的位置發(fā)生變化的時(shí)候)
  • restart(self):將Sokoban實(shí)例進(jìn)行重置,重置為玩家開始游戲之前的狀態(tài)
  • undo(self):撤銷玩家的上一次移動(dòng),使游戲狀態(tài)恢復(fù)到上一次移動(dòng)的時(shí)候,可以重復(fù)調(diào)用以撤銷多次移動(dòng)。如果撤銷被調(diào)用的次數(shù)超過玩家的移動(dòng)次數(shù),則棋盤應(yīng)保持其初始狀態(tài)
  • move(self,direction):試圖將玩家移動(dòng)一個(gè)位置并且推動(dòng)玩家面前的箱子。方向參數(shù)是一個(gè)字符串,其值為w,a,s,d,分別表示向上,向左,向下和向右。只有當(dāng)玩家的位置發(fā)生更新的時(shí)候,才會(huì)計(jì)算移動(dòng)次數(shù)。如果玩家的位置沒有發(fā)生改變,則游戲的狀態(tài)不應(yīng)以任何方式改變
  • __str__(self):返回地圖的字符串表示形式。記住每行中的單元格要用空格分隔

項(xiàng)目實(shí)現(xiàn)過程

前置方法編寫

我們就按文檔中的接口一個(gè)個(gè)實(shí)現(xiàn)。先來看init方法,這個(gè)方法里面我們現(xiàn)在能想到的只有兩件事:

  • 地圖初始化
  • step游戲步數(shù)的初始化
    def __init__(self,board):
        self.board = board
        self.step = 0

然后我們來實(shí)現(xiàn)str方法,在這里使用到的就是二維列表的遍歷,我們只需要要建立一個(gè)空字符串然后把列表中的元素往里面塞就行了:

    def __str__(self):
        show = ''
        num = 0
        for i in self.board:
            num += 1
            for j in i:
                show += j + ' '
            show += '\n'
        return show[:-2]

我們每遍歷完一行就使用\n來控制換行。我們最后對(duì)返回的字符串進(jìn)行了切片是因?yàn)椋何覀內(nèi)绻磺衅脑挘覀冊(cè)诖蛴∽詈笠恍械臅r(shí)候末尾也會(huì)有一個(gè)換行符,這個(gè)是沒有必要的!我們可以把它切去:
python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言
同樣使用了二維列表的遍歷的還有is_complete(self)方法,這個(gè)的思路也就是單純的遍歷地圖看是否還有洞口存在就行,實(shí)現(xiàn)較簡(jiǎn)單;

    def is_complete(self):
        for i in self.board:
            for j in i :
                if j == 'o':
                    return False
        return True

接下來我們來實(shí)現(xiàn)find_player(self)方法,其核心思想仍然是二維列表的遍歷,這里我提供兩種實(shí)現(xiàn)方法:

實(shí)現(xiàn)方法1:

    def find_player(self):
        x = -1;y = -1
        for j in self.board:
            x += 1
            for k in j:
                y += 1
                if k == 'P':
                    return (x,y)
            y = -1

實(shí)現(xiàn)方法2:

    def find_player(self):
        for x in range(self.board_x()):
            for y in range(self.board_x()):
                if self.board[x][y] == 'P':
                    return (x,y)

move核心方法編寫

我們?cè)谒伎糾ove方法的編寫的時(shí)候,乍一想會(huì)發(fā)現(xiàn)有很多需要注意點(diǎn),有非常非常多的限制、判斷,可能想著想著一下子就迷失了方向。其實(shí)我們可以思考一下,我們每執(zhí)行一次move指令其實(shí)就進(jìn)行了兩個(gè)步驟:

  • 判斷能否移動(dòng)
  • 如果可以移動(dòng),則變動(dòng)玩家(可能還有箱子)的位置

也就是說我們現(xiàn)在將一個(gè)指令進(jìn)行了分解,讓他稍微具體了一些。換句話說我們想要實(shí)現(xiàn)move這個(gè)方法,只需要我們完成這兩個(gè)功能就可以了,這里我想了一下如果我們將這兩個(gè)功能都堆疊在move方法中,會(huì)顯得代碼非常的亂,而且涉及if的層層嵌套,會(huì)讓思維容易混亂。所以這里我們可以把判斷能否移動(dòng)這個(gè)功能抽象出來,令作為一個(gè)方法,我們把它命名為check。將實(shí)際的移動(dòng)功能留在move方法中。

因?yàn)樯婕暗降乃膫€(gè)方向,其實(shí)我們知道一個(gè)方向怎么實(shí)現(xiàn)之后,其他的方向?qū)崿F(xiàn)也就是照葫蘆畫瓢,所以這里我只對(duì)check以及move方法中的w方向進(jìn)行講解,然后為了方便我們可以將地圖的長(zhǎng)度和寬度的獲取抽象成一個(gè)方法,方便后面的使用:

    def board_x(self):
        return len(self.board)

    def board_y(self):
        return len(self.board[0])

接下來我們開工!

check()

首先我們先拿到玩家的具體位置,直接調(diào)用find_player方法即可,其位置可以通過如下坐標(biāo)系來理解:
python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言

在w方向上來說,他的移動(dòng)有兩種情況:

  • 情況一:w方向上與它相鄰的位置有箱子(也就是說玩家要推著箱子走)
  • 情況二:只有玩家自己移動(dòng)

而情況一下面又有兩種情況:

  • 在w方向上,箱子的前面一個(gè)是墻

    • 這種情況下就不能移動(dòng)
      python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言
  • 箱子前面沒有墻

    • 這種情況下可以移動(dòng)
      python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言

這里有人會(huì)說應(yīng)該還有一種情況箱子前面是洞口。這說明還沒有完全弄清我們單獨(dú)抽象出這個(gè)check方法的目的,我們的check方法只做一件事,那就是箱子或者箱子和人能不能移動(dòng)。而箱子前面是洞口這種情況屬于可以移動(dòng)的情況,不需要單拿出來討論。至于箱子與洞口的相消與地磚的填充不是我們check方法的功能,我們應(yīng)該把他們放到move方法中去處理。
python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言

考慮完這些情況之后我們還不能開始寫代碼,因?yàn)橛幸稽c(diǎn)我們不能忽略,那就是項(xiàng)目規(guī)則中的最后一條:

  • 如果玩家試圖離開屏幕邊緣或?qū)⑾渥油齐x屏幕邊緣,如果其他規(guī)則允許,玩家或箱子應(yīng)該出現(xiàn)在屏幕的對(duì)側(cè),就像屏幕的兩側(cè)是連接的一樣

這個(gè)地方如果再去加加減減的,然后弄出一大堆情況非常麻煩且容易出現(xiàn)角標(biāo)越界等問題。我們其實(shí)可以想象一下,當(dāng)我們的玩家一直在w方向上前進(jìn)(假設(shè)整列沒有墻不會(huì)阻礙前進(jìn)),到達(dá)頂點(diǎn)之后,又從當(dāng)前列的下方出現(xiàn),這種情景有點(diǎn)類似于循環(huán)列表。我們可以借用取余的思想,這樣就不需要進(jìn)行繁雜的討論,也可以避免角標(biāo)越界等錯(cuò)誤。

接下來我們來寫代碼:

    def check(self,direction):
        # 此時(shí)玩家的位置
        x = self.find_player()[0]
        y = self.find_player()[1]
        if direction not in "wasd":
            return -1
        #每個(gè)方向上的處理
        # 先考慮在你的移動(dòng)方向上沒有箱子的情況
        # 再考慮在你的移動(dòng)方向上有箱子的情況
        # 返回正整數(shù)代表可以移動(dòng) 返回1說明有箱子   返回0說明沒箱子    返回負(fù)數(shù)代表不能移動(dòng)
        if direction == 'w':
            # 代表方向上沒有箱子
            if self.board[(x-1)%self.board_x()][y] != '#':
                if self.board[(x-1)%self.board_x()][y] not in '*o':
                    return 0
                else:
                    return -1
            # 代表方向上有箱子
            else:
                if self.board[(x-2)%self.board_x()][y] not in '*':
                    return 1
                else:
                    return -1

這里我們的返回值;

  • 正整數(shù)代表可以移動(dòng)
    • 0代表不需要推箱子,只有玩家移動(dòng)
    • 1代表需要推箱子,玩家和箱子均需要移動(dòng)
  • 負(fù)數(shù)代表不能移動(dòng)

其他方向同理

move

同樣還是先拿到玩家的坐標(biāo),然后調(diào)用check方法,如果check返回的是一個(gè)負(fù)數(shù)那么直接return不用處理。我們重點(diǎn)來討論如果返回的是正整數(shù)的時(shí)候的情況:

以w方向?yàn)槔M(jìn)行討論

  • 如果check返回的是0(也就是說只有玩家移動(dòng)):
    • 我們只需要將當(dāng)前玩家所處的方格以地磚替代,將前一個(gè)方格使用P替代
  • 如果check返回的是非零整數(shù)(也就是說玩家和箱子都要移動(dòng)),這里再分為兩種情況:
    • 箱子前面是洞
      • 箱子和洞口相消,玩家前移
    • 箱子前面是地磚
      • 箱子和玩家均前移一個(gè)單位

代碼如下:

    def move(self,direction):
        # 此時(shí)玩家的位置
        x = self.find_player()[0]
        y = self.find_player()[1]
        ans = self.check(direction)
        if direction == 'w':
            if ans < 0:
                return
            else:
                self.board[x][y] = ' '
                if ans == 0:
                    self.board[(x-1)%self.board_x()][y] = 'P'
                else:
                    if self.board[(x-2)%self.board_x()][y] == 'o':
                        self.board[(x-2)%self.board_x()][y] = ' '
                        self.board[(x-1)%self.board_x()][y] = 'P'
                    else:
                        self.board[(x-2)%self.board_x()][y] = '#'
                        self.board[(x-1)%self.board_x()][y] = 'P'

項(xiàng)目收尾

截至目前我們還有下面三個(gè)方法沒有實(shí)現(xiàn):

  • steps(self)
  • restart(self)
  • undo(self)

steps方法記錄玩家的移動(dòng)步數(shù),而在我們當(dāng)前項(xiàng)目中,所有的移動(dòng)操作都與move的方法有關(guān),我們可以直接在move方法中對(duì)step進(jìn)行計(jì)數(shù):
python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言

    def steps(self):
        return self.step

注意只有當(dāng)我們的check方法返回非負(fù)數(shù)的時(shí)候我們才會(huì)去計(jì)數(shù)。

接下來我們看看restart(self)和undo(self)方法,這兩個(gè)方法一個(gè)用來重新開始,一個(gè)用來回退。他們都有一個(gè)特點(diǎn)那就是狀態(tài)的回溯。那么我們就可以把他們用同一種思想處理,因?yàn)樗麄兊膮^(qū)別無非就是一個(gè)回溯到開頭狀態(tài),一個(gè)回溯到上一步的狀態(tài)。

具體的做法就是:只要玩家的位置(狀態(tài)) 發(fā)生了變化,我們就將變化前的地圖狀態(tài)進(jìn)行儲(chǔ)存。在代碼層面上來講就是將變化前的board存儲(chǔ)到一個(gè)專門的列表中,這里我們就把這個(gè)列表命名為history:
python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言
python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言
這里要非常注意,像下面這樣存入列表是不行:

self.history.append(self.board)

你最后會(huì)發(fā)現(xiàn)存入history中的所有元素都一樣并且與當(dāng)前的board是一致的。這是因?yàn)榱斜碓赑ython中是可變數(shù)據(jù)類型,即使發(fā)生變化其地址值不會(huì)發(fā)生改變。使用上面的方法我們存入history的一個(gè)個(gè)元素都有著同樣的地址值,也就是說它們是同一個(gè)對(duì)象。所以這里為了避免這種問題,我們應(yīng)該使用深拷貝,而普通的深拷貝對(duì)我們的多維嵌套列表是沒有用的。

這里我嘗試了網(wǎng)上最常見的幾種辦法都沒有用:

  • 列表的copy方法
  • list()方法
  • [:]切片方法

我們可以使用Python內(nèi)置模塊copy中的deepcopy方法,代碼如下:

import copy

···
self.history.append(copy.deepcopy(self.board))

接下來我們只用在對(duì)應(yīng)的方法中從history里取出不同的狀態(tài)即可:

    def restart(self):
        self.board = self.history[0]
        self.step = 0
        self.history.clear();


    def undo(self):
        self.board = self.history[-1]
        self.step -= 1
        self.history.pop()

注意:

  • 我們r(jià)estart之后要將history列表清空
  • 在我們回退時(shí),除了返回history最后的元素,還要把它從列表中刪除,否則在二次或者多次回退時(shí)會(huì)出錯(cuò)

項(xiàng)目完善

我們?cè)诰帉懘a的時(shí)候其實(shí)還忽略了幾個(gè)點(diǎn):

  • 如果撤銷被調(diào)用的次數(shù)超過玩家的移動(dòng)次數(shù),則棋盤應(yīng)保持其初始狀態(tài)

也就是說我們不能一直回退,按照我們的代碼,一直回退下去會(huì)出現(xiàn)以下兩種情況:

  • history的列表長(zhǎng)度問題,會(huì)衍生出角標(biāo)出錯(cuò)
  • 我們的step會(huì)變?yōu)樨?fù)數(shù)

改進(jìn):

    def undo(self):
        if self.step == 0:
            return
        self.board = self.history[-1]
        self.step -= 1
        self.history.pop()
  • 如果我們一開始就restart,或者說連續(xù)多次restart也會(huì)報(bào)錯(cuò)

其本質(zhì)也是因?yàn)閔istory列表為空導(dǎo)致的角標(biāo)出錯(cuò)

改進(jìn):

    def restart(self):
        if len(self.history) == 0:
            return
        self.board = self.history[0]
        self.step = 0
        self.history.clear();

項(xiàng)目整體源碼

'''
 推箱子
 P代表玩家 o代表洞  #代表箱子 空字符代表地磚
 項(xiàng)目要求:
 1)二維網(wǎng)格的元原點(diǎn)位于左上方
 2)每回合只能上下左右移動(dòng)一格
 3)玩家不能移動(dòng)到墻或者洞中
 4)只有當(dāng)玩家推動(dòng)箱子移動(dòng)的下一個(gè)單位是地磚或著洞的時(shí)候才能移動(dòng)成功  否則箱子不會(huì)移動(dòng)
 5)箱子進(jìn)入洞中之后  洞和箱子都會(huì)消失   使用地磚進(jìn)行替代
 6)如果離開屏幕邊緣 在規(guī)則允許的情況下(也就是第4條)  允許出現(xiàn)在對(duì)側(cè)
'''


import copy

class Sokoban:
    def __init__(self,board):
        self.board = board
        self.step = 0
        self.history = []
    def __str__(self):
        show = ''
        num = 0
        for i in self.board:
            num += 1
            for j in i:
                show += j + ' '
            show += '\n'
        return show[:-2]
    def find_player(self):
        for x in range(self.board_x()):
            for y in range(self.board_x()):
                if self.board[x][y] == 'P':
                    return (x,y)

    def is_complete(self):
        for i in self.board:
            for j in i :
                if j == 'o':
                    return False
        return True
    def steps(self):
        return self.step

    def restart(self):
        if len(self.history) == 0:
            return
        self.board = self.history[0]
        self.step = 0
        self.history.clear();


    def undo(self):
        if self.step == 0:
            return
        self.board = self.history[-1]
        self.step -= 1
        self.history.pop()

    def move(self,direction):
        # 此時(shí)玩家的位置
        x = self.find_player()[0]
        y = self.find_player()[1]
        ans = self.check(direction)
        if direction == 'w':
            if ans < 0:
                return
            else:
                self.step += 1
                self.history.append(copy.deepcopy(self.board))
                self.board[x][y] = ' '
                if ans == 0:
                    self.board[(x-1)%self.board_x()][y] = 'P'
                else:
                    if self.board[(x-2)%self.board_x()][y] == 'o':
                        self.board[(x-2)%self.board_x()][y] = ' '
                        self.board[(x-1)%self.board_x()][y] = 'P'
                    else:
                        self.board[(x-2)%self.board_x()][y] = '#'
                        self.board[(x-1)%self.board_x()][y] = 'P'
        elif direction == 'a':
            if ans < 0:
                return
            else:
                self.step += 1
                self.history.append(copy.deepcopy(self.board))

                self.board[x][y] = ' '

                if ans == 0:
                    self.board[x][(y - 1)%self.board_y()] = 'P'
                else:
                    if self.board[x][(y - 2)%self.board_y()] == 'o':
                        self.board[x][(y - 2)%self.board_y()] = ' '
                        self.board[x][(y - 1)%self.board_y()] = 'P'
                    else:
                        self.board[x][(y - 2)%self.board_y()] = '#'
                        self.board[x][(y - 1)%self.board_y()] = 'P'
        elif direction == 's':
            if ans < 0:
                return
            else:
                self.step += 1
                self.history.append(copy.deepcopy(self.board))

                self.board[x][y] = ' '
                if ans == 0:
                    self.board[(x + 1)%self.board_x()][y] = 'P'
                else:
                    if self.board[(x + 2)%self.board_x()][y] == 'o':
                        self.board[(x + 2)%self.board_x()][y] = ' '
                        self.board[(x + 1)%self.board_x()][y] = 'P'
                    else:
                        self.board[(x + 2)%self.board_x()][y] = '#'
                        self.board[(x + 1)%self.board_x()][y] = 'P'
        elif direction == 'd':
            if ans < 0:
                return
            else:
                self.step += 1
                self.history.append(copy.deepcopy(self.board))

                self.board[x][y] = ' '
                if ans == 0:
                    self.board[x][(y + 1)%self.board_y()] = 'P'
                else:
                    if self.board[x][(y + 2)%self.board_y()] == 'o':
                        self.board[x][(y + 2)%self.board_y()] = ' '
                        self.board[x][(y + 1)%self.board_y()] = 'P'
                    else:
                        self.board[x][(y + 2)%self.board_y()] = '#'
                        self.board[x][(y + 1)%self.board_y()] = 'P'

    def check(self,direction):
        # 此時(shí)玩家的位置
        x = self.find_player()[0]
        y = self.find_player()[1]
        if direction not in "wasd":
            return -1
        #每個(gè)方向上的處理
        # 先考慮在你的移動(dòng)方向上沒有箱子的情況
        # 再考慮在你的移動(dòng)方向上有箱子的情況
        # 返回正整數(shù)代表可以移動(dòng) 返回1說明有箱子   返回0說明沒箱子    返回負(fù)數(shù)代表不能移動(dòng)
        if direction == 'w':
            # 代表方向上沒有箱子
            if self.board[(x-1)%self.board_x()][y] != '#':
                if self.board[(x-1)%self.board_x()][y] not in '*o':
                    return 0
                else:
                    return -1
            # 代表方向上有箱子
            else:
                if self.board[(x-2)%self.board_x()][y] not in '*':
                    return 1
                else:
                    return -1
        elif direction == 'a':
            # 代表方向上沒有箱子
            if self.board[x][(y - 1)%self.board_y()] != '#':
                if self.board[x][(y - 1)%self.board_y()] not in '*o':
                    return 0
                else:
                    return -1
            # 代表方向上有箱子
            else:
                if self.board[x][(y - 2)%self.board_y()] not in '*':
                    return 1
                else:
                    return -1
        elif direction == 's':
            # 代表方向上沒有箱子
            if self.board[(x + 1)%self.board_x()][y] != '#':
                if self.board[(x + 1)%self.board_x()][y] not in '*o':
                    return 0
                else:
                    return -1
            # 代表方向上有箱子
            else:
                if self.board[(x + 2)%self.board_x()][y] not in '*':
                    return 1
                else:
                    return -1
        elif direction == 'd':
            # 代表方向上沒有箱子
            if self.board[x][(y + 1)%self.board_y()] != '#':
                if self.board[x][(y + 1)%self.board_y()] not in '*o':
                    return 0
                else:
                    return -1
            # 代表方向上有箱子
            else:
                if self.board[x][(y + 2)%self.board_y()] not in '*':
                    return 1
                else:
                    return -1

    def board_x(self):
        return len(self.board)

    def board_y(self):
        return len(self.board[0])

# 豎著是x軸  橫著是y軸
board = [
    ['*', '*', ' ', '*', '*'],
    ['*', 'o', ' ', ' ', '*'],
    ['#', ' ', 'P', '#', 'o'],
    ['*', ' ', ' ', ' ', '*'],
    ['*', '*', ' ', '*', '*'],
]


game = Sokoban(board)
move = str()
print(game)
print(game.steps(), ':', game.is_complete())
while not game.is_complete():
    move = input('move:')
    if move == 'u':
        game.undo()
    elif move == 'r':
        game.restart()
    else:
        game.move(move)
    print(game)
    print(game.steps(), ':', game.is_complete())

運(yùn)行效果;
python推箱子游戲代碼,娛樂小項(xiàng)目,python,開發(fā)語言

直接cv在IDE中就可以玩,地圖可以自己自定義,記得箱子和洞口數(shù)量要一樣多否則永遠(yuǎn)過不了關(guān)。

項(xiàng)目缺陷分析

  • 項(xiàng)目中使用的數(shù)據(jù)結(jié)構(gòu)較為單一,列表一用用到底。其實(shí)很多地方都可以用棧、隊(duì)列、鏈表等數(shù)據(jù)結(jié)構(gòu)進(jìn)行相關(guān)的優(yōu)化
  • 有些地方的代碼些許冗雜,可以進(jìn)行語法上的優(yōu)化
  • 因?yàn)榻涌谖臋n的束縛,其實(shí)有很多方法可以更加細(xì)化。例如move方法或者說check方法代碼邏輯還是有點(diǎn)多。有一些邏輯兩個(gè)方法可以共用,我們可以抽象出來新建一個(gè)方法。
  • 既然在wasd四個(gè)方向上邏輯相似,那么我們是否可以考慮二次抽象,而不是將四種情況均放在check和move方法中。

項(xiàng)目收獲與反思

這個(gè)推箱子的小游戲是校內(nèi)老師布置的一次小作業(yè)。因?yàn)樽约浩綍r(shí)都是使用一些前端還有java后端方面的東西,python長(zhǎng)時(shí)間不用忘得差不多了。我寫的時(shí)候面向?qū)ο蟮姆矫娴恼Z法以及一些列表相關(guān)方法都是邊查文檔邊寫的。這就導(dǎo)致代碼方面不是非常的成熟健壯。

當(dāng)然收獲也非常的多,一個(gè)是復(fù)習(xí)了python,然后就是取余的思想。平時(shí)可能刷算法題的時(shí)候可能會(huì)遇見,開發(fā)的時(shí)候基本沒怎么用過,這個(gè)項(xiàng)目讓我見識(shí)到了取余在實(shí)際開發(fā)中發(fā)揮的作用:在優(yōu)化了代碼的同時(shí)還能減少出錯(cuò)。一開始沒想到取余的時(shí)候,一個(gè)個(gè)情況的分類討論簡(jiǎn)直讓人抓狂。

還有另外非常重要的一點(diǎn),就是寫代碼之前打草稿的必要性

其實(shí)在平時(shí)我們進(jìn)行不管是前端開發(fā)、后端開發(fā),更多的思考的是:用什么、怎么用,那種很嚴(yán)格的邏輯思考其實(shí)并不是很頻繁。這就導(dǎo)致一臺(tái)電腦一個(gè)文檔基本就可以解決問題。而涉及到算法或者說嚴(yán)格的情況分類與考慮這就需要我們打草稿整理思路再去寫代碼。直接一股腦地去寫代碼,或者說不打草稿非常的影響效率以及質(zhì)量。文章來源地址http://www.zghlxwxcb.cn/news/detail-779296.html

到了這里,關(guān)于手把手教你使用Python實(shí)現(xiàn)推箱子小游戲(附完整源碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 手把手教你使用Python調(diào)用 ChatGPT!支持http代理

    手把手教你使用Python調(diào)用 ChatGPT!支持http代理

    作者:虛壞叔叔 博客:https://xuhss.com 早餐店不會(huì)開到晚上,想吃的人早就來了!?? 前段時(shí)間OpenAI 開放了兩個(gè)新模型的api接口,專門為聊天而生的 gpt-3.5-turbo 和 gpt-3.5-turbo-0301。 ChatGPT is powered by gpt-3.5-turbo, OpenAI’s most advanced language model. 從上面這句話,我們可以知道現(xiàn)在 ch

    2024年02月08日
    瀏覽(30)
  • 手把手教你使用Python寫貪吃蛇游戲(pygame,附源碼)

    貪吃蛇游戲是有史以來最受歡迎的街機(jī)游戲之一。在這個(gè)游戲中,玩家的主要目標(biāo)是在不撞墻或不撞墻的情況下抓住最大數(shù)量的水果。在學(xué)習(xí) Python 或 Pygame 時(shí),可以將創(chuàng)建蛇游戲視為一項(xiàng)挑戰(zhàn)。這是每個(gè)新手程序員都應(yīng)該接受的最好的初學(xué)者友好項(xiàng)目之一。學(xué)習(xí)構(gòu)建視頻游戲

    2024年02月16日
    瀏覽(23)
  • 『爬蟲四步走』手把手教你使用Python抓取并存儲(chǔ)網(wǎng)頁數(shù)據(jù)!

    『爬蟲四步走』手把手教你使用Python抓取并存儲(chǔ)網(wǎng)頁數(shù)據(jù)!

    爬蟲是Python的一個(gè)重要的應(yīng)用,使用Python爬蟲我們可以輕松的從互聯(lián)網(wǎng)中抓取我們想要的數(shù)據(jù),**本文將基于爬取B站視頻熱搜榜單數(shù)據(jù)并存儲(chǔ)為例,詳細(xì)介紹Python爬蟲的基本流程。**如果你還在入門爬蟲階段或者不清楚爬蟲的具體工作流程,那么應(yīng)該仔細(xì)閱讀本文! 第一步:

    2024年02月04日
    瀏覽(49)
  • 手把手教你使用Flask框架構(gòu)建Python接口以及如何請(qǐng)求該接口

    Flask是一個(gè)輕量級(jí)的Web應(yīng)用框架,基于Python編寫,其核心思想是保持簡(jiǎn)潔,靈活性和易于擴(kuò)展。 Flask是一個(gè)輕量級(jí)的Web應(yīng)用框架,基于Python編寫,其核心思想是保持簡(jiǎn)潔,靈活性和易于擴(kuò)展。Flask提供了基本的Web開發(fā)工具和應(yīng)用程序的結(jié)構(gòu),但同時(shí)也允許開發(fā)者自由選擇其他庫

    2024年02月06日
    瀏覽(26)
  • 快速上手WebGL,代碼+圖解手把手教你使用WebGL一步步實(shí)現(xiàn)熱力圖

    快速上手WebGL,代碼+圖解手把手教你使用WebGL一步步實(shí)現(xiàn)熱力圖

    大家好,我是南木元元,熱衷分享有趣實(shí)用的文章。 項(xiàng)目中需要繪制熱力圖,熱力圖其實(shí)就是數(shù)值大小用顏色來進(jìn)行區(qū)分,每個(gè)點(diǎn)的數(shù)值需根據(jù)顏色映射表(調(diào)色板)映射為指定顏色。需要3個(gè)數(shù)值字段,可繪制在平行坐標(biāo)系中(2個(gè)數(shù)值字段分別確定x、y軸,1個(gè)數(shù)值字段確定

    2024年01月18日
    瀏覽(36)
  • 【YOLOv8】實(shí)戰(zhàn)一:手把手教你使用YOLOv8實(shí)現(xiàn)實(shí)時(shí)目標(biāo)檢測(cè)

    【YOLOv8】實(shí)戰(zhàn)一:手把手教你使用YOLOv8實(shí)現(xiàn)實(shí)時(shí)目標(biāo)檢測(cè)

    ????博客主頁: virobotics的CSDN博客:LabVIEW深度學(xué)習(xí)、人工智能博主 ??所屬專欄:『LabVIEW深度學(xué)習(xí)實(shí)戰(zhàn)』 ??上期文章: LabVIEW+OpenCV快速搭建人臉識(shí)別系統(tǒng)(附源碼)) ??如覺得博主文章寫的不錯(cuò)或?qū)δ阌兴鶐椭脑?,還望大家多多支持呀! 歡迎大家?關(guān)注、??點(diǎn)贊、?收

    2024年02月02日
    瀏覽(27)
  • 手把手教你用Python編寫郵箱腳本引擎

    手把手教你用Python編寫郵箱腳本引擎

    版權(quán)聲明:原創(chuàng)不易,本文禁止抄襲、轉(zhuǎn)載需附上鏈接,侵權(quán)必究! 郵箱是傳輸信息方式之一,個(gè)人,企業(yè)等都在使用,朋友之間發(fā)消息,注冊(cè)/登錄信息驗(yàn)證,訂閱郵箱,企業(yè)招聘,向客戶發(fā)送消息等都是郵箱的使用場(chǎng)景;郵箱有兩個(gè)較重要的協(xié)議:SMTP和POP3,均位于OSI7層

    2024年02月06日
    瀏覽(104)
  • 手把手教你實(shí)現(xiàn)SpringBoot的監(jiān)控!

    手把手教你實(shí)現(xiàn)SpringBoot的監(jiān)控!

    任何一個(gè)服務(wù)如果沒有監(jiān)控,那就是兩眼一抹黑,無法知道當(dāng)前服務(wù)的運(yùn)行情況,也就無法對(duì)可能出現(xiàn)的異常狀況進(jìn)行很好的處理,所以對(duì)任意一個(gè)服務(wù)來說,監(jiān)控都是必不可少的。 就目前而言,大部分微服務(wù)應(yīng)用都是基于 SpringBoot 來構(gòu)建,所以了解 SpringBoot 的監(jiān)控特性是非

    2024年02月11日
    瀏覽(24)
  • 手把手教你如何使用SimiliarWeb

    手把手教你如何使用SimiliarWeb

    在之前的“手把手教你如何使用Google Trends”文章中我們講到從事跨境電商的賣家第一步遇到的問題是“客戶在哪里?”該如何推廣我的產(chǎn)品?因此若想自己的店鋪?zhàn)龃笞龊茫瑒t需要工具來幫助分析市場(chǎng)行情,根據(jù)市場(chǎng)行情調(diào)整自己的業(yè)務(wù)狀況。小編在上篇中已經(jīng)講解了三個(gè)特

    2024年02月09日
    瀏覽(103)
  • 手把手教你如何使用Docker

    手把手教你如何使用Docker

    我們?cè)诠鹃_發(fā)中,會(huì)有開發(fā)環(huán)境,測(cè)試環(huán)境,上線環(huán)境, 比如我們開發(fā)人員開發(fā)好了一個(gè)項(xiàng)目,在開發(fā)環(huán)境中運(yùn)行正常,但測(cè)試人員拉到測(cè)試環(huán)境就跑不起來【jdk版本等】,或者上線的時(shí)候運(yùn)行不起來,這時(shí)候就要為每個(gè)機(jī)器配置一個(gè)環(huán)境,那運(yùn)維人員不得累死?【哈哈,

    2024年02月10日
    瀏覽(104)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包