Python 小型项目大全 41~45

news2025/9/20 8:31:51

四十一、幸运星

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

在这个碰运气游戏中,你掷骰子来收集星星。你掷得越多,你能得到的星星就越多,但是如果你得到三个头骨,你就失去了一切!这款快速多人游戏可以支持任意多的玩家,是聚会的理想选择。

在你的回合中,你从骰盅中随机抽取三个骰子并掷出它们。你可以滚动星星,头骨和问号。如果你结束你的回合,你每颗星得一分。如果你选择再次掷骰子,你保留问号,并重新掷骰子来代替星星和头骨。如果你收集到三个头骨,你将失去所有的星星并结束你的回合。

当一个玩家得到 13 分时,在游戏结束前,其他人都有一次机会。谁得分最多谁就赢。

杯子里有六个金骰子、四个银骰子和三个铜骰子。金骰子星星多,铜骰子骷髅头多,银是偶数。

运行示例

当您运行luckystars.py时,输出将如下所示:

Lucky Stars, by Al Sweigart email@protected
`--snip--`
SCORES: Alice=0, Bob=0
It is Alice's turn.

+-----------+ +-----------+ +-----------+
|           | |     .     | |           |
|           | |    ,O,    | |           |
|     ?     | | 'ooOOOoo' | |     ?     |
|           | |   `OOO`   | |           |
|           | |   O' 'O   | |           |
+-----------+ +-----------+ +-----------+
     GOLD          GOLD         BRONZE
Stars collected: 1   Skulls collected: 0
Do you want to roll again? Y/N
> y

+-----------+ +-----------+ +-----------+
|     .     | |    ___    | |           |
|    ,O,    | |   /   \   | |           |
| 'ooOOOoo' | |  |() ()|  | |     ?     |
|   `OOO`   | |   \ ^ /   | |           |
|   O' 'O   | |    VVV    | |           |
+-----------+ +-----------+ +-----------+
     GOLD         BRONZE        BRONZE
Stars collected: 2   Skulls collected: 1
Do you want to roll again? Y/N
`--snip--`

工作原理

该程序中基于文本的图形作为字符串存储在STAR_FACESKULL_FACEQUESTION_FACE变量的列表中。这种格式使它们易于在代码编辑器中编写,而第 154 到 157 行中的代码将它们显示在屏幕上。注意,因为三个骰子显示在一起,所以这段代码必须一次在骰子面上打印每一行水平文本。简单地运行像print(STAR_FACE)这样的代码会导致三个骰子出现在彼此之上,而不是并排。

"""Lucky Stars, by Al Sweigart email@protected
A "press your luck" game where you roll dice to gather as many stars
as possible. You can roll as many times as you want, but if you roll
three skulls you lose all your stars.

Inspired by the Zombie Dice game from Steve Jackson Games.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: large, game, multiplayer"""

import random

# Set up the constants:
GOLD = 'GOLD'
SILVER = 'SILVER'
BRONZE = 'BRONZE'

STAR_FACE = ["+-----------+",
            "|     .     |",
            "|    ,O,    |",
            "| 'ooOOOoo' |",
            "|   `OOO`   |",
            "|   O' 'O   |",
            "+-----------+"]
SKULL_FACE = ['+-----------+',
             '|    ___    |',
             '|   / \\ |',
             '|  |() ()|  |',
             '| \\ ^ /   |',
             '|    VVV    |',
             '+-----------+']
QUESTION_FACE = ['+-----------+',
                '|           |',
                '|           |',
                '|     ?     |',
                '|           |',
                '|           |',
                '+-----------+']
FACE_WIDTH = 13
FACE_HEIGHT = 7

print("""Lucky Stars, by Al Sweigart email@protected

A "press your luck" game where you roll dice with Stars, Skulls, and
Question Marks.

On your turn, you pull three random dice from the dice cup and roll
them. You can roll Stars, Skulls, and Question Marks. You can end your
turn and get one point per Star. If you choose to roll again, you keep
the Question Marks and pull new dice to replace the Stars and Skulls.
If you collect three Skulls, you lose all your Stars and end your turn.

When a player gets 13 points, everyone else gets one more turn before
the game ends. Whoever has the most points wins.

There are 6 Gold dice, 4 Silver dice, and 3 Bronze dice in the cup.
Gold dice have more Stars, Bronze dice have more Skulls, and Silver is
even.
""")

print('How many players are there?')
while True:  # Loop until the user enters a number.
   response = input('> ')
   if response.isdecimal() and int(response) > 1:
       numPlayers = int(response)
       break
   print('Please enter a number larger than 1.')

playerNames = []  # List of strings of player names.
playerScores = {}  # Keys are player names, values are integer scores.
for i in range(numPlayers):
   while True:  # Keep looping until a name is entered.
       print('What is player #' + str(i + 1) + '\'s name?')
       response = input('> ')
       if response != '' and response not in playerNames:
           playerNames.append(response)
           playerScores[response] = 0
           break
       print('Please enter a name.')
print()

