日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python 小型项目大全 36~40

發布時間:2024/1/8 python 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 小型项目大全 36~40 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

三十六、沙漏

原文:http://inventwithpython.com/bigbookpython/project36.html

這個可視化程序有一個粗糙的物理引擎,模擬沙子通過沙漏的小孔落下。沙子堆積在沙漏的下半部分;然后把沙漏翻過來,重復這個過程。

運行示例

圖 36-1 顯示了運行hourglass.py時的輸出。

:沙漏程序在落砂時的輸出

工作原理

沙漏程序實現了一個基本的物理引擎。一個物理引擎是模擬物理物體在重力作用下下落,相互碰撞,按照物理定律運動的軟件。你會發現在視頻游戲、計算機動畫和科學模擬中使用的物理引擎。在第 91 到 102 行,每一粒沙子檢查它下面的空間是否是空的,如果是,就向下移動。否則,它檢查它是否可以向左下方移動(第 104 到 112 行)或向右下方移動(第 114 到 122 行)。當然,運動學,經典物理學的一個分支,處理宏觀物體的運動,遠不止這些。然而,你不需要一個物理學學位來制作一個沙漏中沙子的原始模擬,它看起來是令人愉快的。

"""Hourglass, by Al Sweigart email@protected An animation of an hourglass with falling sand. Press Ctrl-C to stop. This code is available at https://nostarch.com/big-book-small-python-programming Tags: large, artistic, bext, simulation"""import random, sys, timetry:import bext except ImportError:print('This program requires the bext module, which you')print('can install by following the instructions at')print('https://pypi.org/project/Bext/')sys.exit()# Set up the constants: PAUSE_LENGTH = 0.2 # (!) Try changing this to 0.0 or 1.0. # (!) Try changing this to any number between 0 and 100: WIDE_FALL_CHANCE = 50SCREEN_WIDTH = 79 SCREEN_HEIGHT = 25 X = 0 # The index of X values in an (x, y) tuple is 0. Y = 1 # The index of Y values in an (x, y) tuple is 1. SAND = chr(9617) WALL = chr(9608)# Set up the walls of the hour glass: HOURGLASS = set() # Has (x, y) tuples for where hourglass walls are. # (!) Try commenting out some HOURGLASS.add() lines to erase walls: for i in range(18, 37):HOURGLASS.add((i, 1)) # Add walls for the top cap of the hourglass.HOURGLASS.add((i, 23)) # Add walls for the bottom cap. for i in range(1, 5):HOURGLASS.add((18, i)) # Add walls for the top left straight wall.HOURGLASS.add((36, i)) # Add walls for the top right straight wall.HOURGLASS.add((18, i + 19)) # Add walls for the bottom left.HOURGLASS.add((36, i + 19)) # Add walls for the bottom right. for i in range(8):HOURGLASS.add((19 + i, 5 + i)) # Add the top left slanted wall.HOURGLASS.add((35 - i, 5 + i)) # Add the top right slanted wall.HOURGLASS.add((25 - i, 13 + i)) # Add the bottom left slanted wall.HOURGLASS.add((29 + i, 13 + i)) # Add the bottom right slanted wall.# Set up the initial sand at the top of the hourglass: INITIAL_SAND = set() for y in range(8):for x in range(19 + y, 36 - y):INITIAL_SAND.add((x, y + 4))def main():bext.fg('yellow')bext.clear()# Draw the quit message:bext.goto(0, 0)print('Ctrl-C to quit.', end='')# Display the walls of the hourglass:for wall in HOURGLASS:bext.goto(wall[X], wall[Y])print(WALL, end='')while True: # Main program loop.allSand = list(INITIAL_SAND)# Draw the initial sand:for sand in allSand:bext.goto(sand[X], sand[Y])print(SAND, end='')runHourglassSimulation(allSand)def runHourglassSimulation(allSand):"""Keep running the sand falling simulation until the sand stopsmoving."""while True: # Keep looping until sand has run out.random.shuffle(allSand) # Random order of grain simulation.sandMovedOnThisStep = Falsefor i, sand in enumerate(allSand):if sand[Y] == SCREEN_HEIGHT - 1:# Sand is on the very bottom, so it won't move:continue# If nothing is under this sand, move it down:noSandBelow = (sand[X], sand[Y] + 1) not in allSandnoWallBelow = (sand[X], sand[Y] + 1) not in HOURGLASScanFallDown = noSandBelow and noWallBelowif canFallDown:# Draw the sand in its new position down one space:bext.goto(sand[X], sand[Y])print(' ', end='') # Clear the old position.bext.goto(sand[X], sand[Y] + 1)print(SAND, end='')# Set the sand in its new position down one space:allSand[i] = (sand[X], sand[Y] + 1)sandMovedOnThisStep = Trueelse:# Check if the sand can fall to the left:belowLeft = (sand[X] - 1, sand[Y] + 1)noSandBelowLeft = belowLeft not in allSandnoWallBelowLeft = belowLeft not in HOURGLASSleft = (sand[X] - 1, sand[Y])noWallLeft = left not in HOURGLASSnotOnLeftEdge = sand[X] > 0canFallLeft = (noSandBelowLeft and noWallBelowLeftand noWallLeft and notOnLeftEdge)# Check if the sand can fall to the right:belowRight = (sand[X] + 1, sand[Y] + 1)noSandBelowRight = belowRight not in allSandnoWallBelowRight = belowRight not in HOURGLASSright = (sand[X] + 1, sand[Y])noWallRight = right not in HOURGLASSnotOnRightEdge = sand[X] < SCREEN_WIDTH - 1canFallRight = (noSandBelowRight and noWallBelowRightand noWallRight and notOnRightEdge)# Set the falling direction:fallingDirection = Noneif canFallLeft and not canFallRight:fallingDirection = -1 # Set the sand to fall left.elif not canFallLeft and canFallRight:fallingDirection = 1 # Set the sand to fall right.elif canFallLeft and canFallRight:# Both are possible, so randomly set it:fallingDirection = random.choice((-1, 1))# Check if the sand can "far" fall two spaces to# the left or right instead of just one space:if random.random() * 100 <= WIDE_FALL_CHANCE:belowTwoLeft = (sand[X] - 2, sand[Y] + 1)noSandBelowTwoLeft = belowTwoLeft not in allSandnoWallBelowTwoLeft = belowTwoLeft not in HOURGLASSnotOnSecondToLeftEdge = sand[X] > 1canFallTwoLeft = (canFallLeft and noSandBelowTwoLeftand noWallBelowTwoLeft and notOnSecondToLeftEdge)belowTwoRight = (sand[X] + 2, sand[Y] + 1)noSandBelowTwoRight = belowTwoRight not in allSandnoWallBelowTwoRight = belowTwoRight not in HOURGLASSnotOnSecondToRightEdge = sand[X] < SCREEN_WIDTH - 2canFallTwoRight = (canFallRightand noSandBelowTwoRight and noWallBelowTwoRightand notOnSecondToRightEdge)if canFallTwoLeft and not canFallTwoRight:fallingDirection = -2elif not canFallTwoLeft and canFallTwoRight:fallingDirection = 2elif canFallTwoLeft and canFallTwoRight:fallingDirection = random.choice((-2, 2))if fallingDirection == None:# This sand can't fall, so move on.continue# Draw the sand in its new position:bext.goto(sand[X], sand[Y])print(' ', end='') # Erase old sand.bext.goto(sand[X] + fallingDirection, sand[Y] + 1)print(SAND, end='') # Draw new sand.# Move the grain of sand to its new position:allSand[i] = (sand[X] + fallingDirection, sand[Y] + 1)sandMovedOnThisStep = Truesys.stdout.flush() # (Required for bext-using programs.)time.sleep(PAUSE_LENGTH) # Pause after this# If no sand has moved on this step, reset the hourglass:if not sandMovedOnThisStep:time.sleep(2)# Erase all of the sand:for sand in allSand:bext.goto(sand[X], sand[Y])print(' ', end='')break # Break out of main simulation loop.# If this program was run (instead of imported), run the game: if __name__ == '__main__':try:main()except KeyboardInterrupt:sys.exit() # When Ctrl-C is pressed, end the program.

