」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 石頭、剪刀、布,戰鬥!

石頭、剪刀、布,戰鬥!

發佈於2024-11-08
瀏覽:307

Rock, paper, scissors, fight!

Rock, paper, scissors is a great game. Simple to grasp, yet surprisingly complex in terms of strategy. It's an ideal coding challenge to write a computer player capable of consistently winning the game. First though, we need a way to play the game.

Representing the game

We start with two players:

PLAYER1 = 1
PLAYER2 = 2

We then have three choices to play each round:

ROCK = 3
PAPER = 4
SCISSORS = 5

And a set of possible outcomes:

WIN = 6
LOSE = 7
DRAW = 8

With these symbols in place we can model the game state. That is, every possible way a round can end. Let us do this using a Python dictionary, mapping the two player choices (as a tuple) to the game outcome.

GAME_STATES = {
    (ROCK, PAPER): LOSE,
    (ROCK, SCISSORS): WIN,
    (ROCK, ROCK): DRAW
    (PAPER, SCISSORS): LOSE,
    (PAPER, ROCK): WIN,
    (PAPER, PAPER): DRAW,
    (SCISSORS, ROCK): LOSE,
    (SCISSORS, PAPER): WIN,
    (SCISSORS, SCISSORS): DRAW
}

Now we can write a simple function to play one round of the game. We are going to assume each player is an instance of a class that we will define later. For now it is enough to know how this class is called, if not how it will be implemented.

def play_round(p1, p2):
    """ Play one round of the game with the two supplied players. """
    p1_choice = p1.pick()
    p2_choice = p2.pick()
    p1_outcome = GAME_STATES[(p1_choice, p2_choice)]
    p2_outcome = GAME_STATES[(p2_choice, p1_choice)]
    p1.record((p1_choice, p2_choice, p1_outcome))
    p2.record((p2_choice, p1_choice, p2_outcome))
    winner = 0
    if p1_outcome == WIN:
        winner = PLAYER1
    elif p2_outcome == WIN:
        winner = PLAYER2
    return winner

The game round is very simple. We ask each player object to pick a choice to play. We then lookup the result for each player in the GAME_STATES dictionary. We ask each player object to record the result of the game. Finally we return the winner to the caller, or zero if there was a draw.

So what does a player look like? First we define a base class to perform some common initialisation, and recording of the game round data.

class Player:
    """ Base class for a player of the game. """
    def __init__(self, name):
        self.name = name
        self.history = []


    def pick(self):
        """Return one of the three choices: ROCK, PAPER, SCISSORS."""
        raise NotImplementedError()


    def record(self, game_details):
        """Record the details of the round."""
        self.history.append(game_details)

Next we can inherit from this class and implement our picking strategy. Here we have a player that always plays ROCK:

class AlwaysRockPlayer(Player):
    """ Player who always chooses ROCK. """
    def pick(self):
        return ROCK

Not a great strategy I'm sure you'll agree, but we start with the simplest thing we can do. Let's write a slightly more complex player for our rock steady one to go up against:

class RandomPlayer(Player):
    """ Player who always makes a random choice. """
    def pick(self):
        import random
        random.seed()
        return random.randint(ROCK, SCISSORS)

That at least gives us some variety in proceedings! It's still a very simple player though, as it ignores the game history completely. Let's pit these two players against each other in a few rounds.

>>> p1 = AlwaysRockPlayer("The Rock")
>>> p2 = RandomPlayer("Random Rick")
>>> play_round(p1, p2)
0
>>> play_round(p1, p2)
1
>>> play_round(p1, p2)
2
>>> play_round(p1, p2)
2
>>> play_round(p1, p2)
1

OK, so things are working. But to really get a feel for how they perform we need to run them for longer. Let's write a quick loop to run a 100 rounds between these two fearsome opponents:

>>> results = []
>>> for i in range(1,101):
...     results.append(play_round(p1, p2))
...     print(results[i-1], end='')
...     if i % 10 == 0:
...             print()
...
0102201112
0112202100
0121012101
1211200212
0110021121
0000120222
0102000202
2020021110
1112010101
1121020010

Better. A quick tot up of the results shows that... player 1 is the winner! Who'd have thought always playing ROCK was a viable game strategy? OK, so the rock's random opponent is a little dumb in this regard. A human player would soon spot the pattern and counter it consistently. We need better players, and a proper arena for them to duel it out in.

New Arena