turn = 0  # The player at playerNames[0] will go first.
# (!) Uncomment to let a player named 'Al' start with three points:
#playerScores['Al'] = 3
endGameWith = None
while True:  # Main game loop.
   # Display everyone's score:
   print()
   print('SCORES: ', end='')
   for i, name in enumerate(playerNames):
       print(name + ' = ' + str(playerScores[name]), end='')
       if i != len(playerNames) - 1:
           # All but the last player have commas separating their names.
           print(', ', end='')
   print('\n')

   # Start the number of collected stars and skulls at 0.
   stars = 0
   skulls = 0
   # A cup has 6 gold, 4 silver, and 3 bronze dice:
    cup = ([GOLD] * 6) + ([SILVER] * 4) + ([BRONZE] * 3)
    hand = []  # Your hand starts with no dice.
    print('It is ' + playerNames[turn] + '\'s turn.')
    while True:  # Each iteration of this loop is rolling the dice.
        print()

        # Check that there's enough dice left in the cup:
        if (3 - len(hand)) > len(cup):
            # End this turn because there are not enough dice:
            print('There aren\'t enough dice left in the cup to '
                + 'continue ' + playerNames[turn] + '\'s turn.')
            break

        # Pull dice from the cup until you have 3 in your hand:
        random.shuffle(cup)  # Shuffle the dice in the cup.
        while len(hand) < 3:
            hand.append(cup.pop())

        # Roll the dice:
        rollResults = []
        for dice in hand:
            roll = random.randint(1, 6)
            if dice == GOLD:
                # Roll a gold die (3 stars, 2 questions, 1 skull):
                if 1 <= roll <= 3:
                    rollResults.append(STAR_FACE)
                    stars += 1
                elif 4 <= roll <= 5:
                    rollResults.append(QUESTION_FACE)
                else:
                    rollResults.append(SKULL_FACE)
                    skulls += 1
            if dice == SILVER:
                # Roll a silver die (2 stars, 2 questions, 2 skulls):
                if 1 <= roll <= 2:
                    rollResults.append(STAR_FACE)
                    stars += 1
                elif 3 <= roll <= 4:
                    rollResults.append(QUESTION_FACE)
                else:
                    rollResults.append(SKULL_FACE)
                    skulls += 1
            if dice == BRONZE:
                # Roll a bronze die (1 star, 2 questions, 3 skulls):
                if roll == 1:
                    rollResults.append(STAR_FACE)
                    stars += 1
                elif 2 <= roll <= 4:
                    rollResults.append(QUESTION_FACE)
                else:
                    rollResults.append(SKULL_FACE)
                    skulls += 1

        # Display roll results:
        for lineNum in range(FACE_HEIGHT):
            for diceNum in range(3):
                print(rollResults[diceNum][lineNum] + ' ', end='')
            print()  # Print a newline.

        # Display the type of dice each one is (gold, silver, bronze):
        for diceType in hand:
            print(diceType.center(FACE_WIDTH) + ' ', end='')
        print()  # Print a newline.

        print('Stars collected:', stars, '  Skulls collected:', skulls)

        # Check if they've collected 3 or more skulls:
        if skulls >= 3:
            print('3 or more skulls means you\'ve lost your stars!')
            input('Press Enter to continue...')
            break

        print(playerNames[turn] + ', do you want to roll again? Y/N')
        while True:  # Keep asking the player until they enter Y or N:
            response = input('> ').upper()
            if response != '' and response[0] in ('Y', 'N'):
                break
            print('Please enter Yes or No.')

        if response.startswith('N'):
            print(playerNames[turn], 'got', stars, 'stars!')
            # Add stars to this player's point total:
            playerScores[playerNames[turn]] += stars

            # Check if they've reached 13 or more points:
            # (!) Try changing this to 5 or 50 points.
            if (endGameWith == None
                and playerScores[playerNames[turn]] >= 13):
                # Since this player reached 13 points, play one more
                # round for all other players:
                print('\n\n' + ('!' * 60))
                print(playerNames[turn] + ' has reached 13 points!!!')
                print('Everyone else will get one more turn!')
                print(('!' * 60) + '\n\n')
                endGameWith = playerNames[turn]
            input('Press Enter to continue...')
            break

        # Discard the stars and skulls, but keep the question marks:
        nextHand = []
        for i in range(3):
            if rollResults[i] == QUESTION_FACE:
                nextHand.append(hand[i])  # Keep the question marks.
        hand = nextHand

    # Move on to the next player's turn:
    turn = (turn + 1) % numPlayers

    # If the game has ended, break out of this loop:
    if endGameWith == playerNames[turn]:
        break  # End the game.

print('The game has ended...')

# Display everyone's score:
print()
print('SCORES: ', end='')
for i, name in enumerate(playerNames):
    print(name + ' = ' + str(playerScores[name]), end='')
    if i != len(playerNames) - 1:
        # All but the last player have commas separating their names.
        print(', ', end='')
print('\n')

# Find out who the winners are:
highestScore = 0
winners = []
for name, score in playerScores.items():
    if score > highestScore:
        # This player has the highest score:
        highestScore = score
        winners = [name]  # Overwrite any previous winners.
    elif score == highestScore:
        # This player is tied with the highest score.
        winners.append(name)

if len(winners) == 1:
    # There is only one winner:
    print('The winner is ' + winners[0] + '!!!')
else:
    # There are multiple tied winners:
    print('The winners are: ' + ', '.join(winners))

print('Thanks for playing!') 

在输入源代码并运行几次之后,尝试对其进行实验性的修改。标有(!)的注释对你可以做的小改变有建议。

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果删除或注释掉第 114 行的random.shuffle(cup)会发生什么?
  2. 如果把 167 行的skulls >= 3改成skulls > 3会怎么样?
  3. 如果将第 206 行的(turn + 1) % numPlayers改为(turn + 1),会得到什么错误信息?
  4. 如果把 84 行的endGameWith = None改成endGameWith = playerNames[0]会怎么样?
  5. 如果删除或注释掉第 170 行的break会怎么样?
  6. 如果把第 76 行的playerScores[response] = 0改成playerScores[response] = 10会怎么样?

四十二、魔术幸运球

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

魔术幸运球可以预测未来,并使用 Python 的随机数模块以 100%的准确率回答你的是/否问题。这个程序类似于一个魔术八球玩具,除了你不需要摇动它。它还具有缓慢打印文本字符串的功能,每个字符之间有空格,给消息一种怪异、神秘的效果。

大部分代码致力于设置诡异的气氛。程序本身简单地选择一个消息来显示,以响应一个随机数。

运行示例

当您运行magicfortuneball.py时,输出将如下所示:

M A G i C   F O R T U N E   B A L L ,   B Y   A L   S W E i G A R T

A S K   M E   Y O U R   Y E S / N O   Q U E S T i O N .

> Isn't fortune telling just a scam to trick money out of gullible people?
L E T   M E   T H i N K   O N   T H i S . . .

. . . . . . . .

i   H A V E   A N   A N S W E R . . .

A F F i R M A T i V E

工作原理

魔术幸运球实际上做的唯一事情是显示一个随机选择的字符串。完全忽略了用户的疑问。当然,第 28 行调用了input('> '),但是它没有在任何变量中存储返回值,因为程序实际上并没有使用这个文本。让用户输入他们的问题给他们一种感觉,这个程序有一种千里眼的光环。

slowSpacePrint()函数显示大写文本,任何字母I用小写,使消息看起来独特。该函数还在字符串的每个字符之间插入空格,然后缓慢显示,中间有停顿。一个程序不需要复杂到可以预测未来才有趣!

"""Magic Fortune Ball, by Al Sweigart email@protected
Ask a yes/no question about your future. Inspired by the Magic 8 Ball.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: tiny, beginner, humor"""

import random, time


def slowSpacePrint(text, interval=0.1):
    """Slowly display text with spaces in between each letter and
    lowercase letter i's."""
    for character in text:
        if character == 'I':
            # I's are displayed in lowercase for style:
            print('i ', end='', flush=True)
        else:
            # All other characters are displayed normally:
            print(character + ' ', end='', flush=True)
        time.sleep(interval)
    print()  # Print two newlines at the end.
    print()


# Prompt for a question:
slowSpacePrint('MAGIC FORTUNE BALL, BY AL SWEiGART')
time.sleep(0.5)
slowSpacePrint('ASK ME YOUR YES/NO QUESTION.')
input('> ')

# Display a brief reply:
replies = [
    'LET ME THINK ON THIS...',
    'AN INTERESTING QUESTION...',
    'HMMM... ARE YOU SURE YOU WANT TO KNOW..?',
    'DO YOU THINK SOME THINGS ARE BEST LEFT UNKNOWN..?',
    'I MIGHT TELL YOU, BUT YOU MIGHT NOT LIKE THE ANSWER...',
    'YES... NO... MAYBE... I WILL THINK ON IT...',
    'AND WHAT WILL YOU DO WHEN YOU KNOW THE ANSWER? WE SHALL SEE...',
    'I SHALL CONSULT MY VISIONS...',
    'YOU MAY WANT TO SIT DOWN FOR THIS...',
]
slowSpacePrint(random.choice(replies))

# Dramatic pause:
slowSpacePrint('.' * random.randint(4, 12), 0.7)

