robot_factory.py :  » IDE » RUR » rurple1.0rc3 » rur_py » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » RUR 
RUR » rurple1.0rc3 » rur_py » robot_factory.py
""" RUR-PLE: Roberge's Used Robot - a Python Learning Environment
    robot_factory.py - see description below
    Version 0.8.7
    Author: Andre Roberge    Copyright  2005, 2006
    andre.roberge@gmail.com

robot_factory includes four classes:

    Robot_brain1(), which incorporates the basic logic of the robot, including
    a limited ability to sense the outside world.

    Robot_brain2(), which incorporates an "advanced" version, capable of more
    remote sensing ability, akin to Pattis's original Karel as well as
    turning right directly.

    Used_robot() subclasses Robot_brain1 and adds a body (i.e. physical
    representation: images for visual display, time delay for execution
    of movements, etc.)

    New_improved_robot() subclasses both Used_robot (for physical display) and
    Robot_brain2 for the improved logic.
    """

import dialogs
import images
import random
from rur_py.translation import _

#---------------------------------------------------------------------------

class Robot_brain1(object):

    _directions = [ (0, 1), (-1, 0), (0, -1), (1, 0) ]
    _orient_dict = { 'E': 3, 'S': 2, 'W': 1, 'N': 0}

    def __init__(self, parent=None, avenues=1, streets=1,
                 orient_key = 'E', beepers=0):
        # East; value by default - tied to lessons
        self.parent = parent
        #--- Basic variables
        self._beeper_bag = beepers
        self._x = avenues
        self._y = streets
        self._facing = self._orient_dict[orient_key.upper()]

    #--- "public" getter
    def getPos(self):
        """ returns current robot position; intended to be
            accessed by user-defined program."""
        return self._x, self._y

    #--- "private" getters and setters
    def _setPos(self, x, y):
        """ sets robot position (teleport); intended to be
            accessed only through GUI, not by user-defined program."""
        self._x = x
        self._y = y

    def _getOrientation(self):
        """ returns orientation (0, 1, 2, 3); needed for drawing trace.
            Not intended to be accessed by user-defined program."""
        return self._facing

    def _getOrientationKey(self):
        """ returns orientation key ('N', 'E', 'S', W').
            Not intended to be accessed by user-defined program."""
        for key in self._orient_dict.keys():
            if self._orient_dict[key] == self._facing:
                return key

    def _getInfoTuple(self):
        """ returns (avenue, street, orientation, beepers).
            Not intended to be accessed by user-defined program."""
        return self._x, self._y, self._getOrientationKey(), self._beeper_bag

    def _getInfoString(self):
        """ returns (avenue, street, orientation, beepers).
            Not intended to be accessed by user-defined program."""
        return str(self._getInfoTuple())

    #--- built-in tests

    def front_is_clear(self):
        ''' True if no wall or border in front of robot'''
        col = 2*self._x - 1
        row = 2*self._y - 1
        xx, yy = self._directions[self._facing]
        return self.parent.isClear(col+xx, row+yy)

    def facing_north(self):
        ''' True if Robot facing north'''
        if self._facing == 0:
            return True
        else:
            return False

    def any_beepers_in_beeper_bag(self):
        '''True if some beepers are left in Robot's bag'''
        if self._beeper_bag == 0:
            return False
        else:
            return True

    def next_to_a_beeper(self):
        '''True if beepers are present at current robot position.'''
        if (self._x, self._y) in self.parent.beepers_dict:
            return True
        else:
            return False

    def left_is_clear(self):
        '''Returns True if no walls or borders are to the immediate left
           of the robot.'''
        col = 2*self._x - 1
        row = 2*self._y - 1
        facing = self._facing + 1
        facing %= 4
        xx, yy = self._directions[facing]
        if (col+xx, row+yy) in self.parent.walls_list:
            return False
        if (col+xx, row+yy) in self.parent.borders:
            return False
        else:
            return True

    def right_is_clear(self):
        '''Returns True if no walls or borders are to the immediate
           right of the robot.'''
        col = 2*self._x - 1
        row = 2*self._y - 1
        facing = self._facing + 3
        facing %= 4
        xx, yy = self._directions[facing]
        if (col+xx, row+yy) in self.parent.walls_list:
            return False
        if (col+xx, row+yy) in self.parent.borders:
            return False
        else:
            return True

    #--- Actions

    def move(self):
        '''Robot moves one street/avenue in direction where it is facing'''
        if self.front_is_clear():
            xx, yy = self._directions[self._facing]
            self._x += xx
            self._y += yy
        else:
            mesg = _("""That move really hurt!
Please, make sure that there is no wall in front of me!""")
            raise dialogs.HitWallException(mesg)

    def turn_off(self):
        mesg = _("I obey your command:\n turning myself off.")
        raise dialogs.NormalEnd(mesg)

    def turn_left(self):
        '''Robot turns left by 90 degrees.'''
        self._facing += 1
        self._facing %= 4

    def put_beeper(self):
        '''Robot put one beeper down at current location.'''
        if self.any_beepers_in_beeper_bag():
            self._beeper_bag -= 1
            self.parent.addOneBeeper(self._x, self._y)
        else:
            mesg = _("put_beeper() failed.\n I am not carrying any beepers.")
            raise dialogs.PutBeeperException(mesg)

    def pick_beeper(self):
        '''Robot picks one beeper up at current location.'''
        if self.next_to_a_beeper():
            self.parent.removeOneBeeper(self._x, self._y)
            self._beeper_bag += 1
        else:
            mesg = _("""pick_beeper failed.
I must be next to a beeper before I can pick it up.""")
            raise dialogs.PickBeeperException(mesg)