The new arena will play a game over several rounds between two players. It will print the game statistics at the end, so we can easily see how well each player has performed. The new code makes use of our existing play_round function, and the code is given below:

def play_game(p1, p2, rounds=100):
    """ Play several rounds of the game, reporting statistics at the end. """
    print(f"{p1.name} vs {p2.name}")
    results = []
    for i in range(rounds):
        results.append(play_round(p1, p2))
        print(".", end="")
    p1_total = len([x for x in results if x == PLAYER1])
    p2_total = len([x for x in results if x == PLAYER2])
    no_total = len([x for x in results if x == 0])
    total = float(len(results))
    print("")
    print(f"{p1.name}: {(p1_total / total) * 100}%")
    print(f"{p2.name}: {(p2_total / total) * 100}%")
    print(f"Drawn games: {(no_total / total) * 100}%")

Let's pit our two players against each other in this new arena and see if The Rock can retain its crown.

>>> p1 = AlwaysRockPlayer("The Rock")
>>> p2 = RandomPlayer("Random Rick")
>>> play_game(p1, p2)
The Rock vs Random Rick
....................................................................................................
The Rock: 39.0%
Random Rick: 31.0%
Drawn games: 30.0%
>>>

A more even spread this time. Let's try running for a 1000 rounds and see if that makes a difference.

>>> play_game(p1, p2, 1000)
The Rock vs Random Rick
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
The Rock: 34.300000000000004%
Random Rick: 34.5%
Drawn games: 31.2%
>>>

Huh, a much more even spread. In fact this is what we should have expected. With The Rock always picking, well, ROCK, the variation we are seeing is solely down to Random Rick. If the PRNG (pseudo random number generator) in Python is any good, it'll be picking each choice roughly equally. The more rounds we play, the closer to an even split we would get.

No two ways about it, we still need a smarter player.

Remembering

We need a player that can learn from history without becoming predictable. But how to do that? Instead of picking a choice at random, the player picks an entry from its history at random. Then it plays whatever would have beaten its opponent in that round. In theory, if the opponent is playing one choice more than the others, this should give us the edge.

Let's see what that looks like in code:

class RandomHistoryPlayer(Player):
    """ Player who picks at random from historical options of their opponent. """
    BEATEN_BY = {
        ROCK: PAPER,
        PAPER: SCISSORS,
        SCISSORS: ROCK
    }

    def pick(self):
        import random
        random.seed()
        total_rounds = len(self.history)
        if total_rounds == 0:    
            choice = random.randint(ROCK, SCISSORS)
        else:
            idx = random.randint(0, len(self.history) - 1)
            opponents_choice = self.history[idx][1]
            choice = self.__class__.BEATEN_BY[opponents_choice]
        return choice

When playing the first round, we don't have any history to work from, so we fallback to playing at random.

OK, moment of truth. Hoe does it perform?

>>> p1 = RandomHistoryPlayer("Historical Henry")
>>> p2 = AlwaysRockPlayer("The Rock")
>>> play_game(p1, p2)
Historical Henry vs The Rock
....................................................................................................
Historical Henry: 99.0%
The Rock: 0.0%
Drawn games: 1.0%
>>>

It obliterates The Rock. With the exception of the random choice it makes first round, it won every other game. How does it perform against Random Rick?

>>> p1 = RandomHistoryPlayer("Historic Henry")
>>> p2 = RandomPlayer("Random Rick")
>>> play_game(p1, p2)
Historic Henry vs Random Rick
....................................................................................................
Historic Henry: 32.0%
Random Rick: 41.0%
Drawn games: 27.0%
>>>

Oh dear. Best of three? So it fails against a purely random opponent. Surely we can do better?

Forgetting

The trouble with remembering everything is you can get stuck in old ways of thinking. We humans have learnt to forget, or at least discount, things that happened in the dim distant past. What we need is a way to weight the historical results, so that more recent games have a greater influence. Yes, that ought to do it. I'm sure this will give us the intelligent player we seek.