# Give the answer:
slowSpacePrint('I HAVE AN ANSWER...', 0.2)
time.sleep(1)
answers = [
    'YES, FOR SURE',
    'MY ANSWER IS NO',
    'ASK ME LATER',
    'I AM PROGRAMMED TO SAY YES',
    'THE STARS SAY YES, BUT I SAY NO',
    'I DUNNO MAYBE',
    'FOCUS AND ASK ONCE MORE',
    'DOUBTFUL, VERY DOUBTFUL',
    'AFFIRMATIVE',
    'YES, THOUGH YOU MAY NOT LIKE IT',
    'NO, BUT YOU MAY WISH IT WAS SO',
]
slowSpacePrint(random.choice(answers), 0.05) 

在输入源代码并运行几次之后,尝试对其进行实验性的修改。你也可以自己想办法做到以下几点:

  • 检查玩家的问题是否以问号结尾。
  • 添加程序可以给出的其他答案。

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果把第 45 行的random.randint(4, 12)改成random.randint(4, 9999)会怎么样?
  2. 如果把第 49 行的time.sleep(1)改成time.sleep(-1),会得到什么错误?

四十三、曼卡拉

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

棋盘游戏曼卡拉至少有 2000 年的历史,几乎和 63 号项目“乌尔的皇家游戏”一样古老这是一种“播种”游戏,两名玩家选择几袋种子,撒在棋盘上的其他口袋里,同时尽可能多地收集他们商店里的种子。在不同的文化中,这种游戏有几种变体。这个名字来自阿拉伯语naqala,意思是“移动”

玩的时候,从你这边的一个坑里抓种子,然后在每个坑里放一个,逆时针方向走,跳过你对手的仓库。如果你的最后一粒种子落在你的一个空坑里,将对面坑的种子移到那个坑里。如果最后放置的种子在你的商店里,你有一次免费机会。

当一个玩家的所有坑都空了时,游戏结束。另一名玩家声称剩余的种子属于他们的商店,获胜者是拥有最多种子的人。更多关于曼卡拉及其变种的信息可以在en.wikipedia.org/wiki/Mancala找到。

运行示例

当您运行mancala.py时,输出将如下所示:

Mancala, by Al Sweigart email@protected
`--snip--`

+------+------+--<<<<<-Player 2----+------+------+------+
2      |G     |H     |I     |J     |K     |L     |      1
       |   4  |   4  |   4  |   4  |   4  |   4  |
S      |      |      |      |      |      |      |      S
T   0  +------+------+------+------+------+------+   0  T
O      |A     |B     |C     |D     |E     |F     |      O
R      |   4  |   4  |   4  |   4  |   4  |   4  |      R
E      |      |      |      |      |      |      |      E
+------+------+------+-Player 1->>>>>-----+------+------+

Player 1, choose move: A-F (or QUIT)
> f

+------+------+--<<<<<-Player 2----+------+------+------+
2      |G     |H     |I     |J     |K     |L     |      1
       |   4  |   4  |   4  |   5  |   5  |   5  |
S      |      |      |      |      |      |      |      S
T   0  +------+------+------+------+------+------+   1  T
O      |A     |B     |C     |D     |E     |F     |      O
R      |   4  |   4  |   4  |   4  |   4  |   0  |      R
E      |      |      |      |      |      |      |      E
+------+------+------+-Player 1->>>>>-----+------+------+
Player 2, choose move: G-L (or QUIT)
`--snip--`

工作原理

Mancala 使用 ASCII 艺术画来显示棋盘。请注意,每个口袋不仅需要有种子的数量,还需要有一个标签。为了避免混淆,标签上使用了从AL的字母,这样就不会被误认为是每个口袋里的种子数量。字典NEXT_PITOPPOSITE_PIT分别将一个口袋的字母映射到它旁边或对面的坑的字母。这使得表达式NEXT_PIT['A']计算为'B',表达式OPPOSITE_PIT['A']计算为'G'。注意代码是如何使用这些字典的。没有它们,我们的 Mancala 程序将需要一长串的ifelif语句来执行相同的游戏步骤。

"""Mancala, by Al Sweigart email@protected
The ancient seed-sowing game.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: large, board game, game, two-player"""

import sys

# A tuple of the player's pits:
PLAYER_1_PITS = ('A', 'B', 'C', 'D', 'E', 'F')
PLAYER_2_PITS = ('G', 'H', 'I', 'J', 'K', 'L')

# A dictionary whose keys are pits and values are opposite pit:
OPPOSITE_PIT = {'A': 'G', 'B': 'H', 'C': 'I', 'D': 'J', 'E': 'K',
                  'F': 'L', 'G': 'A', 'H': 'B', 'I': 'C', 'J': 'D',
                  'K': 'E', 'L': 'F'}

# A dictionary whose keys are pits and values are the next pit in order:
NEXT_PIT = {'A': 'B', 'B': 'C', 'C': 'D', 'D': 'E', 'E': 'F', 'F': '1',
           '1': 'L', 'L': 'K', 'K': 'J', 'J': 'I', 'I': 'H', 'H': 'G',
           'G': '2', '2': 'A'}

# Every pit label, in counterclockwise order starting with A:
PIT_LABELS = 'ABCDEF1LKJIHG2'

# How many seeds are in each pit at the start of a new game:
STARTING_NUMBER_OF_SEEDS = 4  # (!) Try changing this to 1 or 10.


def main():
   print('''Mancala, by Al Sweigart email@protected

The ancient two-player, seed-sowing game. Grab the seeds from a pit on
your side and place one in each following pit, going counterclockwise
and skipping your opponent's store. If your last seed lands in an empty
pit of yours, move the opposite pit's seeds into your store. The
goal is to get the most seeds in your store on the side of the board.
If the last placed seed is in your store, you get a free turn.

The game ends when all of one player's pits are empty. The other player
claims the remaining seeds for their store, and the winner is the one
with the most seeds.

More info at https://en.wikipedia.org/wiki/Mancala
''')
   input('Press Enter to begin...')

   gameBoard = getNewBoard()
   playerTurn = '1'  # Player 1 goes first.

   while True:  # Run a player's turn.
       # "Clear" the screen by printing many newlines, so the old
       # board isn't visible anymore.
       print('\n' * 60)
       # Display board and get the player's move:
       displayBoard(gameBoard)
       playerMove = askForPlayerMove(playerTurn, gameBoard)

       # Carry out the player's move:
       playerTurn = makeMove(gameBoard, playerTurn, playerMove)

       # Check if the game ended and a player has won:
       winner = checkForWinner(gameBoard)
       if winner == '1' or winner == '2':
           displayBoard(gameBoard)  # Display the board one last time.
           print('Player ' + winner + ' has won!')
           sys.exit()
       elif winner == 'tie':
           displayBoard(gameBoard)  # Display the board one last time.
           print('There is a tie!')
           sys.exit()


def getNewBoard():
   """Return a dictionary representing a Mancala board in the starting
   state: 4 seeds in each pit and 0 in the stores."""

   # Syntactic sugar - Use a shorter variable name:
   s = STARTING_NUMBER_OF_SEEDS

   # Create the data structure for the board, with 0 seeds in the
   # stores and the starting number of seeds in the pits:
   return {'1': 0, '2': 0, 'A': s, 'B': s, 'C': s, 'D': s, 'E': s,
           'F': s, 'G': s, 'H': s, 'I': s, 'J': s, 'K': s, 'L': s}


