#___________________________________________________________________
#1.py
 
# You have now seen how we defined
 
#  a Projectile class (so we could get a cannonball object), and
 
# a MSD (many-sided random die)  class, so we could toss very general die in games/gambling
 
# REVIEW, to make sure you understand class. Let's use the MSD
 
#msd.py    an n-sided die, using Python class definition
 
from random import randrange
 
# notice below how we will define a class, it's constructor (a function that initializes it), and
# its any methods.
 
# 1. How to define the class and constructor function?
 
class MSD:
 
 
    def __init__(self, n):  # self is a "special parameter" used to make whatever object you are
                                       # defining refer (point) to itself. You don't have to use the word "self"
                                       # but the convention is to use that word because other langauages
                                       # also use it, though they do not have to use it as a parameter
 
            self.n = n
            self.value = 1       #any valid value is okay for an initial value
 
#notice the word self. It helps the class refer to ITS OWN variables. These are called "instance
#   variables". The first parameter in each call, while defining the class, will always be "self".

 
#  __init__ () will give the caller an MSD object. But what can he do with it? To use this object
# he needs functions, but such functions in a class are called "methods" 
#Let's write some functions that do the kinds of things we do when we play with dice
           
 
    def roll(self):               # note that roll() throws but does not return a value
 
        self.value = randrange(1,self.n + 1)   # adding 1 because of how randrange works
                                               # calling roll is like rossing the MSD object
 
#Again, look at how we had to use "self" as the first (and in this case only) parameter.  It allows
#the die to get a random integer and store it in its own variable "self.value"
 
#The functions below are similar.

 
    def getValue(self):      # to get the face value after throwing we must call getValue()
 
        return(self.value)       #notice how we are working with the instance variables defined
                                            # in the class init function? __init__() is the CONSTRUCTOR
 
    def setValue(self, value):
 
        self.value = value      # since self always has to be there, we'll say setValue() has only
                                # one parameter which is "value"

                                # Be careful, because you can set it to any value and make instance
                                # variables nonsensical. Such functions are supposed to protect
                                # class instance variables.
 
''' instance variables + methods = attributes   [that's class terminology]'''
 
 
#____________________________________________________________________
 
# Now you know everything you need to know to define a class.  To know how to write a class
# you need to think of your application in terms of objects (i.e., projectiles, dice, airplanes, shapes).
 
 
# If you look at 3.py from Monday's lecture you will see a main() that create
# 3 MSD objects for 3 players in a simple game. This is how you will create and use objects
# in general.
 
