Example #1
0
def plot(data, objects, blacklist, bestCandidate, myVmin=None, myVmax=None,
         myEventX = None, myEventY = None, special_plot_location=None, title=''):
    # make the destination directory if it does not exist
    if not os.path.isdir(PLOT_DIR):
        os.mkdir(PLOT_DIR)
        
    special_plot_dir = ''
    if special_plot_location:
        special_plot_dir = PLOT_DIR + special_plot_location + '.png'
            
    to_circle = range(len(objects))

    fig, ax = plt.subplots()

    if myVmax == None or myVmin == None:
        _im = ax.imshow(data, interpolation='nearest', cmap='gray')
    else:
        _im = ax.imshow(data, interpolation='nearest', cmap='gray',
                        vmin = myVmin, vmax = myVmax)
    # triangle on event location
    p = RegularPolygon((int(myEventX), int(myEventY)), 3, radius=3)
    p.set_edgecolor('purple')
    p.set_facecolor('purple')
    ax.add_artist(p)

    # plot an ellipse for each object
    for i in to_circle:
        e = Ellipse(xy=(objects['x'][i], objects['y'][i]),
                    width=6*objects['a'][i],
                    height=6*objects['b'][i],
                    angle=objects['theta'][i] * 180. / np.pi)
# TODO check if above angle conversion is correct. Where from?
        e.set_facecolor('none')
        if i==bestCandidate:
            e.set_edgecolor('green')
        elif i in blacklist:
            e.set_edgecolor('blue')
        else:
            e.set_edgecolor('red')
        ax.add_artist(e)
    plt.title(title)
    genname = namegen()
    name = special_plot_dir if special_plot_dir else genname
    plt.savefig(name, dpi=150)
    plt.show()
    plt.close()
Example #2
0
class Main:
    """The central part of the program"""

    wizard_color = '#F7B738'
    board_color = '#BCE0DF'
    selected_color = '#AFFFD4'
    spot_color = ['#FFFFFF', '#FF0000', '#0000FF']

    fig_size = 5.5
    fig_pad = 0.25
    spot_radius = 0.15

    fig_mid = fig_size / 2
    fig_unit = (fig_mid - fig_pad) / State.BOARD_SIZE

    def __init__(self, agent1, agent2):

        # assign the agents
        self.players = [agent1, agent2]

        # start with an empty state
        self.current_state = State()
        self.img_nr = -1

        # create the figure
        self.fig = plt.figure(figsize=(Main.fig_size, Main.fig_size),
                              facecolor=self.board_color)
        self.fig.suptitle('Good Luck !', fontsize=12, fontweight='bold')

        self.ax = self.fig.add_axes((0.05, 0.05, 0.9, 0.9),
                                    aspect='equal',
                                    frameon=False,
                                    xlim=(-0.05, Main.fig_size + 0.05),
                                    ylim=(-0.05, Main.fig_size + 0.05))

        self.cows_left = [
            self.ax.text(4 * Main.fig_pad,
                         Main.fig_size,
                         str(self.current_state.cows[0]),
                         bbox={
                             'facecolor': Main.spot_color[1],
                             'alpha': 0.5,
                             'pad': 10
                         }),
            self.ax.text(Main.fig_size - 5 * Main.fig_pad,
                         Main.fig_size,
                         str(self.current_state.cows[0]),
                         bbox={
                             'facecolor': Main.spot_color[2],
                             'alpha': 0.5,
                             'pad': 10
                         })
        ]

        self.player_names = [
            self.ax.text(-0.5 * Main.fig_pad,
                         Main.fig_size,
                         agent1.name,
                         fontsize=14,
                         color=Main.spot_color[1]),
            self.ax.text(Main.fig_size - 2.5 * Main.fig_pad,
                         Main.fig_size,
                         agent2.name,
                         fontsize=14,
                         color=Main.spot_color[2])
        ]

        for axis in (self.ax.xaxis, self.ax.yaxis):
            axis.set_major_formatter(plt.NullFormatter())
            axis.set_major_locator(plt.NullLocator())

        # create the grid of spots
        self.spots = np.array([[[
            Circle(self.graphic_location(l, r, c),
                   linewidth=2,
                   facecolor=self.spot_color[0],
                   radius=self.spot_radius) for c in range(State.BOARD_SIZE)
        ] for r in range(State.BOARD_SIZE)] for l in range(State.BOARD_SIZE)])

        # draw the connections between spots
        for l in range(State.BOARD_SIZE):
            self.ax.add_patch(
                ConnectionPatch(self.graphic_location(l, 0, 0),
                                self.graphic_location(l, 0, 2), "data",
                                "data"))
            self.ax.add_patch(
                ConnectionPatch(self.graphic_location(l, 0, 0),
                                self.graphic_location(l, 2, 0), "data",
                                "data"))
            self.ax.add_patch(
                ConnectionPatch(self.graphic_location(l, 0, 2),
                                self.graphic_location(l, 2, 2), "data",
                                "data"))
            self.ax.add_patch(
                ConnectionPatch(self.graphic_location(l, 2, 0),
                                self.graphic_location(l, 2, 2), "data",
                                "data"))

        for r in range(State.BOARD_SIZE):
            for c in range(State.BOARD_SIZE):
                if (r, c) != (State.GAP_SPOT, State.GAP_SPOT):
                    self.ax.add_patch(
                        ConnectionPatch(self.graphic_location(0, r, c),
                                        self.graphic_location(2, r, c),
                                        "data",
                                        "data",
                                        facecolor=self.board_color))

        # draw the spots
        for l in range(State.BOARD_SIZE):
            for r in range(State.BOARD_SIZE):
                for c in range(State.BOARD_SIZE):
                    if (r, c) != (State.GAP_SPOT, State.GAP_SPOT):
                        self.ax.add_patch(self.spots[l, r, c])

        # draw the central player turn deciding wizard
        self.wizard = RegularPolygon(
            self.graphic_location(0, State.GAP_SPOT, State.GAP_SPOT),
            numVertices=8,
            radius=0.2,
            facecolor=self.wizard_color,
            linewidth=2,
            linestyle='-',
            hatch='*',
            edgecolor=self.spot_color[self.current_state.player_to_move])
        self.ax.add_patch(self.wizard)

        # store the selected entity (for moving pieces)
        self.selected = None

        # create event hook for mouse clicks
        self.fig.canvas.mpl_connect('button_press_event', self.button_press)
        self.fig.canvas.mpl_connect('button_release_event',
                                    self.button_release)

    def graphic_location(self, l, r, c):
        """Maps the mathematical 3 dimensional index of a board state
		to the location in the graphical user interface board"""

        return (Main.fig_mid + (c - 1) *
                (State.BOARD_SIZE - l) * Main.fig_unit, Main.fig_mid +
                (r - 1) * (State.BOARD_SIZE - l) * Main.fig_unit)

    def update_graphical_board(self):
        """Update the graphical board with the context of the current state"""

        # update spots
        for l in range(State.BOARD_SIZE):
            for r in range(State.BOARD_SIZE):
                for c in range(State.BOARD_SIZE):
                    self.spots[l, r, c].set_facecolor(
                        self.spot_color[self.current_state.board[l, r, c]])

        # update wizard
        self.wizard.set_edgecolor(
            self.spot_color[self.current_state.player_to_move])

        self.fig.canvas.draw()

    def spot_clicked(self, x, y):
        """Maps click locations to actual entities lying on the board"""

        for l in range(State.BOARD_SIZE):
            for r in range(State.BOARD_SIZE):
                for c in range(State.BOARD_SIZE):

                    sx, sy = self.graphic_location(l, r, c)

                    if math.sqrt((x - sx)**2 + (y - sy)**2) < self.spot_radius:
                        if (r, c) == (State.GAP_SPOT, State.GAP_SPOT):
                            return "wizard"
                        else:
                            return (l, r, c)

    def button_press(self, event):

        x, y = map(float, (event.xdata, event.ydata))
        self.selected = self.spot_clicked(x, y)

        try:
            if self.current_state.board[self.selected] == self.current_state.player_to_move \
            and sum(self.current_state.cows) == 0:
                self.spots[self.selected].set_edgecolor(self.selected_color)
                self.fig.canvas.draw()
        except IndexError:
            pass
        except ValueError:
            pass

    def button_release(self, event):
        """Handle mouse clicks"""

        player = self.players[self.current_state.player_to_move - 1]

        x, y = map(float, (event.xdata, event.ydata))
        clicked = self.spot_clicked(x, y)

        self.fig.suptitle('')
        self.fig.canvas.draw()

        #------------------------[ player is human ]------------------------#

        if isinstance(player, HumanAgent):

            # possible next board configurations
            possible_next_states = self.current_state.expand_states()
            possible_configurations = [
                state.board for state in possible_next_states
            ]

            current_board = np.copy(self.current_state.board)

            # no moves can be made
            if len(possible_next_states) == 0:
                windex = self.current_state.winner
                if windex:
                    self.fig.suptitle(self.players[windex - 1].name +
                                      ' wins !',
                                      fontsize=12,
                                      fontweight='bold')
                else:
                    self.fig.suptitle('Draw', fontsize=12, fontweight='bold')
                self.fig.canvas.draw()
                return

            # air clicks do not count
            if self.selected == None or clicked == None:
                return

            # not allowed to touch its majesty
            if self.selected == 'wizard' or clicked == 'wizard':
                self.fig.suptitle("Don't touch the wizard !",
                                  fontsize=12,
                                  fontweight='bold')
                self.fig.canvas.draw()
                return

            # clicked and released same entity
            if clicked == self.selected:
                # add a new cow on an empty spot
                if current_board[clicked] == State.EMPTY:
                    current_board[clicked] = self.current_state.player_to_move
                # capture opponent's piece
                elif current_board[
                        clicked] == 3 - self.current_state.player_to_move:
                    current_board[clicked] = State.EMPTY
            # clicked on different spots
            elif current_board[
                    self.selected] == self.current_state.player_to_move:
                current_board[self.selected] = State.EMPTY
                current_board[clicked] = self.current_state.player_to_move

            # verify if the move is valid
            state_valid = False
            for i, possible_board in enumerate(possible_configurations):
                if np.all(possible_board == current_board):
                    state_valid = True
                    state_index = i
                    break

            if state_valid:
                self.current_state = possible_next_states[state_index]
                self.update_graphical_board()
            else:
                self.fig.suptitle('Invalid move !',
                                  fontsize=12,
                                  fontweight='bold')
                self.fig.canvas.draw()

            # flush the mouse press
            if self.selected not in [None, 'wizard']:
                self.spots[self.selected].set_edgecolor(None)
                self.selected = None

        #------------------------[ player is AI ]------------------------#

        else:
            if clicked == "wizard" and self.selected == 'wizard':
                next_state = player.make_move(self.current_state)

                # no move returned
                if next_state == None:
                    windex = self.current_state.winner
                    if windex:
                        self.fig.suptitle(self.players[windex - 1].name +
                                          ' wins !',
                                          fontsize=12,
                                          fontweight='bold')
                    else:
                        self.fig.suptitle('Draw',
                                          fontsize=12,
                                          fontweight='bold')
                    self.fig.canvas.draw()
                    return
                else:
                    self.current_state = next_state
                    self.update_graphical_board()

        if self.current_state.can_capture:
            self.fig.suptitle('Mill ! Shoot a cow !',
                              fontsize=12,
                              fontweight='bold')

        for i in range(2):
            self.cows_left[i].set_text(str(self.current_state.cows[i]))

        self.fig.canvas.draw()