Ejemplo n.º 1
0
 def __init__(self, automata, reverser_class):
     self.automata = automata
     self.reverser_class = reverser_class
     self.rows = self.automata.rows
     self.columns = self.automata.columns
     self.reverser = self.reverser_class(self.automata)
     self.status_line = ''
     self.cursor_row = 0
     self.cursor_column = 0
     self.show_guesses = False
     self.show_numbers = False
     self.show_50s = False
     self.guesses = Guesses()
Ejemplo n.º 2
0
class Interface(object):

    def __init__(self, automata, reverser_class):
        self.automata = automata
        self.reverser_class = reverser_class
        self.rows = self.automata.rows
        self.columns = self.automata.columns
        self.reverser = self.reverser_class(self.automata)
        self.status_line = ''
        self.cursor_row = 0
        self.cursor_column = 0
        self.show_guesses = False
        self.show_numbers = False
        self.show_50s = False
        self.guesses = Guesses()

    def guess(self):
        self.status_line = '\x1b[48;5;21mThinking...\x1b[0m'
        self._draw_status_line()
        if self.reverser.impossible:
            self.reverser.reset()
            self._draw_reverser()

        for (row, column), state in self.guesses.as_dict().items():
            self.reverser.narrow(row, column, c=state)

        try:
            for ((r, c), chance, length) in self.reverser.corroborate():
                self._draw_one_guess((r, c), chance, length)
                self.status_line = '\x1b[48;5;21mThinking...\x1b[0m'
                self._draw_status_line()
        except ZeroDivisionError:
            self.status_line = '\x1b[48;5;196mImpossible!\x1b[0m'
            self._draw_status_line()
        else:
            self.status_line = ''
            self._draw_status_line()

    def _eval_and_draw(self):
        try:
            for ((r, c), chance, length) in self.reverser.evaluate_guesses(self.guesses):
                self._draw_one_guess((r, c), chance, length)
        except ZeroDivisionError:
            return False
        return True

    def autoguess(self):
        self.status_line = '\x1b[48;5;21mAutoguessing...\x1b[0m'
        self._draw_status_line()
        last_failure = None
        while True:
            ok = self._eval_and_draw()
            if ok:
                # Find the next unguessed spot.
                last_failure = None
                rc = self.reverser.next_guessable()
                if rc is None:
                    self.status_line = ''
                    self._draw_status_line()
                    return  # Nothing more to guess.
                # Guess that the next spot in the list was DEAD.
                self.guesses.append(rc, 0)

            else:
                # Failure. Remove the last guess from the list.
                last_failure = self.guesses.pop()
                if last_failure is None:
                    # Uh oh.
                    self.status_line = '\x1b[48;5;196mImpossible!\x1b[0m'
                    self._draw_status_line()
                    return
                rc, failed_guess = last_failure
                if failed_guess == 0:
                    # That spot wasn't DEAD. Try ALIVE.
                    self.guesses.append(rc, 1)
                else:
                    # It wasn't ALIVE either. Unwind.
                    while failed_guess == 1:
                        last_failure = self.guesses.pop()
                        rc, failed_guess = last_failure
                    self.guesses.append(rc, 1)
        self.status_line = ''
        self._draw_status_line()
        self._draw_reverser()

    def _draw_reverser(self):
        if self.reverser is None:
            return

        cloud = self.reverser.cloud

        NORMAL = '\x1b[0m'

        ro, co = 2, 2
        if self.reverser is not None:
            for r, row in enumerate(cloud):
                R = [self._one_cell(ch, le) for (ch, le) in row]
                move_cursor(ro + r, co)
                emit(''.join(R) + NORMAL)
            move_cursor(self.automata.rows + 3, 2)

    def _one_cell(self, chance, length):
        if not length:
            return '\x1b[48;5;196m  '
        if chance == 1.0:
            return '\x1b[48;5;231m[]'
        if chance == 0.0:
            return '\x1b[48;5;16m  '
        if self.show_50s and chance == 0.5:
            return '\x1b[48;5;22m<>'

        ansi_grey = 232 + int(round(chance * 23.0))
        face = '  '
        if self.show_numbers and length < 100:
            face = '%02i' % length
        return '\x1b[48;5;%im%s' % (ansi_grey, face)

    def _draw_one_guess(self, (row, column), chance, length):
        NORMAL = '\x1b[0m'
        ro, co = 2, 2
        move_cursor(ro + row, co + (column * 2))
        emit(self._one_cell(chance, length) + NORMAL)