def displayBoard(board):
   """Displays the game board as ASCII-art based on the board
   dictionary."""

   seedAmounts = []
   # This 'GHIJKL21ABCDEF' string is the order of the pits left to
   # right and top to bottom:
   for pit in 'GHIJKL21ABCDEF':
       numSeedsInThisPit = str(board[pit]).rjust(2)
       seedAmounts.append(numSeedsInThisPit)

   print("""
+------+------+--<<<<<-Player 2----+------+------+------+
2      |G     |H     |I     |J     |K     |L     |      1
| {} | {} | {} | {} | {} | {} |
S      |      |      |      |      |      |      |      S
T {} +------+------+------+------+------+------+ {} T
O      |A     |B     |C     |D     |E     |F     |      O
R      | {} | {} | {} | {} | {} | {} |      R
E      |      |      |      |      |      |      |      E
+------+------+------+-Player 1->>>>>-----+------+------+

""".format(*seedAmounts))


def askForPlayerMove(playerTurn, board):
    """Asks the player which pit on their side of the board they
    select to sow seeds from. Returns the uppercase letter label of the
    selected pit as a string."""

    while True:  # Keep asking the player until they enter a valid move.
        # Ask the player to select a pit on their side:
        if playerTurn == '1':
            print('Player 1, choose move: A-F (or QUIT)')
        elif playerTurn == '2':
            print('Player 2, choose move: G-L (or QUIT)')
        response = input('> ').upper().strip()

        # Check if the player wants to quit:
        if response == 'QUIT':
            print('Thanks for playing!')
            sys.exit()

        # Make sure it is a valid pit to select:
        if (playerTurn == '1' and response not in PLAYER_1_PITS) or (
            playerTurn == '2' and response not in PLAYER_2_PITS
        ):
            print('Please pick a letter on your side of the board.')
            continue  # Ask player again for their move.
        if board.get(response) == 0:
            print('Please pick a non-empty pit.')
            continue  # Ask player again for their move.
        return response


def makeMove(board, playerTurn, pit):
    """Modify the board data structure so that the player 1 or 2 in
    turn selected pit as their pit to sow seeds from. Returns either
    '1' or '2' for whose turn it is next."""

    seedsToSow = board[pit]  # Get number of seeds from selected pit.
    board[pit] = 0  # Empty out the selected pit.

    while seedsToSow > 0:  # Continue sowing until we have no more seeds.
        pit = NEXT_PIT[pit]  # Move on to the next pit.
        if (playerTurn == '1' and pit == '2') or (
            playerTurn == '2' and pit == '1'
        ):
            continue  # Skip opponent's store.
        board[pit] += 1
        seedsToSow -= 1

    # If the last seed went into the player's store, they go again.
    if (pit == playerTurn == '1') or (pit == playerTurn == '2'):
        # The last seed landed in the player's store; take another turn.
        return playerTurn

    # Check if last seed was in an empty pit; take opposite pit's seeds.
    if playerTurn == '1' and pit in PLAYER_1_PITS and board[pit] == 1:
        oppositePit = OPPOSITE_PIT[pit]
        board['1'] += board[oppositePit]
        board[oppositePit] = 0
    elif playerTurn == '2' and pit in PLAYER_2_PITS and board[pit] == 1:
        oppositePit = OPPOSITE_PIT[pit]
        board['2'] += board[oppositePit]
        board[oppositePit] = 0

    # Return the other player as the next player:
    if playerTurn == '1':
        return '2'
    elif playerTurn == '2':
        return '1'


def checkForWinner(board):
    """Looks at board and returns either '1' or '2' if there is a
    winner or 'tie' or 'no winner' if there isn't. The game ends when a
    player's pits are all empty; the other player claims the remaining
    seeds for their store. The winner is whoever has the most seeds."""

    player1Total = board['A'] + board['B'] + board['C']
    player1Total += board['D'] + board['E'] + board['F']
    player2Total = board['G'] + board['H'] + board['I']
    player2Total += board['J'] + board['K'] + board['L']

    if player1Total == 0:
        # Player 2 gets all the remaining seeds on their side:
        board['2'] += player2Total
        for pit in PLAYER_2_PITS:
            board[pit] = 0  # Set all pits to 0.
    elif player2Total == 0:
        # Player 1 gets all the remaining seeds on their side:
        board['1'] += player1Total
        for pit in PLAYER_1_PITS:
            board[pit] = 0  # Set all pits to 0.
    else:
        return 'no winner'  # No one has won yet.

    # Game is over, find player with largest score.
    if board['1'] > board['2']:
        return '1'
    elif board['2'] > board['1']:
        return '2'
    else:
        return 'tie'


# If the program is run (instead of imported), run the game:
if __name__ == '__main__':
    main() 

在输入源代码并运行几次之后,尝试对其进行实验性的修改。你也可以自己想办法做到以下几点:

  • 换个板多点坑。
  • 随机选择一个奖励坑,当最后一粒种子落在坑中时,让玩家进行另一轮游戏。
  • 为四个玩家而不是两个玩家创建一个正方形的棋盘。

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果把 175 行的return '2'改成return '1'会怎么样?
  2. 如果把 208 行的return '2'改成return '1'会怎么样?
  3. 如果把 125 行的response == 'QUIT'改成response == 'quit'会怎么样?
  4. 如果把 147 行的board[pit] = 0改成board[pit] = 1会怎么样?
  5. 如果把 53 行的print('\n' * 60)改成print('\n' * 0)会怎么样?
  6. 如果把第 48 行的playerTurn = '1'改成playerTurn = '2'会怎么样?
  7. 如果把 135 行的board.get(response) == 0改成board.get(response) == -1会怎么样?

四十四、迷宫逃亡者 2D

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

这个二维迷宫向导向玩家展示了你在文本编辑器中创建的迷宫文件的俯视鸟瞰图,比如你用来编写.py文件的 IDE。使用WASD键,玩家可以分别向上、向左、向下和向右移动,将@符号导向由X字符标记的出口。

要创建一个迷宫文件,打开一个文本编辑器并创建以下模式。不要沿着顶部和左侧键入数字;它们仅供参考:

 123456789
1#########
2#S# # # #
3##**#**#**#**#**#**##
4# # # # #
5##**#**#**#**#**#**##
6# # # # #
7##**#**#**#**#**#**##
8# # # #E#
9#########

#字符代表墙壁,S标记起点,E标记出口。粗体的#字符代表您可以移除以形成迷宫的墙壁。奇数列和奇数行的墙不要拆,迷宫的边界不要拆。完成后,将迷宫保存为txt(文本)文件。它可能看起来像这样:

#########
#S    # #
# ### # #
# #   # #
# ##### #
#   #   #
### # # #
#     #E#
#########

当然,这是一个简单的迷宫。您可以创建任意大小的迷宫文件,只要它们的行数和列数为奇数。但是,请确保它仍然适合屏幕!你也可以从invpy.com/mazes下载迷宫文件。

运行示例

当您运行mazerunner2d.py时,输出将如下所示:

Maze Runner 2D, by Al Sweigart email@protected

(Maze files are generated by mazemakerrec.py)
Enter the filename of the maze (or LIST or QUIT):
> maze65x11s1.txt
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░@░     ░       ░               ░                       ░   ░   ░
░ ░░░░░ ░ ░░░ ░ ░ ░░░░░░░ ░░░░░ ░░░░░░░░░░░░░░░░░░░░░ ░░░ ░ ░ ░ ░
░ ░   ░     ░ ░ ░   ░   ░     ░   ░           ░     ░   ░ ░   ░ ░
░ ░ ░ ░░░░░ ░ ░ ░░░░░ ░ ░░░░░ ░░░ ░ ░░░░░░░░░ ░ ░░░ ░░░ ░ ░░░░░ ░
░   ░     ░ ░ ░   ░   ░       ░ ░   ░       ░ ░ ░ ░   ░   ░     ░
░░░░░░░░░ ░░░ ░░░ ░ ░░░░░░░░░░░ ░░░░░ ░ ░░░░░ ░ ░ ░░░ ░░░░░ ░░░░░
░ ░     ░ ░   ░ ░ ░ ░           ░     ░       ░ ░     ░   ░     ░
░ ░ ░ ░░░ ░ ░░░ ░ ░ ░ ░░░░░░░░░░░ ░░░░░░░░░░░░░ ░ ░░░░░ ░ ░░░░░ ░
░   ░       ░       ░                           ░       ░      X░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
                           W
Enter direction, or QUIT: ASD
`--snip--`

工作原理

该程序从一个文本文件中加载迷宫墙壁的数据,并将其加载到存储在maze变量中的字典中。这个字典有用于键的(x, y)元组和用于值的WALLEMPTYSTARTEXIT常量中的字符串。项目 45“迷宫逃亡者 3D”使用了类似的迷宫字典表示。这两个项目的区别在于在屏幕上呈现迷宫的代码。由于迷宫逃亡者 2D 更简单,我推荐在进入迷宫逃亡者 3D 之前先熟悉这个程序。

"""Maze Runner 2D, by Al Sweigart email@protected
Move around a maze and try to escape. Maze files are generated by
mazemakerrec.py.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: large, game, maze"""

import sys, os

# Maze file constants:
WALL = '#'
EMPTY = ' '
START = 'S'
EXIT = 'E'

PLAYER = '@'  # (!) Try changing this to '+' or 'o'.
BLOCK = chr(9617)  # Character 9617 is '░'


def displayMaze(maze):
   # Display the maze:
   for y in range(HEIGHT):
       for x in range(WIDTH):
           if (x, y) == (playerx, playery):
               print(PLAYER, end='')
           elif (x, y) == (exitx, exity):
               print('X', end='')
           elif maze[(x, y)] == WALL:
               print(BLOCK, end='')
           else:
               print(maze[(x, y)], end='')
       print()  # Print a newline after printing the row.


print('''Maze Runner 2D, by Al Sweigart email@protected

(Maze files are generated by mazemakerrec.py)''')

# Get the maze file's filename from the user:
while True:
   print('Enter the filename of the maze (or LIST or QUIT):')
   filename = input('> ')

   # List all the maze files in the current folder:
   if filename.upper() == 'LIST':
       print('Maze files found in', os.getcwd())
       for fileInCurrentFolder in os.listdir():
           if (fileInCurrentFolder.startswith('maze') and
           fileInCurrentFolder.endswith('.txt')):
               print('  ', fileInCurrentFolder)
       continue

   if filename.upper() == 'QUIT':
       sys.exit()

   if os.path.exists(filename):
       break
   print('There is no file named', filename)

# Load the maze from a file:
mazeFile = open(filename)
maze = {}
lines = mazeFile.readlines()
playerx = None
playery = None
exitx = None
exity = None
y = 0
for line in lines:
   WIDTH = len(line.rstrip())
   for x, character in enumerate(line.rstrip()):
       assert character in (WALL, EMPTY, START, EXIT), 'Invalid character at column {}, line {}'.format(x + 1, y + 1)
       if character in (WALL, EMPTY):
           maze[(x, y)] = character
       elif character == START:
           playerx, playery = x, y
           maze[(x, y)] = EMPTY
       elif character == EXIT:
           exitx, exity = x, y
           maze[(x, y)] = EMPTY
   y += 1
HEIGHT = y

assert playerx != None and playery != None, 'No start in maze file.'
assert exitx != None and exity != None, 'No exit in maze file.'

while True:  # Main game loop.
   displayMaze(maze)

   while True:  # Get user move.
       print('                           W')
       print('Enter direction, or QUIT: ASD')
       move = input('> ').upper()

       if move == 'QUIT':
           print('Thanks for playing!')
           sys.exit()

       if move not in ['W', 'A', 'S', 'D']:
           print('Invalid direction. Enter one of W, A, S, or D.')
            continue

        # Check if the player can move in that direction:
        if move == 'W' and maze[(playerx, playery - 1)] == EMPTY:
            break
        elif move == 'S' and maze[(playerx, playery + 1)] == EMPTY:
            break
        elif move == 'A' and maze[(playerx - 1, playery)] == EMPTY:
            break
        elif move == 'D' and maze[(playerx + 1, playery)] == EMPTY:
            break

        print('You cannot move in that direction.')

    # Keep moving in this direction until you encounter a branch point.
    if move == 'W':
        while True:
            playery -= 1
            if (playerx, playery) == (exitx, exity):
                break
            if maze[(playerx, playery - 1)] == WALL:
                break  # Break if we've hit a wall.
            if (maze[(playerx - 1, playery)] == EMPTY
                or maze[(playerx + 1, playery)] == EMPTY):
                break  # Break if we've reached a branch point.
    elif move == 'S':
        while True:
            playery += 1
            if (playerx, playery) == (exitx, exity):
                break
            if maze[(playerx, playery + 1)] == WALL:
                break  # Break if we've hit a wall.
            if (maze[(playerx - 1, playery)] == EMPTY
                or maze[(playerx + 1, playery)] == EMPTY):
                break  # Break if we've reached a branch point.
    elif move == 'A':
        while True:
            playerx -= 1
            if (playerx, playery) == (exitx, exity):
                break
            if maze[(playerx - 1, playery)] == WALL:
                break  # Break if we've hit a wall.
            if (maze[(playerx, playery - 1)] == EMPTY
                or maze[(playerx, playery + 1)] == EMPTY):
                break  # Break if we've reached a branch point.
    elif move == 'D':
        while True:
            playerx += 1
            if (playerx, playery) == (exitx, exity):
                break
            if maze[(playerx + 1, playery)] == WALL:
                break  # Break if we've hit a wall.
            if (maze[(playerx, playery - 1)] == EMPTY
                or maze[(playerx, playery + 1)] == EMPTY):
                break  # Break if we've reached a branch point.

    if (playerx, playery) == (exitx, exity):
        displayMaze(maze)
        print('You have reached the exit! Good job!')
        print('Thanks for playing!')
        sys.exit() 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果将第 74 行的character == START改为character == EXIT,会得到什么错误信息?
  2. 如果把 105 行的playery + 1改成playery – 1会怎么样?
  3. 如果把 156 行的(exitx, exity)改成(None, None)会怎么样?
  4. 如果将第 89 行的while True:改为while False:,会得到什么错误信息?
  5. 如果把 104 行的break改成continue会怎么样?
  6. 如果将第 121 行的break改为continue,会得到什么错误信息?