class Robot_brain2(Robot_brain1):
    def __init__(self, parent=None, avenues=1, streets=1, orient_key = 'E',
                 beepers=0):
        Robot_brain1.__init__(self, parent, avenues, streets,
                              orient_key, beepers)

    #--- Additional built-in tests

    def facing_east(self):
        if self._facing == 3:
            return True
        else:
            return False

    def facing_south(self):
        if self._facing == 2:
            return True
        else:
            return False

    def facing_west(self):
        if self._facing == 1:
            return True
        else:
            return False

    #--- Additional action
    def turn_right(self):
        self._facing += 3
        self._facing %= 4

    def roll_dice(self, n=6):
        return random.randint(1, n)



class Used_robot(Robot_brain1):
    """ Adds physical attributes """

    def __init__(self, avenues=1, streets=1, orient_key = 'E',
                 beepers=0, name = 'robot', colour = 'grey', parent=None):
        Robot_brain1.__init__(self, parent, avenues, streets,
                              orient_key, beepers)
        self._delay = 0.3
        self.name = name
        self.colour = colour.lower()

        # The following are used to follow the robot trail
        self.line_trace = []
        self.set_trace_style(1, "sea green")  # default

    #--- Robot images
        # create a list of four objects
        if self.colour == 'yellow':
            self._image = [images.YELLOW_ROBOT_N, images.YELLOW_ROBOT_W,
                       images.YELLOW_ROBOT_S, images.YELLOW_ROBOT_E]
        elif self.colour == 'blue':
            self._image = [images.BLUE_ROBOT_N, images.BLUE_ROBOT_W,
                       images.BLUE_ROBOT_S, images.BLUE_ROBOT_E]
        elif self.colour == 'light blue':
            self._image = [images.LIGHT_BLUE_ROBOT_N, images.LIGHT_BLUE_ROBOT_W,
                       images.LIGHT_BLUE_ROBOT_S, images.LIGHT_BLUE_ROBOT_E]
        elif self.colour == 'purple':
            self._image = [images.PURPLE_ROBOT_N, images.PURPLE_ROBOT_W,
                       images.PURPLE_ROBOT_S, images.PURPLE_ROBOT_E]
        elif self.colour == 'green':
            self._image = [images.GREEN_ROBOT_N, images.GREEN_ROBOT_W,
                       images.GREEN_ROBOT_S, images.GREEN_ROBOT_E]
        else:
            self._image = [images.GREY_ROBOT_N, images.GREY_ROBOT_W,
                       images.GREY_ROBOT_S, images.GREY_ROBOT_E]

        self.imageOffset = (12, 9)

        # image size (x, y) [all images equal]; for use in automatic scrolling
        self._image_size = self._image[0].GetWidth(), \
                           self._image[0].GetHeight()
        ## Note: for some reason, GetSize() did not work  using
        ## wxPython 2.4, which is why I used GetWidth() and GetHeight()

        # selecting the right image based on initial orientation
        self.robot_image = self._image[self._facing]

    #--- Action over-riden to handle images
    def turn_left(self):
        '''Robot turns left by 90 degrees, and image is updated.'''
        Robot_brain1.turn_left(self)
        self.robot_image = self._image[self._facing]

    def set_trace_style(self, style, colour = "sea green"):
        if style == 1:
           self.trace_offset = [(3, 3), (3, -3), (-3, -3), (-3, 3)]
           self.trace_width = 1
        elif style == 2:
           self.trace_offset = [(5, 5), (5, -5), (-5, -5), (-5, 5)]
           self.trace_width = 1
        elif style == 3:
           self.trace_offset = [(3, 3), (3, -3), (-3, -3), (-3, 3)]
           self.trace_width = 3
        elif style == 4:
           self.trace_offset = [(5, 5), (5, -5), (-5, -5), (-5, 5)]
           self.trace_width = 3
        elif style == 5:
            self.trace_offset = [(0, 0), (0, 0), (0, 0), (0, 0)]
            self.trace_width = 3
        else:
            self.trace_offset = [(0, 0), (0, 0), (0, 0), (0, 0)]
            self.trace_width = 0

        self.trace_style = style
        self.trace_colour = colour

    def get_trace_style(self, style):
        if style == 1:
           trace_offset = [(3, 3), (3, -3), (-3, -3), (-3, 3)]
           trace_width = 1
        elif style == 2:
           trace_offset = [(5, 5), (5, -5), (-5, -5), (-5, 5)]
           trace_width = 1
        elif style == 3:
           trace_offset = [(3, 3), (3, -3), (-3, -3), (-3, 3)]
           trace_width = 3
        elif style == 4:
           trace_offset = [(5, 5), (5, -5), (-5, -5), (-5, 5)]
           trace_width = 3
        elif style == 5:
            trace_offset = [(0, 0), (0, 0), (0, 0), (0, 0)]
            trace_width = 3
        else:
            trace_offset = [(0, 0), (0, 0), (0, 0), (0, 0)]
            trace_width = 0
        return trace_width, trace_offset

    def set_delay(self, delay):
        '''Sets the delay value between robot actions.'''
        if delay >= 0 and delay <= 10:
            self._delay = delay
        else:
            mesg = _("""Setting delay failed.
Accepted values are between 0 and 10.""")
            dialogs.rurMessageDialog(mesg, _("Error"))

    def get_delay(self):
        return self._delay

    delay = property(get_delay, set_delay, None, "Time between robot actions")