在輸入源代碼并運行幾次之后,嘗試對其進行實驗性的修改。標有(!)的注釋對你可以做的小改變有建議。你也可以自己想辦法做到以下幾點:

  • 創建除沙漏以外的墻壁形狀。
  • 在屏幕上創建點,不斷涌出新的沙粒。

探索程序

試著找出下列問題的答案。嘗試對代碼進行一些修改,然后重新運行程序,看看這些修改有什么影響。

  • 如果把第 31 行的range(18, 37)改成range(18, 30)會怎么樣?
  • 如果把第 39 行的range(8)改成range(0)會怎么樣?
  • 如果把第 82 行的sandMovedOnThisStep = False改成sandMovedOnThisStep = True會怎么樣?
  • 如果把 125 行的fallingDirection = None改成fallingDirection = 1會怎么樣?
  • 如果把 136 行的random.random() * 100 <= WIDE_FALL_CHANCE改成random.random() * 0 <= WIDE_FALL_CHANCE會怎么樣?
  • 三十七、饑餓機器人

    原文:http://inventwithpython.com/bigbookpython/project37.html

    你和饑餓的機器人被困在一個迷宮里!你不知道機器人為什么需要吃飯,但你也不想知道。機器人的程序設計很糟糕,即使被墻擋住,它們也會直接向你移動。你必須欺騙機器人互相碰撞(或死亡的機器人)而不被抓住。

    你有一個個人傳送裝置,可以把你送到一個隨機的新地方,但它的電池只夠兩次旅行。此外,你和機器人可以溜過角落!

    運行示例

    當您運行hungryrobots.py時,輸出將如下所示:

    Hungry Robots, by Al Sweigart email@protected `--snip--` ???????????????????????????????????????? ? ? R R ? ? ? ? ? ??? R? ?? ? ? ? ? ? ? ? ? ??? ? ? R? ? ? ?? ?? ? ? ? ?? ? ? ??? ? ? ? ? ?? ? RX??? ? ? ? ? ? ? ? R R R ? ? ? ? ? ? ? ? R ? ? ? ? R R ? R ? R ? ? ? ? ? ? ? ? ? ? ? @ ? ? R??? ? ? ? ? ?? ?? ? ? ? ? ?? ? ? R ?? ??X ? ? ? R ??RR ? R ? ?RR R R ? ? ? R? ? ?? RRR R ? ? ??R ? ? ? R ? ? ? ? ???????????????????????????????????????? (T)eleports remaining: 2(Q) (W) ( )(A) (S) (D) Enter move or QUIT: (Z) (X) ( ) `--snip--`

    工作原理

    在這個游戲中代表位置的 x 和 y 笛卡爾坐標允許我們使用數學來確定機器人應該移動的方向。在編程中,x 坐標向右增加,y 坐標向下增加。這意味著如果機器人的 x 坐標大于玩家的坐標,它應該向左移動(即代碼應該從其當前的 x 坐標中減去)以靠近玩家。如果機器人的 x 坐標更小,它應該向右移動(也就是說,代碼應該添加到其當前的 x 坐標中)。這同樣適用于基于相對 y 坐標的上下移動。

    """Hungry Robots, by Al Sweigart email@protected Escape the hungry robots by making them crash into each other. This code is available at https://nostarch.com/big-book-small-python-programming Tags: large, game"""import random, sys# Set up the constants: WIDTH = 40 # (!) Try changing this to 70 or 10. HEIGHT = 20 # (!) Try changing this to 10. NUM_ROBOTS = 10 # (!) Try changing this to 1 or 30. NUM_TELEPORTS = 2 # (!) Try changing this to 0 or 9999. NUM_DEAD_ROBOTS = 2 # (!) Try changing this to 0 or 20. NUM_WALLS = 100 # (!) Try changing this to 0 or 300.EMPTY_SPACE = ' ' # (!) Try changing this to '.'. PLAYER = '@' # (!) Try changing this to 'R'. ROBOT = 'R' # (!) Try changing this to '@'. DEAD_ROBOT = 'X' # (!) Try changing this to 'R'.# (!) Try changing this to '#' or 'O' or ' ': WALL = chr(9617) # Character 9617 is '?'def main():print('''Hungry Robots, by Al Sweigart email@protectedYou are trapped in a maze with hungry robots! You don't know why robots need to eat, but you don't want to find out. The robots are badly programmed and will move directly toward you, even if blocked by walls. You must trick the robots into crashing into each other (or dead robots) without being caught. You have a personal teleporter device, but it only has enough battery for {} trips. Keep in mind, you and robots can slip through the corners of two diagonal walls! '''.format(NUM_TELEPORTS))input('Press Enter to begin...')# Set up a new game:board = getNewBoard()robots = addRobots(board)playerPosition = getRandomEmptySpace(board, robots)while True: # Main game loop.displayBoard(board, robots, playerPosition)if len(robots) == 0: # Check if the player has won.print('All the robots have crashed into each other and you')print('lived to tell the tale! Good job!')sys.exit()# Move the player and robots:playerPosition = askForPlayerMove(board, robots, playerPosition)robots = moveRobots(board, robots, playerPosition)for x, y in robots: # Check if the player has lost.if (x, y) == playerPosition:displayBoard(board, robots, playerPosition)print('You have been caught by a robot!')sys.exit()def getNewBoard():"""Returns a dictionary that represents the board. The keys are(x, y) tuples of integer indexes for board positions, the values areWALL, EMPTY_SPACE, or DEAD_ROBOT. The dictionary also has the key'teleports' for the number of teleports the player has left.The living robots are stored separately from the board dictionary."""board = {'teleports': NUM_TELEPORTS}# Create an empty board:for x in range(WIDTH):for y in range(HEIGHT):board[(x, y)] = EMPTY_SPACE# Add walls on the edges of the board:for x in range(WIDTH):board[(x, 0)] = WALL # Make top wall.board[(x, HEIGHT - 1)] = WALL # Make bottom wall.for y in range(HEIGHT):board[(0, y)] = WALL # Make left wall.board[(WIDTH - 1, y)] = WALL # Make right wall.# Add the random walls:for i in range(NUM_WALLS):x, y = getRandomEmptySpace(board, [])board[(x, y)] = WALL# Add the starting dead robots:for i in range(NUM_DEAD_ROBOTS):x, y = getRandomEmptySpace(board, [])board[(x, y)] = DEAD_ROBOTreturn boarddef getRandomEmptySpace(board, robots):"""Return a (x, y) integer tuple of an empty space on the board."""while True:randomX = random.randint(1, WIDTH - 2)randomY = random.randint(1, HEIGHT - 2)if isEmpty(randomX, randomY, board, robots):breakreturn (randomX, randomY)def isEmpty(x, y, board, robots):"""Return True if the (x, y) is empty on the board and there's alsono robot there."""return board[(x, y)] == EMPTY_SPACE and (x, y) not in robotsdef addRobots(board):"""Add NUM_ROBOTS number of robots to empty spaces on the board andreturn a list of these (x, y) spaces where robots are now located."""robots = []for i in range(NUM_ROBOTS):x, y = getRandomEmptySpace(board, robots)robots.append((x, y))return robotsdef displayBoard(board, robots, playerPosition):"""Display the board, robots, and player on the screen."""# Loop over every space on the board:for y in range(HEIGHT):for x in range(WIDTH):# Draw the appropriate character:if board[(x, y)] == WALL:print(WALL, end='')elif board[(x, y)] == DEAD_ROBOT:print(DEAD_ROBOT, end='')elif (x, y) == playerPosition:print(PLAYER, end='')elif (x, y) in robots:print(ROBOT, end='')else:print(EMPTY_SPACE, end='')print() # Print a newline.def askForPlayerMove(board, robots, playerPosition):"""Returns the (x, y) integer tuple of the place the player movesnext, given their current location and the walls of the board."""playerX, playerY = playerPosition# Find which directions aren't blocked by a wall:q = 'Q' if isEmpty(playerX - 1, playerY - 1, board, robots) else ' 'w = 'W' if isEmpty(playerX + 0, playerY - 1, board, robots) else ' 'e = 'E' if isEmpty(playerX + 1, playerY - 1, board, robots) else ' 'd = 'D' if isEmpty(playerX + 1, playerY + 0, board, robots) else ' 'c = 'C' if isEmpty(playerX + 1, playerY + 1, board, robots) else ' 'x = 'X' if isEmpty(playerX + 0, playerY + 1, board, robots) else ' 'z = 'Z' if isEmpty(playerX - 1, playerY + 1, board, robots) else ' 'a = 'A' if isEmpty(playerX - 1, playerY + 0, board, robots) else ' 'allMoves = (q + w + e + d + c + x + a + z + 'S')while True:# Get player's move:print('(T)eleports remaining: {}'.format(board["teleports"]))print(' ({}) ({}) ({})'.format(q, w, e))print(' ({}) (S) ({})'.format(a, d))print('Enter move or QUIT: ({}) ({}) ({})'.format(z, x, c))move = input('> ').upper()if move == 'QUIT':print('Thanks for playing!')sys.exit()elif move == 'T' and board['teleports'] > 0:# Teleport the player to a random empty space:board['teleports'] -= 1return getRandomEmptySpace(board, robots)elif move != '' and move in allMoves:# Return the new player position based on their move:return {'Q': (playerX - 1, playerY - 1),'W': (playerX + 0, playerY - 1),'E': (playerX + 1, playerY - 1),'D': (playerX + 1, playerY + 0),'C': (playerX + 1, playerY + 1),'X': (playerX + 0, playerY + 1),'Z': (playerX - 1, playerY + 1),'A': (playerX - 1, playerY + 0),'S': (playerX, playerY)}[move]def moveRobots(board, robotPositions, playerPosition):"""Return a list of (x, y) tuples of new robot positions after theyhave tried to move toward the player."""playerx, playery = playerPositionnextRobotPositions = []while len(robotPositions) > 0:robotx, roboty = robotPositions[0]# Determine the direction the robot moves.if robotx < playerx:movex = 1 # Move right.elif robotx > playerx:movex = -1 # Move left.elif robotx == playerx:movex = 0 # Don't move horizontally.if roboty < playery:movey = 1 # Move up.elif roboty > playery:movey = -1 # Move down.elif roboty == playery:movey = 0 # Don't move vertically.# Check if the robot would run into a wall, and adjust course:if board[(robotx + movex, roboty + movey)] == WALL:# Robot would run into a wall, so come up with a new move:if board[(robotx + movex, roboty)] == EMPTY_SPACE:movey = 0 # Robot can't move horizontally.elif board[(robotx, roboty + movey)] == EMPTY_SPACE:movex = 0 # Robot can't move vertically.else:# Robot can't move.movex = 0movey = 0newRobotx = robotx + movexnewRoboty = roboty + moveyif (board[(robotx, roboty)] == DEAD_ROBOTor board[(newRobotx, newRoboty)] == DEAD_ROBOT):# Robot is at a crash site, remove it.del robotPositions[0]continue# Check if it moves into a robot, then destroy both robots:if (newRobotx, newRoboty) in nextRobotPositions:board[(newRobotx, newRoboty)] = DEAD_ROBOTnextRobotPositions.remove((newRobotx, newRoboty))else:nextRobotPositions.append((newRobotx, newRoboty))# Remove robots from robotPositions as they move.del robotPositions[0]return nextRobotPositions# If this program was run (instead of imported), run the game: if __name__ == '__main__':main()

    在輸入源代碼并運行幾次之后,嘗試對其進行實驗性的修改。標有(!)的注釋對你可以做的小改變有建議。你也可以自己想辦法做到以下幾點:

    • 創造兩種不同的機器人:只能沿對角線移動的機器人和只能沿基本方向移動的機器人。
    • 給玩家一定數量的陷阱,他們可以留下來阻止任何機器人踩到陷阱。
    • 給玩家有限數量的“瞬間墻”,他們可以建立自己的防御。

    探索程序

    試著找出下列問題的答案。嘗試對代碼進行一些修改,然后重新運行程序,看看這些修改有什么影響。

  • 如果把第 22 行的WALL = chr(9617)改成WALL = 'R'會怎么樣?
  • 如果把 237 行的return nextRobotPositions改成return robotPositions會怎么樣?
  • 如果刪除或注釋掉第 44 行的displayBoard(board, robots, playerPosition)會發生什么?
  • 如果刪除或注釋掉第 53 行的robots = moveRobots(board, robots, playerPosition)會發生什么?
  • 三十八、我控訴

    原文:http://inventwithpython.com/bigbookpython/project38.html

    你就是舉世聞名的大偵探瑪蒂爾德·加繆。貓佐菲不見了,你必須篩選線索。嫌疑人要么總是說謊,要么總是說真話。你會及時找到貓佐菲并指控有罪的一方嗎?

    在這個游戲中,你乘出租車到城市的不同地點。每個地方都有一個嫌疑犯和一件物品。可以向嫌疑人詢問其他嫌疑人和物品的情況,將他們的回答與自己的探索筆記進行對比,確定他們是在說謊還是在說真話。有些人會知道誰綁架了佐菲(或者她在哪里,或者在綁架者的位置發現了什么物品),但是你必須確定你是否能相信他們。你有五分鐘時間找到罪犯,但是如果你三次指控錯誤,你就輸了。這款游戲的靈感來源于 Homestar Runner 的“雞蛋在哪里?”游戲。

    運行示例

    當您運行jaccuse.py時,輸出將如下所示:

    J'ACCUSE! (a mystery game) `--snip--` Time left: 5 min, 0 secYou are in your TAXI. Where do you want to go? (A)LBINO ALLIGATOR PIT (B)OWLING ALLEY (C)ITY HALL (D)UCK POND (H)IPSTER CAFE (O)LD BARN (U)NIVERSITY LIBRARY (V)IDEO GAME MUSEUM (Z)OO > aTime left: 4 min, 48 secYou are at the ALBINO ALLIGATOR PIT.ESPRESSA TOFFEEPOT with the ONE COWBOY BOOT is here.(J) "J'ACCUSE!" (3 accusations left) (Z) Ask if they know where ZOPHIE THE CAT is. (T) Go back to the TAXI. (1) Ask about ESPRESSA TOFFEEPOT (2) Ask about ONE COWBOY BOOT > zThey give you this clue: "DUKE HAUTDOG" Press Enter to continue... `--snip--`

    工作原理

    要完全理解這個程序,您應該密切關注clues字典,它位于第 51 行到第 109 行。您可以取消對第 151 到 154 行的注釋,以便在屏幕上顯示它。這個字典有來自SUSPECTS列表的字符串作為鍵,有“線索字典”作為值。每個線索字典都包含來自SUSPECTS和ITEMS的字符串。當被問及另一個嫌疑人或物品時,最初的嫌疑人會用這些字符串回答。例如,如果clues['DUKE HAUTDOG']['CANDLESTICK']設定為'DUCK POND',那么當玩家向杜克·豪特多格詢問燭臺時,他們會說它在鴨塘。每次玩游戲時,嫌疑人、物品、地點和罪犯都會被洗牌。

    這個程序的代碼圍繞著這個數據結構,所以理解它對于理解程序的其余部分是必要的。

    """J'ACCUSE!, by Al Sweigart email@protected A mystery game of intrigue and a missing cat. This code is available at https://nostarch.com/big-book-small-python-programming Tags: extra-large, game, humor, puzzle"""# Play the original Flash game at: # https://homestarrunner.com/videlectrix/wheresanegg.html # More info at: http://www.hrwiki.org/wiki/Where's_an_Egg%3Fimport time, random, sys# Set up the constants: SUSPECTS = ['DUKE HAUTDOG', 'MAXIMUM POWERS', 'BILL MONOPOLIS', 'SENATOR SCHMEAR', 'MRS. FEATHERTOSS', 'DR. JEAN SPLICER', 'RAFFLES THE CLOWN', 'ESPRESSA TOFFEEPOT', 'CECIL EDGAR VANDERTON'] ITEMS = ['FLASHLIGHT', 'CANDLESTICK', 'RAINBOW FLAG', 'HAMSTER WHEEL', 'ANIME VHS TAPE', 'JAR OF PICKLES', 'ONE COWBOY BOOT', 'CLEAN UNDERPANTS', '5 DOLLAR GIFT CARD'] PLACES = ['ZOO', 'OLD BARN', 'DUCK POND', 'CITY HALL', 'HIPSTER CAFE', 'BOWLING ALLEY', 'VIDEO GAME MUSEUM', 'UNIVERSITY LIBRARY', 'ALBINO ALLIGATOR PIT'] TIME_TO_SOLVE = 300 # 300 seconds (5 minutes) to solve the game.# First letters and longest length of places are needed for menu display: PLACE_FIRST_LETTERS = {} LONGEST_PLACE_NAME_LENGTH = 0 for place in PLACES:PLACE_FIRST_LETTERS[place[0]] = placeif len(place) > LONGEST_PLACE_NAME_LENGTH:LONGEST_PLACE_NAME_LENGTH = len(place)# Basic sanity checks of the constants: assert len(SUSPECTS) == 9 assert len(ITEMS) == 9 assert len(PLACES) == 9 # First letters must be unique: assert len(PLACE_FIRST_LETTERS.keys()) == len(PLACES)knownSuspectsAndItems = [] # visitedPlaces: Keys=places, values=strings of the suspect & item there. visitedPlaces = {} currentLocation = 'TAXI' # Start the game at the taxi. accusedSuspects = [] # Accused suspects won't offer clues. liars = random.sample(SUSPECTS, random.randint(3, 4)) accusationsLeft = 3 # You can accuse up to 3 people. culprit = random.choice(SUSPECTS)# Common indexes link these; e.g. SUSPECTS[0] and ITEMS[0] are at PLACES[0]. random.shuffle(SUSPECTS) random.shuffle(ITEMS) random.shuffle(PLACES)# Create data structures for clues the truth-tellers give about each # item and suspect. # clues: Keys=suspects being asked for a clue, value="clue dictionary". clues = {} for i, interviewee in enumerate(SUSPECTS):if interviewee in liars:continue # Skip the liars for now.# This "clue dictionary" has keys=items & suspects,# value=the clue given.clues[interviewee] = {}clues[interviewee]['debug_liar'] = False # Useful for debugging.for item in ITEMS: # Select clue about each item.if random.randint(0, 1) == 0: # Tells where the item is:clues[interviewee][item] = PLACES[ITEMS.index(item)]else: # Tells who has the item:clues[interviewee][item] = SUSPECTS[ITEMS.index(item)]for suspect in SUSPECTS: # Select clue about each suspect.if random.randint(0, 1) == 0: # Tells where the suspect is:clues[interviewee][suspect] = PLACES[SUSPECTS.index(suspect)]else: # Tells what item the suspect has:clues[interviewee][suspect] = ITEMS[SUSPECTS.index(suspect)]# Create data structures for clues the liars give about each item # and suspect: for i, interviewee in enumerate(SUSPECTS):if interviewee not in liars:continue # We've already handled the truth-tellers.# This "clue dictionary" has keys=items & suspects,# value=the clue given:clues[interviewee] = {}clues[interviewee]['debug_liar'] = True # Useful for debugging.# This interviewee is a liar and gives wrong clues:for item in ITEMS:if random.randint(0, 1) == 0:while True: # Select a random (wrong) place clue.# Lies about where the item is.clues[interviewee][item] = random.choice(PLACES)if clues[interviewee][item] != PLACES[ITEMS.index(item)]:# Break out of the loop when wrong clue is selected.breakelse:while True: # Select a random (wrong) suspect clue.clues[interviewee][item] = random.choice(SUSPECTS)if clues[interviewee][item] != SUSPECTS[ITEMS.index(item)]:# Break out of the loop when wrong clue is selected.breakfor suspect in SUSPECTS:if random.randint(0, 1) == 0:while True: # Select a random (wrong) place clue.clues[interviewee][suspect] = random.choice(PLACES)if clues[interviewee][suspect] != PLACES[ITEMS.index(item)]:# Break out of the loop when wrong clue is selected.breakelse:while True: # Select a random (wrong) item clue.clues[interviewee][suspect] = random.choice(ITEMS)if clues[interviewee][suspect] != ITEMS[SUSPECTS.index(suspect)]:# Break out of the loop when wrong clue is selected.break# Create the data structures for clues given when asked about Zophie: zophieClues = {} for interviewee in random.sample(SUSPECTS, random.randint(3, 4)):kindOfClue = random.randint(1, 3)if kindOfClue == 1:if interviewee not in liars:# They tell you who has Zophie.zophieClues[interviewee] = culpritelif interviewee in liars:while True:# Select a (wrong) suspect clue.zophieClues[interviewee] = random.choice(SUSPECTS)if zophieClues[interviewee] != culprit:# Break out of the loop when wrong clue is selected.breakelif kindOfClue == 2:if interviewee not in liars:# They tell you where Zophie is.zophieClues[interviewee] = PLACES[SUSPECTS.index(culprit)]elif interviewee in liars:while True:# Select a (wrong) place clue.zophieClues[interviewee] = random.choice(PLACES)if zophieClues[interviewee] != PLACES[SUSPECTS.index(culprit)]:# Break out of the loop when wrong clue is selected.breakelif kindOfClue == 3:if interviewee not in liars:# They tell you what item Zophie is near.zophieClues[interviewee] = ITEMS[SUSPECTS.index(culprit)]elif interviewee in liars:while True:# Select a (wrong) item clue.zophieClues[interviewee] = random.choice(ITEMS)if zophieClues[interviewee] != ITEMS[SUSPECTS.index(culprit)]:# Break out of the loop when wrong clue is selected.break# EXPERIMENT: Uncomment this code to view the clue data structures: #import pprint #pprint.pprint(clues) #pprint.pprint(zophieClues) #print('culprit =', culprit)# START OF THE GAME print("""J'ACCUSE! (a mystery game)") By Al Sweigart email@protected Inspired by Homestar Runner\'s "Where\'s an Egg?" gameYou are the world-famous detective, Mathilde Camus. ZOPHIE THE CAT has gone missing, and you must sift through the clues. Suspects either always tell lies, or always tell the truth. Ask them about other people, places, and items to see if the details they give are truthful and consistent with your observations. Then you will know if their clue about ZOPHIE THE CAT is true or not. Will you find ZOPHIE THE CAT in time and accuse the guilty party? """) input('Press Enter to begin...')startTime = time.time() endTime = startTime + TIME_TO_SOLVEwhile True: # Main game loop.if time.time() > endTime or accusationsLeft == 0:# Handle "game over" condition:if time.time() > endTime:print('You have run out of time!')elif accusationsLeft == 0:print('You have accused too many innocent people!')culpritIndex = SUSPECTS.index(culprit)print('It was {} at the {} with the {} who catnapped her!'.format(culprit, PLACES[culpritIndex], ITEMS[culpritIndex]))print('Better luck next time, Detective.')sys.exit()print()minutesLeft = int(endTime - time.time()) // 60secondsLeft = int(endTime - time.time()) % 60print('Time left: {} min, {} sec'.format(minutesLeft, secondsLeft))if currentLocation == 'TAXI':print(' You are in your TAXI. Where do you want to go?')for place in sorted(PLACES):placeInfo = ''if place in visitedPlaces:placeInfo = visitedPlaces[place]nameLabel = '(' + place[0] + ')' + place[1:]spacing = " " * (LONGEST_PLACE_NAME_LENGTH - len(place))print('{} {}{}'.format(nameLabel, spacing, placeInfo))print('(Q)UIT GAME')while True: # Keep asking until a valid response is given.response = input('> ').upper()if response == '':continue # Ask again.if response == 'Q':print('Thanks for playing!')sys.exit()if response in PLACE_FIRST_LETTERS.keys():breakcurrentLocation = PLACE_FIRST_LETTERS[response]continue # Go back to the start of the main game loop.# At a place; player can ask for clues.print(' You are at the {}.'.format(currentLocation))currentLocationIndex = PLACES.index(currentLocation)thePersonHere = SUSPECTS[currentLocationIndex]theItemHere = ITEMS[currentLocationIndex]print(' {} with the {} is here.'.format(thePersonHere, theItemHere))# Add the suspect and item at this place to our list of known# suspects and items:if thePersonHere not in knownSuspectsAndItems:knownSuspectsAndItems.append(thePersonHere)if ITEMS[currentLocationIndex] not in knownSuspectsAndItems:knownSuspectsAndItems.append(ITEMS[currentLocationIndex])if currentLocation not in visitedPlaces.keys():visitedPlaces[currentLocation] = '({}, {})'.format(thePersonHere.lower(), theItemHere.lower())# If the player has accused this person wrongly before, they# won't give clues:if thePersonHere in accusedSuspects:print('They are offended that you accused them,')print('and will not help with your investigation.')print('You go back to your TAXI.')print()input('Press Enter to continue...')currentLocation = 'TAXI'continue # Go back to the start of the main game loop.# Display menu of known suspects & items to ask about:print()print('(J) "J\'ACCUSE!" ({} accusations left)'.format(accusationsLeft))print('(Z) Ask if they know where ZOPHIE THE CAT is.')print('(T) Go back to the TAXI.')for i, suspectOrItem in enumerate(knownSuspectsAndItems):print('({}) Ask about {}'.format(i + 1, suspectOrItem))while True: # Keep asking until a valid response is given.response = input('> ').upper()if response in 'JZT' or (response.isdecimal() and 0 < int(response) <= len(knownSuspectsAndItems)):breakif response == 'J': # Player accuses this suspect.accusationsLeft -= 1 # Use up an accusation.if thePersonHere == culprit:# You've accused the correct suspect.print('You\'ve cracked the case, Detective!')print('It was {} who had catnapped ZOPHIE THE CAT.'.format(culprit))minutesTaken = int(time.time() - startTime) // 60secondsTaken = int(time.time() - startTime) % 60print('Good job! You solved it in {} min, {} sec.'.format(minutesTaken, secondsTaken))sys.exit()else:# You've accused the wrong suspect.accusedSuspects.append(thePersonHere)print('You have accused the wrong person, Detective!')print('They will not help you with anymore clues.')print('You go back to your TAXI.')currentLocation = 'TAXI'elif response == 'Z': # Player asks about Zophie.if thePersonHere not in zophieClues:print('"I don\'t know anything about ZOPHIE THE CAT."')elif thePersonHere in zophieClues:print(' They give you this clue: "{}"'.format(zophieClues[thePersonHere]))# Add non-place clues to the list of known things:if zophieClues[thePersonHere] not in knownSuspectsAndItems and zophieClues[thePersonHere] not in PLACES:knownSuspectsAndItems.append(zophieClues[thePersonHere])elif response == 'T': # Player goes back to the taxi.currentLocation = 'TAXI'continue # Go back to the start of the main game loop.else: # Player asks about a suspect or item.thingBeingAskedAbout = knownSuspectsAndItems[int(response) - 1]if thingBeingAskedAbout in (thePersonHere, theItemHere):print(' They give you this clue: "No comment."')else:print(' They give you this clue: "{}"'.format(clues[thePersonHere][thingBeingAskedAbout]))# Add non-place clues to the list of known things:if clues[thePersonHere][thingBeingAskedAbout] not in knownSuspectsAndItems and clues[thePersonHere][thingBeingAskedAbout] not in PLACES:knownSuspectsAndItems.append(clues[thePersonHere][thingBeingAskedAbout])input('Press Enter to continue...')

    探索程序

    試著找出下列問題的答案。嘗試對代碼進行一些修改,然后重新運行程序,看看這些修改有什么影響。

  • 如果把第 16 行的TIME_TO_SOLVE = 300改成TIME_TO_SOLVE = 0會怎么樣?
  • 如果把 176 行的time.time() > endTime or accusationsLeft == 0改成time.time() > endTime and accusationsLeft == 0會怎么樣?
  • 如果把 198 行的place[1:]改成place會怎么樣?
  • 如果把 173 行的startTime + TIME_TO_SOLVE改成startTime * TIME_TO_SOLVE會怎么樣?
  • 三十九、蘭頓的螞蟻

    原文:http://inventwithpython.com/bigbookpython/project39.html

    蘭頓的螞蟻是二維網格上的元胞自動機模擬,類似于項目 13“康威的生命游戲”。在模擬中,一只“螞蟻”從兩種顏色之一的正方形開始。如果空間是第一種顏色,螞蟻將它切換到第二種顏色,向右旋轉 90 度,并向前移動一個空間。如果空間是第二種顏色,螞蟻將它切換到第一種顏色,向左旋轉 90 度,并向前移動一個空間。盡管規則非常簡單,但模擬顯示了復雜的突發行為。模擬可以在同一個空間中展示多只螞蟻,當它們彼此相遇時,會產生有趣的互動。蘭頓的螞蟻是計算機科學家克里斯·蘭頓在 1986 年發明的。更多關于蘭頓螞蟻的信息可以在en.wikipedia.org/wiki/Langton%27s_ant找到。

    運行示例

    圖 39-1 顯示了運行langtonsant.py時的輸出。

    :蘭頓螞蟻細胞自動機的催眠輸出

    工作原理

    這個程序使用了兩種“方向”的含義一方面,代表每只螞蟻的字典存儲了基本方向:北、南、東、西。然而,向左或向右(或逆時針和順時針,因為我們是從上面看螞蟻)是一個旋轉方向。螞蟻應該根據它們所站的瓷磚向左轉或向右轉,所以第 78 到 100 行根據螞蟻當前的基本方向和它們轉向的方向設置了一個新的基本方向。

    """Langton's Ant, by Al Sweigart email@protected A cellular automata animation. Press Ctrl-C to stop. More info: https://en.wikipedia.org/wiki/Langton%27s_ant This code is available at https://nostarch.com/big-book-small-python-programming Tags: large, artistic, bext, simulation"""import copy, random, sys, timetry:import bext except ImportError:print('This program requires the bext module, which you')print('can install by following the instructions at')print('https://pypi.org/project/Bext/')sys.exit()# Set up the constants: WIDTH, HEIGHT = bext.size() # We can't print to the last column on Windows without it adding a # newline automatically, so reduce the width by one: WIDTH -= 1 HEIGHT -= 1 # Adjustment for the quit message at the bottom.NUMBER_OF_ANTS = 10 # (!) Try changing this to 1 or 50. PAUSE_AMOUNT = 0.1 # (!) Try changing this to 1.0 or 0.0.# (!) Try changing these to make the ants look different: ANT_UP = '^' ANT_DOWN = 'v' ANT_LEFT = '<' ANT_RIGHT = '>'# (!) Try changing these colors to one of 'black', 'red', 'green', # 'yellow', 'blue', 'purple', 'cyan', or 'white'. (These are the only # colors that the bext module supports.) ANT_COLOR = 'red' BLACK_TILE = 'black' WHITE_TILE = 'white'NORTH = 'north' SOUTH = 'south' EAST = 'east' WEST = 'west'def main():bext.fg(ANT_COLOR) # The ants' color is the foreground color.bext.bg(WHITE_TILE) # Set the background to white to start.bext.clear()# Create a new board data structure:board = {'width': WIDTH, 'height': HEIGHT}# Create ant data structures:ants = []for i in range(NUMBER_OF_ANTS):ant = {'x': random.randint(0, WIDTH - 1),'y': random.randint(0, HEIGHT - 1),'direction': random.choice([NORTH, SOUTH, EAST, WEST]),}ants.append(ant)# Keep track of which tiles have changed and need to be redrawn on# the screen:changedTiles = []while True: # Main program loop.displayBoard(board, ants, changedTiles)changedTiles = []# nextBoard is what the board will look like on the next step in# the simulation. Start with a copy of the current step's board:nextBoard = copy.copy(board)# Run a single simulation step for each ant:for ant in ants:if board.get((ant['x'], ant['y']), False) == True:nextBoard[(ant['x'], ant['y'])] = False# Turn clockwise:if ant['direction'] == NORTH:ant['direction'] = EASTelif ant['direction'] == EAST:ant['direction'] = SOUTHelif ant['direction'] == SOUTH:ant['direction'] = WESTelif ant['direction'] == WEST:ant['direction'] = NORTHelse:nextBoard[(ant['x'], ant['y'])] = True# Turn counter clockwise:if ant['direction'] == NORTH:ant['direction'] = WESTelif ant['direction'] == WEST:ant['direction'] = SOUTHelif ant['direction'] == SOUTH:ant['direction'] = EASTelif ant['direction'] == EAST:ant['direction'] = NORTHchangedTiles.append((ant['x'], ant['y']))# Move the ant forward in whatever direction it's facing:if ant['direction'] == NORTH:ant['y'] -= 1if ant['direction'] == SOUTH:ant['y'] += 1if ant['direction'] == WEST:ant['x'] -= 1if ant['direction'] == EAST:ant['x'] += 1# If the ant goes past the edge of the screen,# it should wrap around to other side.ant['x'] = ant['x'] % WIDTHant['y'] = ant['y'] % HEIGHTchangedTiles.append((ant['x'], ant['y']))board = nextBoarddef displayBoard(board, ants, changedTiles):"""Displays the board and ants on the screen. The changedTilesargument is a list of (x, y) tuples for tiles on the screen thathave changed and need to be redrawn."""# Draw the board data structure:for x, y in changedTiles:bext.goto(x, y)if board.get((x, y), False):bext.bg(BLACK_TILE)else:bext.bg(WHITE_TILE)antIsHere = Falsefor ant in ants:if (x, y) == (ant['x'], ant['y']):antIsHere = Trueif ant['direction'] == NORTH:print(ANT_UP, end='')elif ant['direction'] == SOUTH:print(ANT_DOWN, end='')elif ant['direction'] == EAST:print(ANT_LEFT, end='')elif ant['direction'] == WEST:print(ANT_RIGHT, end='')breakif not antIsHere:print(' ', end='')# Display the quit message at the bottom of the screen:bext.goto(0, HEIGHT)bext.bg(WHITE_TILE)print('Press Ctrl-C to quit.', end='')sys.stdout.flush() # (Required for bext-using programs.)time.sleep(PAUSE_AMOUNT)# If this program was run (instead of imported), run the game: if __name__ == '__main__':try:main()except KeyboardInterrupt:print("Langton's Ant, by Al Sweigart email@protected")sys.exit() # When Ctrl-C is pressed, end the program.

    在輸入源代碼并運行幾次之后,嘗試對其進行實驗性的修改。標有(!)的注釋對你可以做的小改變有建議。你也可以自己想辦法做到以下幾點:

    • 讓玩家從文本文件中加載并保存棋盤的狀態。
    • 使用新的移動規則創建額外的平鋪狀態,看看會出現什么行為。
    • 為蘭頓的螞蟻實現維基百科文章中建議的一些想法。

    探索程序

    試著找出下列問題的答案。嘗試對代碼進行一些修改,然后重新運行程序,看看這些修改有什么影響。

  • 如果把 149 行的print(' ', end='')改成print('.', end='')會怎么樣?
  • 如果把 106 行的ant['y'] += 1改成ant['y'] -= 1會怎么樣?
  • 如果把第 79 行的nextBoard[(ant['x'], ant['y'])] = False改成nextBoard[(ant['x'], ant['y'])] = True會怎么樣?
  • 如果把第 21 行的WIDTH -= 1改成WIDTH -= 40會怎么樣?
  • 如果把 119 行的board = nextBoard改成board = board會怎么樣?
  • 四十、黑客語

    原文:http://inventwithpython.com/bigbookpython/project40.html

    沒有比用數字替換文本中的字母更好的方法來展示您瘋狂的黑客技能了:m4d h4x0r 5k1llz!!!這個單詞程序自動將普通英語轉換成黑客語,這是最酷的在線交談方式。或者至少是在 1993 年。

    這需要一段時間來適應,但經過一些練習,你最終會流利地閱讀黑客語。比如1t email@protected]<3s 4 w|-|1le +o g37 |_|s3|) 70, b|_|+ y0u (an 3\/3nt|_|/-\lly r3a|) l33t$peak phl|_|3n+ly。黑客語可能一開始很難讀懂,但程序本身很簡單,對初學者來說很好。更多關于黑客語的信息可以在en.wikipedia.org/wiki/Leet找到。

    運行示例

    當您運行leetspeak.py時,輸出將如下所示:

    L3375P34]< (leetspeek) By Al Sweigart email@protectedEnter your leet message: > I am a leet hacker. Fear my mad skills. The 90s were over two decades ago.! @m a l33t email@protected(]<er. email@protected my m4|) $k|ll$. +h3 90s w3r3 0ver tw0 d3(ad3$ 4g0. (Copied leetspeak to clipboard.)

    工作原理

    第 36 行的charMapping變量中的字典將普通英語字符映射到黑客語字符。然而,由于可能有多個可能的黑客語字符(例如字母't'的'7'或'+'),charMapping字典中的每個值都是一個字符串列表。當創建新的黑客語字符串時,程序有 30%的機會簡單地使用原始英文消息中的字符,有 70%的機會使用黑客語字符之一。這意味著同一個英語信息有多種可能的翻譯。

    """Leetspeak, by Al Sweigart email@protected Translates English messages into l33t5p34]<. This code is available at https://nostarch.com/big-book-small-python-programming Tags: tiny, beginner, word"""import randomtry:import pyperclip # pyperclip copies text to the clipboard. except ImportError:pass # If pyperclip is not installed, do nothing. It's no big deal.def main():print('''L3375P34]< (leetspeek) By Al Sweigart email@protectedEnter your leet message:''')english = input('> ')print()leetspeak = englishToLeetspeak(english)print(leetspeak)try:# Trying to use pyperclip will raise a NameError exception if# it wasn't imported:pyperclip.copy(leetspeak)print('(Copied leetspeak to clipboard.)')except NameError:pass # Do nothing if pyperclip wasn't installed.def englishToLeetspeak(message):"""Convert the English string in message and return leetspeak."""# Make sure all the keys in `charMapping` are lowercase.charMapping = {'a': ['4', '@', '/-\\'], 'c': ['('], 'd': ['|)'], 'e': ['3'],'f': ['ph'], 'h': [']-[', '|-|'], 'i': ['1', '!', '|'], 'k': [']<'],'o': ['0'], 's': ['$', '5'], 't': ['7', '+'], 'u': ['|_|'],'v': ['\\/']}leetspeak = ''for char in message: # Check each character:# There is a 70% chance we change the character to leetspeak.if char.lower() in charMapping and random.random() <= 0.70:possibleLeetReplacements = charMapping[char.lower()]leetReplacement = random.choice(possibleLeetReplacements)leetspeak = leetspeak + leetReplacementelse:# Don't translate this character:leetspeak = leetspeak + charreturn leetspeak# If this program was run (instead of imported), run the game: if __name__ == '__main__':main()

    在輸入源代碼并運行幾次之后,嘗試對其進行實驗性的修改。你也可以自己想辦法做到以下幾點:

    • 修改charMapping字典,使其支持新的黑客語字符。
    • 添加一個功能,可以將黑客語轉換回簡單的英語。

    探索程序

    試著找出下列問題的答案。嘗試對代碼進行一些修改,然后重新運行程序,看看這些修改有什么影響。

  • 如果把 51 行的return leetspeak改成return message會怎么樣?
  • 如果把第 44 行的char.lower()改成char會怎么樣?
  • 如果把第 44 行的char.lower()改成char.upper()會怎么樣?
  • 如果把第 47 行的leetspeak = leetspeak + leetReplacement改成leetspeak = leetReplacement會怎么樣?
  • 總結

    以上是生活随笔為你收集整理的Python 小型项目大全 36~40的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。