class WeightedHistoryPlayer(Player):
    """ Computer player that linearly weights the past opponents choices. """
    BEATEN_BY = {
        ROCK: PAPER,
        PAPER: SCISSORS,
        SCISSORS: ROCK
    }


    def pick(self):
        import random
        random.seed()
        total_rounds = len(self.history)
        if total_rounds == 0:
            choice = random.randint(ROCK, SCISSORS)
        else:
            weighted_outcomes = [(i / total_rounds, o) for i, o in enumerate(self.history)]
            totals = { ROCK: 0, PAPER: 0, SCISSORS: 0 }
            totals[ROCK] = sum([w for (w,o) in weighted_outcomes if o[1] == ROCK])
            totals[PAPER] = sum([w for (w,o) in weighted_outcomes if o[1] == PAPER])
            totals[SCISSORS] = sum([w for (w,o) in weighted_outcomes if o[1] == SCISSORS])
            opponents_choice = max(totals, key=totals.get)
            choice = self.__class__.BEATEN_BY[opponents_choice]
        return choice

Is it better than Historical Henry?

>>> p1 = WeightedHistoryPlayer("Forgetful Fiona")
>>> p2 = RandomHistoryPlayer("Historical Henry")
>>> play_game(p1, p2)
Forgetful Fiona vs Historical Henry
....................................................................................................
Forgetful Fiona: 43.0%
Historical Henry: 43.0%
Drawn games: 14.000000000000002%
>>>

A dead heat! How about taking on the current champion Random Rick?

>>> p1 = WeightedHistoryPlayer("Forgetful Fiona")
>>> p2 = RandomPlayer("Random Rick")
>>> play_game(p1, p2)
Forgetful Fiona vs Random Rick
....................................................................................................
Forgetful Fiona: 35.0%
Random Rick: 38.0%
Drawn games: 27.0%
>>>

Drat! Random Rick still retains his crown. We need something else.

Looking for patterns

There must be a pattern in Random Rick that we can exploit. Despite his seemingly random nature, I suspect he is harbouring predictable patterns. How can we write a player to take advantage of them?

N-grams can allow us to look for recurring sequences of symbols. Think of it as a sliding window over the opponents choices. We look at n choices, and then record what the n 1 choice was. Lets show an example using trigrams (n-grams of size 3).

Sequence of opponents moves:

ROCK ROCK PAPER SCISSORS ROCK ROCK ROCK PAPER SCISSORS ROCK ROCK PAPAER

Trigrams:

    ROCK ROCK PAPER     -> SCISSORS
    ROCK PAPER SCISSORS -> ROCK
    PAPER SCISSORS ROCK -> ROCK
    SCISSORS ROCK ROCK  -> ROCK
    ROCK ROCK ROCK      -> PAPER
    ROCK ROCK PAPER     -> SCISSORS
    ROCK PAPER SCISSORS -> ROCK
    PAPER SCISSORS ROCK -> ROCK
    SCISSORS ROCK ROCK  -> PAPER

To predict the next move the opponent makes given the example above, we would look at the latest trigram in the sequence - ROCK ROCK PAPER, look it up in the list of trigrams, and see what has previously come next - SCISSORS. We would play whatever beats that choice, in this case ROCK.

Lets look at some code for this strategy:

class TrigramPlayer(Player):
    """ Computer player that uses trigrams to look for patterns in the opponents choices. """
    BEATEN_BY = {
        ROCK: PAPER,
        PAPER: SCISSORS,
        SCISSORS: ROCK
    }


    def __init__(self, id):
        super().__init__(id)
        self.trigrams = {}


    def pick(self):
        import random
        random.seed()
        total_rounds = len(self.history)
        if total_rounds  1:
                idx = random.randint(0, len(previous_choices) - 1)
                choice = previous_choices[idx]
            else:
                choice = random.randint(ROCK, SCISSORS)
        return choice


    def record(self, game_details):
        super().record(game_details)
        round_num = len(self.history)
        if round_num > 3:
            sequence = [x[1] for x in self.history]
            trigram = tuple(sequence[-4:-1])
            choice = sequence[-1]
            targets = self.trigrams.get(trigram, [])
            targets.append(choice)
            self.trigrams[trigram] = targets

We allow some randomness to creep in here:

  • When we have more than one match for our current trigram.
  • Before round 4, as there simply isn't enough data to build a trigram entry.
  • If we don't find a match in the trigram dictionary.

OK, in at the deep end. How does it perform against Random Rick?

>>> p1 = TrigramPlayer("Trigram Tracy")
>>> p2 = RandomPlayer("Random Rick")
>>> play_game(p1, p2)
Trigram Tracy vs Random Rick
....................................................................................................
Trigram Tracy: 31.0%
Random Rick: 34.0%
Drawn games: 35.0%
>>>

I give up. It seems that as far as rock, paper, scissors goes, randomness is the winning strategy.