四十五、迷宫逃亡者 3D

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

这款三维迷宫游戏为玩家提供了第一人称视角的迷宫。试着找到你的出路!你可以按照项目 44“迷宫逃亡者 2D”中的说明生成迷宫文件,或者从invpy.com/mazes下载迷宫文件。

运行示例

当您运行mazerunner3d.py时,输出将如下所示:

Maze Runner 3D, by Al Sweigart email@protected
(Maze files are generated by mazemakerrec.py)
Enter the filename of the maze (or LIST or QUIT):
> maze75x11s1.txt
░░░░░░░░░░░░░░░░░░░
░  \           /  ░
░   \_________/   ░
░    |       |    ░
░    |       |    ░
░    |       |    ░
░    |       |    ░
░    |       |    ░
░    |       |    ░
░    |       |    ░
░    |       |    ░
░    |_______|    ░
░   /         \   ░
░  /           \  ░
░░░░░░░░░░░░░░░░░░░
Location (1, 1)  Direction: NORTH
                   (W)
Enter direction: (A) (D)  or QUIT.
> d
░░░░░░░░░░░░░░░░░░░
░  \              ░
░   \_____________░
░    |            ░
░    |            ░
░    |            ░
░    |            ░
░    |            ░
░    |            ░
░    |            ░
░    |            ░
░    |____________░
░   /             ░
░  /              ░
░░░░░░░░░░░░░░░░░░░
Location (1, 1)  Direction: EAST
`--snip--`

工作原理

这个 3D 透视 ASCII 艺术画从存储在ALL_OPEN中的多行字符串开始。该字符串描述了没有路径被墙封闭的位置。然后,程序在ALL_OPEN字符串的顶部绘制存储在CLOSED字典中的墙,为封闭路径的任何可能组合生成 ASCII 艺术画。例如,下面是程序如何生成视图,其中墙在玩家的左边:

 \               \
____         ____            \_              \_        ____
   |\       /|                |               |       /|
   ||       ||                |               |       ||
   ||__   __||                |               |__   __||
   || |\ /| ||                |               | |\ /| ||
   || | X | ||        +       |       =       | | X | ||
   || |/ \| ||                |               | |/ \| ||
   ||_/   \_||                |               |_/   \_||
   ||       ||                |               |       ||
___|/       \|___             |               |       \|___
                             /               /
                            /               /

在显示字符串之前,源代码中 ASCII 字符中的句点会被删除;它们的存在只是为了使输入代码更容易,所以你不要插入或遗漏空格。

这是 3D 迷宫的源代码:

"""Maze 3D, by Al Sweigart email@protected
Move around a maze and try to escape... in 3D!
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: extra-large, artistic, maze, game"""

import copy, sys, os

# Set up the constants:
WALL = '#'
EMPTY = ' '
START = 'S'
EXIT = 'E'
BLOCK = chr(9617)  # Character 9617 is '░'
NORTH = 'NORTH'
SOUTH = 'SOUTH'
EAST = 'EAST'
WEST = 'WEST'


def wallStrToWallDict(wallStr):
   """Takes a string representation of a wall drawing (like those in
   ALL_OPEN or CLOSED) and returns a representation in a dictionary
   with (x, y) tuples as keys and single-character strings of the
   character to draw at that x, y location."""
   wallDict = {}
   height = 0
   width = 0
   for y, line in enumerate(wallStr.splitlines()):
       if y > height:
           height = y
       for x, character in enumerate(line):
           if x > width:
               width = x
           wallDict[(x, y)] = character
   wallDict['height'] = height + 1
   wallDict['width'] = width + 1
   return wallDict

EXIT_DICT = {(0, 0): 'E', (1, 0): 'X', (2, 0): 'I',
            (3, 0): 'T', 'height': 1, 'width': 4}

# The way we create the strings to display is by converting the pictures
# in these multiline strings to dictionaries using wallStrToWallDict().
# Then we compose the wall for the player's location and direction by
# "pasting" the wall dictionaries in CLOSED on top of the wall dictionary
# in ALL_OPEN.

ALL_OPEN = wallStrToWallDict(r'''
.................
____.........____
...|\......./|...
...||.......||...
...||__...__||...
...||.|\./|.||...
...||.|.X.|.||...
...||.|/.\|.||...
...||_/...\_||...
...||.......||...
___|/.......\|___
.................
.................'''.strip())
# The strip() call is used to remove the newline
# at the start of this multiline string.

CLOSED = {}
CLOSED['A'] = wallStrToWallDict(r'''
_____
.....
.....
.....
_____'''.strip()) # Paste to 6, 4.

CLOSED['B'] = wallStrToWallDict(r'''
.\.
..\
...
...
...
../
./.'''.strip()) # Paste to 4, 3.

CLOSED['C'] = wallStrToWallDict(r'''
___________
...........
...........
...........
...........
...........
...........
...........
...........
___________'''.strip()) # Paste to 3, 1.

CLOSED['D'] = wallStrToWallDict(r'''
./.
/..
...
...
...
\..
.\.'''.strip()) # Paste to 10, 3.

CLOSED['E'] = wallStrToWallDict(r'''
..\..
...\_
....|
....|
....|
....|
....|
....|
....|
....|
....|
.../.
../..'''.strip()) # Paste to 0, 0.

CLOSED['F'] = wallStrToWallDict(r'''
../..
_/...
|....
|....
|....
|....
|....
|....
|....
|....
|....
.\...
..\..'''.strip()) # Paste to 12, 0.

def displayWallDict(wallDict):
    """Display a wall dictionary, as returned by wallStrToWallDict(), on
    the screen."""
    print(BLOCK * (wallDict['width'] + 2))
    for y in range(wallDict['height']):
        print(BLOCK, end='')
        for x in range(wallDict['width']):
            wall = wallDict[(x, y)]
            if wall == '.':
                wall = ' '
            print(wall, end='')
        print(BLOCK)  # Print block with a newline.
    print(BLOCK * (wallDict['width'] + 2))


def pasteWallDict(srcWallDict, dstWallDict, left, top):
    """Copy the wall representation dictionary in srcWallDict on top of
    the one in dstWallDict, offset to the position given by left, top."""
    dstWallDict = copy.copy(dstWallDict)
    for x in range(srcWallDict['width']):
        for y in range(srcWallDict['height']):
            dstWallDict[(x + left, y + top)] = srcWallDict[(x, y)]
    return dstWallDict


