Пример #1
0
class Player(object):

    def __init__(self, algorithm, number):
        '''Initializes a Player object. Must be given an algorithm
        (a strategy for the player to use, in the form of a function
        like bfs from bfs.py) and a number to use as the player ID
        slash player starting location.'''
        # each player has a strategy (e.g. bfs, dfs)
        self.algorithm = algorithm
        # self.status is True if the player has legal moves remaining.
        self.status = True
        # each player has its own graph.
        self.graph = Graph()
        # number is the starting corner.
        self.number = number
        # 0 = top left, 1 = top right, 2 = bottom left, 3 = bottom right
        self.start_corner = self.graph.get_corners()[self.number]
        self.turn_count = 0

    def play_on_corner(self):
        '''Plays in the player's starting corner. This is not a legal move
        by the normal rules of the game and thus requires its own method
        so that game.py and graph.py know this move is acceptable.'''
        self.graph.play_piece(self.start_corner, self.number, [], first=True)

    def take_turn(self, other_graphs):
        '''Plays a piece according to the rules of the game. Needs the
        graphs of all of the other players so that multiple players
        can interact.'''
        # find all of the playable nodes.
        playable = self.graph.get_susceptible_nodes(other_graphs)
        # if there are no playable nodes, the player is 'dead'.
        if len(playable) == 0:
            print "Player %s is out of places to play." % self.number
            self.status = False
        # use the algorithm self.algorithm to put a piece down.
        if isinstance(self.algorithm, list):
            if isinstance(self.algorithm[0], int):
                seed = randint(0, 100)
                if seed < self.algorithm[0]:
                    visited = self.algorithm[1](self.graph, self.start_corner)
                else:
                    visited = self.algorithm[2](self.graph, self.start_corner)
            elif isinstance(self.algorithm[2], int):
                if self.turn_count < self.algorithm[2]:
                    visited = self.algorithm[0](self.graph, self.start_corner)
                else:
                    visited = self.algorithm[1](self.graph, self.start_corner)
        else:
            visited = self.algorithm(self.graph, self.start_corner)
        for node in visited:
            if node in playable:
                self.graph.play_piece(node, self.number, other_graphs)
                self.turn_count += 1
                break