Only human

So looking for patterns in the choices of Random Rick failed. But can Trigram Tracy find subconscious patterns in the pinnacle of intellect? Not ChatGPT, a human.

Let us write a human player class to interactively prompt for input.

class HumanPlayer(Player):
    """ Human player at a keyboard. """
    CHAR_2_INT = { "r": ROCK, "p": PAPER, "s": SCISSORS }


    def pick(self):
        choice = ""
        while choice not in ['r', 'p', 's']:
            choice = input("(r)ock, (p)aper, or (s)cissors? ")
        return self.__class__.CHAR_2_INT[choice]

Lets see who will win:

>>> p1 = HumanPlayer("Human Rob")
>>> p2 = TrigramPlayer("Trigram Tracy")
>>> play_game(p1, p2)
Human Rob vs Trigram Tracy

... cut lots of prompts for choices ...

Human Rob: 32.0%
Trigram Tracy: 32.0%
Drawn games: 36.0%

Well there you have it. I'm officially as intelligent as a short Python script when it comes to playing Rock, Paper, Scissors. Hardly a ringing endorsement of our AI either.

What have we learnt

There are a lot of possible strategies for playing rock, paper, scissors. Some simple, some more complex. We have learnt that a player picking at random can defeat a more sophisticated artificial intelligence, by virtue of being unpredictable.

Out of curiosity let's ask the font of all modern knowledge - ChatGPT - what it thinks is the best strategy to adopt for playing Rock, Paper, Scissors:

The best strategy for playing Rock, Paper, Scissors against a computer opponent is to play as randomly as possible. This is because computer programs often build strategies based on your play patterns or draw techniques from a massive database of previously recorded rounds. By picking your answer blindly, you render the program’s collected patterns about your behavior useless, and should be able to tie the machine in the long run.

Sometimes being clever is over rated!

Complete program listing

#! /usr/bin/env python3


# Players.
PLAYER1 = 1
PLAYER2 = 2


# Choices.
ROCK = 3
PAPER = 4
SCISSORS = 5


# Outcomes.
WIN = 6
LOSE = 7
DRAW = 8


# All possible game states.
GAME_STATES = {
    (ROCK, PAPER) : LOSE,
    (ROCK, SCISSORS) : WIN,
    (ROCK, ROCK) : DRAW,
    (PAPER, SCISSORS) : LOSE,
    (PAPER, ROCK) : WIN,
    (PAPER, PAPER) : DRAW,
    (SCISSORS, ROCK) : LOSE,
    (SCISSORS, PAPER) : WIN,
    (SCISSORS, SCISSORS) : DRAW
}


class Player:
    """ Base class for a player of the game. """
    def __init__(self, name):
        self.name = name
        self.history = []


    def pick(self):
        """Return one of the three choices: ROCK, PAPER, SCISSORS."""
        raise NotImplementedError()


    def record(self, game_details):
        """Record the details of the round."""
        self.history.append(game_details)


class AlwaysRockPlayer(Player):
    """ Player who always chooses ROCK. """
    def pick(self):
        return ROCK


class RandomPlayer(Player):
    """ Player who always makes a random choice. """
    def pick(self):
        import random
        random.seed()
        return random.randint(ROCK, SCISSORS)


class RandomHistoryPlayer(Player):
    """ Player who picks at random from historical options of their opponent. """
    BEATEN_BY = {
        ROCK: PAPER,
        PAPER: SCISSORS,
        SCISSORS: ROCK
    }


    def pick(self):
        import random
        random.seed()
        total_rounds = len(self.history)
        if total_rounds == 0:    
            choice = random.randint(ROCK, SCISSORS)
        else:
            idx = random.randint(0, len(self.history) - 1)
            opponents_choice = self.history[idx][1]
            choice = self.__class__.BEATEN_BY[opponents_choice]
        return choice


class WeightedHistoryPlayer(Player):
    """ Computer player that linearly weights the past opponents choices. """
    BEATEN_BY = {
        ROCK: PAPER,
        PAPER: SCISSORS,
        SCISSORS: ROCK
    }


    def pick(self):
        import random
        random.seed()
        total_rounds = len(self.history)
        if total_rounds == 0:
            choice = random.randint(ROCK, SCISSORS)
        else:
            weighted_outcomes = [(i / total_rounds, o) for i, o in enumerate(self.history)]
            totals = { ROCK: 0, PAPER: 0, SCISSORS: 0 }
            totals[ROCK] = sum([w for (w,o) in weighted_outcomes if o[1] == ROCK])
            totals[PAPER] = sum([w for (w,o) in weighted_outcomes if o[1] == PAPER])
            totals[SCISSORS] = sum([w for (w,o) in weighted_outcomes if o[1] == SCISSORS])
            opponents_choice = max(totals, key=totals.get)
            choice = self.__class__.BEATEN_BY[opponents_choice]
        return choice