def makeWallDict(maze, playerx, playery, playerDirection, exitx, exity):
    """From the player's position and direction in the maze (which has
    an exit at exitx, exity), create the wall representation dictionary
    by pasting wall dictionaries on top of ALL_OPEN, then return it."""

    # The A-F "sections" (which are relative to the player's direction)
    # determine which walls in the maze we check to see if we need to
    # paste them over the wall representation dictionary we're creating.

    if playerDirection == NORTH:
        # Map of the sections, relative  A
        # to the player @:              BCD (Player facing north)
        #                               email@protected
        offsets = (('A', 0, -2), ('B', -1, -1), ('C', 0, -1),
                   ('D', 1, -1), ('E', -1, 0), ('F', 1, 0))
    if playerDirection == SOUTH:
        # Map of the sections, relative email@protected
        # to the player @:              DCB (Player facing south)
        #                                A
        offsets = (('A', 0, 2), ('B', 1, 1), ('C', 0, 1),
                   ('D', -1, 1), ('E', 1, 0), ('F', -1, 0))
    if playerDirection == EAST:
        # Map of the sections, relative EB
        # to the player @:              @CA (Player facing east)
        #                               FD
        offsets = (('A', 2, 0), ('B', 1, -1), ('C', 1, 0),
                   ('D', 1, 1), ('E', 0, -1), ('F', 0, 1))
    if playerDirection == WEST:
        # Map of the sections, relative  DF
        # to the player @:              email@protected (Player facing west)
        #                                BE
        offsets = (('A', -2, 0), ('B', -1, 1), ('C', -1, 0),
                   ('D', -1, -1), ('E', 0, 1), ('F', 0, -1))

    section = {}
    for sec, xOff, yOff in offsets:
        section[sec] = maze.get((playerx + xOff, playery + yOff), WALL)
        if (playerx + xOff, playery + yOff) == (exitx, exity):
            section[sec] = EXIT

    wallDict = copy.copy(ALL_OPEN)
    PASTE_CLOSED_TO = {'A': (6, 4), 'B': (4, 3), 'C': (3, 1),
                       'D': (10, 3), 'E': (0, 0), 'F': (12, 0)}
    for sec in 'ABDCEF':
        if section[sec] == WALL:
            wallDict = pasteWallDict(CLOSED[sec], wallDict,
                PASTE_CLOSED_TO[sec][0], PASTE_CLOSED_TO[sec][1])

    # Draw the EXIT sign if needed:
    if section['C'] == EXIT:
        wallDict = pasteWallDict(EXIT_DICT, wallDict, 7, 9)
    if section['E'] == EXIT:
        wallDict = pasteWallDict(EXIT_DICT, wallDict, 0, 11)
    if section['F'] == EXIT:
        wallDict = pasteWallDict(EXIT_DICT, wallDict, 13, 11)

    return wallDict


print('Maze Runner 3D, by Al Sweigart email@protected')
print('(Maze files are generated by mazemakerrec.py)')

# Get the maze file's filename from the user:
while True:
    print('Enter the filename of the maze (or LIST or QUIT):')
    filename = input('> ')

    # List all the maze files in the current folder:
    if filename.upper() == 'LIST':
        print('Maze files found in', os.getcwd())
        for fileInCurrentFolder in os.listdir():
            if (fileInCurrentFolder.startswith('maze')
            and fileInCurrentFolder.endswith('.txt')):
                print('  ', fileInCurrentFolder)
        continue

    if filename.upper() == 'QUIT':
        sys.exit()

    if os.path.exists(filename):
        break
    print('There is no file named', filename)

# Load the maze from a file:
mazeFile = open(filename)
maze = {}
lines = mazeFile.readlines()
px = None
py = None
exitx = None
exity = None
y = 0
for line in lines:
    WIDTH = len(line.rstrip())
    for x, character in enumerate(line.rstrip()):
        assert character in (WALL, EMPTY, START, EXIT), 'Invalid character at column {}, line {}'.format(x + 1, y + 1)
        if character in (WALL, EMPTY):
            maze[(x, y)] = character
        elif character == START:
            px, py = x, y
            maze[(x, y)] = EMPTY
        elif character == EXIT:
            exitx, exity = x, y
            maze[(x, y)] = EMPTY
    y += 1
HEIGHT = y

assert px != None and py != None, 'No start point in file.'
assert exitx != None and exity != None, 'No exit point in file.'
pDir = NORTH


while True:  # Main game loop.
    displayWallDict(makeWallDict(maze, px, py, pDir, exitx, exity))

    while True: # Get user move.
        print('Location ({}, {})  Direction: {}'.format(px, py, pDir))
        print('                   (W)')
        print('Enter direction: (A) (D)  or QUIT.')
        move = input('> ').upper()

        if move == 'QUIT':
            print('Thanks for playing!')
            sys.exit()

        if (move not in ['F', 'L', 'R', 'W', 'A', 'D']
            and not move.startswith('T')):
            print('Please enter one of F, L, or R (or W, A, D).')
            continue

        # Move the player according to their intended move:
        if move == 'F' or move == 'W':
            if pDir == NORTH and maze[(px, py - 1)] == EMPTY:
                py -= 1
                break
            if pDir == SOUTH and maze[(px, py + 1)] == EMPTY:
                py += 1
                break
            if pDir == EAST and maze[(px + 1, py)] == EMPTY:
                px += 1
                break
            if pDir == WEST and maze[(px - 1, py)] == EMPTY:
                px -= 1
                break
        elif move == 'L' or move == 'A':
            pDir = {NORTH: WEST, WEST: SOUTH,
                    SOUTH: EAST, EAST: NORTH}[pDir]
            break
        elif move == 'R' or move == 'D':
            pDir = {NORTH: EAST, EAST: SOUTH,
                    SOUTH: WEST, WEST: NORTH}[pDir]
            break
        elif move.startswith('T'):  # Cheat code: 'T x,y'
            px, py = move.split()[1].split(',')
            px = int(px)
            py = int(py)
            break
        else:
            print('You cannot move in that direction.')

    if (px, py) == (exitx, exity):
        print('You have reached the exit! Good job!')
        print('Thanks for playing!')
        sys.exit() 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果把 279 行的move == 'QUIT'改成move == 'quit'会导致什么 bug?
  2. 怎样才能解除心灵运输的欺骗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/411582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【网络编程】UDP

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;Java EE初阶&#x1f447; 目 录&#x1f3ef;一. UDP数据报套接字编程&#x1f3f0;二. 写一个 UDP 版本的 回显服务器-客户端.&#xff08;echo server&#xff09;&#x1f3ed;1. 服务器&#xff1a;&…

咖啡卷到现在,他们开始往里面掺北京豆汁了

咖啡卷到现在&#xff0c;他们开始往里面掺北京豆汁了0. 导读1. 人手一杯&#xff0c;果咖大势所趋2. 双倍成瘾&#xff1a;茶咖和酒咖被重点推荐3. 地方小吃融入咖啡&#xff0c;比如北京豆汁4. 炙手可热的云南咖啡豆5. 咖啡、户外和环保&#xff1a;绑定可持续6. 小结0. 导读…

vue - 【最新】简单快捷的 element ui 组件库的主题色更改,批量统一覆盖替换解决方法,无需npm装包。(适用于新手小白的方法,很简单)

效果图 最新解决方案,简单便捷且不用npm安装任何第三方包就能搞定。 原来的主题色是蓝色 ,可以通过本篇博客提供的方法,统一变成其他主题颜色,比如下面的紫色: 下面就是真实的运行效果,保证可行~ 这样就不用每个组件单独去写样式覆盖颜色了! 定制主

干雾抑尘系统的降尘工作原理

对于干雾抑尘系统&#xff0c;相信大家现在都不陌生&#xff0c;作为工业无组织排放粉尘治理的常用除尘产品&#xff0c;其有着传统喷雾降尘设备无法比拟的优势。今天我们就来了解下&#xff0c;干雾抑尘系统到底是什么&#xff1f;他的工作原理到底是怎样的呢&#xff1f; ​…

进程、线程、协程的区别

目录 1、什么是进程&#xff1f; 2、什么是线程&#xff1f; 3、什么是协程&#xff1f; 4、进程、线程、协程的区别 (1) 进程、线程的区别 (2) 线程、协程的区别 1、什么是进程&#xff1f; 简单来说&#xff0c;进程可以看做是加载到内存里的程序&#xff0c;实际上一…

Qt Quick - ColorDialog 颜色对话框

ColorDialog 颜色对话框使用总结一、概述二、实现的要点三、一些例子的合集1. 按钮点击修改按钮文字颜色一、概述 ColorDialog 就是Qt 提供的标准的颜色对话框。ColorDialog 允许用户选择颜色。 对话框最初是不可见的。你需要首先按需设置属性&#xff0c;然后将visible设置为…

前端 icon 方案该升级了

说到 icon&#xff0c;很多前端开发只能想到 iconfont&#xff0c;或者组件库中提供的那些图标&#xff0c;当然这对于绝大多数开发场景是够用的。 但要知道&#xff0c;iconfont 的方案其实是在 2016 年公开&#xff0c;到现在也已经有 6 年之久&#xff0c;它确实在这一段时…

【产品经理】为什么你画的流程图开发总说看不懂?

在做产品设计时&#xff0c;会碰到非常多的业务流程&#xff0c;当我们需要跟开发解释一个相对复杂的流程时&#xff0c;一个清晰的流程图&#xff0c;便非常重要了。 我们做产品设计的时候&#xff0c;会碰到非常多的业务流程&#xff0c;有简单的&#xff0c;有复杂的&#x…

「业务架构」需求工程——捕获与分析(第二部分)

从用户、客户和其他涉众那里生成系统需求的活动。可行性研究结束后&#xff0c;我们进入下一个阶段;抽取和分析。需求捕获和分析它是一个与客户和最终用户交互的过程&#xff0c;以查明领域需求、系统应该提供什么服务以及其他约束。领域需求反映了系统运行的环境&#xff0c;因…

HTML5 <del> 标签、HTML5 <dd> 标签

HTML5 <del> 标签 实例 一段带有已删除部分和新插入部分的文本&#xff1a; <p>My favorite color is <del>blue</del> <ins>red</ins>!</p> 尝试一下 浏览器支持 所有主流浏览器都支持 <del> 标签。 标签定义及使用说明 …

什么是设计模式?

文章目录01 | 概念02 | 要素03 | 分类04 | 总结“每一个模式描述了一个在我们周围不断重复发生的问题&#xff0c;以及问题的解决方案的核心。这样&#xff0c;你就能一次又一次地使用该方案而不必做重复劳动”。 设计模式的核心&#xff1a;提供了相关问题的解决方案&#xff…

机械硬盘提示格式化的常见原因|3种数据恢复方法

机械硬盘是电脑存储设备中的一种&#xff0c;它的存储容量比较大&#xff0c;通常采用机械运动的方式记录数据。 其内部结构由多个盘片和磁头组成&#xff0c;盘片层层叠放在一起并通过主轴转动&#xff0c;磁头则通过磁臂上下移动并接触盘片表面进行读写操作。但是在日常使用电…

如何用Golang处理每分钟100万个请求

用Golang处理每分钟100万个请求 转载请注明来源&#xff1a;https://janrs.com/9yaq 面临的问题 在我设计一个分析系统中&#xff0c;我们公司的目标是能够处理来自数百万个端点的大量POST请求。web 网络处理程序将收到一个JSON文档&#xff0c;其中可能包含许多有效载荷的集合…

Spring Boot基础学习之(十六):用户认证和授权

本次项目使用静态资源代码免费下载 https://download.csdn.net/download/m0_52479012/87679062?spm1001.2014.3001.5501 在日常的登录网页中&#xff0c;是怎么分辨那些用户是具有那种权限呢&#xff1f; 本次博客实现的功能是&#xff1a;哪些网页是谁有可以访问的&#xff…

进程状态概念详解!(7千字长文详解)

进程状态概念详解 文章目录进程状态概念详解进程状态为什么会有这些状态运行总结阻塞就绪/新建挂起阻塞和挂起的区别&#xff01;linux下的进程状态运行——R睡眠——S暂停——T关于号深度睡眠——D追踪暂停 ——t死亡——X僵尸——Z僵尸进程的危害总结孤儿进程——S状态进程优…

一位腾讯在职7年测试工程师的心声...

作为一个在腾讯工作7年的测试工程师&#xff0c;今天就来聊聊腾讯工作压力到底从何而来。 压力的开始&#xff1a;时间回到7年前&#xff0c;我人生中的第一份实习工作&#xff0c;是在腾讯公司做一个自动化测试工程师。当时的我可谓意气风发&#xff0c;想要大干一场&#xf…

SpringBoot 介绍

1.简介 SpringBoot最开始基于Spring4.0设计&#xff0c;是由Pivotal公司提供的框架。 SpringBoot发展史&#xff1a; 2003年Rod Johnson成立Interface公司&#xff0c;产品是SpringFramework2004年&#xff0c;Spring框架开源&#xff0c;公司改名为Spring Source2008年&…

[MAUI 项目实战] 手势控制音乐播放器(三): 动画

文章目录吸附动画确定位置平移动画回弹动画使用自定义缓动函数多重动画点击动画项目地址上一章节我们创建了手势容器控件PanContainer&#xff0c;它对拖拽物进行包装并响应了平移手势和点击手势。拖拽物现在虽然可以响应手势操作&#xff0c;但视觉效果较生硬&#xff0c;一个…

【ros2】ubuntu18.04同时安装ros1和ros2

序言 ubuntu18.04&#xff08;已安装ros melodic&#xff09;中安装ros2 dashing版本&#xff0c;以支持ros2工程的编译使用 1. 安装ros melodic 参考我之前的文章&#xff1a;docker容器中安装melodic-ros-core过程总结 2. 安装ros2 dashing &#xff08;1&#xff09;设置…

《花雕学AI》12:从ChatGPT的出现看人类与人工智能的互补关系与未来发展

马云说道&#xff0c;ChatGPT这一类技术已经对教育带来挑战&#xff0c;但是ChatGPT这一类技术只是AI时代的开始。 谷歌CEO桑德尔皮猜曾说&#xff1a;“人工智能是我们人类正在从事的最为深刻的研究方向之一&#xff0c;甚至要比火与电还更加深刻。” 360周鸿祎认为&#xf…