Пример #2
0
class GraphTestCase(unittest.TestCase):
    def setUp(self):
        self.graph = Graph()

    def test_size(self):
        for i in xrange(3):
            random_size = randint(2, 30)
            random_graph = Graph(size=random_size)
            self.assertEqual(len(random_graph.nodes), random_size**2)

    def test_corner_degree(self):
        for i in [0, 19, -1, -20]:
            self.assertEqual(self.graph.nodes[i].get_degree(), 2)

    def test_side_degree(self):
        for i in xrange(1, 19):
            self.assertEqual(self.graph.nodes[i].get_degree(), 3)

    def test_center_degree(self):
        for i in xrange(21, 39):
            self.assertEqual(self.graph.nodes[i].get_degree(), 4)

    def test_horizontal_links(self):
        size = self.graph.size
        for i in xrange(size):
            for j in xrange(size):
                node = self.graph.nodes[size*i+j]
                try:
                    last_node = self.graph.nodes[size*i+j-1]
                except IndexError:
                    last_node = False
                try:
                    next_node = self.graph.nodes[size*i+j+1]
                except IndexError:
                    next_node = False
                last_connection = False
                next_connection = False
                for edge in node.edges:
                    nodes = [node.edges[edge].node1, node.edges[edge].node2]
                    if last_node in nodes:
                        last_connection = True
                    if next_node in nodes:
                        next_connection = True
                if j != 0:
                    self.assertEqual(last_connection, True)
                if j != size-1:
                    self.assertEqual(next_connection, True)

    def test_vertical_links(self):
        size = self.graph.size
        for i in xrange(size):
            for j in xrange(size):
                node = self.graph.nodes[size*i+j]
                try:
                    above_node = self.graph.nodes[size*i+j-size]
                except IndexError:
                    above_node = False
                try:
                    below_node = self.graph.nodes[size*i+j+size]
                except IndexError:
                    below_node = False
                above_connection = False
                below_connection = False
                for edge in node.edges:
                    nodes = [node.edges[edge].node1, node.edges[edge].node2]
                    if above_node in nodes:
                        above_connection = True
                    if below_node in nodes:
                        below_connection = True
                if i != 0:
                    self.assertEqual(above_connection, True)
                if i != size-1:
                    self.assertEqual(below_connection, True)

    def test_no_excess_links(self):
        size = self.graph.size
        for i in xrange(size):
            for j in xrange(size):
                node = self.graph.nodes[size*i+j]
                try:
                    last_node = self.graph.nodes[size*i+j-1]
                except IndexError:
                    last_node = False
                try:
                    next_node = self.graph.nodes[size*i+j+1]
                except IndexError:
                    next_node = False
                try:
                    above_node = self.graph.nodes[size*i+j-size]
                except IndexError:
                    above_node = False
                try:
                    below_node = self.graph.nodes[size*i+j+size]
                except IndexError:
                    below_node = False
                for edge in node.edges:
                    nodes = [node.edges[edge].node1, node.edges[edge].node2]
                    left = last_node in nodes and node in nodes
                    right = next_node in nodes and node in nodes
                    up = above_node in nodes and node in nodes
                    down = below_node in nodes and node in nodes
                    self.assertTrue(left or right or up or down)

    def test_get_playable_nodes(self):
        self.assertEqual(len(self.graph.get_playable_nodes([])), 0)

    def test_get_corners(self):
        self.assertEqual(len(self.graph.get_corners()), 4)
        for i in [0, 19, -1, -20]:
            self.assertTrue(self.graph.nodes[i] in self.graph.get_corners())

    def test_playing_corner(self):
        corners = self.graph.get_corners()
        self.graph.play_piece(corners[0], first=True)
        self.assertEqual(corners[0].get_directed_degree(), 3)

    def test_get_diagonal_nodes(self):
        # test one from the center
        center = (self.graph.size**2) / 2 + (self.graph.size / 2)
        cn = self.graph.nodes[center]
        ul = self.graph.nodes[center - self.graph.size - 1]
        ur = self.graph.nodes[center - self.graph.size + 1]
        dl = self.graph.nodes[center + self.graph.size - 1]
        dr = self.graph.nodes[center + self.graph.size + 1]
        self.assertEqual(self.graph.get_diagonal_nodes(cn), [ul, dl, ur, dr])
        # TODO: one from the right edge
        # TODO: one from the left edge
        # TODO: one from the top edge
        # TODO: one from the bottom edge
        # TODO: for now, top left and bottom right will handle the above
        # only one corner for the top left
        tl = self.graph.nodes[0]
        tldr = self.graph.nodes[self.graph.size + 1]
        self.assertEqual(self.graph.get_diagonal_nodes(tl), [tldr])
        # same for the bottom right
        br = self.graph.nodes[-1]
        brul = self.graph.nodes[-1 * self.graph.size - 2]
        self.assertEqual(self.graph.get_diagonal_nodes(br), [brul])

    def test_get_adjacent_nodes(self):
        # test one from the center
        center = (self.graph.size**2) / 2 + (self.graph.size / 2)
        cn = self.graph.nodes[center]
        l = self.graph.nodes[center - 1]
        r = self.graph.nodes[center + 1]
        u = self.graph.nodes[center - self.graph.size]
        d = self.graph.nodes[center + self.graph.size]
        self.assertEqual(self.graph.get_adjacent_nodes(cn), [l, r, u, d])
        # TODO: one from the right edge
        # TODO: one from the left edge
        # TODO: one from the top edge
        # TODO: one from the bottom edge
        # TODO: for now, top left and bottom right will handle the above
        # only one corner for the top left
        tl = self.graph.nodes[0]
        tlr = self.graph.nodes[1]
        tld = self.graph.nodes[self.graph.size]
        self.assertEqual(set(self.graph.get_adjacent_nodes(tl)), set([tlr, tld]))
        # same for the bottom right
        br = self.graph.nodes[-1]
        brl = self.graph.nodes[-2]
        bru = self.graph.nodes[-1*self.graph.size-1]
        self.assertEqual(set(self.graph.get_adjacent_nodes(br)), set([brl, bru]))

    def test_is_played(self):
        pass