简体   繁体   中英

How to make a Cage Fighting Simulation with user input instead of random for Python

Here is my code so far using random to pick moves:

import time
import random

PHealth = 10
CHealth = 10

PShots = [
    "Great Body Shot To Your Opponent!", 
    "Nice Take Down!", 
    "Nice Punch!", 
    "Strong Kick!", 
    "You Have Him Pinned Against The Cage!", 
    "Excellent Counter-Shot!"
]
CShots = [
    "You Took a Shot to the Body!", 
    "You Got Taken Down!", 
    "Strong Kick Hit You!", 
    "You Took A Big Punch!", 
    "You Are Pinned Against The Cage", 
    "Counter-Shot Got Ya!"
]

for i in range(20):
    i = random.randint(0, 100)
    if i >= 51:
        print(random.choice(PShots))
        CHealth = CHealth -1
        if CHealth >= 1:
            print("Player Health", PHealth)
            print("Computer Health", CHealth)
            time.sleep(5)
    if i <= 50:
        print(random.choice(CShots))
        PHealth = PHealth -1
        if PHealth >= 1:
            print("Player Health", PHealth)
            print("Computer Health", CHealth)
            time.sleep(5)
    if CHealth < 1:
        print("What A Shot!")
        time.sleep(1)
        print("Down He Goes!")
        time.sleep(1)
        print("The Referee Has Stopped The Fight!!")
        time.sleep(1)
        print("Player Wins!!!")
        break
    if PHealth < 1:
        print("What A Shot!")
        time.sleep(1)
        print("Down You Go!")
        time.sleep(1)
        print("The Referee Has Stopped The Fight!!")
        time.sleep(1)
        print("Computer Wins!!!")
        break

Basically I'd like to understand how a player can input one move. So if a player inputs body shot it beats take down . If a player inputs kick it beats punch . If a player inputs take down it beats pinned against the cage , etc. Thinking 6-7 variations and counters.

Here is an idea of how you could implement something akin to what you seem to be looking for using a mix of classes and functions.

The following code should work with Python 3.9+ and has no additional dependencies.

First we define a Move class, instances of which need to have a name , a text_used (for when the player successfully uses the move), and a text_affected (for when move is used against the player). Each instance also stores a set of other Move objects, which it trumps, as well as a set of those it is trumped by. We have a helper method should_beat to easily define such a relationship between two moves.

class Move:
    def __init__(self, name: str, text_used: str, text_affected: str, damage: int = 1) -> None:
        self.name: str = name
        self.text_used: str = text_used
        self.text_affected: str = text_affected
        self.damage: int = damage

        self.trumps: set['Move'] = set()
        self.trumped_by: set['Move'] = set()

    def __str__(self) -> str:
        return self.name

    def should_beat(self, other_move: 'Move') -> None:
        self.trumps.add(other_move)
        other_move.trumped_by.add(self)

Next we define a Player class. Its instances have a name and an optional starting_health set to a previously defined constant by default.

A Player also has a use_move method that takes a Move object, another Player object (the opponent), and a second Move object (the move used by the opponent). That method checks which move beats which and calculates the health subtraction accordingly.

Finally, the Player object has win and lose methods that can be called to print out the win/loss statements when necessary.

class Player:
    def __init__(self, name: str, starting_health: int = DEFAULT_STARTING_HEALTH) -> None:
        self.name: str = name
        self.health: int = starting_health

    def __str__(self) -> str:
        return self.name

    def use_move(self, move: Move, vs_player: 'Player', vs_move: Move) -> None:
        if vs_move in move.trumped_by:
            self.health -= vs_move.damage
            print(vs_move.text_affected)
        elif move in vs_move.trumped_by:
            vs_player.health -= move.damage
            print(move.text_used)
        else:
            print(TEXT_NO_EFFECT)

    def win(self, vs: 'Player') -> None:
        print("What A Shot!")
        sleep(1)
        print(f"{vs} Goes Down!")
        sleep(1)
        print("The Referee Has Stopped The Fight!!")
        sleep(1)
        print(f"{self} Wins!!!")

    def lose(self, vs: 'Player') -> None:
        print("What A Shot!")
        sleep(1)
        print(f"Down You Go, {self}!")
        sleep(1)
        print("The Referee Has Stopped The Fight!!")
        sleep(1)
        print(f"{vs} Wins!!!")

Next, we want a function to define our moves and one that conveniently prints a list of moves to the terminal. Obviously you will want to expand the define_moves function to incorporate all your desired moves and their relationships. It should return a list of all your Move objects.

def define_moves() -> list[Move]:
    kick = Move("kick", "Strong Kick!", "Strong Kick Hit You!")
    punch = Move("punch", "Nice Punch!", "You Took A Big Punch!")
    ...
    kick.should_beat(punch)
    ...
    return [
        kick,
        punch,
    ]


def print_moves(moves_list: list[Move]) -> None:
    print("Available moves:")
    for i, move in enumerate(moves_list):
        print(i, "-", move.name)

Now for the fun part, we need our main fighting loop. In each iteration, we prompt the player for a number that corresponds to an index in our list of moves defined earlier. (The player may also type h to see the moves again.) We do some checks to make sure we received a valid number to get our Move object.

Then we randomly chose a move for the computer opponent out of our moves list, and call our use_move method. It does the health calculations for us. So after that we just check, if someone is done to call the appropriate win or lose method and break out of the loop. Otherwise we print the current health stats and continue.

def fight_computer(player: Player, moves_list: list[Move]) -> None:
    computer = Player(name="Computer")
    while True:
        string = input('Choose your move! (or type "h" to see available moves again)\n').strip().lower()
        if string == 'h':
            print_moves(moves_list)
            continue
        try:
            i = int(string)
        except ValueError:
            print("You need to pick a number!")
            continue
        try:
            move = moves_list[i]
        except IndexError:
            print("No move available with number", i)
            continue

        computer_move = choice(moves_list)
        print(computer, "chose", computer_move)
        player.use_move(move, vs_player=computer, vs_move=computer_move)

        if player.health < 1:
            player.lose(vs=computer)
            break
        if computer.health < 1:
            player.win(vs=computer)
            break

        print(player, "health:", player.health)
        print(computer, "health:", computer.health)
        sleep(1)

Lastly, we need a main function to put it all together, prompt the player for his name, etc.

def main() -> None:
    player_name = input("Enter your name: ").strip()
    player = Player(player_name)

    moves_list = define_moves()
    print_moves(moves_list)

    fight_computer(player, moves_list)


if __name__ == '__main__':
    main()

Don't forget to add your imports and constant definitions to the start of the module:

from random import choice
from time import sleep


DEFAULT_STARTING_HEALTH = 10
TEXT_NO_EFFECT = "Your move had no effect!"

All together, this should give you a crude version of the game you described. Try it out. Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM