Python Tools — Session 7B

Advanced Classes — Car Racing and Player Combat

2020.02.20 — Session 7B

Session Navigation

Overview

Building on the class foundations from Session 7A, this session implements two complete games. The first is a car racing simulator where two Car instances race to a target distance using while loops. The second is a player combat game with health and ammo management, shooting mechanics, and probability-based ammo collection.

Key Concepts

  • While Loops — Continuous iteration that runs until a condition is met, used for game loops
  • Class Instance Properties — Tracking state like distance, health, and ammo as instance variables
  • Instance Interaction — One class instance calling methods on another (player shooting a target)
  • Random Mechanics — Using random.randint and random.random for game variability and chance
  • Game Logic — Implementing win conditions, turn-based systems, and state management
  • Resource Management — Tracking and depleting ammo, with probability-based collection mechanics

Code

notes.py — Car Racing Simulation and Player Combat Game

"""
#############################################################################
filename    session_7b.py
author      Matt Osbond 
dP email    m.osbond@digipen.edu
course      CS115
Brief Description:
    Session 7A - Thursday Feb 20th 2020
    More work on introducing classes
#############################################################################
"""

import random

"""
Small project to create a car class, create two instances, and have them "race"
"""

class Car():
    """The base car class
    """    
    def __init__(self, _name):
        """Initialize the class, and set the make and model as provided. 
        """
        self.name = _name        

        self.make = 'Nissan'
        self.model = 'Leaf'

        # Assign the starting distnace to be zero
        self.distance = 0 

    def move(self):
        """get a random distance the car can move in this iteration
        Print the value, as well as "-" multiplied by the distance
        This gives us a crude visualization in the Script Editor
        """
        self.distance += random.randint(1,10)
        print self.name, self.distance, '-' * self.distance


    

# Create  two instances of the car class so we can race them
car_1 = Car('One')
car_2 = Car('Two')

# Set the target distance
target_distance = 100

# This is a WHILE loop
# We stay inside a WHILE loop until the criteria is met
# In this case, while the distance travelled of BOTH cars is under 100
while car_1.distance < 100 and car_2.distance < 100:
    car_1.move()
    car_2.move()

    # Print the winner (car 1 gets to go first so he wins if they both are over 100)
    if car_1.distance >= target_distance:
        print 'Car', car_1.name, 'has won'
    elif car_2.distance >= target_distance:
        print 'Car', car_2.name, 'has won'

    

###########################################################
###########################################################

"""
Small "Bot" fight project
Create a PLayer class to keep track of health and ammo
Create methods to shoot, be attacked and collect ammo
Keep going until one player's health drop to zero
"""

import random

class Player():
    """Base player class
    """
    def __init__(self, name):
        """Initialize, setting the name, health and ammo
        """
        self.name = name 
        self.health = 100 
        self.ammo = 10 

    def shoot(self, target):
        """Method to call when the player shoots
        This takes the target INSTANCE as an argument
        """
        # Get a random number of shots the player can shoot
        shots_fired = random.randint(1, 4)

        # Ensure the shots never exceed the ammo count
        # Note, you can also do this using "max(shots_fired, self.ammo)"
        if shots_fired > self.ammo:
            shots_fired = self.ammo

        # Deplete the ammo supply
        self.ammo -= shots_fired

        # Trigger the target to get hit by the number of shots
        target.get_hit(shots_fired)


            
    def get_hit(self, shots):
        """ Triggered when the player gets hit
        Called from the other player
        """
        # Get a random impact from the shots fired
        impact = random.randint(0, shots)

        # Deplete the health
        self.health -= impact * 3

        # Check if we're dead
        if self.health < 0:
            print '#### %s is out! ####' %self.name


    def attack(self, target):
        """Wrapper to run on each turn
        """
        self.shoot(target)
        self.collect()

        # Print stats about the current player
        print self.name, 'Health', self.health, ('-'*self.health)
        print self.name, 'Ammo', self.ammo, ('*'*self.ammo)

    def collect(self):
        """Collect some ammo
        """
        # We don't want to collect every time, lets add some chance to it
        # random.random() gets a float between 0 and 1
        chance = random.random()
        # If above 0.2, there's an 80% chance of collecting ammo 
        if chance > 0.2:
            self.ammo += random.randint(1,4)

    
# Create two instances
player1 = Player("Player_1")   
player2 = Player("Player_2")       

# Gor for 100 turns
for i in xrange(0, 100):
    # Only continue to attck if both players are alive
    if player1.health > 0 and player2.health > 0:
        player1.attack(player2)
        player2.attack(player1)
← Prev Next →