class TrigramPlayer(Player):
    """ Computer player that uses trigrams to look for patterns in the opponents choices. """
    BEATEN_BY = {
        ROCK: PAPER,
        PAPER: SCISSORS,
        SCISSORS: ROCK
    }


    def __init__(self, id):
        super().__init__(id)
        self.trigrams = {}


    def pick(self):
        import random
        random.seed()
        total_rounds = len(self.history)
        if total_rounds  1:
                idx = random.randint(0, len(previous_choices) - 1)
                choice = previous_choices[idx]
            else:
                choice = random.randint(ROCK, SCISSORS)
        return choice


    def record(self, game_details):
        super().record(game_details)
        round_num = len(self.history)
        if round_num > 3:
            sequence = [x[1] for x in self.history]
            trigram = tuple(sequence[-4:-1])
            choice = sequence[-1]
            targets = self.trigrams.get(trigram, [])
            targets.append(choice)
            self.trigrams[trigram] = targets


class HumanPlayer(Player):
    """ Human player at a keyboard. """
    CHAR_2_INT = { "r": ROCK, "p": PAPER, "s": SCISSORS }


    def pick(self):
        choice = ""
        while choice not in ['r', 'p', 's']:
            choice = input("(r)ock, (p)aper, or (s)cissors? ")
        return self.__class__.CHAR_2_INT[choice]


def play_round(p1, p2):
    """ Play one round of the game with the two supplied players. """
    p1_choice = p1.pick()
    p2_choice = p2.pick()
    p1_outcome = GAME_STATES[(p1_choice, p2_choice)]
    p2_outcome = GAME_STATES[(p2_choice, p1_choice)]
    p1.record((p1_choice, p2_choice, p1_outcome))
    p2.record((p2_choice, p1_choice, p2_outcome))
    winner = 0
    if p1_outcome == WIN:
        winner = PLAYER1
    elif p2_outcome == WIN:
        winner = PLAYER2
    return winner


def play_game(p1, p2, rounds=100):
    """ Play several rounds of the game, reporting statistics at the end. """
    print(f"{p1.name} vs {p2.name}")
    results = []
    for i in range(rounds):
        results.append(play_round(p1, p2))
        print(".", end="")
    p1_total = len([x for x in results if x == PLAYER1])
    p2_total = len([x for x in results if x == PLAYER2])
    no_total = len([x for x in results if x == 0])
    total = float(len(results))
    print("")
    print(f"{p1.name}: {(p1_total / total) * 100}%")
    print(f"{p2.name}: {(p2_total / total) * 100}%")
    print(f"Drawn games: {(no_total / total) * 100}%")
版本聲明 本文轉載於:https://dev.to/robc79/rock-paper-scissors-fight-26ci?1如有侵犯,請洽[email protected]刪除
最新教學 更多>
  • 如何限制動態大小的父元素中元素的滾動範圍?
    如何限制動態大小的父元素中元素的滾動範圍?
    在交互式接口中實現垂直滾動元素的CSS高度限制,控制元素的滾動行為對於確保用戶體驗和可訪問性是必不可少的。一種這樣的方案涉及限制動態大小的父元素中元素的滾動範圍。 問題:考慮一個佈局,其中我們具有與用戶垂直滾動一起移動的可滾動地圖div,同時與固定的固定sidebar保持一致。但是,地圖的滾動無限...
    程式設計 發佈於2025-05-12
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月份)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP...
    程式設計 發佈於2025-05-12
  • 在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    mysql-python安裝錯誤:“ mysql_config找不到”“ 由於缺少MySQL開發庫而出現此錯誤。解決此問題,建議在Ubuntu上使用該分發的存儲庫。使用以下命令安裝Python-MysqldB: sudo apt-get安裝python-mysqldb sudo pip in...
    程式設計 發佈於2025-05-12
  • 反射動態實現Go接口用於RPC方法探索
    反射動態實現Go接口用於RPC方法探索
    在GO 使用反射來實現定義RPC式方法的界面。例如,考慮一個接口,例如:鍵入myService接口{ 登錄(用戶名,密碼字符串)(sessionId int,錯誤錯誤) helloworld(sessionid int)(hi String,錯誤錯誤) } 替代方案而不是依靠反射...
    程式設計 發佈於2025-05-12
  • 找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    如何在mySQL中使用mySql 檢索最大計數,您可能會遇到一個問題,您可能會在嘗試使用以下命令:理解錯誤正確找到由名稱列分組的值的最大計數,請使用以下修改後的查詢: 計數(*)為c 來自EMP1 按名稱組 c desc訂購 限制1 查詢說明 select語句提取名稱列和每個名稱...
    程式設計 發佈於2025-05-12
  • 左連接為何在右表WHERE子句過濾時像內連接?
    左連接為何在右表WHERE子句過濾時像內連接?
    左JOIN CONUNDRUM:WITCHING小時在數據庫Wizard的領域中變成內在的加入很有趣,當將c.foobar條件放置在上面的Where子句中時,據說左聯接似乎會轉換為內部連接。僅當滿足A.Foo和C.Foobar標準時,才會返回結果。 為什麼要變形?關鍵在於其中的子句。當左聯接的右側...
    程式設計 發佈於2025-05-12
  • 如何在Chrome中居中選擇框文本?
    如何在Chrome中居中選擇框文本?
    選擇框的文本對齊:局部chrome-inly-ly-ly-lyly solument 您可能希望將文本中心集中在選擇框中,以獲取優化的原因或提高可訪問性。但是,在CSS中的選擇元素中手動添加一個文本 - 對屬性可能無法正常工作。 初始嘗試 state)</option> < o...
    程式設計 發佈於2025-05-12
  • 您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    在javascript console 中顯示顏色是可以使用chrome的控制台顯示彩色文本,例如紅色的redors,for for for for錯誤消息? 回答是的,可以使用CSS將顏色添加到Chrome和Firefox中的控制台顯示的消息(版本31或更高版本)中。要實現這一目標,請使用以下...
    程式設計 發佈於2025-05-12
  • 如何在php中使用捲髮發送原始帖子請求?
    如何在php中使用捲髮發送原始帖子請求?
    如何使用php 創建請求來發送原始帖子請求,開始使用curl_init()開始初始化curl session。然後,配置以下選項: curlopt_url:請求 [要發送的原始數據指定內容類型,為原始的帖子請求指定身體的內容類型很重要。在這種情況下,它是文本/平原。要執行此操作,請使用包含以下標頭...
    程式設計 發佈於2025-05-12
  • 如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    程式設計 發佈於2025-05-12
  • Java為何無法創建泛型數組?
    Java為何無法創建泛型數組?
    通用陣列創建錯誤 arrayList [2]; JAVA報告了“通用數組創建”錯誤。為什麼不允許這樣做? 答案:Create an Auxiliary Class:public static ArrayList<myObject>[] a = new ArrayList<my...
    程式設計 發佈於2025-05-12
  • 如何實時捕獲和流媒體以進行聊天機器人命令執行?
    如何實時捕獲和流媒體以進行聊天機器人命令執行?
    在開發能夠執行命令的chatbots的領域中,實時從命令執行實時捕獲Stdout,一個常見的需求是能夠檢索和顯示標準輸出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    程式設計 發佈於2025-05-12
  • 為什麼我的CSS背景圖像出現?
    為什麼我的CSS背景圖像出現?
    故障排除:CSS背景圖像未出現 ,您的背景圖像儘管遵循教程說明,但您的背景圖像仍未加載。圖像和样式表位於相同的目錄中,但背景仍然是空白的白色帆布。 而不是不棄用的,您已經使用了CSS樣式: bockent {背景:封閉圖像文件名:背景圖:url(nickcage.jpg); 如果您的html,cs...
    程式設計 發佈於2025-05-12
  • Async Void vs. Async Task在ASP.NET中:為什麼Async Void方法有時會拋出異常?
    Async Void vs. Async Task在ASP.NET中:為什麼Async Void方法有時會拋出異常?
    在ASP.NET async void void async void void void void void的設計無需返回asynchroncon而無需返回任務對象。他們在執行過程中增加未償還操作的計數,並在完成後減少。在某些情況下,這種行為可能是有益的,例如未期望或明確預期操作結果的火災和...
    程式設計 發佈於2025-05-12

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3