Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Functions are very different from classes. It looks like you took a function and just changed the <code>def</code> to <code>class</code>. I guess that <em>mostly</em> works in your case, but it's not how classes are supposed to go.</p> <p>Classes contain functions (methods) and data. For example, you have a ball:</p> <pre><code>class Ball(object): # __init__ is a special method called whenever you try to make # an instance of a class. As you heard, it initializes the object. # Here, we'll initialize some of the data. def __init__(self): # Let's add some data to the [instance of the] class. self.position = (100, 100) self.velocity = (0, 0) # We can also add our own functions. When our ball bounces, # its vertical velocity will be negated. (no gravity here!) def bounce(self): self.velocity = (self.velocity[0], -self.velocity[1]) </code></pre> <p>Now we have a <code>Ball</code> class. How can we use it?</p> <pre><code>&gt;&gt;&gt; ball1 = Ball() &gt;&gt;&gt; ball1 &lt;Ball object at ...&gt; </code></pre> <p>It doesn't look very useful. The data is where it could be useful:</p> <pre><code>&gt;&gt;&gt; ball1.position (100, 100) &gt;&gt;&gt; ball1.velocity (0, 0) &gt;&gt;&gt; ball1.position = (200, 100) &gt;&gt;&gt; ball1.position (200, 100) </code></pre> <p>Alright, cool, but what's the advantage over a global variable? If you have another <code>Ball</code> instance, it will remain independent:</p> <pre><code>&gt;&gt;&gt; ball2 = Ball() &gt;&gt;&gt; ball2.velocity = (5, 10) &gt;&gt;&gt; ball2.position (100, 100) &gt;&gt;&gt; ball2.velocity (5, 10) </code></pre> <p>And <code>ball1</code> remains independent:</p> <pre><code>&gt;&gt;&gt; ball1.velocity (0, 0) </code></pre> <p>Now what about that <code>bounce</code> method (function in a class) we defined?</p> <pre><code>&gt;&gt;&gt; ball2.bounce() &gt;&gt;&gt; ball2.velocity (5, -10) </code></pre> <p>The <code>bounce</code> method caused it to modify the <code>velocity</code> data of itself. Again, <code>ball1</code> was not touched:</p> <pre><code>&gt;&gt;&gt; ball1.velocity </code></pre> <h1>Application</h1> <p>A ball is neat and all, but most people aren't simulating that. You're making a game. Let's think of what kinds of things we have:</p> <ul> <li><strong>A room</strong> is the most obvious thing we could have.</li> </ul> <p>So let's make a room. Rooms have names, so we'll have some data to store that:</p> <pre><code>class Room(object): # Note that we're taking an argument besides self, here. def __init__(self, name): self.name = name # Set the room's name to the name we got. </code></pre> <p>And let's make an instance of it:</p> <pre><code>&gt;&gt;&gt; white_room = Room("White Room") &gt;&gt;&gt; white_room.name 'White Room' </code></pre> <p>Spiffy. This turns out not to be all that useful if you want different rooms to have different functionality, though, so let's make a <em>subclass</em>. A <em>subclass</em> inherits all functionality from its <em>superclass</em>, but you can add more functionality or override the superclass's functionality.</p> <p>Let's think about what we want to do with rooms:</p> <blockquote class="spoiler"> <p> We want to interact with rooms.</p> </blockquote> <p>And how do we do that?</p> <blockquote class="spoiler"> <p> The user types in a line of text that gets responded to.</p> </blockquote> <p>How it's responded do depends on the room, so let's make the room handle that with a method called <code>interact</code>:</p> <pre><code>class WhiteRoom(Room): # A white room is a kind of room. def __init__(self): # All white rooms have names of 'White Room'. self.name = 'White Room' def interact(self, line): if 'test' in line: print "'Test' to you, too!" </code></pre> <p>Now let's try interacting with it:</p> <pre><code>&gt;&gt;&gt; white_room = WhiteRoom() # WhiteRoom's __init__ doesn't take an argument (even though its superclass's __init__ does; we overrode the superclass's __init__) &gt;&gt;&gt; white_room.interact('test') 'Test' to you, too! </code></pre> <p>Your original example featured moving between rooms. Let's use a global variable called <code>current_room</code> to track which room we're in.<sup>1</sup> Let's also make a red room.</p> <p><sup>1. There's better options besides global variables here, but I'm going to use one for simplicity.</sup></p> <pre><code>class RedRoom(Room): # A red room is also a kind of room. def __init__(self): self.name = 'Red Room' def interact(self, line): global current_room, white_room if 'white' in line: # We could create a new WhiteRoom, but then it # would lose its data (if it had any) after moving # out of it and into it again. current_room = white_room </code></pre> <p>Now let's try that:</p> <pre><code>&gt;&gt;&gt; red_room = RedRoom() &gt;&gt;&gt; current_room = red_room &gt;&gt;&gt; current_room.name 'Red Room' &gt;&gt;&gt; current_room.interact('go to white room') &gt;&gt;&gt; current_room.name 'White Room' </code></pre> <p><strong>Exercise for the reader:</strong> Add code to <code>WhiteRoom</code>'s <code>interact</code> that allows you to go back to the red room.</p> <p>Now that we have everything working, let's put it all together. With our new <code>name</code> data on all rooms, we can also show the current room in the prompt!</p> <pre><code>def play_game(): global current_room while True: line = raw_input(current_room.name + '&gt; ') current_room.interact(line) </code></pre> <p>You might also want to make a function to reset the game:</p> <pre><code>def reset_game(): global current_room, white_room, red_room white_room = WhiteRoom() red_room = RedRoom() current_room = white_room </code></pre> <p>Put all of the class definitions and these functions into a file and you can play it at the prompt like this (assuming they're in <code>mygame.py</code>):</p> <pre><code>&gt;&gt;&gt; import mygame &gt;&gt;&gt; mygame.reset_game() &gt;&gt;&gt; mygame.play_game() White Room&gt; test 'Test' to you, too! White Room&gt; go to red room Red Room&gt; go to white room White Room&gt; </code></pre> <p>To be able to play the game just by running the Python script, you can add this at the bottom:</p> <pre><code>def main(): reset_game() play_game() if __name__ == '__main__': # If we're running as a script... main() </code></pre> <p>And that's a basic introduction to classes and how to apply it to your situation.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload