# Version 1.0 Oct 31, 2003

from random import randint

class Game:
    """
    Class for managing the game
    """

    def __init__(self, boardsize):
        self.boardsize = boardsize
        self.players = {}  # empty dictionary, will hold players
        
    def addplayer(self, player):
        """
        Add new player to players dictionary, using name as a key.  Give the
        player a random position on the game board
        """
        player.position = (randint(0,self.boardsize[0]), randint(0,self.boardsize[1]))
        player.boardsize = self.boardsize  # player now knows boardsize
        self.players[player.name] = player
        
    def removeplayer(self, player):
        """
        Remove a player from the dictionary, if s/he's there
        """
        try:
            del self.players[player.name]
        except:
            print "Player %s not found." % player.name

    def showplayers(self):
        """
        List all players and their positions to the screen
        """
        for player in self.players.values():
            print "Player %s is at %s" % (player.name , player.position)

    def showboard(self):
        """
        Paint a primitive game board
        """
        # because (10,10) means from 0,1,2... 10 ( = 11 spaces):
        x = self.boardsize[0] + 1  
        y = self.boardsize[1] + 1

        # make an x-by-y 2 dimensional array of spaces, and fill
        # in coordinates with first letter of character names
        rows = []
        for k in range(y):
            rows.append(x * [' '])
        for player in self.players.values():
            firstletter = player.name[0]
            rows[player.position[1]][player.position[0]] = firstletter
        print " " + ("-" * x)  # top border

        rows.reverse()  # because we think of (0,0) as bottom left

        for r in rows:
            print '|' + ''.join(r) + '|'
        print " " + ("-" * x)  # bottom border

    def __repr__(self):
        return 'A game of %s players' % len(self.players)

class Player:
    """
    Class defining individual characters in the game
    """

    def __init__(self, name):
        self.name = name
        self.boardsize = None

    def move(self, direction, n=1):
        """
        Move n steps in any of four compass directions, or don't move
        if the player would cross the boundary of the board
        """        
        hitwall = False
        
        if self.boardsize == None:
            print "Player not in a game"

        if direction not in ['N','S','E','W']:
            print "Don't know that direction (%s)" % direction
            return # exit move method without further processing
            
        elif direction == 'N':
            newy = self.position[1] + n
            if newy > self.boardsize[1]:
                hitwall = True
            else: 
                self.position = (self.position[0], newy)
            
        elif direction == 'S':
            newy = self.position[1] - n                
            if newy < 0:
                hitwall = True
            else:                 
                self.position = (self.position[0], newy)
                         
        elif direction == 'E':
            newx = self.position[0] + n
            if newx > self.boardsize[0]:
                hitwall = True
            else: 
                self.position = (newx ,self.position[1])
                         
        elif direction == 'W':
            newx = self.position[0] - n
            if newx < 0:
                hitwall = True
            else: 
                self.position = (newx, self.position[1])                         

        if hitwall:
            print "%s hit a wall!" % self.name
        else:
            print "%s moves %s by 1 to %s" % (self.name, direction, self.position)
        

    def __repr__(self):
        """
        Identify self
        """
        return "Player %s" % self.name


def test():    
    mygame = Game((10,10))
    p1 = Player('Gandalf')
    p2 = Player('Frodo')
    mygame.addplayer(p1)
    mygame.addplayer(p2)

    mygame

    mygame.showboard()
    mygame.showplayers()

    p1.move('N')
    p2.move('N')    
    mygame.showboard()    
    mygame.showplayers()

    p1.move('E')
    p2.move('W')    
    mygame.showboard()    
    mygame.showplayers()