class New_improved_robot(Robot_brain2):
    """ Adds physical attributes and better logic."""
    def __init__(self, avenues=1, streets=1, orient_key = 'E',
                 beepers=0, name = 'robot', colour = 'grey', parent=None):
        Robot_brain2.__init__(self, parent, avenues, streets,
                              orient_key, beepers)
        self._delay = 0.3
        self.name = name
        self.colour = colour.lower()

        # The following are used to follow the robot trail
        self.line_trace = []
        self.set_trace_style(1, "sea green")  # default
    #--- Robot images
        # create a list of four objects
        if self.colour == 'yellow':
            self._image = [images.YELLOW_ROBOT_N, images.YELLOW_ROBOT_W,
                       images.YELLOW_ROBOT_S, images.YELLOW_ROBOT_E]
        elif self.colour == 'blue':
            self._image = [images.BLUE_ROBOT_N, images.BLUE_ROBOT_W,
                       images.BLUE_ROBOT_S, images.BLUE_ROBOT_E]
        elif self.colour == 'light blue':
            self._image = [images.LIGHT_BLUE_ROBOT_N, images.LIGHT_BLUE_ROBOT_W,
                       images.LIGHT_BLUE_ROBOT_S, images.LIGHT_BLUE_ROBOT_E]
        elif self.colour == 'purple':
            self._image = [images.PURPLE_ROBOT_N, images.PURPLE_ROBOT_W,
                       images.PURPLE_ROBOT_S, images.PURPLE_ROBOT_E]
        elif self.colour == 'green':
            self._image = [images.GREEN_ROBOT_N, images.GREEN_ROBOT_W,
                       images.GREEN_ROBOT_S, images.GREEN_ROBOT_E]
        else:
            self._image = [images.GREY_ROBOT_N, images.GREY_ROBOT_W,
                       images.GREY_ROBOT_S, images.GREY_ROBOT_E]

        self.imageOffset = (12, 9)

        # image size (x, y) [all images equal]; for use in automatic scrolling
        self._image_size = self._image[0].GetWidth(), \
                           self._image[0].GetHeight()
        ## Note: for some reason, GetSize() did not work  using
        ## wxPython 2.4, which is why I used GetWidth() and GetHeight()

        # selecting the right image based on initial orientation
        self.robot_image = self._image[self._facing]

    #--- Action over-riden to handle images
    def turn_left(self):
        '''Robot turns left by 90 degrees, and image is updated.'''
        Robot_brain1.turn_left(self)
        self.robot_image = self._image[self._facing]

    def set_trace_style(self, style, colour = "sea green"):
        if style == 1:
           self.trace_offset = [(3, 3), (3, -3), (-3, -3), (-3, 3)]
           self.trace_width = 1
        elif style == 2:
           self.trace_offset = [(5, 5), (5, -5), (-5, -5), (-5, 5)]
           self.trace_width = 1
        elif style == 3:
           self.trace_offset = [(3, 3), (3, -3), (-3, -3), (-3, 3)]
           self.trace_width = 3
        elif style == 4:
           self.trace_offset = [(5, 5), (5, -5), (-5, -5), (-5, 5)]
           self.trace_width = 3
        elif style == 5:
            self.trace_offset = [(0, 0), (0, 0), (0, 0), (0, 0)]
            self.trace_width = 3
        else:
            self.trace_offset = [(0, 0), (0, 0), (0, 0), (0, 0)]
            self.trace_width = 0

        self.trace_style = style
        self.trace_colour = colour

    def get_trace_style(self, style):
        if style == 1:
           trace_offset = [(3, 3), (3, -3), (-3, -3), (-3, 3)]
           trace_width = 1
        elif style == 2:
           trace_offset = [(5, 5), (5, -5), (-5, -5), (-5, 5)]
           trace_width = 1
        elif style == 3:
           trace_offset = [(3, 3), (3, -3), (-3, -3), (-3, 3)]
           trace_width = 3
        elif style == 4:
           trace_offset = [(5, 5), (5, -5), (-5, -5), (-5, 5)]
           trace_width = 3
        elif style == 5:
            trace_offset = [(0, 0), (0, 0), (0, 0), (0, 0)]
            trace_width = 3
        else:
            trace_offset = [(0, 0), (0, 0), (0, 0), (0, 0)]
            trace_width = 0
        return trace_width, trace_offset

    def set_delay(self, delay):
        '''Sets the delay value between robot actions.'''
        if delay >= 0 and delay <= 10:
            self._delay = delay
        else:
            mesg = _("""Setting delay failed.
Accepted values are between 0 and 10.""")
            dialogs.rurMessageDialog(mesg, _("Error"))

    def get_delay(self):
        return self._delay

    delay = property(get_delay, set_delay, None, "Time between robot actions")


    # TODO: design "better looking" images for this robot.
    #--- Action over-riden to handle images
    def turn_right(self):
        '''Robot turns right by 90 degrees, and image is updated.'''
        Robot_brain2.turn_right(self)
        self.robot_image = self._image[self._facing]
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.