Пример #1
0
class Wall(object):
    MIN_RED = MIN_GREEN = MIN_BLUE = 0x0
    MAX_RED = MAX_GREEN = MAX_BLUE = 0xFF

    PIXEL_WIDTH = 50

    def __init__(self, width, height):
        self.width = width
        self.height = height
        self._tk_init()
        self.pixels = [(0, 0, 0) for i in range(self.width * self.height)]

    def _tk_init(self):
        self.root = Tk()
        self.root.title("ColorWall %d x %d" % (self.width, self.height))
        self.root.resizable(0, 0)
        self.frame = Frame(self.root, bd=5, relief=SUNKEN)
        self.frame.pack()

        self.canvas = Canvas(self.frame,
                             width=self.PIXEL_WIDTH * self.width,
                             height=self.PIXEL_WIDTH * self.height,
                             bd=0, highlightthickness=0)
        self.canvas.pack()
        self.root.update()

    def set_pixel(self, x, y, hsv):
        self.pixels[self.width * y + x] = hsv

    def get_pixel(self, x, y):
        return self.pixels[self.width * y + x]

    def draw(self):
        self.canvas.delete(ALL)
        for x in range(len(self.pixels)):
            x_0 = (x % self.width) * self.PIXEL_WIDTH
            y_0 = (x / self.width) * self.PIXEL_WIDTH
            x_1 = x_0 + self.PIXEL_WIDTH
            y_1 = y_0 + self.PIXEL_WIDTH
            hue = "#%02x%02x%02x" % self._get_rgb(self.pixels[x])
            self.canvas.create_rectangle(x_0, y_0, x_1, y_1, fill=hue)
        self.canvas.update()

    def clear(self):
        for i in range(self.width * self.height):
            self.pixels[i] = (0, 0, 0)

    def _hsv_to_rgb(self, hsv):
        rgb = colorsys.hsv_to_rgb(*hsv)
        red = self.MAX_RED * rgb[0]
        green = self.MAX_GREEN * rgb[1]
        blue = self.MAX_BLUE * rgb[2]
        return (red, green, blue)

    def _get_rgb(self, hsv):
        red, green, blue = self._hsv_to_rgb(hsv)
        red = int(float(red) / (self.MAX_RED - self.MIN_RED) * 0xFF)
        green = int(float(green) / (self.MAX_GREEN - self.MIN_GREEN) * 0xFF)
        blue = int(float(blue) / (self.MAX_BLUE - self.MIN_BLUE) * 0xFF)
        return (red, green, blue)
Пример #2
0
class WindowInstance(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.parent.title("Window")
        self.pack(fill=BOTH, expand=1)

        self.canvas = Canvas(self)
        self.doubleBuffer = False

        self.fill = "#000"
        self.outline = "#000"

    def setColor(self, c):
        self.fill = c
        self.outline = c

    def drawRectangle(self, x, y, w, h):
        self.canvas.create_rectangle(x, y, x + w, y + h, fill=self.fill, outline=self.outline)
        if not self.doubleBuffer:
            self.canvas.pack(fill=BOTH, expand=1)

    def drawLine(self, x, y, ex, ey):
        self.canvas.create_line(x, y, ex, ey, fill=self.fill)
        if not self.doubleBuffer:
            self.canvas.pack(fill=BOTH, expand=1)

    def drawOval(self, x, y, w, h):
        self.canvas.create_oval(x, y, x + w, y + h, fill=self.fill, outline=self.outline)
        if not self.doubleBuffer:
            self.canvas.pack(fill=BOTH, expand=1)

    def frame(self):
        self.doubleBuffer = True
        self.canvas.pack(fill=BOTH, expand=1)

    def clear(self):
        self.canvas.delete("all")
Пример #3
0
class Example(Frame):
  
    def __init__(self, parent):
        Frame.__init__(self, parent)   

        self.x = 0
        self.y = 0
        
        self.parent = parent        
        parent.bind("<Motion>", self.onMove)
        parent.bind("<Button-1>", self.leftClick)
        parent.bind("<Button-3>", self.rightClick)
        self.parent.title("Colors")        
        self.pack(fill=BOTH, expand=1)

        self.canvas = Canvas(self)
        self.canvas.create_rectangle(30, 10, 120, 80, outline="#fb0", fill="#fb0")
        self.canvas.create_rectangle(150, 10, 240, 80, outline="#f50", fill="#f50")
        self.canvas.create_rectangle(270, 10, 370, 80, outline="#05f", fill="#05f")            
        self.canvas.pack(fill=BOTH, expand=1)
        self.inMotion = False
        self.line = 0#Holder for temp line whilst dragging mouse around

    def onMove(self, e):
        if self.inMotion:
            self.canvas.delete(self.line)
            self.line = self.canvas.create_line(self.x, self.y, e.x, e.y)

    def leftClick(self, e):
        if not(self.inMotion):
            self.canvas.create_line(self.x, self.y, e.x, e.y)
        self.x = e.x
        self.y = e.y
        self.inMotion = True

    def rightClick(self, e):
        self.inMotion = False
Пример #4
0
class Application(Tk):
    def __init__(self):
        super().__init__()
        self.title('Hangman')
        self.geometry('640x480+200+200')
        self.resizable(width=False, height=False)

        menu_bar = Menu(self, tearoff=0)
        self.config(menu=menu_bar)

        game_menu = Menu(menu_bar, tearoff=0)
        game_menu.add_command(label='New game', command=self.__on_new_game)
        game_menu.add_command(label='Quit', command=self.__on_quit)
        menu_bar.add_cascade(label='Game', menu=game_menu)

        self.__hang_canvas = Canvas(self, background='#ffffff')
        self.__hang_canvas.pack(fill=BOTH, expand=True)

        self.__dict_filename = os.path.join(os.path.dirname(__file__), 'dictionary.txt')
        self.__dictionary = []
        self.__secret_word_masked = StringVar()
        self.__game_stages = (
            # (is_circle, x1, y1, x2, y2),
            (False, 50, 300, 200, 300), # podstawa
            (False, 60, 300, 60, 10), # maszt
            (False, 60, 10, 160, 10),
            (False, 60, 30, 100, 10),
            (False, 160, 10, 160, 30),
            (True, 140, 30, 180, 70),
            (False, 160, 70, 160, 200), # tułów
            (False, 140, 120, 160, 70), # lewa reka
            (False, 180, 120, 160, 70), # prawa ręka
            (False, 160, 200, 140, 250),
            (False, 160, 200, 180, 250)
        )
        self.__errors_count = 0

        secret_word_label = Label(self, font=('purisa', 36), textvariable=self.__secret_word_masked)
        secret_word_label.pack(fill=X)

        # user input panel
        Label(self, text='Please input a char:').pack(fill=X)
        self.__user_input_char = StringVar()
        user_input_entry = Entry(self, textvariable=self.__user_input_char)
        user_input_entry.bind('<Return>', self.__on_user_input)
        user_input_entry.pack()

        self.__load_dictionary()
        self.__new_game()

    def __on_user_input(self, event):
        text = self.__user_input_char.get()
        if text:
            c = text[0]
            if c in self.__secret_word:
                self.__secret_word_masked.set(str(self.__secret_word))
                # check is it victory
                if self.__secret_word.is_reveled():
                    self.__do_victory()
            else:
                # check if defeat
                self.__errors_count += 1
                self.__redraw_canvas()
                if self.__errors_count >= len(self.__game_stages):
                    self.__do_defeat()
        self.__user_input_char.set('')

    def __redraw_canvas(self):
        if self.__errors_count <= len(self.__game_stages):
            self.__hang_canvas.delete('all')
            for i in range(self.__errors_count):
                is_circle, x1, y1, x2, y2 = self.__game_stages[i]
                if is_circle:
                    self.__hang_canvas.create_oval(x1, y1, x2, y2)
                else:
                    self.__hang_canvas.create_line(x1, y1, x2, y2)

    def __do_defeat(self):
        pos = (self.__hang_canvas.winfo_width()/2, self.__hang_canvas.winfo_height()/2)
        self.__hang_canvas.create_text(pos, text='Defeat!', fill='#FF0000', font=('purisa', 36))
        print('Defeat!')
        self.__secret_word_masked.set(self.__secret_word.word)


    def __do_victory(self):
        pos = (self.__hang_canvas.winfo_width()/2, self.__hang_canvas.winfo_height()/2)
        self.__hang_canvas.create_text(pos, text='Victory!', fill='#FF0000', font=('purisa', 36))
        print('victory!')

    def __load_dictionary(self):
        with open(self.__dict_filename, 'r') as f:
            for line in f:
                self.__dictionary.append(line.lower().strip())

    def __on_new_game(self):
        self.__new_game()

    def __new_game(self):
        # Reset state of game
        word = random.choice(self.__dictionary)
        self.__secret_word = Riddle(word)
        self.__secret_word_masked.set(str(self.__secret_word))
        self.__errors_count = 0
        self.__redraw_canvas()

    def __on_quit(self):
        print('Goodbye :)')
        self.quit()
Пример #5
0
class rmap():
    _var = [1]
    _nc = 0
    _nr = 0
    _r = 0
    _c = 0
    _size = 0
    _w = 0
    _d = 0
    _NoneUpdate = False
    _Nonelabel = False
    _Nonegettext = False
    _field = []
    _endPoint = (0, 0)

    _robot = ''  # рисунок Робота (синее кольцо)
    _park = ''

    _canvas = ''
    sleep = 0.5
    _task = ''
    _solve = ''
    _test = ''
    _res = ''
    _bum = 0

    m = []
    m.append('task1')
    m.append('task2')
    m.append('task3')
    m.append('task4')
    m.append('task5')

    m.append('task6')
    m.append('task7')
    m.append('task8')
    m.append('task9')
    m.append('task10')
    m.append('task11')
    m.append('task12')
    m.append('task13')

    class _v:  # будет содержать изображение текста и квадратиков закраски и меток. Чтобы можно было "поднимать изображение"
        text = ''
        label = ''
        color = ''

    class _Tcell():
        color = ''
        text = ''
        label = ''  # color
        wUp = False
        wLeft = False
        v = ''

    def help(self):
        """ Вывести список команд Робота
Примеры использования по команде r.help_full()
"""
        print("""
Пояснение по каждой команде: print команда.__doc__
Например:
print r.color.__doc__

---=: Команды перемещения :=---
r.rt() # Вправо
r.lt() # Влево
r.dn() # Вниз
r.up() # Вверх
r.jumpTo(r,c) # Прыжок в точку. Без особых указаний в задачах не использовать
-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=

---=: Команды изменения среды :=---
r.pt([цвет]) # Закрасить указанным цветом. По умолчанию зеленым
r.sw(направление) # Установить стену с указанной стороны
r.settext(тест) # Вписать в клетку текст
-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=

---=: Команды обратной связи :=---
r.cl() # Каким цветом закрашена клетка? r.color()
r.label() # Какого цвета метка в клетке?
r.gettext() # Какой текст в клетке?

r.getCoords() # Где Робот?
r.getCoordR() # В какой строке Робот?
r.getCoordС() # В каком столбце Робот?

r.fu() # Сверху свободно?
r.fd() # Снизу свободно?
r.fr() # Справа свободно?
r.fl() # Слева свободно?

r.wu() # Сверху стена?
r.wd() # Снизу стена?
r.wr() # Справа стена?
r.wl() # Слева стена?

r.isPark # Робот на парковке?
-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=

---=: Дополнительно :=---
r.sleep = 0.4 # Установить размер задержки после каждого хода. Меньше значение - быстрее Робот.
r._NoneUpdate = False # Отключить прорисовку поля
r._NoneUpdate = True # Включить прорисовку поля
r.demo() # Показать, что нужно сделать в текущей задаче
r.demoAll() # Показать все задачи (с решениями, по очереди)
r.randcolor() # Генерировать случайный цвет
-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=

""")

    def help_full(self):
        """ Примеры. Для получения списка команд r.help()
Примеры использования по команде r.help_full()
Больше информации по каждой команде: print команда.__doc__
Например:
print r.color.__doc__
"""
        print("""
Не реализовано в данной версии. 
Если нужно - пишите на [email protected] или на сайте progras.ru
""")

    def demo(self):
        """Показать выполнение задачи
Пример использования:
#-------------------
r.demo()
#-------------------

Для уcкорения использовать r.sleep = 0.01
В задании 10-3(4/5) можно отключить обновление экрана
#-------------------
r._NoneUpdate = True
r.demo()
r._NoneUpdate = False
#-------------------
"""
        global r
        r = self
        exec(self._solve)

    def demoAll(self):
        """Показать выполнение всех заданий в автоматическом режиме
Пример использования:

#-------------------
r.demoAll()
#-------------------

Для того, чтобы Робот двигался быстрее, используйте
#-------------------
r.sleep = 0
r.demoAll()
#-------------------

"""
        global r
        r = self
        for x in r.m:
            r.lm(x)
            print(x)
            r.demo()
            r.pause()

    def __init__(self):
        self._w = 4  # толщина стен
        self._d = 4  # на столько меньше клетки закраска (с каждой стороны)
        self.sleep = 0.5  # замедление
        self._font_size = self._size // 2
        self._tk = Tk()
        self._tk.geometry('+0+0')
        x = (self._tk.winfo_screenwidth() - self._tk.winfo_reqwidth()) / 3
        y = (self._tk.winfo_screenheight() - self._tk.winfo_reqheight()) / 4
        self._tk.wm_geometry("+%d+%d" % (x, y))
        self._tk.title('Robot-hobot')
        self._canvas = Canvas(self._tk, width=(self._size * (self._nc + 1)), height=(self._size * (self._nr + 1)),
                              bg="gray")

        buttons = Frame(self._tk)

        self.task = Label(self._tk, justify='left')
        self.res = Label(self._tk, justify='left')

        self._but_start = Button(buttons, text='start', width=10, height=1)
        self._but_start.bind('<ButtonRelease-1>', self.but1)

        self._but_demo = Button(buttons, text='demo', width=10, height=1)
        self._but_demo.bind('<ButtonRelease-1>', self.but_demo)

        self._but_reload = Button(buttons, text='reload', width=10, height=1)
        self._but_reload.bind('<ButtonRelease-1>', self.but_reload)

        self._but_load_next = Button(buttons, text='load next', width=10, height=1)
        self._but_load_next.bind('<ButtonRelease-1>', self.but_load_next)

        buttons.grid(row=0, column=0, sticky="w")
        self._canvas.grid(row=1, column=0, sticky="e")
        self._but_start.pack(side="left")
        self._but_demo.pack(side="left")
        self._but_reload.pack(side="left")
        self._but_load_next.pack(side="left")
        self.task.grid(row=3, column=0, sticky="w")
        self.res.grid(row=4, column=0, sticky="w")

    ##        self.loadmap()
    def but_load_next(self, event):
        print("load next")
        index = self.m.index(self._cur_map)
        if index < len(self.m) - 1:
            self.lm(self.m[index + 1])
        else:
            self.lm(self.m[0])

    def but_demo(self, event):
        print("demo")
        self.demo()

    def but1(self, event):
        print('start')
        # self.lm(self._cur_map)
        self.solve_task()

    def but_reload(self, event):
        print("reload")
        self.lm(self._cur_map)

    def clear(self):
        "Очистка данных (без перерисовки)"
        self._canvas.delete('all')
        self._field = []
        self._park = []
        self._Nonelabel = False
        self._NoneisPark = False
        self._Nonesettext = False
        self._test = ''
        self._res = ''
        self._bum = 0

        for r in range(1, self._nr + 2):
            row = []
            for c in range(1, self._nc + 2):
                row.append(self._Tcell())
            self._field.append(row)

        for r in range(1, self._nr):
            for c in range(1, self._nc):
                self._field[r][c].text = ''
                self._field[r][c].color = ''
                self._field[r][c].label = ''
                self._field[r][c].wUp = False
                self._field[r][c].wLeft = False
                self._field[r][c].v = self._v()

        for c in range(1, self._nc):
            self._field[1][c].wUp = True
            self._field[self._nr][c].wUp = True

        for r in range(1, self._nr):
            self._field[r][1].wLeft = True
            self._field[r][self._nc].wLeft = True

        self._solve = ''
        self._r = 1
        self._c = 1

    def _paintMap(self):
        "Перерисовка  по имеющимся данным"
        remc = self._c
        remr = self._r
        size = self._size
        sleep = self.sleep
        self.sleep = 0

        self._bg = [self._canvas.create_rectangle(1, 1, (size * (self._nc + 1)), (size * (self._nr + 1)), fill="gray")]
        # создать поле

        for r in range(1, self._nr + 1):
            self._bg.append(self._canvas.create_line(size, r * size, self._nc * size, r * size))
            if r < self._nr: self._canvas.create_text(size / 2, r * size + size / 2, text=r)
        for c in range(1, self._nc + 1):
            self._bg.append(self._canvas.create_line(c * size, size, c * size, self._nr * size))
            if c < self._nc: self._bg.append(self._canvas.create_text(c * size + size / 2, size / 2, text=c))
        # клетки и номера столбцов и строк

        for r in range(1, self._nr):
            for c in range(1, self._nc):
                self._r = r
                self._c = c
                if self._field[r][c].wUp:  # стена сверху
                    self.setWall('up')
                if self._field[r][c].wLeft:  # стена слева
                    self.setWall('left')
                if self._field[r][c].color != '':  # закраска
                    self.paint(self._field[r][c].color)
                if self._field[r][c].label != '':  # метка0000
                    d = self._d
                    x1 = self._size * (c)
                    x2 = self._size * (c + 1)
                    y1 = self._size * (r)
                    y2 = self._size * (r + 1)
                    self._canvas.delete(self._field[r][c].v.label)
                    self._field[r][c].v.label = self._canvas.create_rectangle(x1 + d, y1 + d, x2 - d, y2 - d,
                                                                              width=d - 1,
                                                                              outline=self._field[r][c].label)
                    self._canvas.lift(self._robot)
                self.settext(self._field[r][c].text)  # текст

        for self._c in range(1, self._nc):
            if self._field[self._nr][self._c].wUp:  # стена сверху
                self.setWall('down')

        for self._r in range(1, self._nr):
            if self._field[self._r][self._nc].wLeft:  # стена слева
                self.setWall('right')

        r = self._endPoint[0]
        c = self._endPoint[1]
        self._canvas.delete(self._park)
        if r > 0 and c > 0:
            self._park = self._canvas.create_oval(c * size + 6, r * size + 6, c * size + size - 6, r * size + size - 6,
                                                  width=3, outline='yellow')
        # конечная точка

        self.jumpTo((remr, remc))
        self._task = '\n' + self._task
        self.task.config(text=self._task)
        self.res.config()
        self._update()
        self.sleep = sleep
        # self.pause()

    def _update(self):
        "Обновить canvas"
        if not self._NoneUpdate:
            self._canvas.update()
            time.sleep(self.sleep)

    def start(self, fun):
        self.solve_task = fun
        self._tk.mainloop()

    ##Робот

    def pause(self, t=1):
        """Приостановка выполнения программы. Пауза в секундах.
#-------------------
r.pause() # пауза в одну секунду
#-------------------
r.pause(2) # пауза две секунды
#-------------------
"""
        time.sleep(t)

    def left(self, a=1):
        """Шаг влево
#-------------------
r.left()
#-------------------
r.lt()
#-------------------
r.lt(3)
#-------------------
"""
        if a == 1:
            if self.freeLeft():
                self._c -= 1
                self._canvas.move(self._robot, -self._size * a, 0)
                self._update()
            else:
                self._stop()
        else:
            for z in range(0, a):
                self.left()

    def right(self, a=1):
        """ Шаг вправо
#-------------------
r.right()
#-------------------
r.rt()
#-------------------
r.rt(5)
#-------------------
"""
        if a == 1:
            if self.freeRight():
                self._c += 1
                self._canvas.move(self._robot, self._size * a, 0)
                self._update()
            else:
                self._stop()

        else:
            for z in range(0, a):
                self.right()

    def up(self, a=1):
        """Шаг вверх
#-------------------
r.up()
#-------------------
r.up(3)
#-------------------
"""
        if a == 1:
            if self.freeUp():
                self._r -= 1
                self._canvas.move(self._robot, 0, -self._size * a)
                self._update()
            else:
                self._stop()
        else:
            for z in range(0, a):
                self.up()

    def down(self, a=1):
        """ Шаг вниз
#-------------------
r.down()
#-------------------
r.dn()
#-------------------
r.dn(4)
#-------------------
"""
        if a == 1:
            if self.freeDown():
                self._r += 1
                self._canvas.move(self._robot, 0, self._size * a)
                self._update()
            else:
                self._stop()
        else:
            for z in range(0, a):
                self.down()

    def jumpTo(self, coord=(1, 1)):
        """Прыжок в клетку с указанными координами. Через стены.
#-------------------
r.jumpTo((2,3)) # Робот окажется в третьем столбце второй строки
#-------------------
"""

        r = coord[0]
        c = coord[1]
        if (0 < r < self._nc) and (0 < c < self._nc):
            self._r = r
            self._c = c
            size = self._size
            self._canvas.coords(self._robot, c * size + 4, r * size + 4, c * size + size - 4, r * size + size - 4)
            self._canvas.lift(self._robot)
            self._update()
        else:
            print("Попытка переместиться за пределы поля. Отказано.")

    def paint(self, color='green'):
        """ Закрасить текущую клетку выбранным цветом. Если цвет не указан, то зеленым
#-------------------
r.paint() # Закрасит текущую клетку зеленым цветом
#-------------------
r.pt() # Закрасит текущую клетку зеленым цветом
#-------------------
r.pt('red') # Закрасит текущую клетку красным цветом
#-------------------
r.pt(r.randcolor()) # Закрасит текущую клетку случайным цветом
#-------------------
r.pt(r.label()) # Закрасит текущую клетку цветом метки в этой клетке
#-------------------
"""
        d = self._d + 1
        self._field[self._r][self._c].color = color

        x1 = self._size * (self._c)
        x2 = self._size * (self._c + 1)
        y1 = self._size * (self._r)
        y2 = self._size * (self._r + 1)
        self._canvas.delete(self._field[self._r][self._c].v.color)
        self._field[self._r][self._c].v.color = self._canvas.create_rectangle(x1 + d, y1 + d, x2 - d, y2 - d, width=0,
                                                                              fill=color)
        self._canvas.lift(self._field[self._r][self._c].v.text)
        self._canvas.lift(self._robot)
        self._canvas.lift(self._park)
        self._update()

    def setWall(self, target):
        """ Установить стену с указанной стороны
#-------------------
r.sw('up') # Установить стену сверху
#-------------------
r.sw('left') # Установить стену слева
#-------------------
r.sw('down') # Установить стену снизу
#-------------------
r.sw('right') # Установить стену справа
#-------------------
"""
        size = self._size
        w = self._w
        if target == 'up':
            r = self._r
            c = self._c
            x1 = size * (c) - 1
            x2 = size * (c + 1) + 1
            y1 = size * (r)
            y2 = size * (r + 1)
            self._field[r][c].wUp = True
            self._canvas.create_line(x1, y1, x2, y1, width=w)
        elif target == 'left':
            r = self._r
            c = self._c
            x1 = size * (c)
            x2 = size * (c + 1)
            y1 = size * (r) - 1
            y2 = size * (r + 1) + 1
            self._field[r][c].wLeft = True
            self._canvas.create_line(x1, y1, x1, y2, width=w)
        elif target == 'down':
            r = self._r + 1
            c = self._c
            x1 = size * (c) - 1
            x2 = size * (c + 1) + 1
            y1 = size * (r)
            y2 = size * (r + 1)
            self._field[r][c].wDown = True
            self._canvas.create_line(x1, y1, x2, y1, width=w)
        elif target == 'right':
            r = self._r
            c = self._c + 1
            x1 = size * (c)
            x2 = size * (c + 1)
            y1 = size * (r) - 1
            y2 = size * (r + 1) + 1
            self._field[r][c].wRight = True
            self._canvas.create_line(x1, y1, x1, y2, width=4)
        self._update()

    def wallUp(self):
        """ Возвращает истину, если сверху есть стена
#-------------------
if r.wallUp(): r.pt() # Закрасить, если сверху стена
#-------------------
if r.wu(): r.pt() # Закрасить, если сверху стена
#-------------------
if r.wu():
    r.pt() # Закрасить, если сверху стена
    r.rt() # Перейти вправо
#-------------------
while r.wu(): # Идти вправо, пока сверху есть стена
    r.rt()
"""
        return self._field[self._r][self._c].wUp

    def wallDown(self):
        """ Возвращает истину, если снизу есть стена
#-------------------
if r.wallDown(): r.pt() # Закрасить, если снизу стена
#-------------------
if r.wd(): r.pt() # Закрасить, если снизу стена
#-------------------
if r.wd():
    r.pt() # Закрасить, если снизу стена
    r.rt() # Перейти вправо
#-------------------
while r.wd(): # Идти вправо, пока снизу есть стена
    r.rt()
"""
        return self._field[self._r + 1][self._c].wUp

    def wallLeft(self):
        """ Возвращает истину, если слева есть стена
#-------------------
if r.wallLeft(): r.pt() # Закрасить, если слева стена
#-------------------
if r.wl(): r.pt() # Закрасить, если слева стена
#-------------------
if r.wl():
    r.pt() # Закрасить, если слева стена
    r.dn() # Перейти вниз
#-------------------
while r.wl(): # Идти вниз, пока слева есть стена
    r.dn()
"""
        return self._field[self._r][self._c].wLeft

    def wallRight(self):
        """ Возвращает истину, если справа есть стена
#-------------------
if r.wallRight(): r.pt() # Закрасить, если справа стена
#-------------------
if r.wr(): r.pt() # Закрасить, если справа стена
#-------------------
if r.wr():
    r.pt() # Закрасить, если справа стена
    r.dn() # Перейти вниз
#-------------------
while r.wr(): # Идти вниз, пока справа есть стена
    r.dn()
"""
        return self._field[self._r][self._c + 1].wLeft

    def freeUp(self):
        """ Возвращает истину, если сверху свободно (нет стены)
#-------------------
if r.freeUp(): r.pt() # Закрасить, если сверху свободно
#-------------------
if r.fu(): r.up() # Шагнуть вверх, если сверху свободно
#-------------------
if r.fu():
    r.up() # Шагнуть вверх
    r.pt() # Закрасить
    r.dn() # Перейти вниз
#-------------------
while r.fu(): # Идти вверх, пока сверху свободно
    r.up()
"""
        return not self._field[self._r][self._c].wUp

    def freeDown(self):
        """ Возвращает истину, если снизу свободно (нет стены)
#-------------------
if r.freeDown(): r.pt() # Закрасить, если снизу свободно
#-------------------
if r.fd(): r.dn() # Шагнуть вверх, если снизу свободно
#-------------------
if r.fd():
    r.dn() # Шагнуть снизу
    r.pt() # Закрасить
    r.up() # Перейти вверх
#-------------------
while r.fd(): # Идти вниз, пока снизу свободно
    r.dn()
"""
        return not self._field[self._r + 1][self._c].wUp

    def freeLeft(self):
        """ Возвращает истину, если слева свободно (нет стены)
#-------------------
if r.freeLeft(): r.pt() # Закрасить, если слева свободно
#-------------------
if r.fl(): r.lt() # Шагнуть влево, если слева свободно
#-------------------
if r.fl():
    r.lt() # Шагнуть влево
    r.pt() # Закрасить
    r.rt() # Перейти вправо
#-------------------
while r.fl(): # Идти влево, пока слева свободно
    r.lt()
"""
        return not self._field[self._r][self._c].wLeft

    def freeRight(self):
        """ Возвращает истину, если снизу свободно (нет стены)
#-------------------
if r.freeDown(): r.pt() # Закрасить, если снизу свободно
#-------------------
if r.fd(): r.dn() # Шагнуть вверх, если снизу свободно
#-------------------
if r.fd():
    r.dn() # Шагнуть снизу
    r.pt() # Закрасить
    r.up() # Перейти вверх
#-------------------
while r.fd(): # Идти вниз, пока снизу свободно
    r.dn()
"""
        return not self._field[self._r][self._c + 1].wLeft

    def getCoords(self):
        " Возвращает координаты в виде (row,column)"
        return (self._r, self._c)

    def getCoordR(self):
        " Возвращает номер строки, в которой находиться Робот"
        return self._r

    def getCoordC(self):
        " Возвращает номер столбца, в которой находиться Робот"
        return self._c

    def isPark(self):
        " Возвращает истину, если Робот находиться на парковке"
        if self._NoneisPark:
            self.null()
        else:
            return self._endPoint == self.getCoords()

    def color(self):
        """ Возвращает цвет, которым закрашена клетка
Можно использовать для проверки, закрашена ли клетка:
#-------------------
# Закрасить, если сверху закрашено
r.up()
if r.color():
    r.dn()
    r.pt()
else:
    r.dn()
#-------------------
if r.color() == 'red': r.rt() # Вправо, если закрашено красным
#-------------------
"""
        return self._field[self._r][self._c].color

    def randcolor(self):
        """ Возвращает случайный цвет
#-------------------
r.pt(r.randcolor()) # Закрасить случайным цветом
#-------------------
# Закрасить соседнюю клетку тем же цветом, что и текущая
x = r.color()
r.rt()
r.pt(x)
#-------------------
"""
        cr = rnd(1, 255, 10)
        cg = rnd(1, 255, 10)
        cb = rnd(1, 255, 10)
        color = "#%02X%02X%02X" % (cr, cg, cb)
        return str(color)

    def label(self):
        """ Возвращает цвет метки текущей клетки
#-------------------
if r.label() == 'red': r.pt('red') # Закрасить клетку красным, если метка красная
#-------------------
"""
        if self._Nonelabel:
            self.null()
        else:
            return self._field[self._r][self._c].label

    def gettext(self):
        """ Возвращает текст, записанный в ячейке.
#-------------------
if r.gettext() != '': r.rt() # Перейти вправо, если в ячейке есть какой-нибудь текст
#-------------------
if r.gettext() == '3': r.rt() # Перейти вправо, если в ячейке записано 3
#-------------------
n = r.gettext()
if n: r.rt(n) # Перейти вправо на количество шагов, указанное в клетке
#-------------------
"""
        if self._Nonegettext:
            self.null()
        else:
            return self._field[self._r][self._c].text

    def settext(self, text):
        """ Записать текст в клетку
#-------------------
r.settext(3)
#-------------------
"""
        self._field[self._r][self._c].text = text
        d = 1
        x1 = self._size * (self._c)
        x2 = self._size * (self._c + 1)
        y1 = self._size * (self._r)
        y2 = self._size * (self._r + 1)
        self._canvas.delete(self._field[self._r][self._c].v.text)
        self._field[self._r][self._c].v.text = self._canvas.create_text(self._c * self._size + self._size / 2,
                                                                        self._r * self._size + self._size / 2, text=
                                                                        self._field[self._r][self._c].text,
                                                                        font=('Helvetica', self._font_size, 'bold'))
        self._update()

    def _stop(self):
        print("Bum!")
        self._bum = 1
        self._canvas.delete(self._robot)
        x = self._c
        y = self._r

        self._robot = self._canvas.create_oval(
            x * self._size + 2 * self._d, y * self._size + 2 * self._d,
            x * self._size + self._size - 2 * self._d, y * self._size + self._size - 2 * self._d,
            fill='#FF0000')

    def null(self, *args):
        print('Эта команда запрещена к использованию в данной задаче. Ищите другой способ')
        return ''

    def loadmap(self, mn=m[0], variant=0):
        """ Загрузить карту (задачу)
#-------------------
r.loadmap('task10-5')
#-------------------
r.lm('task10-5') # Загрузить задачу по названию
#-------------------
r.lm(r.m[5]) # Загрузить задачу по номеру
#-------------------
# Вывести полный список названий и номеров заданий
for x in r.m:
    print r.m.index(x),x
#-------------------
"""
        self._tk.title(mn)
        self._cur_map = mn
        self._NoneUpdate = False
        self._endPoint = (0, 0)
        #        self._NoneUpdate = True

        if mn == 'task1':
            self._nc = 7
            self._nr = 5
            self._size = 30

            self.clear()
            self._r = 3
            self._c = 2

            self._solve = ''
            self._endPoint = (3, 5)
            self._task = 'Необходимо перевести Робота по лабиринту\n' \
                         ' из начального положения в конечное.\n'

            self._field[2][2].wUp = True
            self._field[2][3].wUp = True
            self._field[2][4].wUp = True
            self._field[2][5].wUp = True

            self._field[4][2].wUp = True
            self._field[4][3].wUp = True
            self._field[4][4].wUp = True
            self._field[4][5].wUp = True

            self._field[2][4].wLeft = True
            self._field[3][3].wLeft = True
            self._field[3][5].wLeft = True

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task2':
            self._nc = 16
            self._nr = 4
            self._size = 30

            self.clear()
            self._r = 3
            self._c = 1

            self._solve = ''

            self._task = 'Составьте программу рисования узора.\n'

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task3':
            self._nc = 10
            self._nr = 5
            self._size = 30
            self.clear()
            self._r = 2
            self._c = 1

            self._endPoint = (2, 9)
            self._solve = ''
            self._task = 'Необходимо провести Робота вдоль коридора\n' \
                         ' из начального положения в конечное,\n' \
                         ' заглядывая в каждый боковой коридор.'

            for i in range(2, 9):
                self._field[2][i].wUp = True
                if i % 2 == 0:
                    self._field[3][i].wUp = True
                else:
                    self._field[4][i].wUp = True

                if i < 8:
                    self._field[3][i + 1].wLeft = True

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task4':
            self._nc = 8
            self._nr = 12
            self._size = 30
            self.clear()
            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            for i in range(0, 5):
                for j in range(0, 3):
                    self._field[6 + 2 * j - i][2 + i].label = 'red'

            self._solve = ''
            self._task = 'Составьте программу закрашивания\n' \
                         ' клеток поля, отмеченных звездочкой.\n'

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task5':
            self._nc = 16
            self._nr = 11
            self._r = 1
            self._c = 1
            self._size = 30

            self.clear()
            self._solve = ''
            self._task = 'Составьте программу рисования узора.'

        ##--------------------------------------------------------------------------------------------
        ##--------------------------------------------------------------------------------------------
        elif mn == 'task6':
            self._nc = 25
            self._nr = 25
            self._r = 1
            self._c = 1
            self._size = 20
            self.clear()
            self._solve = ''
            self._task = 'Составьте программу рисования фигуры в виде буквы "Т".\n' \
                         ' Вертикальные и горизонтальные размеры пользователь вводит\n' \
                         ' с клавиатуры. Ввод данных можно осуществлять любым способом.\n'

        ##-------------------------------------------------------------------------------------------------------
        elif mn == 'task7':
            self._nc = 16
            self._nr = 11
            self._size = 25

            self.clear()

            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            self._field[3][2].wUp = True
            self._field[2][9].wUp = True
            self._field[3][12].wUp = True
            self._field[6][12].wUp = True
            self._field[7][3].wUp = True
            self._field[7][9].wUp = True
            self._field[8][6].wUp = True
            self._field[9][2].wUp = True
            self._field[9][11].wUp = True

            for i in range(0, 4):
                self._field[4][5 + i].wUp = True
                self._field[5][5 + i].wUp = True

            self._solve = ''

            self._task = 'Где-то в поле Робота находится горизонтальный коридор шириной в одну клетку\n' \
                         ' неизвестной длины. Робот из верхнего левого угла поля должен дойти до\n' \
                         ' коридора и закрасить клетки внутри него, как указано в задании. По полю\n' \
                         ' Робота в произвольном порядке располагаются стены, но расстояние \n' \
                         'между ними больше одной клетки.\n'
        ##--------------------------------------------------------------------------------------------
        elif mn == 'task8':
            self._nc = 16
            self._nr = 11
            self._size = 25

            self.clear()

            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            self._field[2][6].wLeft = True
            self._field[3][6].wLeft = True
            self._field[5][6].wLeft = True
            self._field[6][6].wLeft = True
            self._field[7][6].wLeft = True
            self._field[8][6].wLeft = True

            self._solve = ''
            self._task = 'Где-то в поле Робота находится вертикальная стена с отверстием в одну клетку,\n' \
                         ' размеры которой неизвестны. Робот из произвольной клетки должен дойти до\n' \
                         ' стены и закрасить клетки как показано в задании.\n'

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task9':
            self._nc = 20
            self._nr = 20
            self._size = 25

            self.clear()

            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            c = rnd(2, 16)
            r = rnd(2, 16)
            w = rnd(3, 8)
            h = rnd(3, 8)
            if c + w >= self._nc: w = self._nc - c
            if r + h >= self._nc: h = self._nr - r

            for rcount in range(0, h):
                for ccount in range(0, w):
                    self._field[r + rcount][c + ccount].color = 'green'

            self._solve = ''

            self._task = 'На поле находится квадрат из закрашенных клеток. Вычислить и вывести на экран площадь квадрата.\n'

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task10':
            self._nc = 15
            self._nr = 11
            self._size = 30
            self.clear()
            self._r = 2
            self._c = 1

            self._field[2][1].wUp = True
            self._field[2][2].wUp = True
            self._field[2][4].wUp = True
            self._field[2][5].wUp = True
            self._field[2][6].wUp = True
            self._field[2][8].wUp = True
            self._field[2][9].wUp = True
            self._field[2][11].wUp = True
            self._field[2][12].wUp = True
            self._field[2][13].wLeft = True

            self._field[3][1].wUp = True
            self._field[3][2].wUp = True
            self._field[3][3].wUp = True
            self._field[3][4].wUp = True
            self._field[3][6].wUp = True
            self._field[3][7].wUp = True
            self._field[3][8].wUp = True
            self._field[3][10].wUp = True
            self._field[3][11].wUp = True
            self._field[3][12].wLeft = True

            self._field[4][3].wLeft = True
            self._field[4][3].wUp = True
            self._field[4][4].wUp = True
            self._field[4][5].wUp = True
            self._field[4][6].wUp = True
            self._field[4][8].wUp = True
            self._field[4][9].wUp = True
            self._field[4][10].wUp = True
            self._field[4][11].wUp = True
            self._field[4][13].wLeft = True

            self._field[5][3].wLeft = True
            self._field[5][4].wLeft = True
            self._field[5][4].wUp = True
            self._field[5][6].wUp = True
            self._field[5][7].wUp = True
            self._field[5][8].wUp = True
            self._field[5][10].wUp = True
            self._field[5][11].wUp = True
            self._field[5][12].wUp = True

            self._field[6][3].wLeft = True
            self._field[6][4].wUp = True
            self._field[6][5].wLeft = True

            self._field[7][3].wUp = True
            self._field[7][4].wLeft = True
            self._field[7][6].wUp = True
            self._field[7][7].wLeft = True

            self._field[8][4].wUp = True
            self._field[8][5].wUp = True
            self._field[8][6].wLeft = True
            self._field[8][7].wUp = True
            self._field[8][8].wLeft = True

            self._field[9][6].wUp = True
            self._field[9][7].wLeft = True
            self._field[9][8].wUp = True
            self._field[9][9].wUp = True
            self._field[9][10].wLeft = True

            self._field[10][7].wUp = True
            self._field[10][9].wLeft = True
            self._field[10][10].wLeft = True

            self._endPoint = (10, 1)
            self._solve = """
"""

            self._task = 'Необходимо провести Робота по коридору шириной в одну клетку из начального положения до конца коридора, \n' \
                         'закрашивая при этом все клетки коридора, которые имеют выход. Выходы размером в одну клетку располагаются \n' \
                         'произвольно по всей длине коридора. Коридор заканчивается тупиком. Коридор имеет два горизонтальных и \n' \
                         'диагональный участки. Пример коридора показан на рисунке.\n'

        elif mn == 'task11':
            self._nc = 15
            self._nr = 11
            self._size = 30
            self.clear()

            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            for i in range(1, self._nr):
                for j in range(1, self._nc):
                    self._field[i][j].text = str(rnd(0, 10))

            self._task = 'На поле 10х15 каждой в каждой клетке записана цифра (от 0 до 9).\n Закрасить квадрат 2х2 с наименьшей суммой значений клеток.'

        elif mn == 'task12':
            self._nc = 15
            self._nr = 6
            self._size = 30
            self.clear()

            self._r = 2
            self._c = 13

            self._field[2][2].wUp = True
            self._field[2][3].wLeft = True
            self._field[3][3].wLeft = True
            self._field[4][3].wLeft = True
            self._field[5][3].wUp = True
            self._field[5][4].wUp = True
            self._field[4][5].wLeft = True
            self._field[3][5].wLeft = True
            self._field[2][5].wLeft = True
            self._field[2][5].wUp = True
            self._field[2][6].wLeft = True
            self._field[3][6].wLeft = True
            self._field[4][6].wLeft = True
            self._field[5][6].wUp = True
            self._field[5][7].wUp = True
            self._field[5][8].wUp = True
            self._field[4][9].wLeft = True
            self._field[3][9].wLeft = True
            self._field[2][9].wLeft = True
            self._field[2][9].wUp = True
            self._field[2][10].wUp = True
            self._field[2][11].wLeft = True
            self._field[3][11].wLeft = True
            self._field[4][11].wLeft = True
            self._field[5][11].wUp = True
            self._field[4][12].wLeft = True
            self._field[3][12].wLeft = True
            self._field[2][12].wLeft = True
            self._field[2][12].wUp = True
            self._field[2][13].wUp = True

            self._task = 'Робот движется вдоль стены, профиль которой показан на рисунке,\n' \
                         ' от начального положения до конца стены. Необходимо закрасить\n' \
                         ' все внутренние углы стены, как показано на примере. Размеры стены\n могут быть произвольны.'

        elif mn == 'task13':
            self._nc = 20
            self._nr = 20
            self._size = 25

            self.clear()

            self._r = rnd(self._nr / 2, self._nr)
            self._c = rnd(self._nc / 2, self._nc)

            col = rnd(2, self._nc / 2)
            row = rnd(4, self._nr / 2)
            height = rnd(4, self._nr - 4)

            if row + height >= self._nr:
                height = self._nr - row - 1

            for i in range(row, row + height):
                self._field[i][col].wLeft = True

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

        ##--------------------------------------------------------------------------------------------
        # сделать прямое управление с демонстрацией датчиков и возможностей
        # при запуске робота создавать task.py и справочник :)
        # сделать робота без клеток !!!
        ##--------------------------------------------------------------------------------------------
        ##--------------------------------------------------------------------------------------------
        else:
            print(mn)
            self._task = "Нет задачи с таким номером"
            self._test = '-'

        self._canvas.config(
            width=(self._size * (self._nc + 1)),
            height=(self._size * (self._nr + 1)))
        x = y = 1
        d = self._d
        d = 6
        self._robot = self._canvas.create_oval(
            x * self._size + d, y * self._size + d,
            x * self._size + self._size - d, y * self._size + self._size - d,
            outline='#4400FF', width=3)

        self._paintMap()

    lm = loadmap
    lt = left
    rt = right
    dn = down
    pt = paint
    sw = setWall
    wu = wallUp
    wd = wallDown
    wl = wallLeft
    wr = wallRight
    fu = freeUp
    fd = freeDown
    fl = freeLeft
    fr = freeRight
    cl = color
Пример #6
0
class main:
    def __init__(self, master):
        #master frame
        self.frame = Frame(master)
        self.frame.pack(fill="both", expand=True)

        #canvas where the game is played on
        self.canvas = Canvas(self.frame, width=300, height=300)
        self.canvas.pack(fill="both", expand=True)

        #Shows status of game
        self.label = Label(self.frame,
                           text='Tic Tac Toe Game',
                           height=6,
                           bg='black',
                           fg='blue')
        self.label.pack(fill="both", expand=True)

        #frame to contain the buttons
        self.frameb = Frame(self.frame)
        self.frameb.pack(fill="both", expand=True)

        #Buttons to initiate the game
        self.Start1 = Button(self.frameb,
                             text='Click here to start\ndouble player',
                             height=4,
                             command=self.start1,
                             bg='white',
                             fg='purple')
        self.Start1.pack(fill="both", expand=True, side=RIGHT)
        self.Start2 = Button(self.frameb,
                             text='Click here to start\nsingle player',
                             height=4,
                             command=self.start2,
                             bg='purple',
                             fg='white')
        self.Start2.pack(fill="both", expand=True, side=LEFT)

        #canvas board drawing function call
        self._board()

    def start1(self):
        #Starts double player

        #refresh canvas
        self.canvas.delete(ALL)
        self.label['text'] = ('Tic Tac Toe Game')

        #function call on click
        self.canvas.bind("<ButtonPress-1>", self.sgplayer)
        self._board()

        #Starts the matrix to do calculations
        #of the positions of circles and crosses.
        self.TTT = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

        #counter of turns
        self.i = 0

        #trigger to end game
        self.j = False

    def start2(self):
        #Starts single player
        self.canvas.delete(ALL)
        self.label['text'] = ('Tic Tac Toe Game')
        self.canvas.bind("<ButtonPress-1>", self.dgplayer)
        self._board()
        self.TTT = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
        self.i = 0
        self.j = False
        #Trigger to check the validity of the move
        self.trigger = False

    def end(self):
        #Ends the game
        self.canvas.unbind("<ButtonPress-1>")
        self.j = True

    def _board(self):
        #Creates the board
        self.canvas.create_rectangle(0, 0, 300, 300, outline="black")
        self.canvas.create_rectangle(100, 300, 200, 0, outline="black")
        self.canvas.create_rectangle(0, 100, 300, 200, outline="black")

    def sgplayer(self, event):
        #Double player game loop
        for k in range(0, 300, 100):
            for j in range(0, 300, 100):
                #checks if the mouse input is in a bounding box
                if event.x in range(k, k + 100) and event.y in range(
                        j, j + 100):
                    #checks if there is nothing in the bounding box
                    if self.canvas.find_enclosed(k, j, k + 100, j + 100) == ():
                        #Player plays first
                        if self.i % 2 == 0:
                            #draws circle
                            #no need to create a new function since there is just two cases where this code is used
                            X = (2 * k + 100) / 2
                            Y = (2 * j + 100) / 2
                            X1 = int(k / 100)
                            Y1 = int(j / 100)
                            self.canvas.create_oval(X + 25,
                                                    Y + 25,
                                                    X - 25,
                                                    Y - 25,
                                                    width=4,
                                                    outline="black")
                            self.TTT[Y1][X1] += 1
                            self.i += 1
                        else:
                            #creates the cross.
                            #I don't use the self.cross function here because k and j are not compatible
                            X = (2 * k + 100) / 2
                            Y = (2 * j + 100) / 2
                            X1 = int(k / 100)
                            Y1 = int(j / 100)
                            self.canvas.create_line(X + 20,
                                                    Y + 20,
                                                    X - 20,
                                                    Y - 20,
                                                    width=4,
                                                    fill="black")
                            self.canvas.create_line(X - 20,
                                                    Y + 20,
                                                    X + 20,
                                                    Y - 20,
                                                    width=4,
                                                    fill="black")
                            self.TTT[Y1][X1] += 9
                            self.i += 1
        #After everything, remember to check for wins/losts/draws
        self.check()

    def dgplayer(self, event):
        for k in range(0, 300, 100):
            for j in range(0, 300, 100):
                if self.i % 2 == 0:
                    if event.x in range(k, k + 100) and event.y in range(
                            j, j + 100):
                        if self.canvas.find_enclosed(k, j, k + 100,
                                                     j + 100) == ():
                            X = (2 * k + 100) / 2
                            Y = (2 * j + 100) / 2
                            X1 = int(k / 100)
                            Y1 = int(j / 100)
                            self.canvas.create_oval(X + 25,
                                                    Y + 25,
                                                    X - 25,
                                                    Y - 25,
                                                    width=4,
                                                    outline="black")
                            self.TTT[Y1][X1] += 1
                            self.i += 1
                            self.check()
                            self.trigger = False
                else:
                    print(self.i)
                    #check for wins/losts/draws first
                    #before allowing the computer to make its turn
                    self.check()
                    #Game AI code
                    self.AIcheck()
                    #refresh validity of move
                    self.trigger = False

    def check(self):
        #horizontal check
        for i in range(0, 3):
            if sum(self.TTT[i]) == 27:
                self.label['text'] = ('2nd player wins!')
                self.end()
            if sum(self.TTT[i]) == 3:
                self.label['text'] = ('1st player wins!')
                self.end()
        #vertical check
        #the matrix below transposes self.TTT so that it could use the sum function again
        #for vertical rows
        self.ttt = [[row[i] for row in self.TTT] for i in range(3)]
        for i in range(0, 3):
            if sum(self.ttt[i]) == 27:
                self.label['text'] = ('2nd player wins!')
                self.end()
            if sum(self.ttt[i]) == 3:
                self.label['text'] = ('1st player wins!')
                self.end()
        #check for diagonal wins
        if self.TTT[1][1] == 9:
            if self.TTT[0][0] == self.TTT[1][1] and self.TTT[2][2] == self.TTT[
                    1][1]:
                self.label['text'] = ('2nd player wins!')
                self.end()
            if self.TTT[0][2] == self.TTT[1][1] and self.TTT[2][0] == self.TTT[
                    1][1]:
                self.label['text'] = ('2nd player wins!')
                self.end()
        if self.TTT[1][1] == 1:
            if self.TTT[0][0] == self.TTT[1][1] and self.TTT[2][2] == self.TTT[
                    1][1]:
                self.label['text'] = ('1st player wins!')
                self.end()
            if self.TTT[0][2] == self.TTT[1][1] and self.TTT[2][0] == self.TTT[
                    1][1]:
                self.label['text'] = ('1st player wins!')
                self.end()
        #check for draws
        if self.j == False:
            a = 0
            for i in range(0, 3):
                a += sum(self.TTT[i])
            #As the player starts with a circle(value=1),
            #There will be a total of 5(1) and 4(9)=41
            if a == 41:
                self.label['text'] = ("It's a pass!")
                self.end()

    '''Note for AI game programming:
    There are only three sides to AI actions: Offense, Defense, Neutral
    Offense is what the AI does to win
    In the TTT case, the computer will add another cross to two crosses in a row to win
    
    Defense is what the AI does to prevent the other guy from winning
    In this case, the computer will add another cross to two circles in a row to block
    
    Neutral is when it can't do neither.
    However, we can't really let it do nothing, so instead, we let it do a random move.
    '''

    def AIcheck(self):
        #Offense should come before defense so that the AI will try to win if possible
        #This is built on the self.check function
        self.ttt = [[row[i] for row in self.TTT] for i in range(3)]
        #OFFENSE
        #this is the vertical checklist
        for h in range(0, 3):
            k = 0
            j = 0
            if sum(self.TTT[h]) == 18:
                while k < 3:
                    if k == h:
                        while j < 3:
                            if self.trigger == False:
                                if self.TTT[k][j] == 0:
                                    self.cross(j, k)
                                    break
                            j += 1
                    k += 1
        #this is the horizontal checklist
        for h in range(0, 3):
            k = 0
            j = 0
            if sum(self.ttt[h]) == 18:
                while k < 3:
                    if k == h:
                        while j < 3:
                            if self.trigger == False:
                                if self.ttt[k][j] == 0:
                                    self.cross(k, j)
                                    break
                            j += 1
                    k += 1
        '''In this case, while I could have used a for loop,
        I preferred not to, since there are just four cases, and
        designing a for loop is not worth the effort.
        You can see that from the length of the code, it's just simple
        copy and paste.
        '''
        #this is the diagonal checklist
        if self.TTT[1][1] == 9:
            if self.TTT[0][0] == 9:
                if self.trigger == False:
                    if self.TTT[2][2] == 0:
                        self.cross(2, 2)
            if self.TTT[0][2] == 9:
                if self.trigger == False:
                    if self.TTT[2][0] == 0:
                        self.cross(0, 2)
            if self.TTT[2][0] == 9:
                if self.trigger == False:
                    if self.TTT[0][2] == 0:
                        self.cross(2, 0)
            if self.TTT[2][2] == 9:
                if self.trigger == False:
                    if self.TTT[0][0] == 0:
                        self.cross(0, 0)
        #DEFENSE
        #this is the horizontal checklist
        for h in range(0, 3):
            k = 0
            j = 0
            if sum(self.TTT[h]) == 2:
                while k < 3:
                    if k == h:
                        while j < 3:
                            if self.trigger == False:
                                if self.TTT[k][j] == 0:
                                    self.cross(j, k)
                                    break
                            j += 1
                    k += 1
        #this is the vertical checklist
        for h in range(0, 3):
            k = 0
            j = 0
            if sum(self.ttt[h]) == 2:
                while k < 3:
                    if k == h:
                        while j < 3:
                            if self.trigger == False:
                                if self.ttt[k][j] == 0:
                                    self.cross(k, j)
                                    break
                            j += 1
                    k += 1
        #this is the diagonal checklist
        if self.TTT[1][1] == 1:
            if self.TTT[0][0] == 1:
                if self.trigger == False:
                    if self.TTT[2][2] == 0:
                        self.cross(2, 2)
            if self.TTT[0][2] == 1:
                if self.trigger == False:
                    if self.TTT[2][0] == 0:
                        self.cross(0, 2)
            if self.TTT[2][0] == 1:
                if self.trigger == False:
                    if self.TTT[0][2] == 0:
                        self.cross(2, 0)
            if self.TTT[2][2] == 1:
                if self.trigger == False:
                    if self.TTT[0][0] == 0:
                        self.cross(0, 0)
        #NEUTRAL
        '''The crux of the game is in the center
        So, the computer should get the center when it gets the chance.
        Other than that, it will just do a random move if nothing else works.
        That's  why this code is at the bottom.
        '''
        if self.TTT[1][1] == 0:
            if self.trigger == False:
                self.cross(1, 1)
                self.trigger = True
        else:
            if self.trigger == False:
                self.randmove()

    def cross(self, k, j):
        # k is the x coords
        # j is the y coords
        X = (200 * k + 100) / 2
        Y = (200 * j + 100) / 2
        X1 = int(k)
        Y1 = int(j)
        self.canvas.create_line(X + 20,
                                Y + 20,
                                X - 20,
                                Y - 20,
                                width=4,
                                fill="black")
        self.canvas.create_line(X - 20,
                                Y + 20,
                                X + 20,
                                Y - 20,
                                width=4,
                                fill="black")
        self.TTT[Y1][X1] += 9
        self.check()
        self.i += 1
        self.trigger = True

    def randmove(self):
        # In case there's nothing for the computer to do
        while True:
            k = (randint(0, 2))
            j = (randint(0, 2))
            if self.TTT[j][k] == 0:
                self.cross(k, j)
                break
            else:
                k = (randint(0, 2)) * 100
                j = (randint(0, 2)) * 100
Пример #7
0
class TriangulationGUI(Frame):
    """Class used for representing a triangulation"""

    def __init__(self, parent):
        """Constructor which takes in parent (the main window)"""
        Frame.__init__(self, parent)
        self.parent = parent
        self.initUI()
        self.points = []
        self.delt = None
        self.working = False
        self.edge_dic = {}
        self.visualization = False
        self.voronoi_on = False
        self.voronoi = None

    def draw_point_locate(self, face):
        """Show the point location for a given face"""
        face_points = []
        for vert in face.vertices:
            if vert.point[2] == 0:
                # Inifinity points must be reallllllllly far away
                face_points.append(vert.point[0] * 1000000000)
                face_points.append(vert.point[1] * 1000000000)
            else:
                face_points.append(vert.point[0])
                face_points.append(vert.point[1])
        # Make the polygon
        self.canvas.create_polygon(*face_points, fill="gray",
                                   outline="black", tag="locate")
        self.canvas.update_idletasks()
        # Sleep so that the user can actually see what's happening
        time.sleep(.5)
        self.canvas.delete("locate")  # Delete the highlighted triangle

    def click(self, event):
        """Event for when the user clicks on the screen"""
        # working is used so that the user cannot add points while the
        # algorithm is running. If we don't have this, we would have a weird
        # error sometimes that would cause points not to be added
        if self.working:
            return

        self.working = True
        self.canvas.delete("circle")  # the circumcircle may not be valid
        point = pyVor.primitives.Point(event.x, event.y)
        self.points.append(point)
        self.add_point(point)
        self.clear_vononoi()  # the voronoi diagram may not be valid anymore
        self.add_point(pyVor.primitives.Point(event.x, event.y))
        # if the triangulation exists, add the point to the triangulation,
        # otherwise, make a new triangulation
        if self.delt:
            self.delt.delaunay_add(pyVor.primitives.Point(event.x, event.y),
                                   homogeneous=False)
        else:
            self.delt = pyVor.structures.DelaunayTriangulation(
                (pyVor.primitives.Point(event.x, event.y),),
                randomize=False,
                homogeneous=False,
                # draw_circle=self.draw_circle,
                # location_visualizer=self.draw_point_locate,
                # draw_triangulation=self.draw_triangulation,
                # highlight_edge=self.highlight_edge,
                # delete_edge=self.delete_edge,
                gui=self)
        self.canvas.delete("locate")
        self.draw_triangulation(self.delt)
        if self.voronoi_on:
            self.draw_voronoi()
        self.working = False

    def show_circle(self, event):
        """Shows a circumcircle for a triangle if the user wants to see it"""
        face = self.delt.locate(pyVor.primitives.Point(event.x, event.y, 1))
        self.draw_circle(face)

    def draw_circle(self, face, color="black", delete=False, sleep=False):
        if delete:
            self.canvas.delete("circle")
        for vert in face.vertices:
            if vert.point[2] == 0:
                return
        center = pyVor.utils.circumcenter(
            *[vert.point for vert in face.vertices])
        face_point = next(iter(face.vertices)).point
        distance = float((face_point - center).norm_squared()) ** .5
        self.canvas.create_oval(center[0] - distance, center[1] - distance,
                                center[0] + distance, center[1] + distance,
                                outline=color, dash=(5,), tag="circle")
        self.canvas.update_idletasks()
        if sleep:
            time.sleep(1)

    def highlight_edge(self, facet, color="black", tag="edge", add=True):
        points = []
        for point in facet.points():
            points.append(point[0])
            points.append(point[1])
        line = self.canvas.create_line(*points, fill=color, tag=tag)
        if add:
            self.edge_dic[facet] = line
        self.canvas.update()

    def clear(self, event):
        """Removes all circles"""
        self.canvas.delete("circle")

    def toggle_visualization(self, event):
        """Switch visualization on and off"""
        # if self.visualization:
        #     self.set_visualize(False)
        # else:
        #     self.set_visualize(True)
        self.visualization = not self.visualization

    def toggle_voronoi(self, event):
        """Switches the voronoi diagram on or off"""
        self.voronoi_on = False if self.voronoi_on else True
        if self.voronoi_on:
            self.draw_voronoi()
            self.canvas.update()
        else:
            self.clear_vononoi()

    def clear_vononoi(self):
        """Delete the voronoi diagram from the screen"""
        self.canvas.delete("voronoipoint")
        self.canvas.delete("voronoiedge")

    def draw_voronoi(self):
        """Draws the voronoi diagram"""
        self.voronoi = pyVor.structures.Voronoi(self.delt)
        for point in self.voronoi.points:
            self.add_point(point, color="red", tag="voronoipoint")

        for edge in self.voronoi.edges:
            point1, point2 = edge
            point1 = point1[:-1].to_vector() * 1000000 if point1[-1] == 0\
                else point1[:-1].to_vector()
            point2 = point2[:-1].to_vector() * 1000000 if point2[-1] == 0\
                else point2[:-1].to_vector()
            self.canvas.create_line(*point1, *point2,
                                    fill="red", tag="voronoipoint")

    def initUI(self):
        """Initialize the window"""
        self.parent.title("Delaunay Triangulation")
        self.pack(fill=BOTH, expand=1)
        self.canvas = Canvas(self)
        self.canvas.bind("<Button-1>", self.click)
        self.canvas.bind("c", self.show_circle)
        self.canvas.bind("<Button-2>", self.show_circle)
        self.canvas.bind("<Button-3>", self.show_circle)
        self.canvas.bind("<BackSpace>", self.clear)
        self.canvas.bind("<v>", self.toggle_voronoi)
        self.canvas.bind("s", self.toggle_visualization)
        self.canvas.bind("p", self.print_point_history)
        self.canvas.focus_set()
        self.canvas.pack(fill=BOTH, expand=1)

    def delete_edge(self, facet):
        self.canvas.delete(self.edge_dic[facet])
        self.canvas.update_idletasks()

    def add_point(self, point, color="black", tag=""):
        """Add a point to the screen"""
        self.canvas.create_oval(point[0] - 5, point[1] - 5, point[0] + 5,
                                point[1] + 5,
                                outline=color,
                                fill=color,
                                tag=tag)

    def draw_triangulation(self, triangulation, clear=False, sleep=False):
        """Actually draw the triangulation"""
        self.canvas.delete("triangle")
        self.canvas.delete("circle")
        self.canvas.delete("highlight_edge")
        if clear:
            self.canvas.delete("all")
            for point in self.points:
                self.add_point(point)
        faces = triangulation.face_point_sets(homogeneous=False)
        for face in faces:
            face_points = []
            for point in face:
                face_points.append(point[0])
                face_points.append(point[1])
            self.canvas.create_polygon(*face_points, fill="", outline="black",
                                       tag="triangle")
        # facets = triangulation.get_facets()
        # for facet in facets:
        # if not self.is_infinite(facet):
        #        self.highlight_edge(facet, tag="triangle")
        self.canvas.update_idletasks()
        if sleep:
            time.sleep(0.5)

    def is_infinite(self, facet):
        points = facet.points()
        if points[0][2] == 0 or points[1][2] == 0:
            return True
        return False

    def print_point_history(self, event):
        """Print to stdout the list of points added so far, in order"""
        print(self.delt.point_history.__repr__())
Пример #8
0
class Visual(Frame):
    board = None
    canvas = None

    CELL_SIZE = 20

    def __init__(self, board):
        super().__init__()

        self.board = board

        self.master.geometry(
            f'{(BOARD_WIDTH+6)*self.CELL_SIZE}x' +
            f'{BOARD_HEIGHT*self.CELL_SIZE}'
        )

        self.pack(fill=BOTH, expand=1)
        self.canvas = Canvas(self)
        self.canvas.pack(fill=BOTH, expand=1)

        self.after(DRAW_INTERVAL, self.draw)

        self.focus_set()
        self.bind("<Escape>", self.quit)

    def quit(self, event):
        raise SystemExit

    def draw_cell(self, x, y, color):
        self.canvas.create_rectangle(
            x * self.CELL_SIZE,
            y * self.CELL_SIZE,
            (x+1) * self.CELL_SIZE,
            (y+1) * self.CELL_SIZE,
            fill=color,
            outline=color,
        )

    def draw(self):
        with self.board.lock:
            self.canvas.delete('all')

            if self.board.falling is not None:
                for (x, y) in self.board.falling:
                    self.draw_cell(x, y, self.board.falling.color)

            if self.board.next is not None:
                for (x, y) in self.board.next:
                    self.draw_cell(
                        x + self.board.width + 2,
                        y + 1,
                        self.board.next.color
                    )

            for (x, y) in self.board:
                self.draw_cell(x, y, self.board.cellcolor[x, y])

            x = self.board.width * self.CELL_SIZE + 1
            y = self.board.height * self.CELL_SIZE
            self.canvas.create_line(x, 0, x, y, fill='black')

            self.master.title(f'Score: {self.board.score}')

            self.after(DRAW_INTERVAL, self.draw)
Пример #9
0
class KlicketyGUI:
    """Interface pour le jeu Klickety."""
    def __init__(self):
        # initialisation des structures de données ----------------------------
        self.dim_plateau = (10,                 # nombre de colonnes du plateau
                            16)                 # nombre de lignes du plateau
        self.cote_case = 32          # la longueur du côté d'un bloc à dessiner
        self.largeur_plateau = self.cote_case * self.dim_plateau[0]
        self.hauteur_plateau = self.cote_case * self.dim_plateau[1]
        self.plateau = []
        self.compteur_de_coups = 0

        # initialisation des éléments graphiques ------------------------------
        self.window = Tk()                              # la fenêtre principale
        self.window.resizable(0, 0)           # empêcher les redimensionnements
        self.partie_haut = Frame(self.window, width=self.largeur_plateau,
                                              height=self.hauteur_plateau)
        self.partie_haut.pack(side=TOP)
        self.partie_bas = Frame(self.window)
        self.partie_bas.pack(side=BOTTOM)

        # le canevas affichant le plateau de jeu
        self.plateau_affiche = Canvas(self.partie_haut,
                                      width=self.largeur_plateau,
                                      height=self.hauteur_plateau)
        self.plateau_affiche.pack()
        self.plateau_affiche.bind('<ButtonPress-1>', self.clicPlateau)

        # le bouton "Réinitialiser"
        self.btn = Button(self.partie_bas, text='Réinitialiser',
                          command=self.reinitialiserJeu)
        self.btn.pack(fill=BOTH)

        # Zone d'affichage du nombre de coups
        self.nb_coups_affiche = Canvas(self.partie_bas,
                                       width=self.largeur_plateau, height=32)
        self.nb_coups_affiche.create_text(
            self.largeur_plateau // 2, self.cote_case // 2,
            text="Coups effectués: 0", fill="black"
        )
        self.nb_coups_affiche.pack(fill=BOTH)

        # affichage du nombre de blocs restants
        self.nb_blocs_affiche = Canvas(self.partie_bas,
                                       width=self.largeur_plateau, height=32)
        self.nb_blocs_affiche.pack(fill=BOTH)

        self.reinitialiserJeu()

        self.window.title('Klickety')
        self.window.mainloop()

    def rafraichirNombreBlocs(self, piece=None):
        """Rafraîchit l'affichage du nombre de blocs restants, sur base de la
        pièce que l'on vient de retirer."""
        self.nb_blocs_affiche.delete(ALL)
        if piece is None:  # appel initial, tous les blocs sont encore présents
            self.nb_blocs = self.dim_plateau[0] * self.dim_plateau[1]

        else:  # soustraire du nombre de blocs celui de la pièce retirée
            self.nb_blocs -= len(piece)

        self.nb_blocs_affiche.create_text(
            self.largeur_plateau // 2, self.cote_case // 2,
            text="Blocs restants: " + str(self.nb_blocs), fill="black"
        )

    def compteCoups(self, compteur_de_coups):
        """Compte le nombre de coups effectués durant cette partie."""
        self.nb_coups_affiche.delete(ALL)
        self.nb_coups_affiche.create_text(
            self.largeur_plateau // 2, self.cote_case // 2,
            text="Coups effectués: " + str(compteur_de_coups), fill="black"
        )

    def rafraichirPlateau(self):
        """Redessine le plateau de jeu à afficher."""
        # tracer les blocs
        self.plateau_affiche.delete(ALL)
        couleur_fond = "black"
        for i in range(self.dim_plateau[0]):                    # par défaut 10
            for j in range(self.dim_plateau[1]):                # par défaut 16
                case = self.plateau[i][j]
                if case is not None:  # afficher le pion
                    self.plateau_affiche.create_rectangle(
                        i * self.cote_case, j * self.cote_case,
                        (i + 1) * self.cote_case, (j + 1) * self.cote_case,
                        outline=case, fill=case
                    )
                else:
                    self.plateau_affiche.create_rectangle(
                        i * self.cote_case, j * self.cote_case,
                        (i + 1) * self.cote_case, (j + 1) * self.cote_case,
                        outline=couleur_fond, fill=couleur_fond
                    )

        # tracer le contour des pièces
        # 1) tracer les séparations entre deux pièces adjacentes de
        # couleurs différentes dans la même colonne
        for i in range(0, self.dim_plateau[0]):                 # par défaut 10
            colonne = self.plateau[i]
            for j in range(1, self.dim_plateau[1]):             # par défaut 16
                if colonne[j - 1] != colonne[j]:
                    self.plateau_affiche.create_rectangle(
                        (i) * self.cote_case, j * self.cote_case,
                        (i + 1) * self.cote_case, j * self.cote_case,
                        outline=couleur_fond, fill=couleur_fond, width=1
                    )

        # 2) tracer les séparations entre deux pièces adjacentes de
        # couleurs différentes dans la même ligne
        for i in range(1, self.dim_plateau[0]):                 # par défaut 10
            for j in range(0, self.dim_plateau[1]):             # par défaut 16
                if self.plateau[i - 1][j] != self.plateau[i][j]:
                    self.plateau_affiche.create_rectangle(
                        (i) * self.cote_case, j * self.cote_case,
                        (i) * self.cote_case, (j + 1) * self.cote_case,
                        outline=couleur_fond, fill=couleur_fond, width=1
                    )

    def clicPlateau(self, event):
        """Récupère les coordonnées de la case sélectionnée, et joue le coup
        correspondant s'il est permis."""
        # remarque: le canevas de tkinter interprète (i, j) géométriquement
        # (au lieu de (ligne, colonne)), d'où l'inversion de coordonnées dans
        # la ligne ci-dessous
        (i, j) = (event.x // self.cote_case, event.y // self.cote_case)

        if self.plateau[i][j] is not None:
            piece = set()
            detecterPiece(self.plateau, i, j, piece, self.plateau[i][j])
            #print (piece)

            if len(piece) > 1:  # si la pièce est valide, on la retire
                # retirer la piece en mettant ses cases à None
                for (p, q) in piece:
                    self.plateau[p][q] = None

                # faire descendre les blocs situés au-dessus de la pièce
                mettreAJour(self.plateau, piece)

                # tasser le restant du plateau en supprimant les colonnes vides
                eliminerColonnesVides(self.plateau)

                # rafraîchir le plateau pour répercuter les modifications
                self.rafraichirPlateau()

                self.rafraichirNombreBlocs(piece)
                self.compteur_de_coups += 1
                self.compteCoups(self.compteur_de_coups)
                messagevictoire = partieFinie(self.plateau)
                if messagevictoire:
                    self.plateau_affiche.create_text(
                        int(self.plateau_affiche.cget("width")) // 2,
                        self.cote_case // 2,
                        text=messagevictoire,
                        font=tkinter.font.Font(
                            family="Courier", size=12, weight=tkinter.font.BOLD
                        ),
                        fill="red"
                    )

    def reinitialiserJeu(self):
        """Réinitialise le plateau de jeu et les scores."""
        self.reinitialiserPlateau()
        self.rafraichirNombreBlocs()

        # réinitialiser le nombre de coups
        self.compteur_de_coups = 0
        self.nb_coups_affiche.delete(ALL)
        self.nb_coups_affiche.create_text(self.largeur_plateau // 2, self.cote_case // 2, text="Coups effectués: " + str(self.compteur_de_coups), fill="black")

    def reinitialiserPlateau(self):
        """Réinitialise le plateau de jeu."""
        # réinitialiser la matrice
        self.plateau = initialiserPlateau(*self.dim_plateau)

        # réinitialiser l'affichage
        self.plateau_affiche.delete(ALL)

        if self.plateau:
            self.rafraichirPlateau()
Пример #10
0
class SudokuUI(Frame):
    """
    The Tkinter UI, responsible for drawing the board and accepting user input.
    """
    def __init__(self, parent, game):
        self.game = game
        Frame.__init__(self, parent)
        self.parent = parent

        self.row, self.col = -1, -1

        self.__initUI()

    def __initUI(self):
        self.parent.title("Sudoku")
        self.pack(fill=BOTH)
        self.left_frame = Frame(self,
                                width=WIDTH + 50,
                                height=HEIGHT + 50,
                                bg='grey')
        self.left_frame.grid(row=0, column=0, padx=10, pady=10)
        self.right_frame = Frame(self,
                                 width=200,
                                 height=HEIGHT + 50,
                                 bg='grey')
        self.right_frame.grid(row=0, column=1, padx=10, pady=10)
        self.canvas = Canvas(self.left_frame, width=WIDTH, height=HEIGHT)
        self.canvas.pack(fill=BOTH, side=TOP)
        clear_button = Button(self.right_frame,
                              text="Clear answers",
                              width=15,
                              height=2,
                              command=self.__clear_answers,
                              highlightbackground='#3E4149')
        clear_button.pack(fill=BOTH, side=BOTTOM)
        auto_solve_button = Button(self.right_frame,
                                   text="Solve puzzle",
                                   width=15,
                                   height=2,
                                   command=self.__solve_puzzle,
                                   highlightbackground='#3E4149')
        auto_solve_button.pack(fill=BOTH, side=BOTTOM)
        generate_puzzle_button = Button(self.right_frame,
                                        text="Generate new puzzle",
                                        width=15,
                                        height=2,
                                        command=self.__generate_puzzle,
                                        highlightbackground='#3E4149')
        generate_puzzle_button.pack(fill=BOTH, side=BOTTOM)

        self.__draw_grid()
        self.__draw_puzzle()

        self.canvas.bind("<Button-1>", self.__cell_clicked)
        self.canvas.bind("<Key>", self.__key_pressed)

    def __draw_grid(self):
        """
        Draws grid divided with blue lines into 3x3 squares
        """
        for i in range(10):
            color = "blue" if i % 3 == 0 else "gray"

            x0 = MARGIN + i * SIDE
            y0 = MARGIN
            x1 = MARGIN + i * SIDE
            y1 = HEIGHT - MARGIN
            self.canvas.create_line(x0, y0, x1, y1, fill=color)

            x0 = MARGIN
            y0 = MARGIN + i * SIDE
            x1 = WIDTH - MARGIN
            y1 = MARGIN + i * SIDE
            self.canvas.create_line(x0, y0, x1, y1, fill=color)

    def __draw_puzzle(self):
        self.canvas.delete("numbers")
        for i in range(9):
            for j in range(9):
                answer = self.game.puzzle[i][j]
                if answer != 0:
                    x = MARGIN + j * SIDE + SIDE / 2
                    y = MARGIN + i * SIDE + SIDE / 2
                    original = self.game.start_puzzle[i][j]
                    color = "black" if answer == original else "sea green"
                    self.canvas.create_text(x,
                                            y,
                                            text=answer,
                                            tags="numbers",
                                            fill=color)

    def __draw_cursor(self):
        self.canvas.delete("cursor")
        if self.row >= 0 and self.col >= 0:
            x0 = MARGIN + self.col * SIDE + 1
            y0 = MARGIN + self.row * SIDE + 1
            x1 = MARGIN + (self.col + 1) * SIDE - 1
            y1 = MARGIN + (self.row + 1) * SIDE - 1
            self.canvas.create_rectangle(x0,
                                         y0,
                                         x1,
                                         y1,
                                         outline="red",
                                         tags="cursor")

    def __draw_victory(self):
        # create a oval (which will be a circle)
        x0 = y0 = MARGIN + SIDE * 2
        x1 = y1 = MARGIN + SIDE * 7
        self.canvas.create_oval(x0,
                                y0,
                                x1,
                                y1,
                                tags="victory",
                                fill="dark orange",
                                outline="orange")
        # create text
        x = y = MARGIN + 4 * SIDE + SIDE / 2
        self.canvas.create_text(x,
                                y,
                                text="You win!",
                                tags="victory",
                                fill="white",
                                font=("Arial", 32))

    def __cell_clicked(self, event):
        if self.game.game_over:
            return
        x, y = event.x, event.y
        if (MARGIN < x < WIDTH - MARGIN and MARGIN < y < HEIGHT - MARGIN):
            self.canvas.focus_set()

            # get row and col numbers from x,y coordinates
            row, col = int((y - MARGIN) / SIDE), int((x - MARGIN) / SIDE)

            # if cell was selected already - deselect it
            if (row, col) == (self.row, self.col):
                self.row, self.col = -1, -1
            elif self.game.puzzle[row][col] == 0:
                self.row, self.col = row, col
        else:
            self.row, self.col = -1, -1

        self.__draw_cursor()

    def __key_pressed(self, event):
        if self.game.game_over:
            return
        if self.row >= 0 and self.col >= 0 and event.char in "1234567890":
            self.game.puzzle[self.row][self.col] = int(event.char)
            self.col, self.row = -1, -1
            self.__draw_puzzle()
            self.__draw_cursor()
            if self.game.check_win():
                self.__draw_victory()

    def __clear_answers(self):
        self.game.start()
        self.canvas.delete("victory")
        self.__draw_puzzle()

    def __solve_puzzle(self):
        solver = SudokuSolver(self.game.puzzle)
        solver.solve()
        self.__draw_puzzle()

    def __generate_puzzle(self):
        self.game.start_puzzle = SudokuBoard.create_empty_board()
        self.game.generate_puzzle(self.game.start_puzzle)
        self.game.start()
        self.__draw_puzzle()

    def __undo_move(self):
        self.move_stack = []

    def __erase_cell(self):
        print("ERASE")
Пример #11
0
class Main(object):

    def __init__(self, master):
        self.master = master
        self.master.title('CONWAY\'S GAME OF LIFE')
        self.wid = 910
        self.hei = 680
        smw = self.master.winfo_screenwidth() // 2
        smh = self.master.winfo_screenheight() // 2
        tplft = (smw - self.wid // 2, smh - self.hei // 2)
        self.master.geometry(f'{self.wid}x{self.hei}+{tplft[0]}+{tplft[1]}')
        self.master.resizable(width=False, height=False)

        # create a main field
        self.can_width = 800
        self.can_height = 640

        # variable to continue with right number generation after stop game
        self.global_gen = None
        # start
        self.cell = 1
        self.start_cell = 0
        self.live = set()
        # trick for rigth after_cancel
        self.game_on = (0, 0)
        # population
        self.score = 0
        # variable for max cells
        self.max_score = 0
        # for change speed
        self.timer = 15
        # cursor for place ships
        self.cur = None
        self.invert = None
        self.on = (0, 0)
        self.sample = {'1': 10, '2': 5, '4': 3}

        # erase seeds
        self.erase = True

        # images for ships
        self.glider = PhotoImage(file='data/1_ship.gif')
        self.glider_in = PhotoImage(file='data/1_ship_in.gif')
        self.lss = PhotoImage(file='data/2_lss.gif')
        self.lss_in = PhotoImage(file='data/2_lss_in.gif')
        self.sui = PhotoImage(file='data/3_sucide.gif')
        self.sui_in = PhotoImage(file='data/3_sucide_in.gif')
        self.f5 = PhotoImage(file='data/4_f5.gif')
        self.f5_in = PhotoImage(file='data/4_f5_in.gif')
        self.penta = PhotoImage(file='data/5_penta.gif')
        self.penta_in = PhotoImage(file='data/5_penta_in.gif')
        self.patern = PhotoImage(file='data/6_patern.gif')
        self.patern_in = PhotoImage(file='data/6_patern_in.gif')
        self.fireship = PhotoImage(file='data/7_fireship.gif')
        self.fireship_in = PhotoImage(file='data/7_fireship_in.gif')

        # GUI
        frameWin = Frame(master, bg='white', borderwidth=0)
        frameWin.pack(side=TOP, fill=BOTH)

        frameCanv = Frame(frameWin, bg='white', borderwidth=0)
        frameCanv.pack(side=RIGHT, fill=BOTH)

        # main canvas
        self.window = Canvas(frameCanv,
                             width=self.can_width,
                             height=self.can_height,
                             cursor='plus',
                             bg='white',
                             bd=0,
                             highlightthickness=0)
        self.window.pack(side=TOP)

        self.w_field = self.can_width // self.cell
        self.h_field = self.can_height // self.cell

        self.cell_matrix = PhotoImage(width=self.can_width,
                                      height=self.can_height)
        hor_line = '{' + ' '.join(['#EEEEEE'] * self.can_width) + '}'
        self.cell_matrix.put(' '.join([hor_line] * self.can_height))
        # make copy
        self.original = self.cell_matrix.copy()

        self.cell_img = self.window.create_image(0, 0,
                                                 image=self.cell_matrix,
                                                 anchor=NW)

        # side menu for images
        frameBorderCr = Frame(frameWin, bg='white', bd=3)
        frameBorderCr.pack(side=LEFT, fill=BOTH)
        mes_creat = Label(frameBorderCr, text='CREATURE',
                          height=2, bg='white')
        mes_creat.pack(side=TOP, fill=X)

        frameCreat = Frame(frameBorderCr, bg='gray', bd=2)
        frameCreat.pack(side=TOP, fill=BOTH)

        self.creat = Canvas(frameCreat,
                            height=596,
                            bg='white',
                            highlightthickness=0)
        self.creat.pack(side=TOP, expand=YES, fill=Y)

        # images for ships
        self.creat.create_image(48, 25, image=self.glider)
        self.creat.create_image(48, 73, image=self.lss)
        self.creat.create_image(48, 126, image=self.sui)
        self.creat.create_image(48, 175, image=self.f5)
        self.creat.create_image(48, 256, image=self.penta)
        self.creat.create_image(48, 349, image=self.patern)
        self.creat.create_image(49, 485, image=self.fireship)

        # menu for counters
        frameMB = Frame(frameCanv, bg='white', borderwidth=0)
        frameMB.pack(side=BOTTOM, fill=BOTH)

        message = Label(frameMB, text='SQUARE UNIVERSUM ',
                        height=2, bg='white')
        message.pack(side=LEFT, fill=X)

        # cell part
        frameBor1 = Frame(frameMB, bg='gray', borderwidth=2)
        frameBor1.pack(side=LEFT)
        name_pop = Label(frameBor1, text='CELL')
        name_pop.pack(side=LEFT)
        self.scrPop = Label(frameBor1, text=0, width=7)
        self.scrPop.pack(side=RIGHT)

        # separator
        sep = Frame(frameMB, width=4)
        sep.pack(side=LEFT)

        # cycle part
        frameBor2 = Frame(frameMB, bg='gray', borderwidth=2)
        frameBor2.pack(side=LEFT)
        name_gen = Label(frameBor2, text='CYCLE')
        name_gen.pack(side=LEFT)
        self.scrGen = Label(frameBor2, text=0, width=6)
        self.scrGen.pack(side=RIGHT)

        # buttons
        self.button_Start = Button(frameMB,
                                   text='START',
                                   width=6,
                                   command=self.start_game)

        self.button_Start.pack(side=RIGHT, padx=3)

        self.button_Stop = Button(frameMB,
                                  text='STOP',
                                  width=6,
                                  command=self.stop_game)
        self.button_Stop.pack(side=RIGHT, padx=3)

        self.button_Clear = Button(frameMB,
                                   text='CLEAR',
                                   width=6,
                                   command=self.clear)
        self.button_Clear.pack(side=RIGHT, padx=3)

        blockSpeed = Frame(frameMB, padx=25)
        blockSpeed.pack(side=RIGHT)

        button_Fast = Button(blockSpeed,
                             text='>>',
                             width=3,
                             command=self.fast)
        button_Fast.pack(side=RIGHT, padx=3)

        butSpeedFrame = Frame(blockSpeed, bg='gray', bd=2)
        butSpeedFrame.pack(side=RIGHT)

        self.speedVal = Label(butSpeedFrame, text=int(self.timer), width=3)
        self.speedVal.pack(side=RIGHT)

        button_Slow = Button(blockSpeed,
                             text='<<',
                             width=3,
                             command=self.slow)
        button_Slow.pack(side=RIGHT, padx=3)

        self.window.bind('<B1-Motion>', self.motion_paint)
        self.window.bind('<ButtonPress-1>', self.start_paint)
        self.window.bind('<ButtonPress-2>', self.clear_side_menu)

        self.window.bind('<Leave>', self.clear_side_menu)
        self.creat.bind('<ButtonPress-1>', self.creatures)

        self.master.mainloop()

    def add_pixels(self, x, y):
        pack = []
        dist_x = (x - self.fir_x)
        dist_y = (y - self.fir_y)
        hyp = int(math.hypot(dist_x, dist_y))

        for i in range(hyp):
            x = int(i * (dist_x / hyp) + self.fir_x)
            y = int(i * (dist_y / hyp) + self.fir_y)
            pack.append((x, y))
        return pack

    def motion_paint(self, event):
        self.erase = False
        xcell = int(event.x)
        ycell = int(event.y)
        # 1 pix
        # xcell = int(x // self.cell)
        # ycell = int(y // self.cell)
        # 1 pix
        pack = self.add_pixels(xcell, ycell)

        self.fir_x, self.fir_y = xcell, ycell
        self.black_cell(ycell, xcell)
        for i in pack:
            self.black_cell(i[1], i[0])

    def start_paint(self, event):
        self.erase = True
        # 1 pix
        # self.fir_x = event.x // self.cell
        # self.fir_y = event.y // self.cell

        self.fir_x = event.x
        self.fir_y = event.y

        self.black_cell(self.fir_y, self.fir_x)

    def creatures(self, event):
        # I can realize with standart buttons and compound
        x = int(event.x)
        y = int(event.y)

        if self.invert:
            # clear menu with figures
            self.clear_side_menu()
        else:
            self.on = (0, 0)

        if x in range(32, 65) and y in range(10, 45):
            self.creat_but(x, y, 32, 65, 10, 45, 48, 25,
                           self.glider_in, self.glider, self.ship_1, SE)

        if x in range(20, 75) and y in range(54, 96):
            self.creat_but(x, y, 20, 75, 54, 96, 48, 73,
                           self.lss_in, self.lss, self.ship_2, SE)

        if x in range(32, 65) and y in range(107, 149):
            self.creat_but(x, y, 32, 65, 107, 149, 48, 126,
                           self.sui_in, self.sui, self.fig_1, S)

        if x in range(32, 65) and y in range(161, 192):
            self.creat_but(x, y, 32, 65, 161, 192, 48, 175,
                           self.f5_in, self.f5, self.fig_2, CENTER)

        if x in range(32, 65) and y in range(203, 313):
            self.creat_but(x, y, 32, 65, 203, 313, 48, 256,
                           self.penta_in, self.penta, self.fig_3, S)

        if x in range(21, 75) and y in range(323, 377):
            self.creat_but(x, y, 21, 75, 323, 377, 48, 349,
                           self.patern_in, self.patern, self.fig_4, SE)

        if x in range(6, 93) and y in range(388, 588):
            self.creat_but(x, y, 6, 93, 388, 588, 48, 485,
                           self.fireship_in, self.fireship, self.ship_3, S)

    def creat_but(self, x, y, fnx, lnx, fny, lny,
                  x_im, y_im, img_in, img, bind, al):
        self.window.unbind('<B1-Motion>')
        if self.cur:
            self.window.delete(self.cur)
            self.cur = None
        if (self.on[0] not in range(fnx, lnx) or
                self.on[1] not in range(fny, lny)):

            self.invert = self.creat.create_image(x_im, y_im, image=img_in)
            self.window.bind('<ButtonPress-1>', bind)
            self.on = (x, y)
            # size of pictures depend of self.cell
            size = self.sample[str(self.cell)]
            img = img.subsample(size, size)
            self.window.bind('<Motion>', lambda event, i=img,
                             a=al: self.cursor(event, i, a))

    def cursor(self, event, img, align):
        self.erase = False
        self.window.configure(cursor='none')
        if not self.cur:
            self.cur = self.window.create_image(
                event.x, event.y, image=img, anchor=align)
        self.window.coords(self.cur, (event.x, event.y))

    def ship_1(self, event):
        x = int(event.x)
        y = int(event.y)
        xcell = int(y / self.cell)
        ycell = int(x / self.cell)
        pack = [(xcell, ycell), (xcell - 1, ycell), (xcell, ycell - 1),
                (xcell, ycell - 2), (xcell - 2, ycell - 1)]
        for i in pack:
            self.black_cell(i[0], i[1])

    def ship_2(self, event):
        x = int(event.x)
        y = int(event.y)
        xcell = int(y / self.cell)
        ycell = int(x / self.cell)

        pack = [(xcell, ycell), (xcell - 1, ycell), (xcell - 2, ycell),
                (xcell - 3, ycell - 1), (xcell, ycell - 1),
                (xcell, ycell - 2), (xcell, ycell - 3),
                (xcell - 1, ycell - 4), (xcell - 3, ycell - 4)]
        for i in pack:
            self.black_cell(i[0], i[1])

    def fig_1(self, event):
        x = int(event.x)
        y = int(event.y)
        xcell = int(y / self.cell)
        ycell = int(x / self.cell)

        pack = [(xcell, ycell), (xcell, ycell - 1), (xcell - 1, ycell - 1),
                (xcell - 2, ycell - 1), (xcell - 3, ycell - 1),
                (xcell - 3, ycell - 2)]
        for i in pack:
            self.black_cell(i[0], i[1])

    def fig_2(self, event):
        x = int(event.x)
        y = int(event.y)
        xcell = int(y / self.cell)
        ycell = int(x / self.cell)

        pack = [(xcell, ycell), (xcell - 1, ycell), (xcell - 2, ycell),
                (xcell - 1, ycell - 1), (xcell - 2, ycell + 1)]
        for i in pack:
            self.black_cell(i[0], i[1])

    def fig_3(self, event):
        x = int(event.x)
        y = int(event.y)
        xcell = int(y / self.cell)
        ycell = int(x / self.cell)

        self.black_cell(xcell, ycell)
        self.black_cell(xcell - 1, ycell)
        self.black_cell(xcell - 2, ycell - 1)
        self.black_cell(xcell - 2, ycell + 1)
        self.black_cell(xcell - 3, ycell)
        self.black_cell(xcell - 4, ycell)
        self.black_cell(xcell - 5, ycell)
        self.black_cell(xcell - 6, ycell)
        self.black_cell(xcell - 7, ycell - 1)
        self.black_cell(xcell - 7, ycell + 1)
        self.black_cell(xcell - 8, ycell)
        self.black_cell(xcell - 9, ycell)

    def fig_4(self, event):
        x = int(event.x)
        y = int(event.y)
        xcell = int(y / self.cell)
        ycell = int(x / self.cell)

        self.black_cell(xcell, ycell)
        self.black_cell(xcell - 1, ycell)
        self.black_cell(xcell - 2, ycell)
        self.black_cell(xcell - 2, ycell - 1)
        self.black_cell(xcell - 4, ycell)
        self.black_cell(xcell - 4, ycell - 2)
        self.black_cell(xcell - 4, ycell - 3)
        self.black_cell(xcell - 4, ycell - 4)
        self.black_cell(xcell - 3, ycell - 4)
        self.black_cell(xcell - 1, ycell - 3)
        self.black_cell(xcell - 1, ycell - 2)
        self.black_cell(xcell, ycell - 2)
        self.black_cell(xcell, ycell - 4)

    def ship_3(self, event):
        x = int(event.x)
        y = int(event.y)
        xcell = int(y / self.cell)
        ycell = int(x / self.cell)

        self.black_cell(xcell, ycell)
        self.black_cell(xcell - 1, ycell)
        self.black_cell(xcell - 1, ycell + 1)
        self.black_cell(xcell - 2, ycell)
        self.black_cell(xcell - 2, ycell + 2)
        self.black_cell(xcell - 3, ycell + 2)
        self.black_cell(xcell - 4, ycell + 2)
        self.black_cell(xcell - 3, ycell + 3)
        self.black_cell(xcell - 6, ycell + 1)
        self.black_cell(xcell - 7, ycell)
        self.black_cell(xcell - 9, ycell)
        self.black_cell(xcell - 9, ycell + 1)
        self.black_cell(xcell - 10, ycell + 1)
        self.black_cell(xcell - 10, ycell + 2)
        self.black_cell(xcell - 11, ycell + 3)
        self.black_cell(xcell - 13, ycell + 3)
        self.black_cell(xcell - 14, ycell + 3)
        self.black_cell(xcell - 14, ycell + 1)
        self.black_cell(xcell - 15, ycell)
        self.black_cell(xcell - 16, ycell)
        self.black_cell(xcell - 17, ycell + 1)
        self.black_cell(xcell - 17, ycell + 2)

        self.black_cell(xcell, ycell - 1)
        self.black_cell(xcell - 1, ycell - 1)
        self.black_cell(xcell - 1, ycell - 2)
        self.black_cell(xcell - 2, ycell - 1)
        self.black_cell(xcell - 2, ycell - 3)
        self.black_cell(xcell - 3, ycell - 3)
        self.black_cell(xcell - 3, ycell - 4)
        self.black_cell(xcell - 4, ycell - 3)
        self.black_cell(xcell - 6, ycell - 2)
        self.black_cell(xcell - 7, ycell - 1)
        self.black_cell(xcell - 9, ycell - 1)
        self.black_cell(xcell - 9, ycell - 2)
        self.black_cell(xcell - 10, ycell - 2)
        self.black_cell(xcell - 10, ycell - 3)
        self.black_cell(xcell - 11, ycell - 4)
        self.black_cell(xcell - 13, ycell - 4)
        self.black_cell(xcell - 14, ycell - 4)
        self.black_cell(xcell - 14, ycell - 2)
        self.black_cell(xcell - 15, ycell - 1)
        self.black_cell(xcell - 16, ycell - 1)
        self.black_cell(xcell - 17, ycell - 2)
        self.black_cell(xcell - 17, ycell - 3)

    def black_cell(self, y, x):

        x = x % self.w_field
        y = y % self.h_field
        # 1 pixel
        # x = x * self.cell + self.cell // 2
        # y = y * self.cell + self.cell // 2

        if self.cell_matrix.get(x, y) == (238, 238, 238):
            self.fill_black(x, y, '#000000')

            self.start_cell += 1
            self.live.add((x, y))
        else:
            if self.erase:
                if self.cell_matrix.get(x, y) == (0, 0, 0):
                    self.fill_black(x, y, '#EEEEEE')

                    self.start_cell -= 1
                    self.live.remove((x, y))

    def fill_black(self, x, y, color):
        # leave some borders for 4 px but it is to heavy task
        # for i in range((-self.cell // 2) - 1, (self.cell // 2) - 1):
        #     for j in range((-self.cell // 2) - 1, (self.cell // 2) - 1):
        #         xx = (x + i) % self.can_width
        #         yy = (y + j) % self.can_height
        self.cell_matrix.put(color, (x, y))

    def check_black(self, x, y, color):

        total = 8
        for i in [(-1, -1), (0, -1),
                  (1, -1), (-1, 0),
                  (1, 0), (-1, 1),
                  (0, 1), (1, 1)]:
            # xi = (x + i[0] * self.cell) % self.can_width
            # yi = (y + i[1] * self.cell) % self.can_height
            # 1 pixel
            xi = (x + i[0]) % self.can_width
            yi = (y + i[1]) % self.can_height

            if self.cell_matrix.get(xi, yi) == color:
                total -= 1

        return total

    def start_game(self):
        self.button_Start.configure(state='disabled')
        self.button_Clear.configure(state='disabled')

        self.start_cycle()

    def start_cycle(self):
        if self.global_gen:
            gen = self.global_gen
        else:
            gen = 1

        tot = len(self.live)
        # clean
        self.born = []
        self.dead = []

        for i, j in self.live:

            total = self.check_black(i, j, (238, 238, 238))

            if total < 2:
                self.dead.append((i, j))

            if total > 3:
                self.dead.append((i, j))

            # check if new cell wass born
            for xy in [(i - self.cell, j - self.cell), (i, j - self.cell),
                       (i + self.cell, j - self.cell), (i - self.cell, j),
                       (i + self.cell, j), (i - self.cell, j + self.cell),
                       (i, j + self.cell), (i + self.cell, j + self.cell)]:

                total = self.check_black(xy[0], xy[1], (0, 0, 0))

            # invert rule need 3 cells to born new
                if total == 5:
                    xy0 = xy[0] % self.can_width
                    xy1 = xy[1] % self.can_height
                    self.born.append((xy0, xy1))

        self.scrPop.configure(text=tot)
        self.scrGen.configure(text=gen)

        for i in self.dead:
            self.live.remove(i)
            xd, yd = i
            self.fill_black(xd, yd, '#EEEEEE')

        for i in self.born:
            self.live.add(i)
            xb, yb = i
            self.fill_black(xb, yb, '#000000')

        # counters for maximum population
        if self.max_score is False:
            self.max_score = tot
        elif tot > self.max_score:
            self.max_score = tot
        else:
            self.max_score = self.max_score

        # for generation
        gen += 1
        self.global_gen = gen

        # after dead cells need to check how many stay alive
        tot += len(self.born) - len(self.dead)
        # count population
        self.score += tot

        # start goal for end message
        if tot == 0:
            self.game_over(tot, gen)
        # for stop button
        else:
            self.game_on = self.window.after(self.timer, self.start_cycle)

    def stop_game(self):
        self.window.after_cancel(self.game_on)
        self.button_Start.configure(state='normal')
        self.button_Clear.configure(state='normal')

    def clear_side_menu(self, event=None):
        self.window.unbind('<Motion>')
        self.creat.delete(self.invert)
        self.invert = None
        self.window.bind('<ButtonPress-1>', self.start_paint)
        self.window.bind('<B1-Motion>', self.motion_paint)

        self.window.configure(cursor='plus')
        if self.cur:
            self.window.delete(self.cur)

    def clear(self):
        self.cell_matrix = self.original.copy()
        self.window.itemconfigure(self.cell_img, image=self.cell_matrix)

        self.scrPop.configure(text=0)
        self.scrGen.configure(text=0)
        # clear menu with figures
        self.clear_side_menu()
        self.start_cell = 0
        self.live = set()
        self.score = 0
        self.max_score = 0
        self.global_gen = None

    def fast(self):
        self.timer -= 1
        if self.timer < 1:
            self.timer = 1
        self.speedVal.configure(text=int(self.timer))

    def slow(self):
        self.timer += 1
        if self.timer > 15:
            self.timer = 15
        self.speedVal.configure(text=int(self.timer))

    def game_over(self, tot, gen):
        self.window.after_cancel(self.game_on)
        self.global_gen = 0
        self.scrPop.configure(text=tot)
        self.scrGen.configure(text=self.global_gen)
        self.creat.delete(self.invert)

        self.button_Stop.configure(state='disabled')
        end_menu = End(self.master, gen, self.start_cell,
                       self.score, self.max_score)
        self.window.configure(cursor='left_ptr')
        ans = end_menu.answer()

        if ans is True:
            self.button_Start.configure(state='normal')
            self.button_Clear.configure(state='normal')
            self.button_Stop.configure(state='normal')
            self.window.configure(cursor='plus')
            self.clear()

        elif ans is False:
            self.exit_life()

    def exit_life(self):
        self.master.quit()
Пример #12
0
class SkyviewFrame(Frame):
    """
    Skyview frame class.
    """
    def __init__(self, app, *args, **kwargs):
        """
        Constructor.

        :param Frame app: reference to main tkinter application
        :param args: optional args to pass to Frame parent class
        :param kwargs: optional kwargs to pass to Frame parent class
        """

        self.__app = app  # Reference to main application class
        self.__master = self.__app.get_master()  # Reference to root class (Tk)

        Frame.__init__(self, self.__master, *args, **kwargs)

        def_w, def_h = WIDGETU1
        self.width = kwargs.get("width", def_w)
        self.height = kwargs.get("height", def_h)
        self.bg_col = BGCOL
        self.fg_col = FGCOL
        self._body()

        self.bind("<Configure>", self._on_resize)

    def _body(self):
        """
        Set up frame and widgets.
        """

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        self.can_satview = Canvas(self,
                                  width=self.width,
                                  height=self.height,
                                  bg=self.bg_col)
        self.can_satview.pack(fill=BOTH, expand=YES)

    def init_sats(self):
        """
        Initialise satellite view
        """

        w, h = self.width, self.height
        axis_r = w / 15
        resize_font = font.Font(size=min(int(w / 25), 10))
        self.can_satview.delete("all")
        maxr = min((h / 2), (w / 2)) - (axis_r * 2)
        for r in (0.2, 0.4, 0.6, 0.8, 1):
            self.can_satview.create_circle(w / 2,
                                           h / 2,
                                           maxr * r,
                                           outline=self.fg_col,
                                           width=1)
        self.can_satview.create_line(w / 2, 0, w / 2, h, fill=self.fg_col)
        self.can_satview.create_line(0, h / 2, w, h / 2, fill=self.fg_col)
        self.can_satview.create_text(w - axis_r,
                                     h / 2,
                                     text="90\u00b0\n E",
                                     fill=self.fg_col,
                                     font=resize_font)
        self.can_satview.create_text(axis_r,
                                     h / 2,
                                     text="270\u00b0\n W",
                                     fill=self.fg_col,
                                     font=resize_font)
        self.can_satview.create_text(w / 2,
                                     axis_r,
                                     text="0\u00b0 N",
                                     fill=self.fg_col,
                                     font=resize_font)
        self.can_satview.create_text(w / 2,
                                     h - axis_r,
                                     text="180\u00b0 S",
                                     fill=self.fg_col,
                                     font=resize_font)

    def update_sats(self, data):
        """
        Plot satellites' elevation and azimuth position.

        :param list data: array of satellite tuples (gnssId, svid, elev, azim, cno)

        """

        w, h = self.width, self.height
        axis_r = w / 15
        maxr = min((h / 2), (w / 2)) - (axis_r * 2)
        resize_font = font.Font(size=min(int(maxr / 10), 10))
        self.init_sats()

        for d in sorted(data, key=itemgetter(4)):  # sort by ascending snr
            try:
                gnssId, prn, ele, azi, snr = d
                ele = int(ele)
                azi = (int(azi) - 90) % 360  # adjust so north is upwards
                x, y = cel2cart(ele, azi)
                x = x * maxr
                y = y * maxr
                if snr == "":
                    snr = 0
                else:
                    snr = int(snr)
                (_, ol_col) = GNSS_LIST[gnssId]
                prn = f"{int(prn):02}"
                self.can_satview.create_circle(
                    x + (w / 2),
                    y + (h / 2),
                    (maxr / 10),
                    outline=ol_col,
                    fill=snr2col(snr),
                    width=OL_WID,
                )
                self.can_satview.create_text(
                    x + (w / 2),
                    y + (h / 2),
                    text=prn,
                    fill=self.fg_col,
                    font=resize_font,
                )
            except ValueError:
                pass

        self.can_satview.update()

    def _on_resize(self, event):  # pylint: disable=unused-argument
        """
        Resize frame

        :param event event: resize event
        """

        self.width, self.height = self.get_size()

    def get_size(self):
        """
        Get current canvas size.

        :return: window size (width, height)
        :rtype: tuple
        """

        self.update_idletasks()  # Make sure we know about any resizing
        width = self.can_satview.winfo_width()
        height = self.can_satview.winfo_height()
        return (width, height)
Пример #13
0
class GUI(Frame):
    # constant
    NUMBER_COLLUM = 8
    NUMBER_ROW = 8
    SIZE_SQUARE = 64
    WHITE = '#F0D9B5'
    BLACK = '#B58863'
    YELLOW = '#775cff'
    GREEN = '#1eed28'
    YIELD = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
    MAP = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7}

    def __init__(self, game, root, board, slot):
        self.game = game
        self.board = board
        self.slot = slot
        super().__init__(root)
        #data
        self.piece = {}

        #king
        self.icon = Image.open("../data/image/white/K.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['K'] = self.icon

        self.icon = Image.open("../data/image/black/k.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['k'] = self.icon

        #Queen
        self.icon = Image.open("../data/image/white/Q.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['Q'] = self.icon

        self.icon = Image.open("../data/image/black/q.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['q'] = self.icon

        #Rook
        self.icon = Image.open("../data/image/white/R.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['R'] = self.icon

        self.icon = Image.open("../data/image/black/r.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['r'] = self.icon

        #Bishop
        self.icon = Image.open("../data/image/white/B.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['B'] = self.icon

        self.icon = Image.open("../data/image/black/b.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['b'] = self.icon

        #Knight
        self.icon = Image.open("../data/image/white/N.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['N'] = self.icon

        self.icon = Image.open("../data/image/black/n.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['n'] = self.icon

        #Pawn
        self.icon = Image.open("../data/image/white/P.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['P'] = self.icon

        self.icon = Image.open("../data/image/black/p.png")
        self.icon = self.icon.resize((self.SIZE_SQUARE, self.SIZE_SQUARE))
        self.icon = ImageTk.PhotoImage(self.icon)
        self.piece['p'] = self.icon

        self.square = []
        offsetRank = (self.NUMBER_ROW - 1) * self.SIZE_SQUARE
        for i in range(self.NUMBER_ROW):
            for j in range(self.NUMBER_COLLUM):
                self.square.append(
                    [j * self.SIZE_SQUARE, offsetRank - i * self.SIZE_SQUARE])

        BoardHeight = self.NUMBER_ROW * self.SIZE_SQUARE
        BoardWith = self.NUMBER_COLLUM * self.SIZE_SQUARE
        self.GUIBoard = Canvas(self,
                               width=BoardWith,
                               height=BoardHeight,
                               background='gray')

        self.GUIBoard.pack(side=tkinter.LEFT)

        self.GUIBoard.bind('<Button-1>', self.click)
        self.clickfrom = None
        self.clickTo = None

        self.coordinateClick = []

        self.listHightLight = []
        self.mapHightLight = []
        self.draw()

        self.controlPanel = Frame(self, width=300, background="#d2f0bb")
        self.controlPanel.pack(side=tkinter.LEFT, fill=tkinter.BOTH)

        self.canvas = Canvas(self.controlPanel, background='white', height=256)
        self.canvas.create_text(20,
                                30,
                                anchor='w',
                                font="VNI-Dom 16",
                                text="Information of game:    ")
        self.canvas.create_text(20,
                                60,
                                anchor='w',
                                font="VNI-Dom 14",
                                text="Your color piece is white   ")
        self.canvas.create_text(20,
                                90,
                                anchor='w',
                                font="VNI-Dom 14",
                                text="Color piece of machine is black  ")
        self.canvas.create_text(20,
                                120,
                                anchor='w',
                                font="VNI-Dom 14",
                                text="Alpha beta pruning depth = 3")
        self.canvas.create_text(20,
                                150,
                                anchor='w',
                                font="VNI-Dom 14",
                                text="Oponent move: ",
                                tag="move")
        self.canvas.create_text(20,
                                220,
                                anchor='w',
                                font="VNI-Dom 14",
                                text="Status board: your turn",
                                tag="status")
        self.canvas.pack(fill=tkinter.BOTH, side=tkinter.TOP)

        self.ButtonNewgame = tkinter.Button(self.controlPanel,
                                            text="New game",
                                            width=10,
                                            font="VNI-Dom 14",
                                            background="#1698de")
        self.ButtonNewgame.place(relx=.5, rely=.7, anchor='c')

        self.ButtonNewgame.bind('<Button-1>', self.clearBoard)

    def clearBoard(self, event):
        self.board.reset()
        self.slot[0] = True
        self.canvas.delete("move")
        self.canvas.create_text(20,
                                150,
                                anchor='w',
                                font="VNI-Dom 14",
                                text="Oponent move: ",
                                tag="move")
        self.draw()

    def click(self, event):

        if self.slot[0] == True:  # opponent turn
            x = event.x // self.SIZE_SQUARE
            y = self.NUMBER_ROW - event.y // self.SIZE_SQUARE
            self.coordinateClick.clear()
            self.coordinateClick.append(x)
            self.coordinateClick.append(y)
            traceSquare = (self.NUMBER_ROW - 1 - event.y // self.SIZE_SQUARE
                           ) * self.NUMBER_ROW + (event.x // self.SIZE_SQUARE)

            if self.clickfrom is None:
                pieceAt = self.board.piece_at(traceSquare)
                if pieceAt is not None:
                    self.clickfrom = self.YIELD[self.coordinateClick[0]] + str(
                        self.coordinateClick[1])
                    self.hightLight()
                else:
                    self.draw()
            else:
                if traceSquare in self.mapHightLight:
                    self.move()
                else:
                    self.mapHightLight.clear()
                    self.draw()
                self.clickfrom = None

    def hightLight(self):
        position = self.YIELD[self.coordinateClick[0]] + str(
            self.coordinateClick[1])
        legal_moves = [
            str(legal_move) for legal_move in self.board.legal_moves
        ]
        self.listHightLight.clear()
        self.mapHightLight.clear()
        for legal_move in legal_moves:
            if (position == legal_move[:2]):
                self.listHightLight.append(legal_move)
        for legal_move in self.listHightLight:
            self.mapHightLight.append(self.MAP[legal_move[2]] +
                                      (int(legal_move[3]) - 1) *
                                      self.NUMBER_ROW)

        self.draw()

    def move(self):
        self.clickTo = self.YIELD[self.coordinateClick[0]] + str(
            self.coordinateClick[1])
        move = str(self.clickfrom) + str(self.clickTo)

        #check promotion
        traceFrom = self.MAP[self.clickfrom[0]] + (self.NUMBER_ROW) * (
            int(self.clickfrom[1]) - 1)
        traceFrom = self.board.piece_at(traceFrom)
        if traceFrom.symbol() == 'p' and int(self.clickTo[1]) == 1:
            move += 'q'
        elif traceFrom.symbol() == 'P' and int(self.clickTo[1]) == 8:
            move += 'q'

        #print(move)
        move = chess.Move.from_uci(move)
        self.board.push(move)
        self.mapHightLight.clear()
        self.draw()
        self.slot[0] = False
        self.canvas.delete("move")
        self.canvas.create_text(20,
                                150,
                                anchor='w',
                                font="VNI-Dom 14",
                                text="White move: " + str(move),
                                tag="move")
        self.canvas.delete("status")
        self.canvas.create_text(20,
                                220,
                                anchor='w',
                                font="VNI-Dom 14",
                                text="Status board: Machine turn",
                                tag="status")

        self.game.ROOT.after(1000, self.game.AIplay)

    def draw(self):
        #delete canvas
        self.GUIBoard.delete("square")
        self.GUIBoard.delete("piece")
        collor = self.WHITE
        positonClick = None
        if len(self.coordinateClick):
            positonClick = self.coordinateClick[0] + (self.NUMBER_ROW) * (
                self.coordinateClick[1] - 1)
            #print(positonClick)
        for i in range(self.NUMBER_ROW):
            collor = self.BLACK if collor == self.WHITE else self.WHITE
            for j in range(self.NUMBER_COLLUM):
                pos = i * self.NUMBER_ROW + j
                if (collor == self.WHITE):
                    if positonClick is not None and positonClick == pos:
                        self.GUIBoard.create_rectangle(
                            self.square[pos][0],
                            self.square[pos][1],
                            self.square[pos][0] + self.SIZE_SQUARE,
                            self.square[pos][1] + self.SIZE_SQUARE,
                            fill=self.GREEN,
                            tag="square")
                    elif (pos in self.mapHightLight):
                        self.GUIBoard.create_rectangle(
                            self.square[pos][0],
                            self.square[pos][1],
                            self.square[pos][0] + self.SIZE_SQUARE,
                            self.square[pos][1] + self.SIZE_SQUARE,
                            fill=self.YELLOW,
                            tag="square")
                    else:
                        self.GUIBoard.create_rectangle(
                            self.square[pos][0],
                            self.square[pos][1],
                            self.square[pos][0] + self.SIZE_SQUARE,
                            self.square[pos][1] + self.SIZE_SQUARE,
                            fill=self.WHITE,
                            tag="square")
                    collor = self.BLACK
                else:
                    if positonClick is not None and positonClick == pos:
                        self.GUIBoard.create_rectangle(
                            self.square[pos][0],
                            self.square[pos][1],
                            self.square[pos][0] + self.SIZE_SQUARE,
                            self.square[pos][1] + self.SIZE_SQUARE,
                            fill=self.GREEN,
                            tag="square")
                    elif (pos in self.mapHightLight):
                        self.GUIBoard.create_rectangle(
                            self.square[pos][0],
                            self.square[pos][1],
                            self.square[pos][0] + self.SIZE_SQUARE,
                            self.square[pos][1] + self.SIZE_SQUARE,
                            fill=self.YELLOW,
                            tag="square")
                    else:
                        self.GUIBoard.create_rectangle(
                            self.square[pos][0],
                            self.square[pos][1],
                            self.square[pos][0] + self.SIZE_SQUARE,
                            self.square[pos][1] + self.SIZE_SQUARE,
                            fill=self.BLACK,
                            tag="square")
                    collor = self.WHITE

        offset = self.NUMBER_ROW * self.NUMBER_COLLUM
        for i in range(offset):
            pieceAtSquare = self.board.piece_at(i)
            if (pieceAtSquare is not None):
                image = pieceAtSquare.symbol()
                self.GUIBoard.create_image(
                    self.SIZE_SQUARE // 2 + self.square[i][0],
                    self.SIZE_SQUARE // 2 + self.square[i][1],
                    image=self.piece[image],
                    tag="piece")
Пример #14
0
class View():

    selected_piece_position = None
    all_squares_to_be_highlighted = []
    images = {}
    board_color_1 = BOARD_COLOR_1
    board_color_2 = BOARD_COLOR_2
    highlight_color = HIGHLIGHT_COLOR

    def __init__(self, parent, controller):
        self.controller = controller
        self.parent = parent
        self.create_chess_base()
        self.canvas.bind("<Button-1>", self.on_square_clicked)
        self.start_new_game()

    def reload_colors(self, color_1, color_2, highlight_color):
        self.board_color_1 = color_1
        self.board_color_2 = color_2
        self.highlight_color = highlight_color
        self.draw_board()
        self.draw_all_pieces()

    def on_preference_menu_clicked(self):
        self.show_preferences_window()

    def show_preferences_window(self):
        preferenceswindow.PreferencesWindow(self)

    def create_bottom_frame(self):
        self.bottom_frame = Frame(self.parent, height=64)
        self.info_label = Label(self.bottom_frame,
                                text="   White to Start the Game  ")
        self.info_label.pack(side=RIGHT, padx=8, pady=5)
        self.bottom_frame.pack(fill="x", side="bottom")

    def create_top_menu(self):
        self.menu_bar = Menu(self.parent)
        self.create_file_menu()
        self.create_edit_menu()
        self.create_about_menu()

    def create_file_menu(self):
        self.file_menu = Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label="New Game",
                                   command=self.on_new_game_menu_clicked)
        self.menu_bar.add_cascade(label="File", menu=self.file_menu)
        self.parent.config(menu=self.menu_bar)

    def create_edit_menu(self):
        self.edit_menu = Menu(self.menu_bar, tearoff=0)
        self.edit_menu.add_command(label="Preferences",
                                   command=self.on_preference_menu_clicked)
        self.menu_bar.add_cascade(label="Edit", menu=self.edit_menu)
        self.parent.config(menu=self.menu_bar)

    def create_about_menu(self):
        self.about_menu = Menu(self.menu_bar, tearoff=0)
        self.about_menu.add_command(label="About",
                                    command=self.on_about_menu_clicked)
        self.menu_bar.add_cascade(label="About", menu=self.about_menu)
        self.parent.config(menu=self.menu_bar)

    def create_canvas(self):
        canvas_width = NUMBER_OF_COLUMNS * DIMENSION_OF_EACH_SQUARE
        canvas_height = NUMBER_OF_ROWS * DIMENSION_OF_EACH_SQUARE
        self.canvas = Canvas(self.parent,
                             width=canvas_width,
                             height=canvas_height)
        self.canvas.pack(padx=8, pady=8)

    def create_chess_base(self):
        self.create_top_menu()
        self.create_canvas()
        self.draw_board()
        self.create_bottom_frame()

    def start_new_game(self):
        self.controller.reset_game_data()
        self.controller.reset_to_initial_locations()
        self.draw_all_pieces()
        self.info_label.config(text="   White to Start the Game  ")

    def reset_board_state(self):
        self.selected_piece_position = None
        self.all_squares_to_be_highlighted = []
        self.images = {}

    def on_new_game_menu_clicked(self):
        self.start_new_game()

    def get_clicked_row_column(self, event):
        col_size = row_size = DIMENSION_OF_EACH_SQUARE
        clicked_column = event.x // col_size
        clicked_row = 7 - (event.y // row_size)
        return (clicked_row, clicked_column)

    def on_square_clicked(self, event):
        clicked_row, clicked_column = self.get_clicked_row_column(event)
        position_of_click = self.controller.get_alphanumeric_position(
            (clicked_row, clicked_column))
        # on second click
        if self.selected_piece_position:
            self.shift(self.selected_piece_position, position_of_click)
            self.selected_piece_position = None
        self.update_highlight_list(position_of_click)
        self.draw_board()
        self.draw_all_pieces()

    def shift(self, start_pos, end_pos):
        selected_piece = self.controller.get_piece_at(start_pos)
        piece_at_destination = self.controller.get_piece_at(end_pos)
        if not piece_at_destination or piece_at_destination.color != selected_piece.color:
            try:
                self.controller.pre_move_validation(start_pos, end_pos)
            except exceptions.ChessError as error:
                self.info_label["text"] = error.__class__.__name__
            else:
                self.update_label(selected_piece, start_pos, end_pos)

    def update_label(self, piece, start_pos, end_pos):
        turn = ('white' if piece.color == 'black' else 'black')
        self.info_label["text"] = '' + piece.color.capitalize() + "  :  " + \
            start_pos + end_pos + '    ' + turn.capitalize() + '\'s turn'

    def update_highlight_list(self, position):
        self.all_squares_to_be_highlighted = None
        try:
            piece = self.controller.get_piece_at(position)
        except:
            piece = None
        if piece and (piece.color == self.controller.player_turn()):
            self.selected_piece_position = position
            self.all_squares_to_be_highlighted = list(
                map(
                    self.controller.get_numeric_notation,
                    self.controller.get_piece_at(position).moves_available(
                        position)))

    def get_x_y_coordinate(self, row, col):
        x = (col * DIMENSION_OF_EACH_SQUARE)
        y = ((7 - row) * DIMENSION_OF_EACH_SQUARE)
        return (x, y)

    def draw_board(self):
        current_color = self.board_color_2
        for row in range(NUMBER_OF_ROWS):
            current_color = self.get_alternate_color(current_color)
            for col in range(NUMBER_OF_COLUMNS):
                x1, y1 = self.get_x_y_coordinate(row, col)
                x2, y2 = x1 + DIMENSION_OF_EACH_SQUARE, y1 + DIMENSION_OF_EACH_SQUARE
                if (self.all_squares_to_be_highlighted
                        and (row, col) in self.all_squares_to_be_highlighted):
                    self.canvas.create_rectangle(x1,
                                                 y1,
                                                 x2,
                                                 y2,
                                                 fill=self.highlight_color)
                else:
                    self.canvas.create_rectangle(x1,
                                                 y1,
                                                 x2,
                                                 y2,
                                                 fill=current_color)
                current_color = self.get_alternate_color(current_color)

    def get_alternate_color(self, current_color):
        if current_color == self.board_color_2:
            next_color = self.board_color_1
        else:
            next_color = self.board_color_2
        return next_color

    def calculate_piece_coordinate(self, row, col):
        x0 = (col * DIMENSION_OF_EACH_SQUARE) + \
            int(DIMENSION_OF_EACH_SQUARE / 2)
        y0 = ((7 - row) * DIMENSION_OF_EACH_SQUARE) + \
            int(DIMENSION_OF_EACH_SQUARE / 2)
        return (x0, y0)

    def draw_single_piece(self, position, piece):
        x, y = self.controller.get_numeric_notation(position)
        if piece:
            filename = "../pieces_image/{}_{}.png".format(
                piece.name.lower(), piece.color)
            if filename not in self.images:
                self.images[filename] = PhotoImage(file=filename)
            x0, y0 = self.calculate_piece_coordinate(x, y)
            self.canvas.create_image(x0,
                                     y0,
                                     image=self.images[filename],
                                     tags=("occupied"),
                                     anchor="c")

    def draw_all_pieces(self):
        self.canvas.delete("occupied")
        for position, piece in self.controller.get_all_peices_on_chess_board():
            self.draw_single_piece(position, piece)

    def on_about_menu_clicked(self):
        messagebox.showinfo(
            "From the Book:",
            "Tkinter GUI Application\n Development Blueprints")
Пример #15
0
class MastermindUI(Frame):
    """
    The Tkinter UI, responsible for drawing the board and accepting user input.
    """

    def init_grids(self):
        self.grid = [['E', 'E', 'E', 'E'],
                     ['E', 'E', 'E', 'E'],
                     ['E', 'E', 'E', 'E'],
                     ['E', 'E', 'E', 'E'],
                     ['E', 'E', 'E', 'E'],
                     ['E', 'E', 'E', 'E']]
        self.evaluationGrid = [['E', 'E', 'E', 'E'],
                               ['E', 'E', 'E', 'E'],
                               ['E', 'E', 'E', 'E'],
                               ['E', 'E', 'E', 'E'],
                               ['E', 'E', 'E', 'E'],
                               ['E', 'E', 'E', 'E']]

    def __init__(self, parent, game, ai):
        self.game = game
        self.ai = ai
        Frame.__init__(self, parent)
        self.parent = parent
        self.grid = []
        self.evaluationGrid = []
        self.init_grids()

        self.row, self.col = 5, 0

        self.newWindow = Toplevel(self.parent)
        self.aiApp = GameAIUI.GameAIUI(self.newWindow, self.ai)

        self.__init_ui()

    def __init_ui(self):
        self.parent.title("Mastermind")  # Set Window Title
        self.pack(fill=BOTH)
        self.canvas = Canvas(self,
                             width=WIDTH,
                             height=HEIGHT)
        self.canvas.pack(fill=BOTH, side=TOP)
        submit_button = Button(self,
                               text="Clear Answers",
                               command=self.__clear_answers)
        submit_button.pack(fill=BOTH, side=BOTTOM)

        self.__draw_grid()
        self.__draw_puzzle()
        self.__draw_cursor()
        self.canvas.focus_set()

        self.canvas.bind("<Button-1>", self.__cell_clicked)
        self.canvas.bind("<Key>", self.__key_pressed)
        self.canvas.bind("<Return>", self.__submit_answers)
        self.canvas.bind("<Left>", self.__left_key)
        self.canvas.bind("<Right>", self.__right_key)
        self.canvas.bind("<space>", self.__clear_cell)

    def __draw_grid(self):
        color = "white"

        for i in range(12):
            for j in range(2):
                self.canvas.create_rectangle(MARGIN + j * SIDE / 2, MARGIN + i * SIDE / 2,
                                             MARGIN + j * SIDE / 2 + SIDE / 2,
                                             MARGIN + i * SIDE / 2 + SIDE / 2, fill=color)

        color = "white"
        for i in range(6):
            for j in range(4):
                self.canvas.create_rectangle(MARGIN + j * SIDE + SIDE, MARGIN + i * SIDE,
                                             MARGIN + j * SIDE + SIDE + SIDE,
                                             MARGIN + i * SIDE + SIDE, fill=color)

    def __draw_puzzle(self):
        self.canvas.delete("numbers")

        for i in range(6):
            for j in range(4):
                answer = self.grid[i][j]
                color = colors[answer]
                self.canvas.create_rectangle(MARGIN + j * SIDE + SIDE, MARGIN + i * SIDE,
                                             MARGIN + j * SIDE + SIDE + SIDE,
                                             MARGIN + i * SIDE + SIDE, fill=color)
        for i in range(6):
            for j in range(2):
                eval_answer = self.evaluationGrid[i][j]
                color = eval_colors[eval_answer]
                self.canvas.create_rectangle(MARGIN + j * SIDE / 2, MARGIN + i * SIDE,
                                             MARGIN + j * SIDE / 2 + SIDE / 2,
                                             MARGIN + i * SIDE + SIDE / 2, fill=color)
        for i in range(6):
            for j in range(2, 4):
                eval_answer = self.evaluationGrid[i][j]
                color = eval_colors[eval_answer]
                _j = j - 2
                self.canvas.create_rectangle(MARGIN + _j * SIDE / 2, MARGIN + i * SIDE + SIDE / 2,
                                             MARGIN + _j * SIDE / 2 + SIDE / 2,
                                             MARGIN + i * SIDE + SIDE, fill=color)

    def __draw_cursor(self):
        self.canvas.delete("cursor")

        if self.row >= 0 and self.col >= 0:
            x0 = MARGIN + SIDE + self.col * SIDE + 1
            y0 = MARGIN + self.row * SIDE + 1
            x1 = MARGIN + SIDE + (self.col + 1) * SIDE - 1
            y1 = MARGIN + (self.row + 1) * SIDE - 1
            self.canvas.create_rectangle(
                x0, y0, x1, y1,
                outline="red", tags="cursor"
            )

    def __draw_victory(self):
        # create a oval (which will be a circle)
        x0 = y0 = MARGIN + SIDE * 1
        x1 = y1 = MARGIN + SIDE * 4
        self.canvas.create_oval(
            x0, y0, x1, y1,
            tags="ending", fill="dark orange", outline="orange"
        )
        # create text
        x = y = MARGIN + 2 * SIDE + SIDE / 2
        self.canvas.create_text(
            x, y,
            text="You win! \nIt took {} seconds".format(self.game.get_time_elapsed()), tags="ending",
            fill="white", font=("Arial", 12)
        )

    def __draw_defeat(self):
        # create a oval (which will be a circle)
        x0 = y0 = MARGIN + SIDE * 1
        x1 = y1 = MARGIN + SIDE * 4
        self.canvas.create_oval(
            x0, y0, x1, y1,
            tags="ending", fill="dark red", outline="red"
        )
        # create text
        x = y = MARGIN + 2 * SIDE + SIDE / 2
        self.canvas.create_text(
            x, y,
            text="You lose! \nIt took {} seconds".format(self.game.get_time_elapsed()), tags="ending",
            fill="white", font=("Arial", 12)
        )

    def __cell_clicked(self, event):
        # if self.game.game_over:
        #    return
        x, y = event.x, event.y
        if MARGIN + SIDE < x < WIDTH - MARGIN and MARGIN < y < HEIGHT - MARGIN:

            # get row and col numbers from x,y coordinates
            row, col = int((y - MARGIN) / SIDE), int((x - MARGIN - SIDE) / SIDE)
            # if cell was selected already - deselect it
            if (row, col) == (self.row, self.col):
                self.row, self.col = -1, -1
            elif self.game.get_level() == 6 - row:
                self.row, self.col = row, col
        else:
            self.row, self.col = -1, -1

        self.__draw_cursor()

    def __clear_cell(self, _):
        if self.row >= 0 and self.col >= 0:
            self.grid[self.row][self.col] = 'E'
            self.__draw_puzzle()
            self.__draw_cursor()

    def __key_pressed(self, event):
        if self.row >= 0 and self.col >= 0 and len(event.char) == 1 and event.char in MastermindConstants.valid_keys:
            self.grid[self.row][self.col] = event.char
            # self.game.puzzle[self.row][self.col] = int(event.char)
            self.col, self.row = self.col + 1, self.row
            if self.col == 4:
                self.col, self.row = self.col - 1, self.row
            self.__draw_puzzle()
            self.__draw_cursor()

    def __right_key(self, _):
        if self.row >= 0 and 0 <= self.col < 3:
            self.col, self.row = self.col + 1, self.row
            self.__draw_puzzle()
            self.__draw_cursor()

    def __left_key(self, _):
        if self.row >= 0 and self.col > 0:
            self.col, self.row = self.col - 1, self.row
            self.__draw_puzzle()
            self.__draw_cursor()

    def __clear_answers(self):
        self.game.reset()
        self.game.pick_answer()
        self.init_grids()
        self.canvas.delete("ending")
        self.row, self.col = 5, 0
        self.__draw_puzzle()
        self.__draw_cursor()
        self.ai.reset()
        self.aiApp.reset()

    def __submit_answers(self, _):
        index = 6 - self.game.get_level()
        current_choices = self.grid[index]

        if 'E' in current_choices:
            return
        self.game.make_guess(current_choices)

        evaluation = self.game.get_evaluation()
        self.ai.cull_possibilities(current_choices, evaluation)
        self.evaluationGrid[index] = list(evaluation)
        self.col, self.row = 0, index - 1,
        self.__draw_puzzle()
        self.__draw_cursor()
        self.ai.smart_eval(debug=False)
        self.aiApp.update_selection()
        if self.game.get_status() == "Won":
            print("Well done, you have won.")
            self.__draw_victory()
            self.aiApp.update_selection()
        if self.game.get_level() == 7 and self.game.get_status() != "Won":
            print("Oh no, better luck next time")
            self.__draw_defeat()
            self.aiApp.update_selection()
Пример #16
0
class EdemPresenceGUI():

    config = None

    def __init__(self, parent):

        self.read_config_file()

        self.external_file = EdemExternalFile(
            filepath=self.configs['save_to_file'])

        self.photos = self.load_photos(
            file_path=self.configs['photos_directory'])

        edemcard = EdemCard(enrollment='0000')
        self.edempresence = EdemPresence(card=edemcard,
                                         external_file=self.external_file)
        filename = self.edempresence.filename()
        self.external_file.filepath = self.configs[
            'save_to_file'] + '/' + filename

        top = self.top = tk.Toplevel(parent)
        self.myEntryBox = tk.Entry(root, width=6)
        self.myEntryBox.config(font=("Courier", 44, 'bold'))
        self.myEntryBox.bind("<Return>", self.show_student_picture)

        self.myEntryBox.focus_set()
        self.myEntryBox.pack()

        Button(root, text="SAIR", command=root.destroy).pack()

        self.canvas = Canvas(root, width=300, height=400)

    def load_photos(self, file_path):

        db_fotos = {}

        files = glob.glob(file_path + "/*")

        for f in files:
            file_name = os.path.basename(f)

            records = file_name.split('_')
            last = records[-1:]

            mean_parts = last[0].split('.')
            enrollment = mean_parts[0]

            if len(enrollment) == 4:
                enrollment = '00' + str(enrollment)

            if len(enrollment) == 5:
                enrollment = '0' + str(enrollment)

            db_fotos[str(enrollment)] = f

        return db_fotos

    def show_student_picture(self, event):

        if self.canvas:
            self.canvas.delete("all")

        self.canvas = Canvas(root, width=300, height=400)

        if str(self.myEntryBox.get()) in self.photos.keys():
            picture = self.photos[str(self.myEntryBox.get())]
            print(self.photos[str(self.myEntryBox.get())])
        else:
            picture = os.getcwd() + '/default_picture/default.jpg'

        if not os.path.exists(picture):
            picture = os.getcwd() + '/default_picture/default.jpg'

        print("FOTO DO ALUNO: " + str(picture))
        im = Image.open(picture)
        im = im.resize((300, 400), Image.ANTIALIAS)
        self.canvas.image = ImageTk.PhotoImage(im)
        self.canvas.create_image(0, 0, image=self.canvas.image, anchor='nw')

        self.edempresence.enrollment = str(self.myEntryBox.get())

        data = self.edempresence.generate_full_presence_record()
        self.edempresence.write_external_presence_data(data)

        #self.canvas.pack(0,0)
        #self.canvas.pack(side="left", fill="both", expand=True)
        self.canvas.place(x=150, y=120)

        self.myEntryBox.focus_set()
        self.myEntryBox.delete(0, 'end')

    def read_config_file(self):
        with open('edempresence.yaml', 'r') as config:
            self.configs = yaml.load(config)
Пример #17
0
class PigChaseHumanAgent(GuiAgent):
    def __init__(self, name, environment, keymap, max_episodes, max_actions,
                 visualizer, quit):
        self._max_episodes = max_episodes
        self._max_actions = max_actions
        self._action_taken = 0
        self._episode = 1
        self._scores = []
        self._rewards = []
        self._episode_has_ended = False
        self._episode_has_started = False
        self._quit_event = quit
        super(PigChaseHumanAgent, self).__init__(name, environment, keymap,
                                                 visualizer=visualizer)

    def _build_layout(self, root):
        # Left part of the GUI, first person view
        self._first_person_header = ttk.Label(root, text='First Person View', font=(None, 14, 'bold')) \
            .grid(row=0, column=0)
        self._first_person_view = ttk.Label(root)
        self._first_person_view.grid(row=1, column=0, rowspan=10)

        # Right part, top
        self._first_person_header = ttk.Label(root, text='Symbolic View', font=(None, 14, 'bold')) \
            .grid(row=0, column=1)
        self._symbolic_view = Canvas(root)
        self._symbolic_view.configure(width=ENV_BOARD_SHAPE[0]*CELL_WIDTH,
                                      height=ENV_BOARD_SHAPE[1]*CELL_WIDTH)
        self._symbolic_view.grid(row=1, column=1)

        # Bottom information
        self._information_panel = ttk.Label(root, text='Game stats', font=(None, 14, 'bold'))
        self._current_episode_lbl = ttk.Label(root, text='Episode: 0', font=(None, 12))
        self._cum_reward_lbl = ttk.Label(root, text='Score: 0', font=(None, 12, 'bold'))
        self._last_action_lbl = ttk.Label(root, text='Previous action: None', font=(None, 12))
        self._action_done_lbl = ttk.Label(root, text='Actions taken: 0', font=(None, 12))
        self._action_remaining_lbl = ttk.Label(root, text='Actions remaining: 0', font=(None, 12))

        self._information_panel.grid(row=2, column=1)
        self._current_episode_lbl.grid(row=3, column=1, sticky=W, padx=20)
        self._cum_reward_lbl.grid(row=4, column=1, sticky=W, padx=20)
        self._last_action_lbl.grid(row=5, column=1, sticky=W, padx=20)
        self._action_done_lbl.grid(row=6, column=1, sticky=W, padx=20)
        self._action_remaining_lbl.grid(row=7, column=1, sticky=W, padx=20)
        self._overlay = None

        # Main rendering callback
        self._pressed_binding = root.bind('<Key>', self._on_key_pressed)
        self._user_pressed_enter = False

        # UI Update callback
        root.after(self._tick, self._poll_frame)
        root.after(1000, self._on_episode_start)

        root.focus()

    def _draw_arrow(self, yaw, x, y, cell_width, colour):
        if yaw == 0.:
            x1, y1 = (x + .15) * cell_width, (y + .15) * cell_width
            x2, y2 = (x + .5) * cell_width, (y + .4) * cell_width
            x3, y3 = (x + .85) * cell_width, (y + .85) * cell_width

            self._symbolic_view.create_polygon(x1, y1, x2, y3, x3, y1, x2, y2, fill=colour)
        elif yaw == 90.:
            x1, y1 = (x + .15) * cell_width, (y + .15) * cell_width
            x2, y2 = (x + .6) * cell_width, (y + .5) * cell_width
            x3, y3 = (x + .85) * cell_width, (y + .85) * cell_width

            self._symbolic_view.create_polygon(x1, y2, x3, y1, x2, y2, x3, y3, fill=colour)
        elif yaw == 180.:
            x1, y1 = (x + .15) * cell_width, (y + .15) * cell_width
            x2, y2 = (x + .5) * cell_width, (y + .6) * cell_width
            x3, y3 = (x + .85) * cell_width, (y + .85) * cell_width

            self._symbolic_view.create_polygon(x1, y3, x2, y1, x3, y3, x2, y2, fill=colour)
        else:
            x1, y1 = (x + .15) * cell_width, (y + .15) * cell_width
            x2, y2 = (x + .4) * cell_width, (y + .5) * cell_width
            x3, y3 = (x + .85) * cell_width, (y + .85) * cell_width

            self._symbolic_view.create_polygon(x1, y3, x2, y2, x1, y1, x3, y2, fill=colour)

    def _poll_frame(self):
        """
        Main callback for UI rendering.
        Called at regular intervals.
        The method will ask the environment to provide a frame if available (not None).
        :return:
        """
        cell_width = CELL_WIDTH
        circle_radius = 10

        # are we done?
        if self._env.done and not self._episode_has_ended:
            self._on_episode_end()

        # build symbolic view
        board = None
        if self._env is not None:
            board, _ = self._env._internal_symbolic_builder.build(self._env)
        if board is not None:
            board = board.T
            self._symbolic_view.delete('all')  # Remove all previous items from Tkinter tracking
            width, height = board.shape
            for x in range(width):
                for y in range(height):
                    cell_contents = str.split(str(board[x][y]), '/')
                    for block in cell_contents:
                        if block == 'sand':
                            self._symbolic_view.create_rectangle(x * cell_width, y * cell_width,
                                                                 (x + 1) * cell_width, (y + 1) * cell_width,
                                                                 outline="black", fill="orange", tags="square")
                        elif block == 'grass':
                            self._symbolic_view.create_rectangle(x * cell_width, y * cell_width,
                                                                 (x + 1) * cell_width, (y + 1) * cell_width,
                                                                 outline="black", fill="lawn green", tags="square")
                        elif block == 'lapis_block':
                            self._symbolic_view.create_rectangle(x * cell_width, y * cell_width,
                                                                 (x + 1) * cell_width, (y + 1) * cell_width,
                                                                 outline="black", fill="black", tags="square")
                        elif block == ENV_TARGET_NAMES[0]:
                            self._symbolic_view.create_oval((x + .5) * cell_width - circle_radius,
                                                            (y + .5) * cell_width - circle_radius,
                                                            (x + .5) * cell_width + circle_radius,
                                                            (y + .5) * cell_width + circle_radius,
                                                            fill='pink')
                        elif block == self.name:
                            yaw = self._env._world_obs['Yaw'] % 360
                            self._draw_arrow(yaw, x, y, cell_width, 'red')
                        elif block == ENV_AGENT_NAMES[0]:
                            # Get yaw of other agent:
                            entities = self._env._world_obs[ENV_ENTITIES]
                            other_agent = list(
                                map(Entity.create, filter(lambda e: e['name'] == ENV_AGENT_NAMES[0], entities)))
                            if len(other_agent) == 1:
                                other_agent = other_agent.pop()
                                yaw = other_agent.yaw % 360
                                self._draw_arrow(yaw, x, y, cell_width, 'blue')

        # display the most recent frame
        frame = self._env.frame
        if frame is not None:
            from PIL import ImageTk
            self._first_person_view.image = ImageTk.PhotoImage(image=frame)
            self._first_person_view.configure(image=self._first_person_view.image)
            self._first_person_view.update()

        self._first_person_view.update()

        # process game state (e.g., has the episode started?)
        if self._episode_has_started and time.time() - self._episode_start_time < 3:
            if not hasattr(self, "_init_overlay") or not self._init_overlay:
                self._create_overlay()
            self._init_overlay.delete("all")
            self._init_overlay.create_rectangle(
                10, 10, 590, 290, fill="white", outline="red", width="5")
            self._init_overlay.create_text(
                300, 80, text="Get ready to catch the pig!",
                font=('Helvetica', '18'))
            self._init_overlay.create_text(
                300, 140, text=str(3 - int(time.time() - self._episode_start_time)),
                font=('Helvetica', '18'), fill="red")
            self._init_overlay.create_text(
                300, 220, width=460,
                text="How to play: \nUse the left/right arrow keys to turn, "
                     "forward/back to move. The pig is caught if it is "
                     "cornered without a free block to escape to.",
                font=('Helvetica', '14'), fill="black")
            self._root.update()

        elif self._episode_has_ended:

            if not hasattr(self, "_init_overlay") or not self._init_overlay:
                self._create_overlay()
            self._init_overlay.delete("all")
            self._init_overlay.create_rectangle(
                10, 10, 590, 290, fill="white", outline="red", width="5")
            self._init_overlay.create_text(
                300, 80, text='Finished episode %d of %d' % (self._episode, self._max_episodes),
                font=('Helvetica', '18'))
            self._init_overlay.create_text(
                300, 120, text='Score: %d' % sum(self._rewards),
                font=('Helvetica', '18'))
            if self._episode > 1:
                self._init_overlay.create_text(
                    300, 160, text='Average over %d episodes: %.2f' % (self._episode, np.mean(self._scores)),
                    font=('Helvetica', '18'))
            self._init_overlay.create_text(
                300, 220, width=360,
                text="Press RETURN to start the next episode, ESC to exit.",
                font=('Helvetica', '14'), fill="black")
            self._root.update()

        elif hasattr(self, "_init_overlay") and self._init_overlay:
            self._destroy_overlay()

        # trigger the next update
        self._root.after(self._tick, self._poll_frame)

    def _create_overlay(self):
        self._init_overlay = Canvas(self._root, borderwidth=0, highlightthickness=0, width=600, height=300, bg="gray")
        self._init_overlay.place(relx=0.5, rely=0.5, anchor='center')

    def _destroy_overlay(self):
        self._init_overlay.destroy()
        self._init_overlay = None

    def _on_key_pressed(self, e):
        """
        Main callback for keyboard events
        :param e:
        :return:
        """
        if e.keysym == 'Escape':
            self._quit()

        if e.keysym == 'Return' and self._episode_has_ended:

            if self._episode >= self._max_episodes:
                self._quit()

            # start the next episode
            self._action_taken = 0
            self._rewards = []
            self._episode += 1
            self._env.reset()

            self._on_episode_start()
            print('Starting episode %d' % self._episode)

        if self._episode_has_started and time.time() - self._episode_start_time >= 3:
            if e.keysym in self._keymap:
                mapped_action = self._keymap.index(e.keysym)

                _, reward, done = self._env.do(mapped_action)
                self._action_taken += 1
                self._rewards.append(reward)
                self._on_experiment_updated(mapped_action, reward, done)

    def _on_episode_start(self):
        self._episode_has_ended = False
        self._episode_has_started = True
        self._episode_start_time = time.time()
        self._on_experiment_updated(None, 0, self._env.done)

    def _on_episode_end(self):
        # do a turn to ensure we get the final reward and observation
        no_op_action = 0
        _, reward, done = self._env.do(no_op_action)
        self._action_taken += 1
        self._rewards.append(reward)
        self._on_experiment_updated(no_op_action, reward, done)

        # report scores
        self._scores.append(sum(self._rewards))
        self.visualize(self._episode, 'Reward', sum(self._rewards))

        # set flags to start a new episode
        self._episode_has_started = False
        self._episode_has_ended = True

    def _on_experiment_updated(self, action, reward, is_done):
        self._current_episode_lbl.config(text='Episode: %d' % self._episode)
        self._cum_reward_lbl.config(text='Score: %d' % sum(self._rewards))
        self._last_action_lbl.config(text='Previous action: %s' % action)
        self._action_done_lbl.config(text='Actions taken: {0}'.format(self._action_taken))
        self._action_remaining_lbl.config(text='Actions remaining: %d' % (self._max_actions - self._action_taken))
        self._first_person_view.update()

    def _quit(self):
        self._quit_event.set()
        self._root.quit()
        sys.exit()
Пример #18
0
class RulesInput():
    """
    Class to manage gui and logic for entry fields of rules
    in Parameters frame
    """
    def __init__(self, parent_class):
        """
        Initialize parent_frame to the provided class to hold self.frame
        self.frame contains all the elements
        self.entries is a list of dynamically generated entries
        """
        self.parent_class = parent_class
        # frame in parent Parameters class
        self.frame = Frame(parent_class.frame)
        self.preview_canvas = None  # canvas to preview curve
        self.entries = []  # list of dictionaries, each dictionary
        # contains the keys for frame, and its children
        self.add_button = None
        self.sub_button = None
        self.radio_angle_var = BooleanVar(
            self.frame)  # initially set to radians
        self.radio_angle_var.set(True)
        self.init_preview_canvas()
        self.init_info_labels()
        self.init_add_entry_button()
        self.init_sub_entry_button()
        # self.init_extract_rules_button()
        self.frame.grid(row=7, column=0, columnspan=3, sticky='nw', pady=10)

    def create_entry_dictionary(self):
        """
        Creates and returns a dictionary which contains references
        to a frame and entries in it
        keys: ["frame", "ent_len", "ent_angle", "chk_is_flip",
        "chk_is_rev", "flip_state","reverse_state"]
        """
        vcmd = (self.frame.register(self.validate_float), '%P')
        entry_frame = Frame(self.frame)
        ent_length = Entry(entry_frame,
                           validate='key',
                           width=8,
                           validatecommand=vcmd)
        ent_angle = Entry(entry_frame,
                          validate='key',
                          width=8,
                          validatecommand=vcmd)
        is_reversed_state = BooleanVar(entry_frame)
        is_flipped_state = BooleanVar(entry_frame)
        chkbtn_is_reversed = Checkbutton(entry_frame,
                                         text='reverse',
                                         var=is_reversed_state)
        chkbtn_is_flipped = Checkbutton(entry_frame,
                                        text='flip',
                                        var=is_flipped_state)

        ent_angle.pack(side=LEFT)
        ent_length.pack(side=LEFT)
        chkbtn_is_flipped.pack(side=LEFT)
        chkbtn_is_reversed.pack(side=LEFT)
        entry_frame.grid(row=len(self.entries) + 3, columnspan=4)
        entry_dict = {
            "frame": entry_frame,
            "ent_len": ent_length,
            "ent_angle": ent_angle,
            "chk_is_flip": chkbtn_is_flipped,
            "chk_is_rev": chkbtn_is_reversed,
            "flip_state": is_flipped_state,
            "reverse_state": is_reversed_state
        }
        return entry_dict

    def init_add_entry_button(self):
        """
        Initialize the button which adds frames for entry of each rule
        """
        def add_entry():
            """
            create a new entry and add to self.entries
            """
            new_entry = self.create_entry_dictionary()
            self.entries.append(new_entry)
            self.render_preview()

        self.add_button = Button(self.frame, text='+', command=add_entry)
        self.add_button.grid(row=1, column=2)

    def init_sub_entry_button(self):
        """
        Initialize the button to remove entry fields
        """
        def sub_entry():
            """
            Pop and destroy the last entry from self.entries
            """
            if self.entries != []:
                self.entries.pop()["frame"].destroy()
            self.render_preview()

        self.sub_button = Button(self.frame, text='-', command=sub_entry)
        self.sub_button.grid(row=1, column=3)

    def validate_float(self, p_str):
        """
        Validate if input is a valid floating point number
        """
        # may validate only '[+-].' which needs to be handled later
        float_pattern = r"^[\+\-]?([0-9]*[.])?[0-9]*$"
        if re.search(float_pattern, p_str) or p_str == "":
            return True
        return False

    def extract_rules(self):
        """
        Extract rules from the input fields to a list
        """
        def get_float_value(entry_string):
            """
            Get the float value out of entry strings
            (function to handle corner cases)
            """
            if entry_string in ['', '.', '+.', '-.', '+', '-']:
                return 0.0
            return float(entry_string)

        extracted_rules = []
        for entry in self.entries:
            if self.radio_angle_var.get(
            ):  # if true, means radians, extract as is
                ent_angle = get_float_value(entry["ent_angle"].get())
            else:
                ent_angle = get_float_value(entry["ent_angle"].get(
                )) * RAD_FAC  # convert degree to radians
            ent_angle = ent_angle % (2 * PI)
            ent_len = get_float_value(entry["ent_len"].get())
            is_reversed = entry["reverse_state"].get()
            is_flipped = entry["flip_state"].get()
            if ent_angle or ent_len:
                # user entered something, otherwise nothing changed
                extracted_rules.append(
                    (ent_angle, ent_len, is_flipped, is_reversed))
        return extracted_rules

    def fill_entries_from_rules(self, rules):
        """
        Fill in the entries in GUI for user feedback
        """
        for rule in rules:
            angle, length, is_flipped, is_reversed = rule
            new_entry = self.create_entry_dictionary()
            # clear and insert angle
            new_entry['ent_angle'].delete(0, END)
            if self.radio_angle_var.get():  # if angle in radians
                new_entry['ent_angle'].insert(0, str(angle))
            else:
                new_entry['ent_angle'].insert(0, str(angle * DEG_FAC))
            # clear and insert length
            new_entry['ent_len'].delete(0, END)
            new_entry['ent_len'].insert(0, str(length))
            # set booleans
            new_entry['reverse_state'].set(is_reversed)
            new_entry['flip_state'].set(is_flipped)

            self.entries.append(new_entry)


#     def init_extract_rules_button(self):
#         """
#         Test button to check extracted rules
#         """
#         def print_extracted():
#             """
#             Print the extracted rules to stdout
#             """
#             print("Extracted:")
#             print(self.extract_rules())
#
#         self.test_button = Button(
#             self.frame, text="extract", command=print_extracted)
#         self.test_button.pack()

    def init_preview_canvas(self):
        """
        Canvas to draw the base curve from rules and give
        preview to the user
        """
        self.preview_canvas = Canvas(self.frame, width=200, height=200)
        self.preview_canvas.grid(row=0, columnspan=4, sticky=W)

    def form_base_curve(self, rules):
        """
        Form the base curve from extracted rules for previewing
        Resized to fit into the preview canvas
        """
        curve = [(0, 0)]
        for theta, scale_fac, _, _ in rules:
            last_x, last_y = curve[-1]
            curve.append((last_x + scale_fac * cos(theta),
                          last_y + scale_fac * sin(theta)))

        min_x = min(point[0] for point in curve)
        min_y = min(point[1] for point in curve)
        scale_y = max(point[1] - min_y for point in curve)
        scale_x = max(point[0] - min_x for point in curve)
        if scale_x == 0 or scale_y == 0:
            return curve
        canvas_width = self.preview_canvas.winfo_width()
        canvas_height = self.preview_canvas.winfo_height()
        to_scale = min(canvas_width / scale_x, canvas_height / scale_y) * 0.8
        curve = [((point[0] - min_x) * to_scale + canvas_width / 10,
                  (point[1] - min_y) * to_scale + canvas_height / 10)
                 for point in curve]
        return curve

    def render_preview(self):
        """
        Render the preview on canvas on calling the function
        Desired to be called by some update function
        """
        # Not the best way to do it but the curve size is of constant
        # order, <20 segments, so it wouldnt create much difference
        extracted_rules = self.extract_rules()
        self.set_rules_in_curve(extracted_rules)
        # set the rules in the parent curve dynamically
        curve = self.form_base_curve(extracted_rules)
        self.preview_canvas.delete("all")
        if len(curve) > 1:  # draw only if there are more than one points
            self.preview_canvas.create_line(curve, arrow=LAST)

    def init_info_labels(self):
        """
        Initialize the labels providing info about input fields
        """
        Radiobutton(self.frame,
                    variable=self.radio_angle_var,
                    value=False,
                    text="Degrees").grid(row=1, column=0)
        Radiobutton(self.frame,
                    variable=self.radio_angle_var,
                    value=True,
                    text="Radians").grid(row=1, column=1)
        Label(self.frame, text="Angle").grid(row=2, column=0, sticky=W)
        Label(self.frame, text="Length").grid(row=2, column=1, sticky=W)

    def set_rules_in_curve(self, rules):
        """
        Set the rules entries received into the rules of Curve
        class
        """
        self.parent_class.parent_class.classes["fractal"].set_rules(rules)
Пример #19
0
class App(Tk):
    def __init__(self, *args, **kwargs):
        '''
        the ui stuff
        '''
        super().__init__(*args, **kwargs)
        
        self.color = 'blue'
        
        self.winfo_toplevel().title('Judgy Hexagon')

        #Menu for a bit of documentation and help
        self.menu = Menu(self)
        self.menu.add_command(label='Change Color', command=self.change_color)
        self.menu.add_command(label='Help', command=self.help)
        self.menu.add_command(label='People', command=self.people)
        self.config(menu=self.menu)
        


        #the main canvas to show the hexagon
        self.canvas = Canvas(self, height=566, width=800)
        self.canvas.grid(row=1, column=1)

        
        #frame to put all the sliders in
        self.sf = Frame(self)
        self.sf.grid(row=1, column=3)

        #entries for the trait names (with default values)
        self.sl1 = Entry(self.sf)
        self.sl1.grid(row=0, column=0)
        self.sl1.insert(END, 'IQ')
        self.sl2 = Entry(self.sf, text='EQ')
        self.sl2.grid(row=1, column=0)
        self.sl2.insert(END, 'EQ')
        self.sl3 = Entry(self.sf)
        self.sl3.grid(row=2, column=0)
        self.sl3.insert(END, 'Attractiveness')
        self.sl4 = Entry(self.sf)
        self.sl4.grid(row=3, column=0)
        self.sl4.insert(END, 'Personality')
        self.sl5 = Entry(self.sf)
        self.sl5.grid(row=4, column=0)
        self.sl5.insert(END, 'Athleticism')
        self.sl6 = Entry(self.sf)
        self.sl6.grid(row=5, column=0)
        self.sl6.insert(END, 'Artisticness')


        #sliders
        self.t1scale = Scale(self.sf, from_=0, to=9, orient=HORIZONTAL)
        self.t1scale.grid(column=1, row=0)
        self.t2scale = Scale(self.sf, from_=0, to=9, orient=HORIZONTAL)
        self.t2scale.grid(column=1, row=1)
        self.t3scale = Scale(self.sf, from_=0, to=9, orient=HORIZONTAL)
        self.t3scale.grid(column=1, row=2)
        self.t4scale = Scale(self.sf, from_=0, to=9, orient=HORIZONTAL)
        self.t4scale.grid(column=1, row=3)
        self.t5scale = Scale(self.sf, from_=0, to=9, orient=HORIZONTAL)
        self.t5scale.grid(column=1, row=4)
        self.t6scale = Scale(self.sf, from_=0, to=9, orient=HORIZONTAL)
        self.t6scale.grid(column=1, row=5)

        #the labels to make clear which line is which trait
        self.l1 = Label(self, text=self.sl1.get(),
              font=('Calibri', 20))
        self.l1.grid(row=1, column=2, sticky=E) 
        self.l2 = Label(self, text=self.sl2.get(),
              font=('Calibri', 20))
        self.l2.grid(row=1, column=1, sticky=SE)
        self.l3 = Label(self, text=self.sl3.get(),
              font=('Calibri', 20))
        self.l3.grid(row=1, column=1, sticky=SW)
        self.l4 = Label(self, text=self.sl4.get(),
              font=('Calibri', 20))
        self.l4.grid(row=1, column=0, sticky=W)
        self.l5 = Label(self, text=self.sl5.get(),
              font=('Calibri', 20))
        self.l5.grid(row=1, column=1, sticky=NW)
        self.l6 = Label(self, text=self.sl6.get(),
              font=('Calibri', 20))
        self.l6.grid(row=1, column=1, sticky=NE) #:)



        #put the person's name in here
        self.nameentry = Entry(self.sf)
        self.nameentry.grid(row=7, column=1)

        Label(self.sf, text='\n\nName of person\n\n').grid(row=7, column=0)
        
        
        self.namelabel = Label(self, text='Name', font=('Calibri', 20), fg='red')
        self.namelabel.grid(row=0, column=1)

        
        #6 lists of points
        self.listright = [(400+40*i, 200*2**0.5)
                          for i in range(10)]
        self.listrightdown = [(400+20*i, 200*2**0.5+i*20*2**0.5)
                              for i in range(10)]
        self.listleftdown = [(400-20*i, 200*2**0.5+i*20*2**0.5)
                              for i in range(10)]
        self.listleft = [(400-40*i, 200*2**0.5)
                         for i in range(10)]
        self.listleftup = [(400-20*i, 200*2**0.5-i*20*2**0.5)
                           for i in range(10)]
        self.listrightup = [(400+20*i, 200*2**0.5-i*20*2**0.5)
                            for i in range(10)]
        


        
        #Draw the 10 hexagons
        for i in range(10):
            self.canvas.create_polygon([self.listright[i][0],
                                        self.listright[i][1],
                                        self.listrightdown[i][0],
                                        self.listrightdown[i][1],
                                        self.listleftdown[i][0],
                                        self.listleftdown[i][1],
                                        self.listleft[i][0],
                                        self.listleft[i][1],
                                        self.listleftup[i][0],
                                        self.listleftup[i][1],
                                        self.listrightup[i][0],
                                        self.listrightup[i][1],],
                                        fill='', width=1, outline='black')
            
    def change_color(self):
        self.color = clr.askcolor(title='Choose a color for the shape')[1]

    def help(self):
        msg.showinfo(title='Help', message='''
How to use this app:
Move around the sliders and enter a name.
Type your 6 character traits in the 6 entries.
You can change the color of shape by clicking on the 'Change Color' menu option.
Then, take a snip of the part without the sliders.

Tutorial on judgy hexagons in real life:
First, draw like 8 nested hexagons.
Connect all the points with 6 lines.
Label each of the lines with a trait (should be the traits below).
For each of the traits, rank them from 1-8 and draw the point on the line.
The outer hexagons are higher.
Now, connect all 6 points, and color in the polygon made by them.''')

    def people(self):
        msg.showinfo(title='People', message='''
List of people related to this:

Ideas: Aileen Liang (probably more this person), Hanting Li
Python implementation: Owen Fei
Another app to check out: Owen Zhang''')

                                      
    def judge(self, t1, t2, t3, t4, t5, t6):
        '''
        Draws the filled-in polygon in blue.
        '''

        #Get which point each level of trait is
        t1 = self.listright[t1]
        t2 = self.listrightdown[t2]
        t3 = self.listleftdown[t3]
        t4 = self.listleft[t4]
        t5 = self.listleftup[t5]
        t6 = self.listrightup[t6]

        #REmove the last shape if possible
        try:
            self.canvas.delete(self.last_polygon)
        except:
            pass

        #Draw the new polygon
        self.last_polygon = self.canvas.create_polygon([t1[0],
                                                        t1[1],
                                                        t2[0],
                                                        t2[1],
                                                        t3[0],
                                                        t3[1],
                                                        t4[0],
                                                        t4[1],
                                                        t5[0],
                                                        t5[1],
                                                        t6[0],
                                                        t6[1],],
                                                        fill=self.color,
                                                        width=1,
                                                        outline=self.color)
        self.canvas.update()

    def main(self):
        '''
        Constantly draws the new polygon.
        Constantly updates the name.
        '''
        while True:
            #Update the name
            self.namelabel.config(text=self.nameentry.get())

            #Call judge() on the values of the sliders
            self.judge(self.t1scale.get(),
                       self.t2scale.get(),
                       self.t3scale.get(),
                       self.t4scale.get(),
                       self.t5scale.get(),
                       self.t6scale.get())

            #Updates the labels with trait names.
            self.l1.config(text=self.sl1.get())
            self.l2.config(text=self.sl2.get())
            self.l3.config(text=self.sl3.get())
            self.l4.config(text=self.sl4.get())
            self.l5.config(text=self.sl5.get())
            self.l6.config(text=self.sl6.get())
            

            
            self.update()
Пример #20
0
class World(Tk):
    def __init__(self, filename=None, block=50, debug=True, delay=0.25,
                 image=False, width=10, height=10):
        Tk.__init__(self)
        self.title("")
        arg = block
        self.width = width
        self.height = height
        self.beepers = {}
        self.ovals = {}
        self.numbers = {}
        self.robots = {}
        self.walls = {}
        self.m = arg * (width + 3)
        self.n = arg * (height + 3)
        self.t = arg
        self.delay = delay
        self.debug = debug
        self.use_image = image
        a = self.t + self.t / 2
        b = self.m - self.t / 2
        c = self.n - self.t / 2
        self.canvas = Canvas(self, bg="white", width=self.m, height=self.n)
        self.canvas.pack()
        count = 1
        for k in range(2*self.t, max(self.m, self.n)-self.t, self.t):
            if k < b:
                self.canvas.create_line(k, c, k, a, fill="red")
                self.canvas.create_text(k, c+self.t/2, text=str(count),
                                        font=("Times",
                                              max(-self.t*2/3, -15), ""))
            if k < c:
                self.canvas.create_line(b, k, a, k, fill="red")
                self.canvas.create_text(a-self.t/2, self.n-k, text=str(count),
                                        font=("Times",
                                              max(-self.t*2/3, -15), ""))
            count += 1
        self.canvas.create_line(a, c, b, c, fill="black", width=3)
        self.canvas.create_line(a, a, a, c, fill="black", width=3)
        if filename is not None:
            self.read_world(filename)
        self.refresh()

    def read_world(self, filename):
        try:
            infile = open("worlds\\{0}.wld".format(filename), "r")
        except IOError:
            try:
                infile = open("worlds/{0}.wld".format(filename), "r")
            except IOError:
                infile = open(filename, "r")
        text = infile.read().split("\n")
        infile.close()
        for t in text:
            if t.startswith("eastwestwalls"):
                s = t.split(" ")
                y, x = int(s[1]), int(s[2])
                self.add_wall(x, y, -1, y)
            if t.startswith("northsouthwalls"):
                s = t.split(" ")
                x, y = int(s[1]), int(s[2])
                self.add_wall(x, y, x, -1)
            if t.startswith("beepers"):
                s = t.split(" ")
                y, x, n = int(s[1]), int(s[2]), int(s[3])
                if n is INFINITY:
                    self.add_infinite_beepers(x, y)
                else:
                    for k in range(n):
                        self.add_beeper(x, y)

    def pause(self):
        sleep(self.delay)

    def is_beeper(self, x, y):
        return (x, y) in list(self.beepers.keys()) and not \
            self.beepers[(x, y)] == 0

    def count_robots(self, x, y):
        if (x, y) not in list(self.robots.keys()):
            return 0
        return len(self.robots[(x, y)])

    def crash(self, x1, y1, x2, y2):
        if 0 in (x1, y1, x2, y2):
            return True
        if (x2, y2) in list(self.walls.keys()) and \
                (x1, y1) in self.walls[(x2, y2)]:
            return True
        if (x1, y1) in list(self.walls.keys()) and \
                (x2, y2) in self.walls[(x1, y1)]:
            return True
        return False

    def add_infinite_beepers(self, x, y):
        flag = (x, y) not in list(self.beepers.keys()) or \
            self.beepers[(x, y)] is 0
        self.beepers[(x, y)] = INFINITY
        text = "oo"
        a = self.t + x * self.t
        b = self.n - (self.t + y * self.t)
        t = self.t / 3
        if flag:
            self.ovals[(x, y)] = self.canvas.create_oval(a-t, b-t, a+t,
                                                         b+t, fill="black")
            self.numbers[(x, y)] = self.canvas.create_text(a, b, text=text,
                                                           fill="white",
                                                           font=("Times",
                                                                 max(-self.t/2,
                                                                     -20),
                                                                 ""))
        else:
            self.canvas.itemconfig(self.numbers[(x, y)], text=text)
        if (x, y) in list(self.robots.keys()):
            for robot in self.robots[(x, y)]:
                robot.lift()

    def add_beeper(self, x, y):
        if (x, y) in list(self.beepers.keys()) and \
                self.beepers[(x, y)] is INFINITY:
            return
        flag = (x, y) not in list(self.beepers.keys()) or \
            self.beepers[(x, y)] is 0
        if flag:
            self.beepers[(x, y)] = 1
        else:
            self.beepers[(x, y)] += 1
        text = str(self.beepers[(x, y)])
        a = self.t + x * self.t
        b = self.n - (self.t + y * self.t)
        t = self.t / 3
        if flag:
            self.ovals[(x, y)] = self.canvas.create_oval(a-t, b-t, a+t, b+t,
                                                         fill="black")
            self.numbers[(x, y)] = self.canvas.create_text(a, b, text=text,
                                                           fill="white",
                                                           font=("Times",
                                                                 max(-self.t/2,
                                                                     -20),
                                                                 ""))
        else:
            self.canvas.itemconfig(self.numbers[(x, y)], text=text)
        if (x, y) in list(self.robots.keys()):
            for robot in self.robots[(x, y)]:
                robot.lift()

    def remove_beeper(self, x, y):
        if self.beepers[(x, y)] is INFINITY:
            return
        self.beepers[(x, y)] -= 1
        flag = self.beepers[(x, y)] is 0
        text = str(self.beepers[(x, y)])
        if flag:
            self.canvas.delete(self.ovals[(x, y)])
            self.canvas.delete(self.numbers[(x, y)])
        else:
            self.canvas.itemconfig(self.numbers[(x, y)], text=text)
        if (x, y) in list(self.robots.keys()):
            for robot in self.robots[(x, y)]:
                robot.lift()

    def add_wall(self, x1, y1, x2, y2):
        if not x1 == x2 and not y1 == y2:
            return
        if x1 == x2:
            y1, y2 = min(y1, y2), max(y1, y2)
            if y1 == -1:
                y1 = y2
            for k in range(y1, y2+1):
                self.walls.setdefault((x1, k), []).append((x1+1, k))
                a = self.t + x1 * self.t+self.t / 2
                b = self.n - (self.t + k * self.t) + self.t / 2
                c = self.t + x1 * self.t + self.t / 2
                d = self.n - (self.t + k * self.t) - self.t / 2
                self.canvas.create_line(a, b+1, c, d-1, fill="black", width=3)
        else:
            x1, x2 = min(x1, x2), max(x1, x2)
            if x1 == -1:
                x1 = x2
            for k in range(x1, x2+1):
                self.walls.setdefault((k, y1), []).append((k, y1+1))
                a = self.t + k * self.t - self.t / 2
                b = self.n - (self.t + y1 * self.t) - self.t / 2
                c = self.t + k * self.t + self.t / 2
                d = self.n - (self.t + y1 * self.t) - self.t / 2
                self.canvas.create_line(a-1, b, c+1, d, fill="black", width=3)

    def draw(self, x, y, d, img):
        t = self.t / 2
        angle = 120
        x = self.t + x * self.t
        y = self.n - (self.t + y * self.t)
        x1 = x + 3 ** 0.5 * t / 2 * cos(radians(d))
        y1 = y - 3 ** 0.5 * t / 2 * sin(radians(d))
        x2 = x + t * cos(radians(d + angle))
        y2 = y - t * sin(radians(d + angle))
        x3 = x + t / 4 * cos(radians(d + 180))
        y3 = y - t / 4 * sin(radians(d + 180))
        x4 = x + t * cos(radians(d - angle))
        y4 = y - t * sin(radians(d - angle))
        if img is not None:
            self.canvas.delete(img)
        return self.canvas.create_polygon(x1, y1, x2, y2, x3, y3, x4, y4,
                                          fill="blue")

    def erase(self, img):
        self.canvas.delete(img)

    def record_move(self, count, x1, y1, x2, y2):
        for robot in self.robots[(x1, y1)]:
            if robot.count == count:
                self.robots[(x1, y1)].remove(robot)
                self.robots.setdefault((x2, y2), []).append(robot)
                break

    def lift(self, img):
        self.canvas.lift(img)

    def refresh(self):
        self.canvas.update()
        self.pause()

    def register(self, x, y, robot):
        self.robots.setdefault((x, y), []).append(robot)

    def remove(self, x, y, robot):
        self.robots[(x, y)].remove(robot)
Пример #21
0
class SudokuUI(Frame):
    """
    The Tkinter UI, responsible for drawing the board and accepting user input.UI is User Interface
    Frame is defined as a “rectangular region on the screen”. This is essentially just a widget of our puzzle
    """
    def __init__(self, parent, game):
        self.game = game
        Frame.__init__(self, parent)
        self.parent = parent

        self.row, self.col = -1, -1

        self.__initUI()

    def __initUI(self):
        '''
        This private method of the SudokuUI class is the logic that sets up the actual user interface.
        '''
        self.parent.title("Deez Nutz")
        self.pack(fill=BOTH)
        '''Next is the canvas attribute. canvas is a general-purpose widget that we will use to display our board. 
        We will use the earlier-defined global variables'''
        self.canvas = Canvas(self, width=WIDTH, height=HEIGHT)
        self.canvas.pack(fill=BOTH, side=TOP)
        clear_button = Button(self,
                              text="Clear answers",
                              command=self.__clear_answers)
        clear_button.pack(fill=BOTH, side=BOTTOM)

        self.__draw_grid()
        self.__draw_puzzle()
        '''So here, when the user clicks on the puzzle with a single left-click of the mouse, 
our UI will call __cell_clicked function, which we will define in a bit.
The bind method will actually pass in the x and y location of the cursor, 
which in __cell_clicked we will turn into actual cells of the puzzle.'''
        self.canvas.bind("<Button-1>", self.__cell_clicked)
        self.canvas.bind("<Key>", self.__key_pressed)

    def __draw_grid(self):
        """
        Draws grid divided with blue lines into 3x3 squares
        """
        for i in range(10):
            color = "blue" if i % 3 == 0 else "gray"
            #creates column
            x0 = MARGIN + i * SIDE
            y0 = MARGIN
            x1 = MARGIN + i * SIDE
            y1 = HEIGHT - MARGIN
            self.canvas.create_line(x0, y0, x1, y1, fill=color)
            #creates row
            x0 = MARGIN
            y0 = MARGIN + i * SIDE
            x1 = WIDTH - MARGIN
            y1 = MARGIN + i * SIDE
            self.canvas.create_line(x0, y0, x1, y1, fill=color)

    '''The __draw_puzzle private method then draws the puzzle by filling in the cells 
with the pre-filled numbers defined in whatever .sudoku board we pass in.
We first call delete on the canvas to clear out any previous numbers. 
This is helpful for when the user wants to clear out the puzzle and start over.
We then iterate over rows and columns, and create a cell. 
We then grab the same X & Y location of the cell from the game’s puzzle. 
If it isn’t zero, then fill it in with the appropriate number, otherwise just leave it blank.'''

    def __draw_puzzle(self):
        self.canvas.delete("numbers")
        for i in range(9):
            for j in range(9):
                answer = self.game.puzzle[i][j]
                if answer != 0:
                    x = MARGIN + j * SIDE + SIDE / 2
                    y = MARGIN + i * SIDE + SIDE / 2
                    original = self.game.start_puzzle[i][j]
                    color = "black" if answer == original else "sea green"
                    self.canvas.create_text(x,
                                            y,
                                            text=answer,
                                            tags="numbers",
                                            fill=color)

    def __draw_cursor(self):
        self.canvas.delete("cursor")
        if self.row >= 0 and self.col >= 0:
            x0 = MARGIN + self.col * SIDE + 1
            y0 = MARGIN + self.row * SIDE + 1
            x1 = MARGIN + (self.col + 1) * SIDE - 1
            y1 = MARGIN + (self.row + 1) * SIDE - 1
            self.canvas.create_rectangle(x0,
                                         y0,
                                         x1,
                                         y1,
                                         outline="red",
                                         tags="cursor")

    def __draw_victory(self):
        # create a oval (which will be a circle)
        x0 = y0 = MARGIN + SIDE * 2
        x1 = y1 = MARGIN + SIDE * 7
        self.canvas.create_oval(x0,
                                y0,
                                x1,
                                y1,
                                tags="victory",
                                fill="dark orange",
                                outline="orange")
        # create text
        x = y = MARGIN + 4 * SIDE + SIDE / 2
        self.canvas.create_text(x,
                                y,
                                text="You win!",
                                tags="victory",
                                fill="white",
                                font=("Arial", 32))

    def __cell_clicked(self, event):
        if self.game.game_over:
            return
        x, y = event.x, event.y
        if (MARGIN < x < WIDTH - MARGIN and MARGIN < y < HEIGHT - MARGIN):
            self.canvas.focus_set()

            # get row and col numbers from x,y coordinates
            row, col = (y - MARGIN) / SIDE, (x - MARGIN) / SIDE

            # if cell was selected already - deselect it
            if (row, col) == (self.row, self.col):
                self.row, self.col = -1, -1
            elif self.game.puzzle[int(row)][int(col)] == int(0):
                self.row, self.col = int(row), int(col)
        else:
            self.row, self.col = -1, -1

        self.__draw_cursor()

    def __key_pressed(self, event):
        if self.game.game_over:
            return
        if self.row >= 0 and self.col >= 0 and event.char in "1234567890":
            self.game.puzzle[int(self.row)][int(self.col)] = int(event.char)
            self.col, self.row = -1, -1
            self.__draw_puzzle()
            self.__draw_cursor()
            if self.game.check_win():
                self.__draw_victory()

    def __clear_answers(self):
        self.game.start()
        self.canvas.delete("victory")
        self.__draw_puzzle()
Пример #22
0
class GraphView(View):
	WIN_PADDING_Y = 16
	POINT_MARGIN = 2

	def __init__(self, params):
		super(GraphView, self).__init__(params)

		self._ids = params["ids"] if "ids" in params else ""
		self._ids = [int(i) for i in self._ids.split(' ')]
		self._labels = params["labels"] if "labels" in params else ""
		self._labels = [l for l in self._labels.split(' ')]
		self._colors = [c for c in params["colors"].split(' ')] if "colors" in \
				params else None
		if not self._colors:
			self._colors = self._get_auto_colors(len(self._ids))
		if not len(self._ids) == len(self._labels) == len(self._colors):
			raise RuntimeError("ids, labels and colors must share the same size")

		self._min = float(params["min"]) if "min" in params else -1000
		self._max = float(params["max"]) if "max" in params else 1000
		if self._min > self._max:
			self._min, self._max = self._max, self._min
		self._diff = abs(self._max - self._min)

		self._data = [_GraphData() for _ in range(len(self._ids))]
		self._data_view = [_GraphDataView(self._colors[i]) for i in range(
				len(self._ids))]
		self._graph_x = 0

		self._tk = Tk()
		self._tk.title("Graph view %s" % str(self._labels))

		self._canvas = Canvas(self._tk, width = 640, height = 480)
		self._canvas.pack(fill = tkinter.BOTH, expand = 1)

		self._tk.update()
		self._win_size = self._tk.winfo_width(), self._tk.winfo_height()
		# graph_rect only works as providing the area but not coord
		self._graph_rect = self._win_size
		self._tk.minsize(320, 240)
		self._tk.protocol("WM_DELETE_WINDOW", self.on_press_close)

		self._tk.bind("<Configure>", self.on_config)
		self._canvas.config(background = config.COL_GREY_900)

		self._full_redraw()

		self._file = open("graph_%s_%i.csv" % (str(self._labels),
				int(time.time() * 1000)), "w")
		self._file.write(','.join(self._labels) + '\n')

		self._tk.after(16, self._refresh)

	def run(self):
		super(GraphView, self).run()
		self._tk.mainloop()

	def on_new_input(self):
		try:
			hex_data = binascii.unhexlify(self.get_input())
		except TypeError as e:
			logging.debug(str(e))
			return

		count = int(len(hex_data) / GraphView._MSG_SIZE)
		for i in (x * 6 for x in range(count)):
			if hex_data[i] in self._ids:
				value_type = hex_data[i + 1]
				value_bytes = hex_data[i + 2:i + 6]
				if value_type == GraphView._MSG_TYPE_INT:
					value = int.from_bytes(value_bytes, byteorder = "big",
							signed = True)
				elif value_type == GraphView._MSG_TYPE_FLOAT:
					value = struct.unpack(">f", value_bytes)[0]
				else:
					logging.error("Unknown type: " + str(value_type))
					continue
				self._tk.after_idle(self._put_value, hex_data[i], value)

	def on_dismiss(self):
		self._tk.after_idle(self.on_press_close)

	def on_press_close(self):
		self._tk.destroy()
		self.join_io_thread()

	def on_config(self, event):
		win_size = (event.width, event.height)
		if win_size != self._win_size:
			self._win_size = win_size
			self._full_redraw()

	def is_test_input(self):
		return False

	def gen_test_input(self):
		while True:
			for i in range(int(self._min), int(self._max)):
				sleep(0.1)
				yield "0000%08x" % (random.randrange(-100, 100) & 0xFFFFFFFF) \
						+ "0100%08x\n" % (i & 0xFFFFFFFF)

	def _put_value(self, id, value):
		pos = self._ids.index(id)
		if self._data[pos].size() == 0:
			for d in self._data:
				d.append()
		elif self._data[pos].get_value(-1) is not None:
			for d in self._data:
				d.append()
			if self._data[pos].size() > 1:
				self._write_prev_records()
		self._data[pos].put_value(value)

		graph_w = self._win_size[0] - self._graph_x;
		count = int(graph_w / GraphView.POINT_MARGIN + 1)

		for d in self._data:
			d.shrink(count)

	def _write_prev_records(self):
		write = ','.join((str(d.get_value(-2)) for d in self._data)) + '\n'
		self._file.write(write)
		self._file.flush()

	def _refresh(self):
		self._redraw_graph()
		self._tk.after(16, self._refresh)

	def _full_redraw(self):
		self._canvas.delete("all")
		bounding_box = self._redraw_data_labels()
		self._graph_rect = 0, 0, self._win_size[0], bounding_box[1]
		self._redraw_y_labels()
		for v in self._data_view:
			v.clear_lines();
		self._redraw_graph()

	def _redraw_data_labels(self):
		top = self._win_size[1]
		x = GraphView._DATA_LABEL_PADDING
		for l, c in zip(self._labels, self._colors):
			t = self._canvas.create_text(x,
					self._win_size[1] - GraphView._DATA_LABEL_PADDING,
					anchor = tkinter.SW, fill = c, font = config.FONT,
					text = '-' + l)
			bounding_box = self._canvas.bbox(t)
			top = min(top, bounding_box[1])
			x = bounding_box[2] + GraphView._DATA_LABEL_PADDING
		return 0, top, x, self._win_size[1]

	def _redraw_y_labels(self):
		height = self._graph_rect[3] - self._graph_rect[1] \
				- GraphView.WIN_PADDING_Y * 2
		count = max(int(height / 50), 2)

		labels = []
		max_label_size = 0
		longest_label = None
		longest_label_i = None
		for i in range(count):
			ratio = i / (count - 1)
			value = self._max - self._diff * ratio
			value_label = ("%.2f" % value) if value % 1 != 0 else str(value)
			labels.append(value_label)
			if len(value_label) > max_label_size:
				max_label_size = len(value_label)
				longest_label = value_label
				longest_label_i = i

		label_id = self._canvas.create_text(0, height * (longest_label_i \
						/ (count - 1)) + GraphView.WIN_PADDING_Y,
				anchor = tkinter.W, fill = config.COL_GREY_100,
				font = config.FONT, text = longest_label)
		bounding_box = self._canvas.bbox(label_id)
		width = bounding_box[2] - bounding_box[0]
		self._graph_x = width + GraphView.POINT_MARGIN

		for i in range(count):
			ratio = i / (count - 1)
			y = height * ratio + GraphView.WIN_PADDING_Y
			if i != longest_label_i:
				self._canvas.create_text(width, y, anchor = tkinter.E,
						fill = config.COL_GREY_100, font = config.FONT,
						text = labels[i])
			self._canvas.create_line(self._graph_x, y, self._graph_rect[2], y,
					fill = config.COL_GREY_700)

	def _redraw_graph(self):
		graph_h = self._graph_rect[3] - GraphView.WIN_PADDING_Y * 2
		for d, v in zip(self._data, self._data_view):
			v.populate(d.get_values(), self._max, self._diff, self._graph_x,
					graph_h)
			v.draw(self._canvas)

	def _get_auto_colors(self, size) -> list:
		product = GraphView._COLOR_REPO[:min(size, len(GraphView._COLOR_REPO))]
		while len(product) < size:
			product.append("#%06x" % random.randrange(0xFFFFFF))
		return product

	_LABEL_SIZE = 10
	_DATA_LABEL_PADDING = 8
	_MSG_SIZE = 6
	_MSG_TYPE_INT = 0
	_MSG_TYPE_FLOAT = 1
	_COLOR_REPO = ["#F44336", "#4CAF50", "#2196F3", "#FFEB3B", "#607D8B",
			"#9C27B0", "#009688", "#673AB7", "#795548"]
Пример #23
0
class Main(Frame):
    REMOTE_UPDATE_URL = "http://www.aiquimist.com/update/parameters.json"

    data = None
    shouldUpdate = False
    snapshot_dir = "snapshots"
    canvas = None
    capture = None
    photo = None
    delay = 15

    def __init__(self, parent=None):
        super().__init__(parent)
        self.pack(side=LEFT, fill=BOTH, expand=True)
        self.columnconfigure(0, weight=1)
        self.rowconfigure(1, weight=1)

        self.bind("<configure>", self.on_window_resize())
        self.master.protocol("WM_DELETE_WINDOW", self.on_window_close)

        style = AppStyle()

        # Read application settings.
        self.data = read_settings()

        # Top frame styles.
        style.configure("TOP.TFrame")

        # Bottom frame styles.
        style.configure("BOT.TFrame")

        # Button styles.
        style.configure("TOP.TMenubutton", padding=13)

        top_frame = Frame(self, padding=10, style="TOP.TFrame")
        top_frame.grid(row=0, column=0, sticky="ew")

        top_frame.columnconfigure(0, weight=1)
        top_frame.columnconfigure(7, weight=1)

        cams_list = self.get_cams_list()
        self.selected_camera_var = StringVar()
        self.selected_camera_var.trace('w', self.on_camera_option_select)

        self.cameras_option = OptionMenu(top_frame,
                                         self.selected_camera_var,
                                         None,
                                         *cams_list,
                                         command=self.on_camera_option_select,
                                         style="TOP.TMenubutton")
        self.cameras_option.grid(row=0, column=1, padx=[0, 10])

        self._biometry_image = PhotoImage(file="resources/biometrical.gif")
        biometry_button = Button(top_frame,
                                 image=self._biometry_image,
                                 compound=LEFT,
                                 text="Recognize",
                                 command=self.on_recognize_button_click)
        biometry_button.grid(row=0, column=2, padx=[0, 10])

        self._open_image = PhotoImage(file="resources/folder_open.gif")
        open_button = Button(top_frame,
                             image=self._open_image,
                             compound=LEFT,
                             text="Open",
                             command=self.on_open_button_click)
        open_button.grid(row=0, column=3, padx=[0, 10])

        self._config_image = PhotoImage(file="resources/config.gif")
        config_button = Button(top_frame,
                               image=self._config_image,
                               compound=LEFT,
                               text="Config",
                               command=self.on_config_button_click)
        config_button.grid(row=0, column=4, padx=[0, 10])

        self._update_image = PhotoImage(file="resources/download.gif")
        update_button = Button(top_frame,
                               image=self._update_image,
                               compound=LEFT,
                               text="Update",
                               command=self.on_update_button_click)
        update_button.grid(row=0, column=5, padx=[0, 10])

        self._close_image = PhotoImage(file="resources/close.gif")
        close_button = Button(top_frame,
                              image=self._close_image,
                              compound=LEFT,
                              text="Close",
                              command=self.on_window_close)
        close_button.grid(row=0, column=6, padx=[0, 10])

        bottom_frame = Frame(self,
                             padding=10,
                             style="BOT.TFrame",
                             relief=SUNKEN)
        bottom_frame.grid(row=1,
                          column=0,
                          padx=10,
                          pady=[0, 10],
                          sticky="nsew")

        self.canvas = Canvas(bottom_frame, bg="black")
        self.canvas.pack(fill=BOTH, expand=True)

        # Set the default camera.
        self.selected_camera_var.set(cams_list[0])

    def get_cams_list(self):
        cams = []
        # Load cameras section
        for cam in self.data["cameras"]:
            cams.append(cam)

        # Return the sorted list
        return sorted(cams)

    def on_window_close(self):
        self.shouldUpdate = False
        self.master.quit()

    def on_window_resize(self):
        if self.canvas is not None:
            self.canvas.configure(relx=0.5, rely=0.5, anchor=CENTER)

    def on_camera_option_select(self, *args):
        # Delete the existing capture object.
        if self.capture is not None:
            del self.capture

        source = self.data["cameras"][self.selected_camera_var.get()]
        self.init_video(source)

    def init_video(self, source):
        # Convert source to integer if numeric.
        if source.isnumeric():
            source = int(source)

        try:
            self.capture = VideoCapture(video_source=source,
                                        snapshot_dir=self.snapshot_dir)
        except ValueError as e:
            msg = "Couldn't open the stream: {0}".format(str(e))
            logging.critical(msg)
            messagebox.showerror("Error Opening Stream", msg)
            self.canvas.delete("all")
            return

        self.shouldUpdate = True

        while self.shouldUpdate:
            self.master.after(self.delay, self.update_canvas())

    def update_canvas(self):
        if self.capture is not None:
            # Force update values.
            self.canvas.update()
            can_width = self.canvas.winfo_width()
            can_height = self.canvas.winfo_height()

            # Get a frame from the video source.
            try:
                ret, frame = self.capture.get_frame(can_width, can_height)
                if ret:
                    self.photo = PhotoImage(image=fromarray(frame))
                    self.canvas.create_image(can_width / 2,
                                             can_height / 2,
                                             image=self.photo)
            except Exception as e:
                self.shouldUpdate = False

    def on_recognize_button_click(self):
        ret = self.capture.take_snapshot()
        if ret:
            messagebox.showinfo("Image Capture", "Snapshot saved!")
        else:
            messagebox.showerror("Image Capture", "Failed to save snapshot.")

    def on_open_button_click(self):
        open_file(self.snapshot_dir)

    def on_config_button_click(self):
        child = Toplevel(self)
        child.title("Config")
        child.geometry("400x235")
        center_window(child)
        child.transient(self)
        child.resizable(False, False)
        child.grab_set()
        Config(child)
        self.wait_window(child)

        # Read the new settings.
        self.data = read_settings()

    def on_update_button_click(self):
        try:
            opener = URLopener()
            opener.retrieve(self.REMOTE_UPDATE_URL,
                            "resources/parameters.json")

            # Read the new settings.
            self.data = read_settings()
            messagebox.showinfo(
                "Settings Update",
                "Settings successfully updated from the server.")
        except Exception as e:
            logging.critical(
                "Couldn't open the remote settings file: {0}".format(str(e)))
            messagebox.showerror("Couldn't Update Settings",
                                 "Couldn't open the remote settings file.")
Пример #24
0
def Graph(canvas: Canvas):
    def CheckTable():
        memory = GetMemoryField('table')
        for y in range(0, 5):
            for x in range(0, 14):
                if memory[y][x] == '':
                    return False
        return True

    canvas.delete('all')
    SetPage(6)

    canvas.create_text(960, 50, text='График', font='JetBrainsMono 40')

    # Подсказка про выход в меню
    canvas.create_text(960, 1055, text='Для выхода в меню нажмите Esc', font='JetBrainsMono 15')

    Memory = GetMemoryField('table')
    Errors = GetMemoryField('error')

    canvas.create_line(150, 980, 150, 150, width=3, arrow='last')
    canvas.create_line(149, 980, 1920 - 150, 980, width=3, arrow='last')
    canvas.create_text(150, 120, text='S, см', font='JetBrainsMono 20')
    canvas.create_text(1835, 980, text='α, ⁰', font='JetBrainsMono 20')

    x = 150
    for a in range(0, 90, 15):
        canvas.create_oval(x - 3, 980 - 3, x + 3, 980 + 3, fill='black')
        canvas.create_text(x, 995, text=f'{a}', font='JetBrainsMono 15')
        x += 300

    if CheckTable():
        def parabola():
            for i in Memory:
                if not (float(i[13]) - float(i[11]) > float(i[10])) and (float(i[13]) + float(i[11]) < float(i[10])):
                    return False
            return True

        x = 450
        for a in range(5):
            y = (750 / float(Memory[2][13])) * float(Memory[a][13])
            canvas.create_oval(x - 3, 980 - y - 3, x + 3, 980 - y + 3, fill='black')
            canvas.create_text(120, 980 - y, text=f'{Memory[a][13]}', font='JetBrainsMono 15')
            canvas.create_oval(150 - 3, 980 - y - 3, 150 + 3, 980 - y + 3, fill='black')
            x += 300
        y = (750 / float(Memory[2][13])) * float(Memory[1][13])
        x1, y1 = 750, 980 - y
        x2, y2 = 1050, 980 - 750
        x3, y3 = 1350, 980 - y

        a = (y3 - (x3 * (y2 - y1) + x2 * y1 - x1 * y2) / (x2 - x1)) / (x3 * (x3 - x1 - x2) + x1 * x2)
        b = (y2 - y1) / (x2 - x1) - a * (x1 + x2)
        c = (x2 * y1 - x1 * y2) / (x2 - x1) + a * x1 * x2

        for x in range(150, 1920 - 150 + 1):
            y = a * x ** 2 + b * x + c
            if y <= 980:
                canvas.create_oval(x - 1, y - 1, x + 1, y + 1)

        if not parabola():
            canvas.create_text(960, 700, text='Значения не попадают на 1 кривую!', font='JetBrainsMono 40')
    else:
        canvas.create_text(960, 540, text='Заполните все поля таблиц!', font='JetBrainsMono 60')
Пример #25
0
class CanvasWrapper:
    """
    该类是画布的wrapper类,包含画布组件的操作,并且保存了当前画布上的数据
    """
    doodle_id = 1
    analyze_service = AnalyzeServiceIMP()

    def __init__(self, master):
        self.side_info = None
        self.c = Canvas(master, width=700, height=500, cursor='pencil', relief='groove', bd=5)
        self.c.pack()
        self.prev = None
        self.doodles = []
        self.lines = []
        self.segments = []

    def set_side_info(self, s):
        self.side_info = s

    def handle_mouse_click(self, e):
        self.lines.append(copy.deepcopy(self.segments))
        self.segments = []
        self.prev = e

    @staticmethod
    def distance_between(a,b):
        return ((a.x-b.x)**2+(a.y-b.y)**2)**.5

    def handle_mouse_move(self, e):
        if self.distance_between(e,self.prev) > 5:
            self.c.create_line(self.prev.x, self.prev.y, e.x, e.y, width=2, tags='doodle'+str(self.doodle_id))
            self.segments.append(e.x)
            self.segments.append(e.y)
            self.prev = e

    def start_paint(self):
        """
        开始记录画笔的轨迹
        :return:
        """
        self.c.bind('<Button-1>', self.handle_mouse_click)
        self.c.bind('<B1-Motion>', self.handle_mouse_move)
        self.lines = []
        self.segments = []
        pass

    def finish_paint(self):
        """
        结束一次涂鸦,将记录的轨迹用于生成一个Doodle类对象,并进行形状分析
        :return:
        """
        self.c.unbind('<Button-1>')
        self.c.unbind('<B1-Motion>')
        d = Doodle(self.doodle_id)
        self.doodle_id = self.doodle_id+1
        self.lines.append(copy.deepcopy(self.segments))
        d.lines = copy.deepcopy(self.lines)
        d.shape = self.analyze_service.analyze_shape(d)
        self.c.create_text(self.lines[-1][-2],self.lines[-1][-1], text=str(d.shape),tags='doodle'+str(d.id))
        self.doodles.append(d)
        self.side_info.insert(END, str(d.id)+'-'+str(d.shape))
        pass

    def set_tag(self, did=0, tag=''):
        for doodle in self.doodles:
            if doodle.id == int(did):
                doodle.tag = tag

    def get_tag(self, did=0, tag=''):
        for doodle in self.doodles:
            if doodle.id == int(did):
                return doodle.tag
        return ''

    def set_doodles(self, doodles):
        """
        读取Doodle类的信息重新绘制到画布上
        :param doodles:
        :return:
        """
        self.c.delete('all')
        self.side_info.delete_all()
        self.doodles = copy.deepcopy(doodles)
        self.doodle_id = doodles[-1].id+1
        for doodle in self.doodles:
            for line in doodle.lines:
                if len(line) >= 4:
                    prev_x = line[0]
                    prev_y = line[1]
                    i = 2
                    while i < len(line):
                        self.c.create_line(prev_x,prev_y,line[i],line[i+1], width=2, tags='doodle'+str(doodle.id))
                        prev_x = line[i]
                        prev_y = line[i+1]
                        i += 2
            self.side_info.insert(END, str(doodle.id) + '-' + str(doodle.shape))
            self.c.create_text(doodle.lines[-1][-2],doodle.lines[-1][-1],text=str(doodle.shape),tags='doodle'+str(doodle.id))

    def highlight(self, tag):
        """
        对选中的涂鸦设置高亮显示
        :param tag:
        :return:
        """
        for i in range(1, self.doodle_id+1):
            if str(i) == tag:
                self.c.itemconfigure('doodle'+str(i), fill='blue')
            else:
                self.c.itemconfigure('doodle'+str(i), fill='black')

    def remove_doodle(self, did):
        self.c.delete('doodle'+str(did))
        for doodle in self.doodles:
            if doodle.id == did:
                self.doodles.remove(doodle)
                break
class gfxView():
    def __init__(self, tk, model):
        tk.title('Lidar. IP: {}. Port: {}'.format(model.ip, model.port))
        tk.geometry('800x600+10+10')

        self.canvas = Canvas(tk)
        self.canvas.pack(fill=BOTH, expand=1)
        self.model = model

    # view the window at the start
    def view_first(self):
        self.prepare_view()
        self.rec(*self.frame, fill='white', outline='')
        self.draw_frame()
        for zone, color in self.model.detect_zones:
            self.rec_zone(zone, fill=color)
        self.draw_grid()

    # view result of a scan
    def view_scan(self):
        self.prepare_view()
        self.draw_bg()
        self.draw_zones()
        self.draw_grid()
        self.draw_frame()
        self.draw_data()

    def prepare_view(self):
        # get canvas size
        H = self.canvas.winfo_height()
        W = self.canvas.winfo_width()

        # margin
        self.M = self.model.margin

        # spagetti sauce
        H -= self.M

        # radius
        if 2 * H > W:
            self.R = W / 2
        else:
            self.R = H

        # center of sensor view
        self.x0 = self.R
        self.y0 = self.R
        self.center = (self.x0, self.y0)

        # frame of sensor view
        self.frame = (self.M, self.M, 2 * self.R - self.M, self.R)

        # scale_factor
        self.scale = (self.R - self.M) / self.model.max

        # clear canvas
        self.canvas.delete('all')

    # draw the background
    def draw_bg(self):
        self.rec(*self.frame, fill='white', outline='')
        self.draw_cone(*self.model.angle, self.model.min)

    # draw the detecting zone
    def draw_zones(self):
        for zone, color in self.model.zones:
            self.rec_zone(zone, fill=color)

    # draw the data points
    def draw_data(self):
        for value, phi in self.model.data:
            # scale value to graph
            v = value * self.scale
            x, y = self.pol2car(v, phi)
            if in_rec(x, y, *self.frame):
                self.point(x, y, outline='', fill='blue')

    # draw the frame of the sensor view
    def draw_frame(self):
        self.rec(*self.frame)
        sr = self.model.sensor_size * self.scale
        if sr < 1:
            sr = 1
        self.cir(*self.center, sr, fill='blue')

    # draw sensor's cone of view
    def draw_cone(self, a0, a1, min):
        x0, y0, x1, _ = self.frame
        xp0, yp0, p0 = self.angle_intersect(a0)
        xp1, yp1, p1 = self.angle_intersect(a1)

        poly = list()
        poly.extend(self.center)
        poly.extend((xp0, yp0))
        if in_range(x1, p1, p0):
            poly.extend((x1, y0))
        if in_range(x0, p1, p0):
            poly.extend((x0, y0))
        poly.extend((xp1, yp1))
        self.canvas.create_polygon(*poly, fill=self.model.detect_color)
        self.arc(min * self.scale,
                 a0,
                 a1,
                 style=PIESLICE,
                 fill='white',
                 outline='')

    # draw grid on the sensor view
    def draw_grid(self):
        for i in range(0, self.model.max, self.model.grid):
            r_i = (i + self.model.grid) * self.scale
            l_i = (i + self.model.grid) * 1e-3
            self.canvas.create_text(self.R + r_i, self.R + 20, text=str(l_i))
            self.canvas.create_text(self.R - r_i, self.R + 20, text=str(l_i))
            self.arc(r_i, 0, 180, style=ARC)

    # check intersect of a line from the center to the edge of the sensor view
    def angle_intersect(self, a):
        x0, y0, x1, y1 = self.frame
        t = tan(deg2rad(a))
        xcen = (x1 + x0) / 2
        xlen = (x1 - x0) / 2
        x = xcen * (1 + 1 / t)
        if x < x0:
            return x0, y1 + xlen * t, x
        if x > x1:
            return x1, y1 - xlen * t, x
        return x, y0, x

    # draw rectangle of detection zone
    def rec_zone(self, zone, *args, **kwargs):
        x0, y0, x1, y1 = zone
        nx0 = self.R + x0 * self.scale
        nx1 = self.R + x1 * self.scale
        ny0 = self.R - y0 * self.scale
        ny1 = self.R - y1 * self.scale
        self.rec(nx0, ny0, nx1, ny1, *args, **kwargs)

    # draw line
    def line(self, x0, y0, x1, y1, *args, **kwargs):
        self.canvas.create_line(x0, y0, x1, y1, *args, **kwargs)

    # draw point
    def point(self, x, y, *args, **kwargs):
        self.cir(x, y, 2, *args, **kwargs)

    # draw circle
    def cir(self, x, y, r, *args, **kwargs):
        self.canvas.create_oval(cen2rec(x, y, r), *args, **kwargs)

    # draw arc
    def arc(self, r, start_angle, end_angle, *args, **kwargs):
        phi = end_angle
        d_phi = start_angle - end_angle
        self.canvas.create_arc(cen2rec(self.x0, self.y0, r),
                               start=phi,
                               extent=d_phi,
                               *args,
                               **kwargs)

    def rec(self, x0, y0, x1, y1, *args, **kwargs):
        self.canvas.create_rectangle(x0, y0, x1, y1, *args, **kwargs)

    # convert from polar to cartesian coordinate
    def pol2car(self, r, angle):
        phi = deg2rad(angle)
        return self.x0 + r * cos(phi), self.y0 - r * sin(phi)
class ShipPlacementPanel(Frame):
    '''A frame which contains visualizations for placing ships.'''

    # the size of a single tile
    SHIP_TILE_SIZE = 20
    SHIP_TILE_COLOR = "steel blue"
    TAG = "staging_ship"
    CANVAS_WIDTH = 150

    def __init__(self, master):
        '''Create a new panel with the given parent.'''

        Frame.__init__(self, master)
        self._ship_name = StringVar()
        self._create_ui()
        self.reset()

    def reset(self):
        '''Alias for unstage_all'''

        self.unstage_all()

    def _create_ui(self):
        '''Create all UI objects.'''

        #self._tl = Label(self, text="Staged Ship", f)
        self._sl = Label(self, textvariable=self._ship_name)
        self._c = Canvas(self)
        self._c.config(width=self.CANVAS_WIDTH)
        self._rb = Button(self,
                          text="Rotate",
                          command=self.rotate_current_ship)

        self.pack_ui()

    def pack_ui(self):
        '''(re) pack the UI.
        Created mostly to counter hiding by unpacking.'''

        #self._tl.pack()
        #self._tl.grid(row=0)
        self._sl.pack()
        self._sl.grid(row=1, pady=10)
        self._c.pack()
        self._c.grid(row=2, pady=15)
        self._rb.pack()
        self._rb.grid(row=3)

    def unstage_all(self):
        '''Remove all ships from staging area.
        Clear all staging preferences.'''

        self._staged_ship = None
        self._clear_staging_grid()
        self._ship_name.set("")
        self._disable_rotate_button()

    def _clear_staging_grid(self):
        '''Remove previously staged ships from staging grid.'''

        for item in self._c.find_withtag(self.TAG):
            self._c.delete(item)

    def _draw_staged_ship(self):
        '''Draw the currently staged ship.'''

        # remove prior drawings
        self._clear_staging_grid()

        if self._staged_ship.is_vertical():
            x = 0
            x_pad = (self._c.winfo_width() - self.SHIP_TILE_SIZE) / 2.0
            y_pad = (self._c.winfo_height() -
                     self.SHIP_TILE_SIZE * self._staged_ship.get_size()) / 2.0

            for y in range(self._staged_ship.get_size()):
                self._draw_ship_tile(x_pad + x * self.SHIP_TILE_SIZE,
                                     y_pad + y * self.SHIP_TILE_SIZE)
        else:
            y = 0
            x_pad = (self._c.winfo_width() -
                     self.SHIP_TILE_SIZE * self._staged_ship.get_size()) / 2.0
            y_pad = (self._c.winfo_height() - self.SHIP_TILE_SIZE) / 2.0

            for x in range(self._staged_ship.get_size()):
                self._draw_ship_tile(x_pad + x * self.SHIP_TILE_SIZE,
                                     y_pad + y * self.SHIP_TILE_SIZE)

    def add_ship(self, s):
        '''Alias for stage ship.'''

        self.stage_ship(s)

    def _disable_rotate_button(self):
        '''Disable / hide the rotate button.'''

        self._rb.grid_forget()

    def _enable_rotate_button(self):
        '''Enable / show the rotate button.'''

        self._rb.grid(row=3)

    def stage_ship(self, s):
        '''Add a ship to the staging area. 
        Display what it would look like on the grid.
        Create support for accidentally adding ship that isn't ready'''

        if s is not None:
            self._staged_ship = s
            self._ship_name.set(s.get_full_name().title())
            self._draw_staged_ship()

            self._enable_rotate_button()
        else:
            self._disable_rotate_button()

    def _draw_ship_tile(self, x, y):
        '''Draw a single tile for the ship at given coordinates.'''

        self._c.create_rectangle(x,
                                 y,
                                 x + self.SHIP_TILE_SIZE,
                                 y + self.SHIP_TILE_SIZE,
                                 fill=self.SHIP_TILE_COLOR,
                                 outline="black",
                                 tag=self.TAG)

    def get_staged_ship(self):
        '''Return the currently staged ship.'''

        return self._staged_ship

    def rotate_current_ship(self):
        '''Rotate the currently staged ship.'''

        if self._staged_ship is not None:
            self._staged_ship.rotate()
            self._draw_staged_ship()
Пример #28
0
class GUI:
    def __init__(self, pointset):
        self.master = Tk()
        self.master.title('D7013E Lab 1')
        self.pointset = pointset

        self.label = Label(self.master, text='Algorithm 1')
        self.label.pack()

        self.canvas = Canvas(self.master, width=500, height=500)
        self.canvas.pack()

        self.random_button = Button(self.master,
                                    text='Random',
                                    command=self.random)
        self.random_button.pack()

        self.load_button = Button(self.master, text='Load', command=self.load)
        self.load_button.pack()

        self.compute_button = Button(self.master,
                                     text='Compute',
                                     command=self.compute)
        self.compute_button.pack()

        self.close_button = Button(self.master,
                                   text='Close',
                                   command=self.master.quit)
        self.close_button.pack()

    def _add_point(self, point: Point):
        self.canvas.create_oval(point.x,
                                point.y,
                                point.x,
                                point.y,
                                fill='#000000',
                                width=10)

    def _add_segment(self, segment: Segment):
        self.canvas.create_line(segment.p1.x, segment.p1.y, segment.p2.x,
                                segment.p2.y)

    def random(self):
        self.clear()
        self.pointset.random_points(NUM_POINTS)
        self.draw()

    def clear(self):
        self.pointset.clear()
        self.canvas.delete(ALL)

    def draw(self):
        for p in self.pointset.points:
            self._add_point(p)

        for s in self.pointset.segments:
            self._add_segment(s)

    def load(self):
        file = filedialog.askopenfilename(initialdir=os.getcwd(),
                                          title="Select file")
        self.clear()
        self.pointset.load(file)
        self.draw()

    def compute(self):
        self.pointset.run_algorithm()
        self.draw()

    def mainloop(self):
        self.master.mainloop()
Пример #29
0
class Scene(object):
    def __init__(self, master, device, mouse_tracking=False):
        self.master = master
        self.device = device
        self.frame = tk.Frame(master)
        self.feedbackButton = tk.Button(
            self.frame,
            text="Feedback window",
            width=25,
            command=self.open_feedback
        )
        self.feedbackButton.pack()
        self.explore_canvas = Canvas(master, width=500, height=500)
        self.explore_canvas.pack()

        if mouse_tracking:
            self.explore_canvas.bind(
                '<Motion>', lambda event, device=device: motion(event, device))

        self.enable_position_feedback()
        self.network_drawings = []

        self.frame.pack()
        self.app = None
        self.update()

    def activate_key_listening(self, listener):
        # Will focus frame, needed for key binding
        self.explore_canvas.bind(
            "<Button-1>",
            lambda event,
            frame=self.explore_canvas: focus(event, frame)
        )
        self.explore_canvas.bind(
            "<Key>",
            lambda event: listener.update_pressed_key(str(event.char))
        )

    def desactivate_key_listening(self):
        self.explore_canvas.unbind("<Button-1>")
        self.explore_canvas.unbind("<Key>")

    def enable_position_feedback(self):
        self.device_cursor = self.explore_canvas.create_oval(
            self.device.position.x - 2.5, self.device.position.y - 2.5,
            self.device.position.x + 2.5, self.device.position.y + 2.5)

    def draw_network(self, network):
        self.explore_canvas.delete('all')
        self.enable_position_feedback()
        for node in network.nodes:
            pos_x = node.x - 5
            pos_y = node.y - 5
            self.explore_canvas.create_oval(
                pos_x, pos_y, pos_x + 10, pos_y + 10, fill="blue")
        for link in network.links:
            pt_a = link.first
            pt_b = link.sec
            self.explore_canvas.create_line(
                pt_a.x, pt_a.y, pt_b.x, pt_b.y)

    def update(self):
        coords = self.explore_canvas.coords(self.device_cursor)
        if len(coords) <= 3:
            self.master.after(50, self.update)
            return
        center = ((coords[0] + coords[2]) / 2, (coords[1] + coords[3]) / 2)
        self.explore_canvas.move(
            self.device_cursor,
            self.device.position.x - center[0],
            self.device.position.y - center[1])
        if self.app and not self.app.closed:
            self.app.update()
        self.master.after(50, self.update)

    def open_feedback(self):
        self.feedbackWindow = tk.Toplevel(self.master)
        self.app = Feedback(self.feedbackWindow, self.device)
Пример #30
0
class Window:
    def __init__(self, root, width, height, points_per_line):
        self.width = width
        self.height = height
        self.canvas = Canvas(root, width=width, height=height)
        self.canvas.pack()
        self.canvas.canvas = self.canvas
        self.canvas.data = {}
        self.points_per_line = points_per_line
        self.alive_squares = dict()

        self._draw_grid()

    def _draw_grid(self):
        for begin, end in self._horizontal_line_coordinates:
            self.canvas.create_line(begin.x, begin.y, end.x, end.y)

        for begin, end in self._vertical_line_coordinates:
            self.canvas.create_line(begin.x, begin.y, end.x, end.y)

    @property
    def _horizontal_line_coordinates(self):
        y = 0

        while y < self.height:
            y = y + self.height / self.points_per_line
            begin = Point(0, y)
            end = Point(self.width, y)
            yield begin, end

    @property
    def _vertical_line_coordinates(self):
        x = 0

        while x <= self.width:
            begin = Point(x, 0)
            end = Point(x, self.height)

            yield begin, end
            x = x + self.width / self.points_per_line

    def draw_dead(self, x, y):
        try:
            rectangle = self.alive_squares[(x, y)]
            self.canvas.delete(rectangle)
            del self.alive_squares[(x, y)]
        except KeyError:
            pass

    def draw_alive(self, x, y):
        if (x, y) in self.alive_squares:
            return

        left_corner = Point(x * self.width / self.points_per_line,
                            y * self.height / self.points_per_line)
        right_corner = Point((x + 1) * self.width / self.points_per_line,
                             (y + 1) * self.height / self.points_per_line)
        rectangle = self.canvas.create_rectangle(left_corner.x,
                                                 left_corner.y,
                                                 right_corner.x,
                                                 right_corner.y,
                                                 fill="green")
        self.alive_squares[(x, y)] = rectangle
Пример #31
0
class GameScreen:
    def __init__(self, master, params, model=None):
        self.master = master

        self.controller = GameScreenController(params, model=model)

        self.width = self.controller.model.width
        self.height = self.controller.model.height

        self.graphic_init()

        self.is_run = True
        self.run()

    def draw(self):
        # Сделать 4 солнца
        model = self.controller.model
        x, y = model.sun_x, model.sun_y
        suns = [(x, y), (x - self.width, y), (x, y - self.height), (x - self.width, y - self.height)]
        for x, y in suns:
            self.canvas.create_rectangle(
                max(0, x),
                max(0, y),
                min(x + model.sun_size, self.width + 1),
                min(y + model.sun_size, self.height + 1),
                fill="yellow",
            )

        for coord, creature in model.creatures.items():
            color = "#00{:0>2}00".format(hex(int(creature.life * 255))[2:])

            if not creature.alive:
                color = "red"

            func = self.canvas.create_oval
            func(coord[0], coord[1], coord[0] + 6, coord[1] + 6, fill=color)

    def graphic_init(self):
        self.frame = Frame(self.master, bd=2)

        self.button_frame = Frame(self.frame, bd=2)
        self.button_frame.grid_bbox(row=1, column=4)

        self.start_stop_button = Button(self.button_frame, text="Пауза", command=self.start_stop_pressed)
        self.start_stop_button.grid(row=1, column=2)

        self.save_button = Button(self.button_frame, text="Сохранить", command=self.save_pressed)
        self.save_button.grid(row=1, column=1)

        self.info_button = Button(self.button_frame, text="Инфо", command=self.info_pressed, state=DISABLED)
        self.info_button.grid(row=1, column=4)

        self.add_button = Button(self.button_frame, text="Добавить существо", command=self.add_pressed)
        self.add_button.grid(row=1, column=3)

        self.canvas = Canvas(self.frame, width=self.width, height=self.height)
        self.canvas.pack(side=TOP)

        self.button_frame.pack()

        self.frame.pack()

    def start_stop_pressed(self):
        self.is_run = not self.is_run

        self.start_stop_button.config(text="Пауза" if self.is_run else "Старт")
        self.info_button.config(state=DISABLED if self.is_run else ACTIVE)

        self.run()

    def save_pressed(self):
        filename = asksaveasfilename(title="Сохранить мир")
        if filename:
            try:
                self.controller.save_pressed(filename)
            except Exception as e:
                messagebox.showerror("Не удалось сохранить файл", str(e))

    def info_pressed(self):
        InfoWindow(self.controller.model)

    def add_pressed(self):
        self.controller.add_pressed()

    def run(self):
        if self.is_run:
            self.canvas.delete("all")
            self.controller.run()
            self.draw()
            self.master.after(1, self.run)
Пример #32
0
class GUI(Frame):
    def __init__(self, game, size, margin, colors=('black', 'white'), master=None):
        color = '#333333'
        Frame.__init__(self, master, bg=color)
        self.game = game
        self.cell_size = (size - 2*margin) / self.game.size
        self.coordinates = lambda position: self.cell_size * (np.array(position) + 1/2) + margin
        self.player_move = lambda event: self.move(pause=1000, event=event)
        self.grid()
        self.master.title("Pythello")
        self.colors = colors[::-1]  # Flip color order so that the first color input corresponds to player 1

        max_turns = self.game.size**2 - 4
        figure = Figure(figsize=(size/100, size/100), dpi=100, facecolor=color)
        axes = figure.add_subplot(111, axisbg=color)
        self.line = axes.plot(0, 0, 'w-', [0, max_turns], [0, 0], 'w--')[0]
        axes.grid(True, color='w')
        axes.set_xlim(0, max_turns)
        axes.set_ylim(-max_turns, max_turns)
        [tick.set_color('w') for axis in [axes.xaxis, axes.yaxis] for tick in axis.get_ticklines()]
        [label.set_color('w') for axis in [axes.xaxis, axes.yaxis] for label in axis.get_ticklabels()]
        [axes.spines[side].set_color('w') for side in ['top', 'bottom', 'left', 'right']]

        self.canvas = Canvas(self, width=size, height=size, background=color, highlightthickness=0)
        self.canvas.create_rectangle(margin, margin, size - margin, size - margin, outline='white')
        self.canvas.grid(row=0, column=1, rowspan=50)
        self.figure = FigureCanvasTkAgg(figure, master=self)
        self.figure.get_tk_widget().grid(row=0, column=2, rowspan=50)
        self.refresh()

        if all([isinstance(player, AI) for player in self.game.players]):
            self.play_button = Button(self, text='Play', highlightbackground=color, command=self.play)
            self.move_button = Button(self, text='Move', highlightbackground=color, command=self.move)
            self.reset_button = Button(self, text='Reset', highlightbackground=color, command=self.reset)
            self.play_button.grid(row=0, column=0)
            self.move_button.grid(row=1, column=0)
            self.reset_button.grid(row=2, column=0)
            self.running = False
        else:
            Button(self, text='Reset', highlightbackground=color, command=self.reset).grid(row=0, column=0)
            self.running = True

        for i in range(self.game.size):
            line_shift = self.cell_size * (i+1) + margin
            self.canvas.create_text(margin-10, line_shift - self.cell_size/2, text=str(i+1), fill='white')
            self.canvas.create_text(line_shift - self.cell_size/2, margin-10, text=chr(97+i), fill='white')
            self.canvas.create_line(margin, line_shift, size - margin, line_shift, fill='white')
            self.canvas.create_line(line_shift, margin, line_shift, size - margin, fill='white')

    def configure_buttons(self):
        (state, text, command) = ('disabled', 'Pause', self.pause) if self.running else ('normal', 'Reset', self.reset)
        self.play_button.config(state=state)
        self.move_button.config(state=state)
        self.reset_button.config(text=text, command=command)

    def draw_piece(self, position, radius, color):
        (y, x) = self.coordinates(position)
        return self.canvas.create_oval(x-radius, y-radius, x+radius, y+radius, fill=color, tags='circle')

    def move(self, pause=10, event=None):
        if event is None:
            move = self.game.player.move(self.game)
        else:
            move = eval(self.canvas.gettags(event.widget.find_withtag("current"))[-2])

        self.game.move(move)
        is_over = self.game.is_over()
        self.refresh()

        if not is_over and isinstance(self.game.player, AI) and self.running:
            self.after(pause, self.move)
        elif is_over:
            self.reset_button.config(text='Reset', command=self.reset)

    def pause(self):
        self.running = False
        self.configure_buttons()

    def play(self):
        self.running = True
        self.configure_buttons()
        self.move()

    def refresh(self):
        self.line.set_data(range(len(self.game.score)), self.game.score)
        self.figure.draw()
        [self.canvas.delete(tag) for tag in ['circle', 'text']]

        for position in zip(*np.nonzero(self.game.board)):
            color = self.colors[int((self.game.board[position] + 1) / 2)]
            self.draw_piece(position, (self.cell_size-2) / 2, color)

        if not isinstance(self.game.player, AI):
            for position in self.game.valid:
                (y, x) = self.coordinates(position)
                turned = len(self.game.valid[position]) - 1
                valid = self.draw_piece(position, self.cell_size / 4, 'green')
                self.canvas.addtag(str(position), 'withtag', valid)
                text = self.canvas.create_text(x+1, y+1, text=str(turned), tags=('text', str(position)))
                [self.canvas.tag_bind(tag, "<Button-1>", self.player_move) for tag in [valid, text]]

    def reset(self):
        self.running = not all([isinstance(player, AI) for player in self.game.players])
        self.game.reset()
        self.refresh()

        if not self.running:
            self.configure_buttons()
Пример #33
0
class GameUI(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.game = Game()
        self.row, self.col = 0, 0
        self.init_UI()


    def init_UI(self):
        self.pack(fill=BOTH, expand=1)

        self.canvas = Canvas(self,
            width=WIDTH,
            height=HEIGHT,
            highlightthickness=0,
            relief='ridge',
            bg='gray10'
        )
        self.canvas.pack(fill=BOTH, side=TOP)

        Button(self,
            text='RESTART',
            height=24,
            fg='white',
            bg='gray20',
            activeforeground='white',
            activebackground='gray15',
            border=0,
            font=('Arial', 12, 'bold'),
            highlightthickness=0,
            relief='ridge',
            command=self.restart
        ).pack(fill=BOTH, side=BOTTOM)

        self.draw_grid()
        self.canvas.bind('<Button-1>', self.play)


    def restart(self):
        self.game = Game()
        self.row, self.col = 0, 0
        self.canvas.delete('all')
        self.draw_grid()


    def draw_grid(self):
        for i in range(self.game.width + 1):
            x0 = MARGIN + i * SIDE
            y0 = MARGIN
            x1 = MARGIN + i * SIDE
            y1 = HEIGHT - MARGIN
            self.canvas.create_line(x0, y0, x1, y1, fill='gray25')

            x0 = MARGIN
            y0 = MARGIN + i * SIDE
            x1 = HEIGHT - MARGIN
            y1 = MARGIN + i * SIDE
            self.canvas.create_line(x0, y0, x1, y1, fill='gray25')

        self.board = [ [ self.game.get_cell_value(x, y) for x in range(self.game.width + 1) ] for y in range(self.game.height + 1) ]
        self.load_board(self.board)


    def load_board(self, board):
        for y in range(self.game.height + 1):
            for x in range(self.game.width + 1):
                player = self.game.get_cell_value(y, x)
                if player != ' ':
                    self.row, self.col = (self.game.width - 1) - x, y
                    self.draw_player(player)


    def play(self, event):
        if self.game.get_winner():
            return

        x, y = event.x, event.y

        if MARGIN < x < WIDTH - MARGIN and MARGIN < y < HEIGHT - MARGIN:
            row, col = int((y - MARGIN)  / SIDE), int((x - MARGIN) / SIDE)
            real_x, real_y = col, (self.game.width - 1) - row

            if self.game.is_cell_free(real_x, real_y):
                self.row, self.col = row, col
                player = self.game.get_next_players_turn()
                self.game.make_move(real_x, real_y, player)
                self.draw_player(player)
                winner = self.game.get_winner()
                if winner:
                    self.draw_victory(winner)


    def draw_player(self, player):
        if self.row >= 0 and self.col >=0:
            x0 = MARGIN + self.col * SIDE + 1
            y0 = MARGIN + self.row * SIDE + 1
            x1 = MARGIN + (self.col + 1) * SIDE - 1
            y1 = MARGIN + (self.row + 1) * SIDE - 1

            self.canvas.create_rectangle(
                x0, y0, x1, y1,
                fill=self.get_color(player),
                outline=''
            )

            x = x0 + SIDE / 2
            y = y0 + SIDE / 2

            self.canvas.create_text(
                x, y,
                text=player,
                fill='white',
                font=('Arial', 12)
            )


    def draw_victory(self, winner):
        x0 = y0 = MARGIN + SIDE * 2
        x1 = y1 = MARGIN + SIDE * 8
        self.canvas.create_oval(
            x0, y0, x1, y1,
            fill=self.get_color(winner),
            outline=''
        )

        x = y = MARGIN + 4 * SIDE + SIDE
        message = '{} player wins'.format(winner)
        self.canvas.create_text(
            x, y,
            text=message,
            fill='white',
            font=('Arial', 28)
        )


    def get_color(self, player):
        return 'dark slate gray' if player == 'X' else 'sea green'
Пример #34
0
class ImageViewer(Frame):

    def __init__(self, master=None):
        Frame.__init__(self, master=master, bg="gray", width=600, height=400)

        self.shown_image = None
        self.x = 0
        self.y = 0
        self.crop_start_x = 0
        self.crop_start_y = 0
        self.crop_end_x = 0
        self.crop_end_y = 0
        self.draw_ids = list()
        self.rectangle_id = 0
        self.ratio = 0
        self.colorCode = ((0, 0, 255), 'red')

        self.canvas = Canvas(self, bg="gray", width=600, height=400)
        self.canvas.place(relx=0.5, rely=0.5, anchor=CENTER)

    def show_image(self, img=None):
        """
        Displays the image passed to the function
        @:param img is the image to be displayed which is defaulted to None
        """
        self.clear_canvas()

        if img is None:
            image = self.master.processed_image.copy()
        else:
            image = img

        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        height, width, channels = image.shape
        ratio = height / width

        new_width = width
        new_height = height

        if height > self.winfo_height() or width > self.winfo_width():
            if ratio < 1:
                new_width = self.winfo_width()
                new_height = int(new_width * ratio)
            else:
                new_height = self.winfo_height()
                new_width = int(new_height * (width / height))

        self.shown_image = cv2.resize(image, (new_width, new_height))
        self.shown_image = ImageTk.PhotoImage(Image.fromarray(self.shown_image))

        self.ratio = height / new_height

        self.canvas.config(width=new_width, height=new_height)
        self.canvas.create_image(new_width / 2, new_height / 2, anchor=CENTER, image=self.shown_image)

    def set_color_code(self, color_code):
        """
        Sets the colorCode to the passed value
        @:param colorCode the new colorCode value
        """
        self.colorCode = color_code

    def activate_draw(self):
        """
        Activates the draw functionality
        """
        self.canvas.bind("<ButtonPress>", self.start_draw)
        self.canvas.bind("<B1-Motion>", self.draw)

        self.master.is_draw_state = True

    def activate_crop(self):
        """
        Activates the crop functionality
        """
        self.canvas.bind("<ButtonPress>", self.start_crop)
        self.canvas.bind("<B1-Motion>", self.crop)
        self.canvas.bind("<ButtonRelease>", self.end_crop)

        self.master.is_crop_state = True

    def deactivate_draw(self):
        """
        Deactivates the draw functionality
        """
        self.canvas.unbind("<ButtonPress>")
        self.canvas.unbind("<B1-Motion>")

        self.master.is_draw_state = False

    def deactivate_crop(self):
        """
        Deactivates the crop functionality
        """
        self.canvas.unbind("<ButtonPress>")
        self.canvas.unbind("<B1-Motion>")
        self.canvas.unbind("<ButtonRelease>")

        self.master.is_crop_state = False

    def start_draw(self, event):
        """
        Begins the draw
        @:param is the x and y coordinates of the mouse
        """
        self.x = event.x
        self.y = event.y

    def draw(self, event):
        """
        Draws on the image
        @:param is the x and y coordinates of the mouse
        """
        self.draw_ids.append(self.canvas.create_line(self.x, self.y, event.x, event.y, width=2,
                                                     fill=self.colorCode[1], capstyle=ROUND, smooth=True))

        cv2.line(self.master.processed_image, (int(self.x * self.ratio), int(self.y * self.ratio)),
                 (int(event.x * self.ratio), int(event.y * self.ratio)),
                 self.colorCode[0], thickness=int(self.ratio * 2),
                 lineType=8)

        self.x = event.x
        self.y = event.y

    def start_crop(self, event):
        """
        Begins the crop
        @:param is the x and y coordinates of the mouse
        """
        self.crop_start_x = event.x
        self.crop_start_y = event.y

    def crop(self, event):
        """
        Crops the image
        @:param is the x and y coordinates of the mouse
        """
        if self.rectangle_id:
            self.canvas.delete(self.rectangle_id)

        self.crop_end_x = event.x
        self.crop_end_y = event.y

        self.rectangle_id = self.canvas.create_rectangle(self.crop_start_x, self.crop_start_y,
                                                         self.crop_end_x, self.crop_end_y, width=1)

    def end_crop(self, event):
        """
        Ends the Crop
        @:param an unused event parameter required due to how the function is called
        """
        if self.crop_start_x <= self.crop_end_x and self.crop_start_y <= self.crop_end_y:
            start_x = int(self.crop_start_x * self.ratio)
            start_y = int(self.crop_start_y * self.ratio)
            end_x = int(self.crop_end_x * self.ratio)
            end_y = int(self.crop_end_y * self.ratio)
        elif self.crop_start_x > self.crop_end_x and self.crop_start_y <= self.crop_end_y:
            start_x = int(self.crop_end_x * self.ratio)
            start_y = int(self.crop_start_y * self.ratio)
            end_x = int(self.crop_start_x * self.ratio)
            end_y = int(self.crop_end_y * self.ratio)
        elif self.crop_start_x <= self.crop_end_x and self.crop_start_y > self.crop_end_y:
            start_x = int(self.crop_start_x * self.ratio)
            start_y = int(self.crop_end_y * self.ratio)
            end_x = int(self.crop_end_x * self.ratio)
            end_y = int(self.crop_start_y * self.ratio)
        else:
            start_x = int(self.crop_end_x * self.ratio)
            start_y = int(self.crop_end_y * self.ratio)
            end_x = int(self.crop_start_x * self.ratio)
            end_y = int(self.crop_start_y * self.ratio)

        x = slice(start_x, end_x, 1)
        y = slice(start_y, end_y, 1)

        self.master.processed_image = self.master.processed_image[y, x]

        self.show_image()

    def clear_canvas(self):
        """
        Clears all edits to the image
        """
        self.canvas.delete("all")

    def clear_draw(self):
        """
        Clears all drawings done on the image
        """
        self.canvas.delete(self.draw_ids)
Пример #35
0
class Window(Tk):
    def __init__(self):
        # INIT WINDOW
        Tk.__init__(self)
        self.geometry("{}x{}+10+10".format(gb.WINDOW_WIDTH, gb.WINDOW_HEIGHT))
        self.fond = Canvas(self,
                           width=gb.WINDOW_WIDTH,
                           height=gb.WINDOW_HEIGHT,
                           bg=gb.WINDOW_BG)
        self.fond.pack()
        self.real_bg = self.fond.create_rectangle(0,
                                                  0,
                                                  gb.WINDOW_WIDTH,
                                                  gb.WINDOW_HEIGHT,
                                                  fill=gb.WINDOW_BG)
        self.init_input_output()

        # ATTRIBUTS
        self.main_gate = New_gate(self, "MAIN")
        Gate.__init__(self.main_gate, [], [])
        self.gates = set()
        self.selected = None
        self.link = None
        self.generators = set()
        self.gate_gen_x = 0
        self.max_gate_gen_x = 0
        self.node_select = set()
        self.inout_frame = (0, 0, 0, 0)
        self.inout_pos = (0, 0)

        # BINDINGS
        self.bindings = {
            "<Control-Key-s>": self.save_conf_name,
            "<Motion>": self.move,
            "<ButtonRelease-1>": self.release_clic,
            "<Button-2>": self.cancel_link,
            "<Button-1>": GB_INFO,
            "<MouseWheel>": self.scroll,  # for windows
            "<Button-4>": self.scroll,  # for linux
            "<Button-5>": self.scroll  # for linux
        }
        self.enable_bindings()

        # LOAD GATES
        self.load_below_gates()

        # MAINLOOP
        self.after(100, self.clock_update)
        self.mainloop()

    ######################### INPUT/OUTPUT #########################

    def init_input_output(self):
        self.input_line = self.fond.create_rectangle(0,
                                                     gb.INPUT_HEIGHT,
                                                     gb.WINDOW_WIDTH,
                                                     gb.INPUT_HEIGHT,
                                                     width=20,
                                                     fill="black")
        self.fond.tag_bind(self.input_line, "<Button-3>", self.input_select)
        self.fond.tag_bind(self.input_line, "<Button-1>",
                           self.add_single_input)
        self.output_line = self.fond.create_rectangle(
            0,
            gb.WINDOW_HEIGHT - gb.OUTPUT_HEIGHT,
            gb.WINDOW_WIDTH,
            gb.WINDOW_HEIGHT - gb.OUTPUT_HEIGHT,
            width=20,
            fill="black")
        self.fond.tag_bind(self.output_line, "<Button-3>", self.output_select)
        self.fond.tag_bind(self.output_line, "<Button-1>",
                           self.add_single_output)

    def order_inputs_outputs(self):
        self.main_gate.inputs.sort(key=lambda x: x.center[0])
        self.main_gate.outputs.sort(key=lambda x: x.center[0])

    def clean_select(self):
        for id in self.node_select:
            self.fond.delete(id)
        self.node_select = set()
        self.inout_pos = (0, 0)
        self.inout_frame = (0, 0, 0, 0)

    def load_node_choice(self, x, y, node_type, in_out):
        table = {
            "input": {
                "Single": self.add_single_input,
                "Count": self.add_count_input,
                "Clock": self.add_clock_input
            },
            "output": {
                "Single": self.add_single_output,
                "Count": self.add_count_output
            }
        }
        node_frame = self.fond.create_rectangle(x, y, x + 60, y + 30)
        self.node_select.add(node_frame)
        self.fond.tag_bind(node_frame, "<Button-1>", table[in_out][node_type])

        node_text = self.fond.create_text(x + 30, y + 15, text=node_type)
        self.node_select.add(node_text)
        self.fond.tag_bind(node_text, "<Button-1>", table[in_out][node_type])

    ## _________________ INPUT _____________________ ##

    def input_select(self, evt):
        x = min(evt.x, gb.WINDOW_WIDTH - 70)
        y = evt.y
        self.inout_pos = (evt.x, evt.y)
        frame_id = self.fond.create_rectangle(x - 3,
                                              y - 3,
                                              x + 63,
                                              y + 97,
                                              fill="lightgray")
        self.inout_frame = (x - 3, y - 3, x + 63, y + 97)
        self.node_select.add(frame_id)

        self.load_node_choice(x, y, "Single", "input")
        self.load_node_choice(x, y + 32, "Count", "input")
        self.load_node_choice(x, y + 64, "Clock", "input")

    def add_single_input(self, evt):
        if not self.inout_pos[0]:
            self.inout_pos = (evt.x, evt.y)
        node = Main_input_node(self.main_gate, self)
        node.center = (self.inout_pos[0], gb.INPUT_HEIGHT)
        self.main_gate.inputs += [node]
        self.draw_node(node)
        self.fond.tag_bind(node.id, "<Button-2>", node.destroy)
        self.clean_select()

    def add_count_input(self, evt):
        node = Main_input_count_node(self.main_gate, self)
        node.master_node = node  # this is overriden if called from an ext_node
        node.node_amount = 1
        node.next_node = None
        node.center = (self.inout_pos[0], gb.INPUT_HEIGHT)
        self.main_gate.inputs += [node]
        self.draw_node(node)
        self.fond.tag_bind(node.id, "<Button-2>", node.destroy_count)
        self.clean_select()
        return node

    def add_clock_input(self, evt):
        node = Clock_node(self.main_gate, self)
        node.center = (self.inout_pos[0], gb.INPUT_HEIGHT)
        self.main_gate.inputs += [node]
        self.draw_node(node)
        self.fond.tag_bind(node.id, "<Button-2>", node.destroy)
        self.clean_select()

    ## _________________ OUTPUT _____________________ ##

    def output_select(self, evt):
        x = min(evt.x, gb.WINDOW_WIDTH - 70)
        y = evt.y
        self.inout_pos = (evt.x, evt.y)
        frame_id = self.fond.create_rectangle(x - 3,
                                              y - 65,
                                              x + 63,
                                              y + 3,
                                              fill="lightgray")
        self.inout_frame = (x - 3, y - 65, x + 63, y + 3)
        self.node_select.add(frame_id)

        self.load_node_choice(x, y - 62, "Single", "output")
        self.load_node_choice(x, y - 30, "Count", "output")

    def add_single_output(self, evt):
        if not self.inout_pos[0]:
            self.inout_pos = (evt.x, evt.y)
        node = Main_output_node(self.main_gate, self)
        node.center = (self.inout_pos[0], gb.WINDOW_HEIGHT - gb.OUTPUT_HEIGHT)
        self.main_gate.outputs += [node]
        self.draw_node(node)
        self.fond.tag_bind(node.id, "<Button-2>", node.destroy)
        self.clean_select()

    def add_count_output(self, evt):
        node = Main_output_count_node(self.main_gate, self)
        node.master_node = node  # this is overriden if called from an ext_node
        node.node_amount = 1
        node.next_node = None
        node.center = (self.inout_pos[0], gb.WINDOW_HEIGHT - gb.OUTPUT_HEIGHT)
        self.main_gate.outputs += [node]
        self.draw_node(node)
        self.fond.tag_bind(node.id, "<Button-2>", node.destroy_count)
        self.clean_select()
        return node

    ######################### BINDINGS #########################
    def enable_bindings(self):
        gb.debug("Bindings enabled")
        for to_bind in self.bindings:
            self.bind(to_bind, self.bindings[to_bind])

    def disable_bindings(self):
        gb.debug("Bindings disabled")
        for to_unbind in self.bindings:
            self.unbind(to_unbind)

    def save_pressed_key(self, evt):
        if evt.keycode == 22:
            self.gate_name = self.gate_name[:-1]
        elif evt.char.upper() in "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 ":
            self.gate_name += evt.char.upper()
        self.fond.itemconfig(self.name_id, text=self.gate_name)

    ######################### MOVE EVENTS #########################
    def cancel_link(self, evt):
        if self.link:
            self.link.delete_aff()
            self.link = None

    def release_clic(self, evt):
        self.selected = None

    def move(self, evt):
        if self.selected:
            dx = self.selected.delta_x
            dy = self.selected.delta_y
            self.selected.center = (evt.x + dx, evt.y + dy)
            self.selected.update_nodes_coords()
            self.update(self.selected)
        if self.link:
            # mise à jour de l'affichage du link
            self.link.points_list[-1] = (evt.x, evt.y)
            self.update(self.link)
        if self.inout_frame[0]:
            if not (self.inout_frame[0] < evt.x < self.inout_frame[2]
                    and self.inout_frame[1] < evt.y < self.inout_frame[3]):
                self.clean_select()

    ######################### GATE GENERATOR #########################
    def load_below_gates(self):
        for i, gate_name in enumerate(os.listdir("lib/structs/")):
            x = i * 110 + 10 + self.gate_gen_x
            y = 25
            generator = Generator(gate_name, self)
            self.generators.add(generator)
            generator.id = self.fond.create_rectangle(x,
                                                      y - 20,
                                                      x + 100,
                                                      y + 20,
                                                      width=2,
                                                      fill=gb.BOX_BG)
            generator.name_id = self.fond.create_text(x + 50,
                                                      y,
                                                      text=gate_name)
            self.fond.tag_bind(generator.id, "<Button-1>",
                               generator.create_gate)
            self.fond.tag_bind(generator.name_id, "<Button-1>",
                               generator.create_gate)
        self.max_gate_gen_x = x

    def reload_below_gate(self):
        for generator in self.generators:
            self.fond.delete(generator.id)
            self.fond.delete(generator.name_id)
        self.load_below_gates()

    def scroll(self, evt):
        if evt.delta != 0:  # for windows
            self.gate_gen_x += evt.delta / 30
        if evt.num == 4:  # for linux
            self.gate_gen_x += 30
            self.gate_gen_x = min(self.gate_gen_x, 0)
        if evt.num == 5:  # for linux
            self.gate_gen_x -= 30
            delta = self.max_gate_gen_x - gb.WINDOW_WIDTH + 100
            if delta < 0:
                self.gate_gen_x += 30
        self.reload_below_gate()

    ######################### SAVING CONFIGURATION #########################
    def save_conf_name(self, evt):
        """
        Permet de selectionner le nom de la gate créée
        """
        self.disable_bindings()
        x, y = gb.WINDOW_WIDTH / 2, gb.WINDOW_HEIGHT / 2
        self.rectangle_name_id = self.fond.create_rectangle(x - 50,
                                                            y - 25,
                                                            x + 50,
                                                            y + 25,
                                                            width=3,
                                                            fill="white")
        self.gate_name = ""
        self.name_id = self.fond.create_text(x, y, text="")
        self.bind("<KeyPress>", self.save_pressed_key)
        self.bind("<Return>", self.save_conf)
        self.bind("<Escape>", self.cancel_save_conf)

    def cancel_save_conf(self, evt):
        self.clean_save_conf()

    def save_conf(self, evt):
        self.order_inputs_outputs()
        if not self.gate_name in os.listdir("lib/structs/"):
            with open("lib/structs/" + self.gate_name, "w") as f:
                # Ajoute les gate au fichier
                for gate in self.gates:
                    f.write(str(gate))

                # Ajoute les nodes d'entrée et de sortie au fichier
                for node in self.main_gate.inputs:
                    f.write(str(node))
                for node in self.main_gate.outputs:
                    f.write(str(node))

                # ajoute les nodes de chaque gate au fichier
                for gate in self.gates:
                    for node in gate.inputs:
                        f.write(str(node))
                    for node in gate.outputs:
                        f.write(str(node))
        self.clean_save_conf()
        self.reload_below_gate()

    def clean_save_conf(self):
        self.unbind("<KeyPress>")
        self.unbind("<Return>")
        self.unbind("<Escape>")
        self.fond.delete(self.rectangle_name_id)
        self.fond.delete(self.name_id)
        self.name_id = None
        self.rectangle_name_id = None
        self.gate_name = ""
        self.enable_bindings()

    ######################### DRAWING #########################
    def get_center_from_point(self, node_or_tuple):
        try:
            return node_or_tuple.center
        except:
            return node_or_tuple

    def draw_link(self, link):
        """
        Dessine un link
        """
        x, y = self.get_center_from_point(link.points_list[-1])
        link.id_list += [
            self.fond.create_line(x, y, x, y, fill="white", width=2)
        ]
        self.fond.tag_bind(link.id_list[-1], "<Button-3>", link.r_clic)

    def draw_node(self, node):
        """
        Dessine une node
        """
        x, y = node.center
        node.id = self.fond.create_oval(x - gb.NODE_SIZE,
                                        y - gb.NODE_SIZE,
                                        x + gb.NODE_SIZE,
                                        y + gb.NODE_SIZE,
                                        outline="black",
                                        width=2,
                                        fill="white")
        self.fond.tag_bind(node.id, "<Button-1>", node.clic)
        self.fond.tag_bind(node.id, "<Button-3>", node.r_clic)
        self.fond.tag_bind(node.id, "<Button-2>", node.destroy)
        if gb.DEBUG:
            node.text = self.fond.create_text(x, y, text=str(node.id))
            self.fond.tag_bind(node.text, "<Button-1>", node.clic)
            self.fond.tag_bind(node.text, "<Button-3>", node.r_clic)
            self.fond.tag_bind(node.text, "<Button-2>", node.destroy)
        if node.get_sub_type() == "count":
            # count node : on ajoute une pastille d'ajout
            n = gb.NODE_SIZE // 2
            px, py = x + gb.NODE_SIZE, y
            ext_node_id = self.fond.create_oval(px - n,
                                                py - n,
                                                px + n,
                                                py + n,
                                                fill="red")
            self.fond.tag_bind(ext_node_id, "<Button-1>", node.add_ext_node)
            self.fond.tag_bind(ext_node_id, "<Button-2>", node.delete_ext)
            node.ext_node_id = ext_node_id
        if node.get_type() not in ("main_input", "main_output"):
            if gb.DEBUG:
                self.fond.tag_bind(node.text, "<Button-1>", node.gate.clic)
            self.fond.tag_bind(node.id, "<Button-1>", node.gate.clic)

    def draw_gate(self, gate):
        """
        Affiche une gate et les nodes associées
        """
        x, y = gate.center
        gate.id = self.fond.create_rectangle(x - gate.width,
                                             y - gb.BOX_HEIGHT,
                                             x + gate.width,
                                             y + gb.BOX_HEIGHT,
                                             outline="black",
                                             fill=gb.BOX_BG,
                                             width=3)
        self.fond.tag_bind(gate.id, "<Button-1>", gate.clic)
        self.fond.tag_bind(gate.id, "<Button-2>", gate.delete)
        gate.name_id = self.fond.create_text(x, y, text=gate.name)
        self.fond.tag_bind(gate.name_id, "<Button-1>", gate.clic)
        self.fond.tag_bind(gate.name_id, "<Button-2>", gate.delete)

        for node in gate.inputs:
            self.draw_node(node)
        for node in gate.outputs:
            self.draw_node(node)

    ######################### UPDATE DISPLAY #########################
    def clock_update(self):
        self.update_all()
        self.after(300, self.clock_update)

    def update_all(self):
        """
        Deux update sont nécéssaire pour que les flip flop marchent
        Un update se fait en 3 étapes :
        1) On update les nodes d'entrée, afin de mettre à jour leur date de MAJ
        et mettre à jour l'affichage, meme de celles qui ne sont pas reliées
        2) On update toutes les gates, afin de mettre à jour les gates, meme
        celles qui ne sont pas connectées
        3) On update en partant des nodes de sortie
        """
        t_in = time.perf_counter()
        gb.PRE_UPDATE()
        # 1)
        for node in self.main_gate.inputs:
            node.need_previous()
        # 2)
        for gate in self.gates:
            for output_node in gate.outputs:
                output_node.need_previous()
        # 3)
        for node in self.main_gate.outputs:
            node.need_previous()

        t_out = time.perf_counter()

        gb.debug("update time = {}".format(t_out - t_in))

    def update(self, item):
        target_class = item.__class__.__bases__

        if type(item) == Link:
            x2, y2 = self.get_center_from_point(item.points_list[-1])
            x1, y1 = self.get_center_from_point(item.points_list[-2])
            self.fond.coords(item.id_list[-1], x1, y1, x2, y2)
            x2, y2 = self.get_center_from_point(item.points_list[0])
            x1, y1 = self.get_center_from_point(item.points_list[1])
            self.fond.coords(item.id_list[0], x1, y1, x2, y2)

            if item.get_output():
                # Permet d'afficher le lien en rouge lorsque la node d'entrée est active
                item.active = item.get_output().active
            for link_seg_id in item.id_list:
                self.fond.itemconfig(link_seg_id,
                                     fill="red" if item.active else "white")
            self.fond.tag_lower(item.id_list[-1])

        elif type(item) in (Input_node, Output_node, Main_input_node,
                            Main_output_node, Clock_node,
                            Main_input_count_node, Main_output_count_node):
            x, y = item.center
            self.fond.coords(item.id, x - gb.NODE_SIZE, y - gb.NODE_SIZE,
                             x + gb.NODE_SIZE, y + gb.NODE_SIZE)
            self.fond.itemconfig(item.id,
                                 fill="red" if item.active else "white")
            if gb.DEBUG:
                self.fond.coords(item.text, x, y)

            # On update les liens avant et après la node
            for link in item.next_links:
                self.update(link)
            if item.prev_link:
                self.update(item.prev_link)

            if item.get_sub_type() == "count" and item.master_node == item:
                item.update_value_display()

        else:
            if item.name != "MAIN":
                # c'est une gate normale
                x, y = item.center
                dx, dy = item.delta_x, item.delta_y
                self.fond.coords(item.id, x - item.width, y - gb.BOX_HEIGHT,
                                 x + item.width, y + gb.BOX_HEIGHT)
                self.fond.coords(item.name_id, x, y)

            for node in item.inputs:
                self.update(node)
            for node in item.outputs:
                self.update(node)

        self.fond.tag_lower(self.real_bg)
Пример #36
0
class simpleGui(tkinter.Tk):
    
    def __init__(self, parent):
        tkinter.Tk.__init__(self, parent)
        self.parent = parent
        self.initialize()
        
    def initialize(self):
        self.grid()
        self.config(bg="white")
        self.geometry("600x500")
        
        self.algo = ACAlgo()
        self.wordFrames=[]
        
        self.path=""
        self.lastCanvasIndex=0
        
        rowLine=0
        
        
        self.entryPath = tkinter.Entry(self, width=75)
        self.entryPath.grid(column=0, row=rowLine,columnspan=3, sticky='NEW')
        self.entryPath.bind("<Return>", self.setPath)
        
        buttonSetPath = tkinter.Button(self, text="Set path", width=21, height=1, command=self.setPath)
        buttonSetPath.grid(column=3, row=rowLine, sticky='EWN')
                
                
                
        rowLine=rowLine+1
        
        self.entry = tkinter.Entry(self, width=75)
        self.entry.grid(column=0, row=rowLine,columnspan=2, sticky='NEWS')
        self.entry.bind("<Return>", self.addWords)

        buttonAddWords = tkinter.Button(self, text="Add words", width=21,height=1, command=self.addWords)
        buttonAddWords.grid(column=3, row=rowLine, sticky='EWNS')
        
        
        
        rowLine=rowLine+1
        self.grid_rowconfigure(rowLine, weight=1)
        self.textBox = tkst.ScrolledText(self, width=20, height=10)
        self.textBox.grid(column=0, row=rowLine, columnspan=3, sticky='NWES')
        
        self.textBox.config(state=DISABLED)
        
       
        self.canvas= Canvas(master=self,width=150)
        self.vscroll = Scrollbar(self)
        
        self.vscroll.config(command=self.canvas.yview)
        self.canvas.config(yscrollcommand=self.vscroll.set) 

        self.canvas.grid( row=rowLine, column=3,  sticky='NES')
        self.vscroll.grid(padx=1,  pady=1, row=rowLine, column=4, sticky='NEWS')
        
        
        
        rowLine=rowLine+1
                
        buttonClearHighlight = tkinter.Button(self, text="Clear highlight", width=20, command=self.removeHighlightsBtn)
        buttonClearHighlight.grid(column=0, row=rowLine, sticky="WS")


        buttonDeleteWords = tkinter.Button(self, text="Delete words", width=20, command=self.resetAll)
        buttonDeleteWords.grid(column=3, row=rowLine, sticky="ES")
        
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)

    def setPath(self):
        try:
            open(self.entryPath.get())
        except:
            return
        self.path=self.entryPath.get()
        self.textBox.config(state=NORMAL)
        self.textBox.insert(tkinter.INSERT, open(self.path).read())
        self.textBox.config(state=DISABLED)
        
    def removeHighlights(self):
        for wordFrame in self.wordFrames:
            wordFrame.removeHighLight()

    def removeHighlightsBtn(self, entry=""):
        for wordFrame in self.wordFrames:
            wordFrame.removeHighLight()
        
        self.update_idletasks()
            
    def resetAll(self, entry=""):
        self.removeHighlights()
        self.algo.resetTree()
        self.lastCanvasIndex=0;
        self.wordFrames=[]
        self.canvas.delete("all")
        self.update_idletasks()
        
    def addWords(self, event=""):
        if(self.path==""):
            return
        if(self.entry.get().strip()==""):
            self.entry.delete(0,len(self.entry.get()))
            return
        self.resetAll()
        for word in self.entry.get().split(" "):
            if word.lower() not in self.algo.foundWords.keys() and word != "" and word!=None:
                
                self.algo.addWord(word)
                self.addToCanvas(word)
                
                
        self.entry.delete(0,len(self.entry.get()))
        
        self.algo.addFails()
        
        self.algo.readFile(self.path)
        self.updateCanvasPositions();

    def updateCanvasPositions(self):
        
        for word in self.wordFrames:
            self.wordFrames[self.wordFrames.index(word)].updatePositions(self.algo.foundWords[word.getWord().lower()])
            self.wordFrames[self.wordFrames.index(word)].addTags()
            
    def addToCanvas(self, word):
             
        frame=wordFrame(self.canvas, self, word, self.algo.foundWords[word.lower()])
        self.wordFrames.append(frame)
        self.canvas.create_window(0, 50+self.lastCanvasIndex*50,anchor="w", window=frame, height=50)
            
                
        self.canvas.config(scrollregion=(0,0,70+self.lastCanvasIndex*50,70+self.lastCanvasIndex*50))
        self.canvas.update_idletasks()
        self.update_idletasks()
        
        self.lastCanvasIndex=self.lastCanvasIndex+1;
Пример #37
0
 def delete(self, canvas: Canvas):
     canvas.delete(self.id)
Пример #38
0
class SudokuUI(Frame):
    """
    The Tkinter UI, responsible for displaying the UI.
    """
    def __init__(self, parent, game):
        self.game = game
        self.parent = parent
        Frame.__init__(self, parent)

        self.row, self.col = 0, 0

        self.__initUI()

        def __initUI(self):
            self.parent.title("Sudoku")
            self.pack(fill=BOTH, expand=1)  # Use all available space
            self.canvas = Canvas(self, width=WIDTH, heigh=HEIGHT)
            self.canvas.pack(fill=BOTH, side=TOP)  # Pull board to top of frame
            clear_button = Button(self, text="Clear answers", command=self.__clear_answers)
            clear_button.pack(fill=BOTH, side=BOTTOM)

            self.__draw_grid()
            self.__draw_puzzle()

            self.canvas.bind("<Button-1>", self.__cell_clicked)
            self.canvas.bind("<Key>", self.__key_pressed)

        def __draw_grid(self):
            """
            Draws grid divided with blue lines into 3 x 3 grid
            :return:
            """
            for i in range(10):
                color = 'blue' if i % 3 == 0 else "gray"

                x0 = MARGIN + i * SIDE
                y0 = MARGIN
                x1 = MARGIN + i * SIDE
                y1 = HEIGHT - MARGIN
                self.canvas.create_line(x0, y0, x1, y1, fill=color)

                x0 = MARGIN
                y0 = MARGIN + i * SIDE
                x1 = WIDTH - MARGIN
                y1 = MARGIN + i * SIDE
                self.canvas.create_line(x0, y0, x1, y1, fill=color)

        def __draw_puzzle(self):
            self.canvas.delete("numbers")
            for i in xrange(9):
                for j in xrange(9):
                    answer = self.game.puzzle[i][j]
                    if answer != 0:
                        x = MARGIN + j * SIDE + SIDE / 2
                        y = MARGIN + i * SIDE + SIDE / 2
                        original = self.game.start_puzzle[i][j]
                        color = "black" if answer == original else "sea green"
                        self.canvas.create_text(x, y, text=answer, tags="number", fill=color)

        def __clear_answers(self):
            self.game.start()
            self.canvas.delete("victory")
            self.__draw_puzze()

        def __cell_clicked(self, event):  # event has x, y coords of mouse click
            if self.game.game_over:
                return

            x, y = event.x, event.y
            if (MARGIN < x < WIDTH - MARGIN) and (MARGIN < Y < HEIGHT - MARGIN):
                self.canvas.focus_set()

                # get row and col numbers from x, y coords
                row, col = (y - MARGIN) / SIDE, (x - MARGIN) / SIDE

                # if cell already selected then deselect it
                if (row, col) == (self.row, self.col):
                    self.row, self.col = -1, -1  # outside the grid
                elif self.game.puzzle[row][col] == 0:
                    self.row, self.col = row, col

            self.__draw_cursor()

        def __draw_cursor(self):
            self.canvas.delete("cursor")
            if self.row >= 0 and self.col >= 0:
                x0 = MARGIN + self.col * SIDE + 1
                y0 = MARGIN + self.row * SIDE + 1
                x1 = MARGIN + (self.col + 1) * SIDE - 1
                y1 = MARGIN + (self.row + 1) * SIDE - 1
                self.canvas.create_rectangle(
                    x0, y0, x1, y1,
                    outline ="red", tags ="cursor"
                )
Пример #39
0
class NEATPanel(Frame):
    def __init__(self, tile_size):
        self.root = Tk()
        self.root.geometry("780x640")
        self.root.update()
        self.root.config(bg='gray')
        self.entry = Entry(self.root)
        self.entry.grid(row=0, column=2)
        self.root.bind('<Return>', self.hit_enter)
        self.canvas = Canvas(self.root, width=640, height=640, bg='light gray')
        self.canvas.grid(row=0, column=0)

    def start(self):
        self.root.mainloop()

    def hit_enter(self, event):
        # _input = int(self.entry.get())
        g = Genome()
        self.canvas.delete("all")

        g.mutate_add_connection()
        g.mutate_add_node()

        self.display_genome(g)

        #self.canvases[_input].place(x=0, y=0)
    
    def display_genome(self, genome):
        nodes = {
            'input':[], 
            'hidden':[], 
            'output':[]
        }

        for i in genome.nodeGenes:
            nodes[i.type].append(i)
        
        for i, v in enumerate(nodes['input']):
            v.x = 40
            v.y = (i+.5)*(640/len(nodes['input']))
        
        for i, v in enumerate(nodes['output']):
            v.x = 600
            v.y = (i+.5)*(640/len(nodes['output']))
                
        for i in nodes['hidden']:
            x, y = 0, 0
            connected_num = len(i.connected_ids)

            for j in i.connected_ids:
                n = genome.get_nodeGene_by_id(j)
                x += n.x
                y += n.y

            x /= connected_num
            y /= connected_num
            i.x = x
            i.y = y

        for i in genome.connectionGenes:
            self.canvas.create_line(i.in_node.x, i.in_node.y, i.out_node.x, i.out_node.y, width=i.weight*5, fill='blue')
            self.canvas.create_text((i.in_node.x+i.out_node.x)/2, (i.in_node.y+i.out_node.y)/2, text=i.id, fill='black')

        for i in genome.nodeGenes:
            self.canvas.create_oval(i.x-15, i.y-15, i.x+15, i.y+15, fill='red', outline='red')
            self.canvas.create_text(i.x, i.y, text=i.id, fill='white')
Пример #40
0
class Window(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent, background="dark gray")
        self.parent = parent
        self.initUI()
        self.initPuzzles()
        self.run()

    def initUI(self):
        self.parent.title("Block")
        self.pack(fill=BOTH, expand=1)
        self.initCanvas()
        self.initInterfaceZone()

    def initCanvas(self):
        self.canvas = Canvas(self, background="dark gray")
        self.canvas.pack(expand=1,fill=BOTH,padx=1,pady=1)

    def initInterfaceZone(self):
        # Draw the play, step and loading buttons
        self.interfaceFrame = Frame(self, background="dark gray")
        self.playFrame = Frame(self.interfaceFrame, background="dark gray")
        self.loadFrame = Frame(self.interfaceFrame, background="dark gray")

        self.isPlaying = False

        #Do the run buttons
        playButton = Button(self.playFrame, text=">", command=self.playPress)
        playButton.grid(row=0,column=0)
        pauseButton = Button(self.playFrame, text="||", command=self.pausePress)
        pauseButton.grid(row=0,column=1)
        stepBackButton = Button(self.playFrame, text="|<", command=self.stepBackPress)
        stepBackButton.grid(row=1,column=0)
        stepForwardButton = Button(self.playFrame, text=">|", command=self.stepForwardPress)
        stepForwardButton.grid(row=1,column=1)

        self.playFrame.pack(side=LEFT, expand=1, fill=BOTH)

        #Do the load-y stuff
        self.boardInputField = Entry(self.loadFrame)
        self.boardInputField.grid(row=0, column=0)
        boardInputButton = Button(self.loadFrame, text="Load Board", command=self.loadBoardPress)
        boardInputButton.grid(row=0, column=1)
        self.moveInputField = Entry(self.loadFrame)
        self.moveInputField.grid(row=1,column=0)
        moveInputButton = Button(self.loadFrame, text="Load Moves", command=self.loadMovesPress)
        moveInputButton.grid(row=1, column=1)

        self.loadFrame.pack(side=LEFT, expand=1, fill=BOTH)

        self.interfaceFrame.pack(side=BOTTOM)

    def initPuzzles(self):
        self.pieces = [] # Once a puzzle's loaded, will be a list of drawnBlocks
        self.boardWidth = 100
        self.boardHeight = 100
        self.blockWidth = 30
        self.blockHeight = 30

        self.rosterBlockWidth = 0
        self.rosterBlockHeight = 0
        self.rosterStartX = 0

        self.moveList = []
        self.atMove = 0

    def run(self):
        self.after(DELAY,self.onTimer)

    def loadPuzzle(self, puzzle):
        # Accept a puzzle and load it into the GUI

        # First clear memory
        self.pieces = []
        self.canvas.delete("all")
        self.moveList = []
        self.atMove = 0

        #Set up the board and piece roster
        squareSize = min(maxBoardWidth/puzzle.cols, maxBoardHeight/puzzle.rows)
        self.blockWidth = squareSize
        self.blockHeight = squareSize
        self.boardWidth = self.blockWidth*puzzle.cols
        self.boardHeight = self.blockHeight*puzzle.rows

        self.rosterStartX = boardStartX + self.boardWidth + extRosterPadding

        rosterX = self.rosterStartX
        rosterY = boardStartY + intRosterPadding
        maxHeight = 0

        #Start creating pieces, filling roster as we go
        for piece in puzzle.universe:
            label = piece.getLabel()
            if rosterX + intRosterPadding + piece.cols*self.blockWidth + intRosterPadding - self.rosterStartX <= rosterWidth:
                self.pieces.append(drawnBlock(self.canvas,piece,rosterX+intRosterPadding,rosterY,label=label, colour = colourDict[label], boxSize = self.blockWidth))
                rosterX += intRosterPadding + piece.cols*self.blockWidth
                if piece.rows*self.blockHeight>maxHeight:
                    maxHeight = piece.rows*self.blockHeight
            else:
                rosterX = self.rosterStartX
                rosterY += maxHeight + intRosterPadding
                maxHeight = piece.rows*self.blockHeight
                self.pieces.append(drawnBlock(self.canvas,piece,rosterX+intRosterPadding,rosterY,label=label, colour = colourDict[label], boxSize = self.blockWidth))
                rosterX += intRosterPadding + piece.cols*self.blockWidth

        #Draw board and roster
        for i in range(1,puzzle.rows):

            tag=self.canvas.create_rectangle(boardStartX+i*self.blockWidth - 1, boardStartY,
                                             boardStartX+i*self.blockWidth + 1, boardStartY+self.boardHeight, fill="#333333",width=0)
            self.canvas.tag_lower(tag)
        for j in range(1,puzzle.cols):
            tag=self.canvas.create_rectangle(boardStartX, boardStartY + j*self.blockHeight - 1,
                                             boardStartX + self.boardWidth, boardStartY+j*self.blockHeight+1, fill="#333333",width=0)
            self.canvas.tag_lower(tag)
        tag=self.canvas.create_rectangle(boardStartX, boardStartY, boardStartX + self.boardWidth, boardStartY + self.boardHeight,fill="white",width=2)
        self.canvas.tag_lower(tag)

        tag = self.canvas.create_rectangle(boardStartX + self.boardWidth + extRosterPadding, boardStartY,
                                  boardStartX + self.boardWidth + extRosterPadding + rosterWidth, rosterY + maxHeight + intRosterPadding, fill="white")
        self.canvas.tag_lower(tag)



    def move(self, move):
        #Puts a piece into (i,j) or sends it home

        piece = self.getPiece(move.tag)
        if move.home:
            piece.setMove(piece.homeX,piece.homeY)
        else:
            x = boardStartX + move.i*self.blockWidth
            y = boardStartY + move.j*self.blockHeight
            piece.setMove(x,y)

    def getPiece(self, tag):
        foundPiece = -1
        for piece in self.pieces:
                if piece.label == tag:
                    foundPiece = piece
                    break
        if foundPiece == -1:
            print("Error: No piece for tag \'"+ str(tag) + "\' found")
        return piece

    def getMoveStatus(self):
        if self.atMove < len(self.moveList):
            currentMove = self.moveList[self.atMove]
            piece = self.getPiece(currentMove.tag)
            if piece.isMoving:
                return False
            else:
                return True

        else:
            return True

    def handleMoves(self):
        moveCompleted = self.getMoveStatus()
        if moveCompleted:
            if self.atMove < len(self.moveList) - 1:
                self.atMove += 1
                self.move(self.moveList[self.atMove])
            else:
                self.isPlaying = False

    def playPress(self):
        print("Play")
        self.isPlaying=True
        #Start the next move
        if self.atMove < len(self.moveList):
            self.move(self.moveList[self.atMove])

    def pausePress(self):
        print("Pause")
        self.isPlaying=False


    def stepBackPress(self):
        print("Back")

    def stepForwardPress(self):
        print("Forward")

    def loadBoardPress(self):
        print("Load Board")
        input = self.boardInputField.get()
        if input == "":
            self.boardInputField.delete(0,END)
            self.boardInputField.insert(0,"Must enter a board here")
        else:
            prePuzzle = eval(input)
            # Now read in
            rows = prePuzzle[0]
            cols = prePuzzle[1]
            pieceList = prePuzzle[2]
            realPieces = []
            for piece in pieceList:
                realPieces.append(pz.Block(np.array(piece)))
            universe = frozenset(realPieces)
            puzzle = pz.Puzzle(rows,cols,universe)
            self.loadPuzzle(puzzle)

    def loadMovesPress(self):
        print("Load Moves")
        input = self.moveInputField.get()
        if input == "":
            self.moveInputField.delete(0,END)
            self.moveInputField.insert(0,"Must enter a move list here")
        else:
            preMoves = eval(input)
            self.moveList = []
            self.atMove = 0
            for move in preMoves:
                #Expect form [tag, i, j] with i = j = -1 when home is desired
                if move[1]==-1:
                    self.moveList.append(Move(move[0],0,0,home=True))
                else:
                    self.moveList.append(Move(move[0],move[1],move[2]))





    def onTimer(self):
        if self.isPlaying:
            self.handleMoves()
        for piece in self.pieces:
            if piece.isMoving:
                piece.move()
        self.after(DELAY,self.onTimer)
Пример #41
0
class SudokuUI(Frame):
    def __init__(self, parent, game):
        self.game = game
        self.parent = parent
        Frame.__init__(self, parent)

        self.row = 0
        self.col = 0

        self.__initUI()

    def __initUI(self):
        self.parent.title("Sudoku")
        self.pack(fill=BOTH, expand=1)
        self.canvas = Canvas(self, width=WIDTH, heigh=HEIGHT)
        self.canvas.pack(fill=BOTH, side=TOP)
        clear_button = Button(self,
                              text="Clear answers",
                              command=self.__clear_answers)
        clear_button.pack(fill=BOTH, side=BOTTOM)

        self.__draw_grid()
        self.__draw_puzzle()

        self.canvas.bind("<Button-1>", self.__cell_clicked)
        self.canvas.bind("<Key>", self.__key_pressed)

    def __draw_grid(self):
        for i in range(10):
            if i % 3 == 0:
                color = "blue"
            else:
                color = "gray"

            x0 = MARGIN + i * CELL
            y0 = MARGIN
            x1 = MARGIN + i * CELL
            y1 = HEIGHT - MARGIN
            self.canvas.create_line(x0, y0, x1, y1, fill=color)

            x0 = MARGIN
            y0 = MARGIN + i * CELL
            x1 = WIDTH - MARGIN
            y1 = MARGIN + i * CELL
            self.canvas.create_line(x0, y0, x1, y1, fill=color)

    def __draw_puzzle(self):
        self.canvas.delete("numbers")
        for i in range(9):
            for j in range(9):
                answer = self.game.puzzle[i][j]
                if answer != 0:
                    x = MARGIN + j * CELL + CELL / 2
                    y = MARGIN + i * CELL + CELL / 2
                    original = self.game.start_puzzle[i][j]
                    color = "black" if answer == original else "green"
                    self.canvas.create_text(x,
                                            y,
                                            text=answer,
                                            tags="numbers",
                                            fill=color)

    def __clear_answers(self):
        self.game.start()
        self.canvas.delete("victory")
        self.__draw_puzzle()

    def __cell_clicked(self, event):
        if self.game.game_over:
            return
        x, y = event.x, event.y
        if MARGIN < x < WIDTH - MARGIN and MARGIN < y < HEIGHT - MARGIN:
            self.canvas.focus_set()

            row, col = int((y - MARGIN) / CELL), int((x - MARGIN) / CELL)

            if (row, col) == (self.row, self.col):
                self.row, self.col = -1, -1
            elif self.game.puzzle[row][col] == 0:
                self.row, self.col = row, col

        self.__draw_cursor()

    def __draw_cursor(self):
        self.canvas.delete("cursor")
        if self.row >= 0 and self.col >= 0:
            x0 = MARGIN + self.col * CELL + 1
            y0 = MARGIN + self.row * CELL + 1
            x1 = MARGIN + (self.col + 1) * CELL - 1
            y1 = MARGIN + (self.row + 1) * CELL - 1
            self.canvas.create_rectangle(x0,
                                         y0,
                                         x1,
                                         y1,
                                         outline="red",
                                         tags="cursor")

    def __key_pressed(self, event):
        if self.game.game_over:
            return
        if self.row >= 0 and self.col >= 0 and event.char in "1234567890":
            self.game.puzzle[self.row][self.col] = int(event.char)
            self.col, self.row = -1, -1
            self.__draw_puzzle()
            self.__draw_cursor()
            if self.game.check_win():
                self.__draw_victory()

    def __draw_victory(self):
        x0 = y0 = MARGIN + CELL * 2
        x1 = y1 = MARGIN + CELL * 7
        self.canvas.create_oval(x0,
                                y0,
                                x1,
                                y1,
                                tags="victory",
                                fill="dark orange",
                                outline="blue")

        x = y = MARGIN + 4 * CELL + CELL / 2
        self.canvas.create_text(x,
                                y,
                                text="You win!",
                                tags="winner",
                                fill="white",
                                font=("Arial", 32))
Пример #42
0
class View():
    def __init__(self, root, controller):
        self.__controller = controller
        root.wm_title("Bomber")
        self.__windowsystem = root.call('tk', 'windowingsystem')
        self.__frame = root
        self.__canvas = Canvas(self.__frame, width=int(CANVAS_WIDTH),
                               height=int(CANVAS_HEIGHT), bg="white")
        self.__canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
        self.__init_fonts()
        self.__init_arena()
        self.__init_score()
        self.__block_views = [] # type: List[BlockView]
        self.__blockfield_view = BlockfieldView()
        self.__messages = []

    def __init_fonts(self):
        self.bigfont = font.nametofont("TkDefaultFont")
        self.bigfont.configure(size=int(48))
        self.scorefont = font.nametofont("TkDefaultFont")
        self.scorefont.configure(size=int(20))


    def __init_score(self):
        self.score_text = self.__canvas.create_text(5, 5, anchor="nw")
        self.__canvas.itemconfig(self.score_text, text="Score:", font=self.scorefont)

    def __init_arena(self):
        self.__canvas.create_rectangle(LEFT_OFFSET, TOP_OFFSET,
                                       LEFT_OFFSET + MAXCOL*GRID_SIZE,
                                       TOP_OFFSET+MAXROW*GRID_SIZE, fill="black")

        nextblocktext = self.__canvas.create_text(GRID_SIZE,
                                                  TOP_OFFSET + GRID_SIZE * 4, anchor="nw")
        self.__canvas.itemconfigure(nextblocktext, text="Next:",
                                    font=self.bigfont, fill="black")

        self.__autoplay_text = self.__canvas.create_text(LEFT_OFFSET + GRID_SIZE * 5,
                                                         TOP_OFFSET - GRID_SIZE, anchor="c")
        self.__canvas.itemconfigure(self.__autoplay_text, text="Play mode",
                                    font=self.bigfont, fill="black")

    def register_block(self, block):
        block_view = BlockView(block)
        self.__block_views.append(block_view)

    def unregister_block(self, block):
        for block_view in self.__block_views:
            if block_view.block is block:
                block_view.erase(self.__canvas)
                self.__block_views.remove(block_view)

    def update_blockfield(self, blockfield):
        self.__blockfield_view.redraw(self.__canvas, blockfield)

    def display_score(self):
        self.__canvas.itemconfig(self.score_text, text="Score: " + str(self.__controller.score),
                                 font=self.scorefont)

    def show_autoplay(self, autoplay):
        if autoplay:
            self.__canvas.itemconfig(self.__autoplay_text, text="Auto-play mode",
                                     font=self.scorefont, fill="black")
        else:
            self.__canvas.itemconfig(self.__autoplay_text, text="Manual mode",
                                     font=self.scorefont, fill="black")

    def game_over(self):
        text1 = self.__canvas.create_text(LEFT_OFFSET + GRID_SIZE*MAXCOL//2,
                                          CANVAS_HEIGHT/2, anchor="c")
        text2 = self.__canvas.create_text(LEFT_OFFSET + GRID_SIZE*MAXCOL//2,
                                          CANVAS_HEIGHT/2 + 100, anchor="c")
        text1_shadow = self.__canvas.create_text(2 + LEFT_OFFSET + GRID_SIZE*MAXCOL//2,
                                                 2 + CANVAS_HEIGHT/2, anchor="c")
        text2_shadow = self.__canvas.create_text(2 + LEFT_OFFSET + GRID_SIZE*MAXCOL//2,
                                                 2 + CANVAS_HEIGHT/2 + 100, anchor="c")
        self.__messages.append(text1)
        self.__messages.append(text2)
        self.__messages.append(text1_shadow)
        self.__messages.append(text2_shadow)
        self.__canvas.itemconfig(text1, text="GAME OVER!",
                                 font=self.bigfont, fill="white")
        self.__canvas.itemconfig(text2, text="Press r to play again.",
                                 font=self.scorefont, fill="white")
        self.__canvas.itemconfig(text1_shadow, text="GAME OVER!",
                                 font=self.bigfont, fill="black")
        self.__canvas.itemconfig(text2_shadow, text="Press r to play again.",
                                 font=self.scorefont, fill="black")
        self.__canvas.tag_raise(text1)
        self.__canvas.tag_raise(text2)

    def clear_messages(self):
        for txt in self.__messages:
            self.__canvas.delete(txt)
        self.__messages.clear()

    def update(self):
        for block_view in self.__block_views:
            block_view.redraw(self.__canvas)
        self.display_score()
class ProductSheet():
    def __init__(self, container=None, displayer=None, session=None):
        """ 'container'     (Obj  ): instance of Container.
            'displayer'     (obj  ): instance of Displayer.
            'session,'      (obj  ): instance of Session.
            'grid'          (Obj  ): instance of Grid.

            'f_container'   (Frame): container frame.
            'm_frame'       (Frame): master frame of view.

            'name'          (str  ): name of view.
            'json_script'   (dict ): json dict of script.

            'width'         (int  ): view width.
            'height'        (int  ): view height.
            'padx'          (int  ): view
            'pady'          (int  ): view
            'bg'            (str  ): view bg. """

        # Instances
        self.container = container
        self.displayer = displayer
        self.session = session
        self.grid = None

        # Frames
        self.f_container = self.container.f_container
        self.m_frame = None

        # Informations
        self.name = None

        # Script
        self.json_script = None

        # Style Sheet
        self.width = self.container.width
        self.height = self.container.height
        self.padx = 0
        self.pady = 0
        self.bg = "#ffffff"

        # Tk control variables

        # Widgets row 0
        self.w_title = None
        # Widgets row 1
        self.w_img_product = None
        self.w_name_product = None
        self.w_brand_product = None
        self.w_nutriscore_product = None
        # Widgets row 2
        self.w_best_button = None
        self.w_edit_button = None
        self.w_trash_button = None
        self.w_add_button = None

        # Widgets row 4
        self.canvas_calories = None
        self.w_calories_img = None
        self.w_calories_label = None

        # Widgets row 5
        self.canvas_sugar = None
        self.w_sugar_img = None
        self.w_sugar_label = None
        self.w_sugar_value = None

        # Widgets row 6
        self.w_stores_img = None
        self.w_stores_label = None
        self.w_stores_value = None
        # Widgets row 7
        self.w_author_img = None
        self.w_author_label = None
        self.w_author_value = None
        # Widgets row 8
        self.w_submit_button = None

        self.favorite_status = False

        self.product = None
        self.product_id = 0
        self.product_img = None
        self.product_name = None
        self.product_brand = None
        self.product_nutriscore = None
        self.product_kcal = 0
        self.product_sugar = 0
        self.product_author = None
        self.product_store = None

        # Fill status
        self.fill_status = False

        # Previous View in **kwargs
        self.previous_view = None

        # -- Displayer initialisation -- #
        self.construct()

    def construct(self, **kwargs):
        """ Construt view.
            to not fill the view during initialization.
            'grid'      (obj): Instance of Grid.
            'm_frame'   (Frame): Tkinter master frame of view. """

        # 1. Create new grid in page container.
        self.grid = Grid(frame=self.f_container,
                         width=self.width,
                         height=self.height,
                         padx=self.padx,
                         pady=self.pady,
                         bg=self.bg)
        # 2. Get view frame for displayer function
        self.m_frame = self.grid.master_frame

        # 3. Construct the view rows
        self.row_0(action="construct")
        self.row_1(action="construct")
        self.row_2(action="construct")
        self.row_3(action="construct")
        self.row_4(action="construct")
        self.row_5(action="construct")
        self.row_6(action="construct")
        self.row_7(action="construct")

    def fill(self, **kwargs):
        """ Fill the view rows.
            'json_script'   (dict): texts for view.
            'name'          (str): view name. """

        for key, value in kwargs.items():

            if key == "view":
                self.previous_view = value
            elif key == "product_id":
                self.product_id = value

        # 1. Get the script.
        self.json_script = self.session.get_script(package_name="product",
                                                   file_name="sheet")
        # 2. Save name of view for displayer.
        self.name = self.json_script.get("view_name")

        # Get product informations
        self.product = self.session.dbmanager.db_product.read(
            action="id", product_id=self.product_id)

        favorite = self.session.dbmanager.db_user_prod.read(
            action="test",
            user_id=self.session.user_id,
            product_id=self.product_id)

        if len(favorite) == 1:
            self.favorite_status = True
        else:
            self.favorite_status = False

        self.product_img = self.product[0]["product_img_url"]
        self.product_name = self.product[0]["product_name"]
        self.product_brand = self.product[0]["product_brand"]
        self.product_nutriscore = self.product[0]["product_nutriscore"]
        self.product_kcal = self.product[0]["product_kcal"]
        self.product_sugar = self.product[0]["product_sugar"]
        self.product_author = self.product[0]["product_creator"]
        self.product_store = self.product[0]["product_store"]

        # 3. Refresh rows.
        if self.fill_status is True:
            self.row_0(action="refresh")
            self.row_1(action="refresh")
            self.row_2(action="refresh")
            self.row_3(action="refresh")
            self.row_4(action="refresh")
            self.row_5(action="refresh")
            self.row_6(action="refresh")
            self.row_7(action="refresh")

        # 4. Fill the view rows.
        self.row_0(action="fill")
        self.row_1(action="fill")
        self.row_2(action="fill")
        self.row_3(action="fill")
        self.row_4(action="fill")
        self.row_5(action="fill")
        self.row_6(action="fill")
        self.row_7(action="fill")
        self.fill_status = True

    def display_substitutes(self):
        """ Display substitues. """

        self.displayer.display(c_view="product_sheet",
                               f_view="product_substitutes",
                               product_id=self.product_id)

    def display_edit(self):
        """ Display product edit. """

        self.displayer.display(c_view="product_sheet",
                               f_view="product_edit",
                               product_id=self.product_id)

    def display_search(self):
        """ Display "search". """

        self.displayer.display(c_view="product_sheet", f_view="search_engine")

    def add_product(self):
        """ Add product to favorite in database. """

        self.session.dbmanager.db_user_prod.create(
            user_id=self.session.user_id, product_id=self.product_id)

        self.favorite_status = True
        self.row_1("refresh")
        self.row_1("fill")

    def del_product_to_favorite(self):
        """ Add product to favorite in database. """

        self.session.dbmanager.db_user_prod.delete(
            user_id=self.session.user_id, product_id=self.product_id)

        self.favorite_status = False
        self.row_1("refresh")
        self.row_1("fill")

    def trash_product(self):
        """ Delete product to database. """

        self.session.dbmanager.db_product.delete(product_id=self.product_id)

        self.display_search()

    def row_0(self, action=None):
        """ Name : PRODUCT IMAGE
            cols : 3 """

        if action == "construct":

            # -- CREATE ROW -- #
            self.grid.row(width=self.width,
                          height=250,
                          padx=self.padx,
                          pady=self.pady,
                          bg="#ffffff")
            # -- CREATE COLS -- #
            self.grid.column(span=6,
                             row=0,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=5,
                             row=0,
                             width=None,
                             height=None,
                             padx=30,
                             pady=30,
                             bg=None)
            self.grid.column(span=1,
                             row=0,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)

        elif action == "fill":

            if self.w_img_product is None:
                # -- COLUMN 1 : PRODUCT IMAGE -- #
                if self.product_img == "empty":
                    img = Image.open("frontend/images/no_image.png")
                else:
                    req = requests.get(self.product_img)
                    img = Image.open(BytesIO(req.content))

                img_resize = img.resize((150, 200), Image.ANTIALIAS)
                tk_img_product = ImageTk.PhotoImage(img_resize)
                self.w_img_product = Label(self.grid.col_frames[0][0],
                                           image=tk_img_product,
                                           bg="#ffffff")
                self.w_img_product.image = tk_img_product
                self.w_img_product.pack(fill='both', expand=True)

            if self.w_name_product is None:
                # -- COLUMN 2 : PRODUCT NAME -- #
                self.w_name_product = Label(self.grid.col_frames[0][1],
                                            text="{}".format(
                                                self.product_name),
                                            bg="#ffffff",
                                            fg="#000000",
                                            font="Helvetica 13 normal")
                self.w_name_product.pack(fill='both')

            if self.w_brand_product is None:
                # -- COLUMN 2 : PRODUCT BRAND -- #
                self.w_brand_product = Label(self.grid.col_frames[0][1],
                                             text="{}".format(
                                                 self.product_brand),
                                             bg="#ffffff",
                                             fg="#000000",
                                             font="Helvetica 13 bold")
                self.w_brand_product.pack(fill='both')

            if self.w_nutriscore_product is None:
                # -- COLUMN 2 : PRODUCT NUTRISCORE -- #
                img = Image.open(
                    "frontend/images/nutriscores/nutriscore_{}.png".format(
                        self.product_nutriscore))
                imgResize = img.resize((160, 90), Image.ANTIALIAS)
                nutriscore_img = ImageTk.PhotoImage(imgResize)

                self.w_nutriscore_product = Label(self.grid.col_frames[0][1],
                                                  image=nutriscore_img,
                                                  bg="#ffffff")
                self.w_nutriscore_product.image = nutriscore_img
                self.w_nutriscore_product.pack(fill="both", expand=True)

        elif action == "refresh":

            self.w_img_product.pack_forget()
            self.w_name_product.pack_forget()
            self.w_brand_product.pack_forget()
            self.w_nutriscore_product.pack_forget()

            self.w_img_product = None
            self.w_name_product = None
            self.w_brand_product = None
            self.w_nutriscore_product = None

    def row_1(self, action=None):
        """ Name : BUTTONS
            cols : 6 """

        if action == "construct":

            # -- CREATE ROW -- #
            self.grid.row(width=self.width,
                          height=50,
                          padx=0,
                          pady=0,
                          bg="#ffffff")
            # -- CREATE COLS -- #
            self.grid.column(span=7,
                             row=1,
                             width=None,
                             height=None,
                             padx=5,
                             pady=5,
                             bg=None)
            self.grid.column(span=1,
                             row=1,
                             width=None,
                             height=None,
                             padx=5,
                             pady=5,
                             bg=None)
            self.grid.column(span=1,
                             row=1,
                             width=None,
                             height=None,
                             padx=5,
                             pady=5,
                             bg=None)
            self.grid.column(span=1,
                             row=1,
                             width=None,
                             height=None,
                             padx=5,
                             pady=5,
                             bg=None)
            self.grid.column(span=1,
                             row=1,
                             width=None,
                             height=None,
                             padx=5,
                             pady=5,
                             bg=None)
            self.grid.column(span=1,
                             row=1,
                             width=None,
                             height=None,
                             padx=5,
                             pady=5,
                             bg=None)

        elif action == "fill":

            # -- COLUMN 1 : EMPTY -- #

            if self.w_best_button is None:

                # -- COLUMN 3 : SUBSTITUTES BUTTON -- #
                img = Image.open(
                    "frontend/images/views/product_sheet/best_product_1.png")
                imgResize = img.resize((25, 25), Image.ANTIALIAS)
                best_img = ImageTk.PhotoImage(imgResize)

                self.w_best_button = Button(self.grid.col_frames[1][1],
                                            image=best_img,
                                            bg="#ffffff",
                                            command=self.display_substitutes)
                self.w_best_button.image = best_img
                self.w_best_button.pack(fill='both', expand=True)

            if self.w_edit_button is None:

                # -- COLUMN 4 : PRODUCT SHEET BUTTON -- #
                img = Image.open(
                    "frontend/images/views/product_sheet/edit.png")
                imgResize = img.resize((25, 25), Image.ANTIALIAS)
                edit_img = ImageTk.PhotoImage(imgResize)

                self.w_edit_button = Button(self.grid.col_frames[1][2],
                                            image=edit_img,
                                            bg="#ffffff",
                                            command=self.display_edit)
                self.w_edit_button.image = edit_img
                self.w_edit_button.pack(fill='both', expand=True)

            if self.w_trash_button is None:

                # -- COLUMN 5 : TRASH BUTTON -- #
                img = Image.open(
                    "frontend/images/views/product_sheet/trash.png")
                imgResize = img.resize((25, 25), Image.ANTIALIAS)
                trash_img = ImageTk.PhotoImage(imgResize)

                self.w_trash_button = Button(self.grid.col_frames[1][3],
                                             image=trash_img,
                                             bg="#ffffff",
                                             command=self.trash_product)
                self.w_trash_button.image = trash_img
                self.w_trash_button.pack(fill='both', expand=True)

            if self.w_add_button is None:

                img = Image.open(
                    "frontend/images/views/product_sheet/icon_add_{}.png".
                    format(self.product_nutriscore))
                imgResize = img.resize((25, 25), Image.ANTIALIAS)
                add_img = ImageTk.PhotoImage(imgResize)

                if self.favorite_status is False:
                    # -- COLUMN 6 : ADD BUTTON -- #
                    self.w_add_button = Button(self.grid.col_frames[1][4],
                                               image=add_img,
                                               bg="#ffffff",
                                               command=self.add_product)
                    self.w_add_button.image = add_img
                    self.w_add_button.pack(fill='both', expand=True)
                else:
                    img = Image.open(
                        "frontend/images/views/product_sheet/favorite.png")
                    imgResize = img.resize((25, 25), Image.ANTIALIAS)
                    add_img = ImageTk.PhotoImage(imgResize)
                    # -- COLUMN 6 : ADD BUTTON -- #
                    self.w_add_button = Button(
                        self.grid.col_frames[1][4],
                        image=add_img,
                        bg="#ffffff",
                        command=self.del_product_to_favorite)
                    self.w_add_button.image = add_img
                    self.w_add_button.pack(fill='both', expand=True)

        elif action == "refresh":

            self.w_best_button.pack_forget()
            self.w_edit_button.pack_forget()
            self.w_trash_button.pack_forget()
            self.w_add_button.pack_forget()

            self.w_best_button = None
            self.w_edit_button = None
            self.w_trash_button = None
            self.w_add_button = None

    def row_2(self, action=None):
        """ Name : SPACE
            cols : 1 """

        if action == "construct":

            # -- CREATE ROW -- #
            self.grid.row(width=self.width,
                          height=25,
                          padx=self.padx,
                          pady=self.pady,
                          bg="#ffffff")
            # -- CREATE COLS -- #
            self.grid.column(span=12,
                             row=2,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)

        elif action == "fill":
            pass

        elif action == "refresh":
            pass

    def row_3(self, action=None):
        """ Name : PRODUCT CALORIES
            cols : 3 """

        line = "line_empty"
        line_lenght = 90

        if self.product_kcal == 0:
            line = "line_empty"
            line_lenght = 90
        elif self.product_kcal <= 100:
            line = "line_a"
            line_lenght = 90
        elif self.product_kcal <= 500:
            line = "line_b"
            line_lenght = 180
        elif self.product_kcal <= 1000:
            line = "line_c"
            line_lenght = 270
        elif self.product_kcal <= 1500:
            line = "line_d"
            line_lenght = 360
        elif self.product_kcal > 1501:
            line = "line_e"
            line_lenght = 450

        if action == "construct":

            # -- CREATE ROW -- #
            self.grid.row(width=self.width,
                          height=55,
                          padx=0,
                          pady=5,
                          bg="#ffffff")
            # -- CREATE COLS -- #
            self.grid.column(span=1,
                             row=3,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=2,
                             row=3,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.col = self.grid.column(span=9,
                                        row=3,
                                        width=None,
                                        height=None,
                                        padx=None,
                                        pady=None,
                                        bg=None)

        elif action == "fill":

            # Get texts for this row
            txt = self.json_script.get("row_3")

            if self.w_calories_img is None:

                # -- COLUMN 1 : CALORIES IMAGE -- #
                img = Image.open(
                    "frontend/images/views/product_sheet/calories.png")
                imgResize = img.resize((30, 30), Image.ANTIALIAS)
                calories_img = ImageTk.PhotoImage(imgResize)

                self.w_calories_img = Label(self.grid.col_frames[3][0],
                                            image=calories_img,
                                            bg="#ffffff")
                self.w_calories_img.image = calories_img
                self.w_calories_img.pack(fill="both", expand=True)

            if self.w_calories_label is None:

                # -- COLUMN 2 : CALORIES NAME -- #
                self.w_calories_label = Label(self.grid.col_frames[3][1],
                                              anchor="w",
                                              text=txt.get("calories_label"),
                                              bg="#ffffff",
                                              font="Helvetica 11 bold")
                self.w_calories_label.pack(fill="both", expand=True)

            if self.canvas_calories is None:

                img = Image.open(
                    "frontend/images/views/product_sheet/{}.png".format(line))
                imgResize = img.resize((line_lenght, 35), Image.ANTIALIAS)
                kcal_img = ImageTk.PhotoImage(imgResize)

                self.canvas_calories = Canvas(self.grid.col_frames[3][2],
                                              width=self.width,
                                              height=35,
                                              highlightthickness=0,
                                              bg="#ffffff")
                self.canvas_calories.pack(expand=True, fill="both")

                self.canvas_calories.create_image(0,
                                                  0,
                                                  image=kcal_img,
                                                  anchor="nw")
                self.canvas_calories.image = kcal_img

                self.canvas_calories.create_text(5,
                                                 9,
                                                 text=" {} Kcal".format(
                                                     self.product_kcal),
                                                 anchor='nw',
                                                 fill="#ffffff",
                                                 font="Helvetica 10 bold")

        elif action == "refresh":

            self.canvas_calories.delete("all")
            self.canvas_calories.pack_forget()
            self.w_calories_label.pack_forget()
            self.w_calories_img.pack_forget()

            self.canvas_calories = None
            self.w_calories_label = None
            self.w_calories_img = None

    def row_4(self, action=None):
        """ Name : PRODUCT SUGAR
            cols : 3 """

        line = "line_empty"
        line_lenght = 90

        # ----- ROW 5 : PRODUCT SUGAR ----- #
        if self.product_sugar == 0:
            line = "line_empty"
            line_lenght = 90
        elif self.product_sugar <= 10:
            line = "line_a"
            line_lenght = 90
        elif self.product_sugar <= 50:
            line = "line_b"
            line_lenght = 180
        elif self.product_sugar <= 100:
            line = "line_c"
            line_lenght = 270
        elif self.product_sugar <= 150:
            line = "line_d"
            line_lenght = 360
        elif self.product_sugar > 151:
            line = "line_e"
            line_lenght = 450

        if action == "construct":

            # -- CREATE ROW -- #
            self.grid.row(width=self.width,
                          height=55,
                          padx=self.padx,
                          pady=self.pady,
                          bg="#ffffff")
            # -- CREATE COLS -- #
            self.grid.column(span=1,
                             row=4,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=2,
                             row=4,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=9,
                             row=4,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)

        elif action == "fill":

            # Get texts for this row
            txt = self.json_script.get("row_4")

            if self.w_sugar_img is None:

                # -- COLUMN 1 : SUGAR IMAGE -- #
                img = Image.open(
                    "frontend/images/views/product_sheet/sugar.png")
                img_resize = img.resize((30, 30), Image.ANTIALIAS)
                sugar_img = ImageTk.PhotoImage(img_resize)

                self.w_sugar_img = Label(self.grid.col_frames[4][0],
                                         image=sugar_img,
                                         bg="#ffffff")
                self.w_sugar_img.image = sugar_img
                self.w_sugar_img.pack(side=RIGHT, fill="both", expand=True)

            if self.w_sugar_label is None:

                # -- COLUMN 2 : SUGAR LABEL -- #
                self.w_sugar_label = Label(self.grid.col_frames[4][1],
                                           anchor="w",
                                           text=txt.get("sugar_label"),
                                           bg="#ffffff",
                                           font="Helvetica 11 bold")
                self.w_sugar_label.pack(fill="both", expand=True)

            if self.canvas_sugar is None:

                img = Image.open(
                    "frontend/images/views/product_sheet/{}.png".format(line))
                imgResize = img.resize((line_lenght, 35), Image.ANTIALIAS)
                kcal_img = ImageTk.PhotoImage(imgResize)

                self.canvas_sugar = Canvas(self.grid.col_frames[4][2],
                                           width=self.width,
                                           height=35,
                                           highlightthickness=0,
                                           bg="#ffffff")
                self.canvas_sugar.pack(expand=True, fill="both")

                self.canvas_sugar.create_image(0,
                                               0,
                                               image=kcal_img,
                                               anchor="nw")
                self.canvas_sugar.image = kcal_img

                self.canvas_sugar.create_text(5,
                                              9,
                                              text=" {} g".format(
                                                  self.product_sugar),
                                              anchor='nw',
                                              fill="#ffffff",
                                              font="Helvetica 10 bold")

        elif action == "refresh":

            self.canvas_sugar.delete("all")
            self.canvas_sugar.pack_forget()

            self.w_sugar_img.pack_forget()
            self.w_sugar_label.pack_forget()

            self.w_sugar_img = None
            self.w_sugar_label = None
            self.canvas_sugar = None

    def row_5(self, action=None):
        """ Name : PRODUCT STORES
            cols : 3 """

        if action == "construct":

            # -- CREATE ROW -- #
            self.grid.row(width=self.width,
                          height=55,
                          padx=self.padx,
                          pady=self.pady,
                          bg="#ffffff")
            # -- CREATE COLS -- #
            self.grid.column(span=1,
                             row=5,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=2,
                             row=5,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=9,
                             row=5,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)

        elif action == "fill":

            # Get texts for this row
            txt = self.json_script.get("row_5")

            if self.w_stores_img is None:

                # -- COLUMN 1 : STORES IMAGE -- #
                img = Image.open(
                    "frontend/images/views/product_sheet/store.png")
                img_resize = img.resize((30, 30), Image.ANTIALIAS)
                store_img = ImageTk.PhotoImage(img_resize)

                self.w_stores_img = Label(self.grid.col_frames[5][0],
                                          image=store_img,
                                          bg="#ffffff")
                self.w_stores_img.image = store_img
                self.w_stores_img.pack(side=RIGHT, fill="both", expand=True)

            if self.w_stores_label is None:

                # -- COLUMN 2 : STORES LABEL -- #
                self.w_stores_label = Label(self.grid.col_frames[5][1],
                                            anchor="w",
                                            text=txt.get("stores_label"),
                                            bg="#ffffff",
                                            font="Helvetica 11 bold")
                self.w_stores_label.pack(fill="both", expand=True)

            if self.w_stores_value is None:

                # -- COLUMN 3 : STORES VALUE -- #
                self.w_stores_value = Label(self.grid.col_frames[5][2],
                                            anchor="w",
                                            text=" {}".format(
                                                self.product_store),
                                            bg="#ffffff")
                self.w_stores_value.pack(fill="both", expand=True)

        elif action == "refresh":

            self.w_stores_img.pack_forget()
            self.w_stores_label.pack_forget()
            self.w_stores_value.pack_forget()

            self.w_stores_img = None
            self.w_stores_label = None
            self.w_stores_value = None

    def row_6(self, action=None):
        """ Name : AUTHOR
            cols : 3 """

        if action == "construct":

            # -- CREATE ROW -- #
            self.grid.row(width=self.width,
                          height=55,
                          padx=self.padx,
                          pady=self.pady,
                          bg="#ffffff")
            # -- CREATE COLS -- #
            self.grid.column(span=1,
                             row=6,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=2,
                             row=6,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=9,
                             row=6,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)

        elif action == "fill":

            # Get texts for this row
            txt = self.json_script.get("row_6")

            if self.w_author_img is None:
                # -- COLUMN 1 : AUTHOR IMAGE -- #
                img = Image.open(
                    "frontend/images/views/product_sheet/copyright.png")
                img_resize = img.resize((30, 30), Image.ANTIALIAS)
                store_img = ImageTk.PhotoImage(img_resize)

                self.w_author_img = Label(self.grid.col_frames[6][0],
                                          image=store_img,
                                          bg="#ffffff")
                self.w_author_img.image = store_img
                self.w_author_img.pack(side=RIGHT, fill="both", expand=True)

            if self.w_author_label is None:
                # -- COLUMN 2 : AUTHOR LABEL -- #
                self.w_author_label = Label(self.grid.col_frames[6][1],
                                            anchor="w",
                                            text=txt.get("author_label"),
                                            bg="#ffffff",
                                            font="Helvetica 11 bold")
                self.w_author_label.pack(fill="both", expand=True)

            if self.w_author_value is None:
                # -- COLUMN 3 : AUTHOR VALUE -- #
                self.w_author_value = Label(self.grid.col_frames[6][2],
                                            anchor="w",
                                            text=" {}".format(
                                                self.product_author),
                                            bg="#ffffff")
                self.w_author_value.pack(fill="both", expand=True)

        elif action == "refresh":

            self.w_author_img.pack_forget()
            self.w_author_label.pack_forget()
            self.w_author_value.pack_forget()

            self.w_author_img = None
            self.w_author_label = None
            self.w_author_value = None

    def row_7(self, action=None):
        """ Name : SUBMIT BUTTON
            cols : 4 """

        if action == "construct":

            # -- CREATE ROW -- #
            self.grid.row(width=self.width,
                          height=100,
                          padx=self.padx,
                          pady=self.pady,
                          bg="#ffffff")
            # -- CREATE COLS -- #
            self.grid.column(span=4,
                             row=7,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=4,
                             row=7,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)
            self.grid.column(span=4,
                             row=7,
                             width=None,
                             height=None,
                             padx=None,
                             pady=None,
                             bg=None)

        elif action == "fill":

            # Get texts for this row
            txt = self.json_script.get("row_7")

            # -- COLUMN 1 : EMPTY -- #
            if self.w_submit_button is None:
                # -- COLUMN 3 : SUBMIT BUTTON -- #
                self.w_submit_button = Button(self.grid.col_frames[7][1],
                                              text=txt.get("submit_button"),
                                              fg="#ffffff",
                                              bg="#7A57EC",
                                              activeforeground="#ffffff",
                                              activebackground="#845EFF",
                                              command=self.display_search)
                self.w_submit_button.pack(side=BOTTOM, fill=X, expand=True)

            # -- COLUMN 4 : EMPTY -- #

        elif action == "refresh":

            self.w_submit_button.pack_forget()
            self.w_submit_button = None
Пример #44
0
class Gem:
	def __init__(self):
		self.frame = Tk();
		self.frame.resizable(False, False)

		self.status = 1
		self.scorePlayerA = 0
		self.scorePlayerB = 0

		self.scoreRoundA = 0
		self.scoreRoundB = 0

		self.countRound = 0
		self.quitMatch = 0
		self.isQuitRound = 0

		self.canvas_after_2 = 0
		self.canvas_after_1 = 0
		self.isPause = 0

		#register event
		self.frame.bind("<F4>", self.quitGame)
		self.frame.bind("<F5>", self.pauseGame)
		self.frame.protocol("WM_DELETE_WINDOW", self.on_closing)

		self.registerKeyboard()

	def setName(self, title):
		self.frame.title(title)

	def setBall(self, ball):
		self.ball = ball

	def setLeftBar(self, bar):
		self.leftBar = bar

	def setRightBar(self, bar):
		self.rightBar = bar

	def run(self):
		self.frame.mainloop()

	def getFrame(self):
		return self.frame;

	def getCanvas(self):
		return self.canvas

	def setSize(self, size):
		self.frame.geometry(("%dx%d")%(size[0], size[1]))
		self.frame.update()

	def getSize(self):
		return (self.frame.winfo_width(), self.frame.winfo_height())

	def setBackground(self, color):
		self.background = color

	def setPlayers(self, players):
		self.players = players

	def setScoreBoard(self):
		players = self.players
		size = self.getSize()
		mid = round(size[0]/2)
		# Board
		self.canvas.create_rectangle(mid - 100, 0, mid + 100, 35, fill="grey58", outline="white", tag="boarda")

		# Player name 1
		self.canvas.create_text(mid - 80, 15, text=players[0], fill="magenta2", tag="boardb")

		# Round score 1
		r1 = players[0]+"a"
		self.canvas.create_text(mid - 80, 28, text="0", fill="pale green", tag="scoreplayera")

		# Player name 2
		self.canvas.create_text(mid + 80, 15, text=players[1], fill="magenta2", tag="boardc")

		# Round score 2
		self.canvas.create_text(mid + 80, 28, text="0", fill="pale green", tag="scoreplayerb")

		# Box score 1
		self.canvas.create_rectangle(mid - 50, 5, mid - 10, 25, fill="thistle3", outline="white", tag="boardd")

		# Score 1
		self.canvas.create_text(mid - 30, 15, text="000", fill="cyan", tag=players[0])

		# Box score 2
		self.canvas.create_rectangle(mid + 10, 5, mid + 50, 25, fill="thistle3", outline="white", tag="boarde")

		# Score 2
		self.canvas.create_text(mid + 30, 15, text="000", fill="cyan", tag=players[1])

		self.canvas.pack()
		self.frame.update()

	def clearScoreBoard(self):
		self.canvas.delete(self.players[0])
		self.canvas.delete(self.players[1])
		self.canvas.delete("boarda")
		self.canvas.delete("boardb")
		self.canvas.delete("boardc")
		self.canvas.delete("boardd")
		self.canvas.delete("boarde")
		self.canvas.delete("scoreplayera")
		self.canvas.delete("scoreplayerb")
		self.canvas.update()

	def initCanvas(self):
		canvas_width = self.frame.winfo_width()
		canvas_height = self.frame.winfo_height()
		self.canvas = Canvas(self.frame, width=canvas_width, height=canvas_height, bg=self.background)
		self.frame.update()

	def setDashboard(self):
		size = self.getSize();
		midw = round(size[0]/2)
		midh = round(size[1]/2)
		self.canvas.create_oval(midw - 120, midh - 70, midw + 120, midh+70, fill="alice blue", outline="white", tag="dash1")
		self.canvas.create_text(midw, midh - 35, text="F1: Machine Vs Machine", fill="blue violet", tag="dash2")
		self.canvas.create_text(midw, midh - 10, text="F2: Human Vs Machine  ", fill="blue violet", tag="dash3")
		self.canvas.create_text(midw, midh + 15, text="F3: Human Vs Human     ", fill="blue violet", tag="dash4")
		self.canvas.create_text(midw, midh + 38, text="F4: Quit Game                  ", fill="blue violet", tag="dash5")
		self.canvas.pack()

	def clearDashboard(self):
		self.canvas.delete("dash1")
		self.canvas.delete("dash2")
		self.canvas.delete("dash3")
		self.canvas.delete("dash4")
		self.canvas.delete("dash5")
		self.canvas.update()

	def setWinter(self, status = -1):
		size = self.getSize();
		midw = round(size[0]/2)
		midh = round(size[1]/2)

		if status == 1:
			textstr = self.players[0] + " Win"
		elif status == 2:
			textstr = self.players[1] + " Win"
		elif self == 3 and self.scorePlayerA != self.scorePlayerB:
			if self.scoreRoundB > self.scorePlayerA:
				textstr = self.players[1] + " Win"
			else:
				textstr = self.players[0] + " Win"
		else:
			textstr = "Not Match"

		self.canvas.create_oval(midw - 50, midh - 20, midw + 50, midh+20, fill="alice blue", outline="white", tag="wintera")
		self.canvas.create_text(midw, midh, text=textstr, fill="blue violet", tag="winterb")

		self.canvas.pack()
		self.canvas.update();

	def clearWinter(self):
		self.canvas.delete("wintera")
		self.canvas.delete("winterb")
		self.canvas.update()

	def quitRound(self, status):
		if self.scorePlayerA >= self.maxRoundScore and self.scorePlayerB >= self.maxRoundScore:
			self.isQuitRound = 1
		if status == 1 or status == 2 or self.isQuitRound == 1 or self.quitMatch == 1:
			if self.isQuitRound == 0:
				self.updateScoreRound(status - 1)
			self.isQuitRound = 1
			self.ball.quit(self.canvas)
			self.leftBar.quit(self.canvas)
			self.rightBar.quit(self.canvas)
		return self.isQuitRound

	def nextRound(self, status):
		self.canvas.after_cancel(self.canvas_after_2)
		if status == 2 or status == 1:
			if self.maxRound > self.countRound:
				#self.ball.quit(self.canvas)
				#self.leftBar.quit(self.canvas)
				#self.rightBar.quit(self.canvas)
				self.resetRound()
				self.countRound += 1
				self.leftBar.reset(self.canvas)
				self.rightBar.reset(self.canvas)
				if status == 1:
					self.leftBar.transferBall(self.canvas, self.ball)
				else:
					self.leftBar.transferBall(self.canvas, self.ball)
				#print(self.canvas.find_withtag(self.ball.name))
			else:
				self.stopMatch()

	def play(self, event):
		self.clearDashboard()
		self.unRegisterKeyboard()

		if event.keycode == 112:
			self.isPause = 4
			self.startMatch()
			self.machineVSmachine()
		elif event.keycode == 113:
			self.isPause = 5
			self.leftBar.registerKeyboard(self.frame)
			self.startMatch()
			self.machineVShuman()
		elif event.keycode == 114:
			self.isPause = 6
			self.leftBar.registerKeyboard(self.frame)
			self.rightBar.registerKeyboard(self.frame)
			self.startMatch()
			self.humanVShuman()

	def machineVSmachine(self):
		try:
			if self.ball.exists == False:
				self.isQuitRound = 0
			if self.isQuitRound == 0:
				rs = self.ball.move(self.canvas)
				self.leftBar.autoMove(self.canvas)
				self.rightBar.autoMove(self.canvas)

				rs = self.update(rs)
				if rs == 1:
					return ;
			self.canvas_after_1 = self.canvas.after(10, self.machineVSmachine)
		except:
			print("I am so sorry!")
			self.stopMatch(0)

	def machineVShuman(self):
		try:
			if self.ball.exists == False:
				self.isQuitRound = 0

			if self.isQuitRound == 0:
				rs = self.ball.move(self.canvas)
				self.leftBar.move(self.canvas)
				self.rightBar.autoMove(self.canvas)

				rs = self.update(rs)
				if rs == 1:
					return ;
			self.canvas_after_1 = self.canvas.after(10, self.machineVShuman)
		except:
			print("I am so sorry!")
			self.stopMatch(0)

	def humanVShuman(self):
		try:
			if self.ball.exists == False:
				self.isQuitRound = 0
			if self.isQuitRound == 0:
				rs = self.ball.move(self.canvas)
				self.leftBar.move(self.canvas)
				self.rightBar.move(self.canvas)

				rs = self.update(rs)
				if rs == 1:
					return ;
			self.canvas_after_1 = self.canvas.after(10, self.humanVShuman)
		except:
			print("I am so sorry!")
			self.stopMatch(0)

	def startMatch(self):
		self.setScoreBoard()
		self.quitMatch = 0
		self.isQuitRound = 0
		self.countRound = 0
		self.nextRound(1)

	def resetRound(self):
		self.scorePlayerA = 0
		self.scorePlayerB = 0
		self.isQuitRound = 0
		self.updateScorePlayer()
		self.leftBar.registerKeyboard(self.frame)
		self.rightBar.registerKeyboard(self.frame)

	def update(self, status):
		self.updateScorePlayer(status-3)

		self.canvas.update()
		if self.quitRound(status) == 1 and self.quitMatch == 0:
			self.leftBar.unRegisterKeyboard(self.frame)
			self.rightBar.unRegisterKeyboard(self.frame)
			self.canvas_after_2 = self.canvas.after(800, self.nextRound, status)
		if self.quitMatch == 1:
			self.leftBar.unRegisterKeyboard(self.frame)
			self.rightBar.unRegisterKeyboard(self.frame)
			self.isQuitRound == 1
		return self.quitMatch

	def updateScoreRound(self, status):
		if self.scorePlayerB == 0 and self.scorePlayerA == 0:
			return
		if status == 0:
			self.scoreRoundA += 1
			self.canvas.itemconfig("scoreplayera", text=self.scoreRoundA)
		elif status == 1:
			self.scoreRoundB += 1
			self.canvas.itemconfig("scoreplayerb", text=self.scoreRoundB)

	def updateScorePlayer(self, status = 5):
		if status == 0:
			self.scorePlayerA += 1
			self.canvas.itemconfig(self.players[0], text=self.__countScore(self.scorePlayerA))
			if self.scorePlayerA != 0 and self.scorePlayerA % 5 == 0:
				self.ball.speed +=1
		elif status == 1:
			self.scorePlayerB += 1
			self.canvas.itemconfig(self.players[1], text=self.__countScore(self.scorePlayerB))
		elif status == 5:
			self.canvas.itemconfig(self.players[0], text=self.__countScore(self.scorePlayerA))
			self.canvas.itemconfig(self.players[1], text=self.__countScore(self.scorePlayerB))

		self.canvas.update()

	def __countScore(self, score):
		if score < 10:
			scorestr = "00" + str(score);
		elif score < 100:
			scorestr = "0" + str(score)
		else:
			scorestr = str(score)
		return scorestr

	def stopMatch(self, event = 0):
		self.isQuitRound = 1
		self.quitMatch = 1
		self.leftBar.unRegisterKeyboard(self.frame)
		self.rightBar.unRegisterKeyboard(self.frame)
		self.canvas.after_cancel(self.canvas_after_1);
		self.canvas_after_3 = self.canvas.after(500, self.returnMenu)

	def quitGame(self, event):
		self.isQuitRound = 1
		self.quitMatch = 1
		self.leftBar.unRegisterKeyboard(self.frame)
		self.rightBar.unRegisterKeyboard(self.frame)
		self.canvas.after_cancel(self.canvas_after_1);
		self.canvas_after_3 = self.canvas.after(200, self.destroy)

	def destroy(self):
		self.canvas.after_cancel(self.canvas_after_3)
		self.frame.destroy()

	def returnMenu(self):
		self.canvas.after_cancel(self.canvas_after_3)
		self.ball.quit(self.canvas)
		self.leftBar.quit(self.canvas)
		self.rightBar.quit(self.canvas)
		self.clearScoreBoard()
		self.clearWinter()
		self.setDashboard()
		self.registerKeyboard()

	def setMaxRound(self, max):
		self.maxRound = max

	def setMaxRoundScore(self, max):
		self.maxRoundScore = max

	def registerKeyboard(self):
		self.frame.bind("<F1>", self.play)
		self.frame.bind("<F2>", self.play)
		self.frame.bind("<F3>", self.play)
		self.frame.unbind("<Escape>")

	def unRegisterKeyboard(self):
		self.frame.unbind("<F1>")
		self.frame.unbind("<F2>")
		self.frame.unbind("<F3>")
		self.frame.bind("<Escape>", self.stopMatch)

	def on_closing(self):
		self.quitGame(0)
	def pauseGame(self, event):
		if self.isPause == 1:
			self.isPause += 3
			self.machineVSmachine()
		elif self.isPause == 2:
			self.isPause += 3
			self.machineVShuman()
		elif self.isPause == 3:
			self.isPause += 3
			self.humanVShuman()
		elif self.isPause > 3:
			self.canvas.after_cancel(self.canvas_after_1)
			self.isPause -= 3
Пример #45
0
class Game:
    def __init__(self):
        # レベル
        self.level = 1
        # 点数
        self.score = 0
        # 表示速度
        self.speed = 500
        # レベルアップのためのカウンタ用変数
        self.counter = 0
        self.create_new_game = True

        # メインのフレーム
        self.root = Tk()
        self.root.title("Puzzle")
        label_font = ("System", 10)
        # レベルとスコアを表示する文字
        self.status_var = StringVar()
        self.status_var.set("レベル: 1  スコア: 0")
        # レベルとスコアを表示するラベル
        self.status_label = Label(self.root,
                                  textvariable=self.status_var,
                                  font=label_font)
        self.status_label.pack()
        # ブロックを表示するキャンバス
        self.canvas = Canvas(self.root,
                             width=WINDOW_WIDTH,
                             height=WINDOW_HEIGHT)
        self.canvas.pack()
        # キー操作に対応するイベントを登録します
        self.root.bind("<Key>", self.event_handler)

    def event_handler(self, event):
        if event.keysym == "Left":
            self.current_block.move(-1, 0)
        if event.keysym == "Right":
            self.current_block.move(1, 0)
        if event.keysym == "Down":
            self.current_block.move(0, 1)
        if event.keysym == "Up":
            self.current_block.rotate()

    def start(self):
        # タイマー処理を開始します
        self.timer()
        # フレーム表示
        self.root.mainloop()

    def timer(self):
        if self.create_new_game == True:
            # ゲームを開始時点で新しいブロックを作ります
            self.current_block = Block(self.canvas)
            self.create_new_game = False

        if not self.current_block.fall():
            # 画面の下端に到達、または他のブロックに重なったので移動が終了しました
            # そろっているブロックは削除します
            lines = self.remove_complete_lines()
            # 削除しなかった場合、False、削除した場合、削除行数が返ります
            if lines:
                # 削除した行数に応じて、スコアアップ
                # 10 * levelの2乗 * linesの2乗
                self.score += 10 * self.level**2 * lines**2
                # スコアを表示
                self.status_var.set("レベル: %d  スコア: %d" %
                                    (self.level, self.score))

            # 新しいブロックを作成して、画面に表示します
            self.current_block = Block(self.canvas)

            # ゲームオーバーの判定
            if self.is_game_over():
                # ゲームオーバーなので終了処理
                self.create_new_game = True
                self.game_over()

            # ブロックを5個処理するとレベルアップする機能
            self.counter += 1
            if self.counter == 5:
                # レベルアップ
                self.level += 1
                # スピードアップ
                self.speed -= 20
                # レベルアップカウンタを初期化
                self.counter = 0
                # スコアを表示
                self.status_var.set("レベル: %d  スコア: %d" %
                                    (self.level, self.score))

        # self.speedの間隔でself.timerを何度も呼び出す
        self.root.after(self.speed, self.timer)

    # ゲームオーバーの判定
    def is_game_over(self):
        # ブロックが移動することができない場合、ゲームオーバー
        for box in self.current_block.boxes:
            if not self.current_block.can_move_box(box, 0, 1):
                # 移動できないのでゲームオーバー
                return True
        # ゲームは継続
        return False

    # 落下が終了した後に、ボックスがそろっている行があれば、削除します
    def remove_complete_lines(self):
        # 現在の処理対象ボックスの右下角のY座標をリストに代入します
        block_boxes_coords = []
        for box in self.current_block.boxes:
            # coords は[x1, y1, x2, y2]の形式で座標を取得します
            # x1, y1はボックスの左上角、x2とy2は右下角
            block_boxes_coords.append(self.canvas.coords(box)[3])

        # キャンバス内のすべてのオブジェクトを取り出します
        all_boxes = self.canvas.find_all()

        # 全ボックスの右下角のY座標をリストに追加します
        all_boxes_y = []
        for box in all_boxes:
            all_boxes_y.append(self.canvas.coords(box)[3])
        # 全ボックスと座標を合体したリストにします
        zipped = zip(all_boxes, all_boxes_y)

        # 全てのオブジェクトを辞書にします
        # 辞書のキーはオブジェクトID、辞書の値はY座標
        all_boxes_coords = {}
        for d in zipped:
            all_boxes_coords[d[0]] = d[1]

        # setに変換して、重複値を除く
        lines_to_check = set(block_boxes_coords)

        # 現在処理中のブロックのボックスと同じ行のボックスを取り出す
        boxes_to_check = {}
        for k, v in all_boxes_coords.items():
            # 現在のボックスと同じ行のボックスを取り出します
            for line in lines_to_check:
                if v == line:
                    # Y座標が同じであれば同じ行とします
                    boxes_to_check[k] = v
                    break

        # 同じ行にあるボックス数を計算します
        counter = Counter()
        for box in boxes_to_check.values():
            counter[box] += 1

        # 同じ行のボックス数が、「ウィンドウの幅/BOX_SIZE」と同じなら
        # 行がボックスで埋まったことになります
        complete_lines = []
        for k, v in counter.items():
            if v == (WINDOW_WIDTH / BOX_SIZE):
                # 1行がそろったので削除対象の行を追加します
                complete_lines.append(k)

        # 削除する行がない場合、ここで処理は終わり、Falseを返します
        if not complete_lines: return False

        # そろっている行のブロックを削除します
        for k, v in boxes_to_check.items():
            # 対象のブロックが、削除する行に含まれている
            if v in complete_lines:
                # 対象のブロックをキャンバスから消します
                self.canvas.delete(k)
                # 全てのブロックを保持するリストからも消します
                del all_boxes_coords[k]

        # 削除した行の分だけ、全体を下に移動させる
        for (box, coords) in all_boxes_coords.items():
            for line in complete_lines:
                # 削除行した行よりも上に位置するかどうかを判定します
                if coords < line:
                    # 削除した行よりも上なので、ボックスを下方向に移動
                    self.canvas.move(box, 0, BOX_SIZE)
        return len(complete_lines)

    # ゲーム―オーバー処理
    def game_over(self):
        # 全てのオブジェクトを削除
        self.canvas.delete(ALL)
        # メッセージ表示
        messagebox.showinfo("ゲームオーバー", "スコア:%d " % self.score)
        # 画面を閉じる
        self.root.quit()
Пример #46
0
class GPIOSim(Frame):
    #********** Settings *******

    #             ND;     ND;      IN_LOW;    IN_HIGH;  OUT_LOW;   OUT_HIGH;  GPIO_ND;  GPIO_ND
    PIN_COLORS = ["black","black",   "#9ADA90", "green",  "#74C6BD", "blue",  "yellow", "yellow"]

    PIN_SIZE = 15
    PIN_DISTANCE = 10

    START_X = 140
    START_Y = 20


    GPIO_STATE_DEFAULT = [
            0, 0,  #3v3   , 5v
            3, 0,  #GPIO2 , 5V
            3, 0,  #GPIO3 , GND 
            3, 3,  #GPIO4 , GPIO14
            0, 3,  #GND   , GPIO15
            3, 3,  #GPIO17, GPIO18
            3, 0,  #GPIO27, GND
            3, 3,  #GPIO22, GPIO23
            0, 3,  #3V3   , GPIO24
            3, 0,  #GPIO10, GND
            3, 3,  #GPIO9 , GPIO25
            3, 3,  #GPIO11, GPIO8
            0, 3,  #GND   , GPIO7
            0, 0,  #I2C   , I2C     #FROM HERE
            3, 0,  #GPIO5 , GND     #RPI >= B+
            3, 3,  #GPIO6 , GPIO12
            3, 0,  #GPIO13, GND
            3, 3,  #GPIO19, GPIO16
            3, 3,  #GPIO26, GPIO20
            0, 3   #GND   , GPIO21
        ]

    GPIO_NAMES = [
            "3v3","5v",
            "GPIO2","5V",
            "GPIO3","GND",
            "GPIO4","GPIO14",
            "GND","GPIO15",
            "GPIO17","GPIO18",
            "GPIO27","GND",
            "GPIO22","GPIO23",
            "3V3","GPIO24",
            "GPIO10","GND",
            "GPIO9","GPIO25",
            "GPIO11","GPIO8",
            "GND","GPIO7",
            "I2C","I2C",
            "GPIO5","GND",
            "GPIO6","GPIO12",
            "GPIO13","GND",
            "GPIO19","GPIO16",
            "GPIO26","GPIO20",
            "GND","GPIO21"
        ]


    

    BG_COLOR = "white"
    TEXT_COLOR = "black"
    #******** End Settings ********

    WIN_WIDTH = 2*START_X + 2*PIN_SIZE + PIN_DISTANCE
    WIN_HEIGHT = 2*START_Y + 20*PIN_SIZE + 19*PIN_DISTANCE
    
    WIN_SIZE = str(WIN_WIDTH) + "x" + str(WIN_HEIGHT) + "+200+100"

    STATE_ND = 0
    STATE_GPIO_IN = 1
    STATE_GPIO_OUT = 2
    STATE_GPIO_ND = 3

    VALUE_HIGH = 1
    VALUE_LOW = 0

    WORK_DIR = os.path.join(tempfile.gettempdir(), "GPIOSim") #os.path.join(os.path.expanduser('~'), '.GPIOSim') 
    WORK_FILE = os.path.join(WORK_DIR, "pins.ini")

    currState = [None]*40
    currValue = [None]*40

    def __init__(self, parent):
        Frame.__init__(self, parent)   
         


        if not os.path.exists(self.WORK_FILE):
            os.makedirs(self.WORK_DIR)
            self.simulateReboot(True)




        self.parent = parent

        menu = Menu(self.parent)
        menu1 = Menu(menu,tearoff=0)
        menu1.add_command(label="Simulate Reboot",command=self.simulateReboot)
        menu1.add_separator()
        menu1.add_command(label="Quit!", command=self.parent.quit)
        menu.add_cascade(label="Menu",menu=menu1)

        # display the menu
        self.parent.config(menu=menu)

        self.parent.title("GPIOSim")        
        self.pack(fill=BOTH, expand=1)

        self.canvas = None
        self.canvas = Canvas(self, bg=self.BG_COLOR) 
        #self.canvas.bind("<Button-1>",self.click)


        #Images (gif base64 encoded)
        imgInLeft = "R0lGODlhHgASAOf7AAoMCAITBBcQCAYbAAsaEBUYEBEaCRMeCB0ZIREhGRkhFB0gEyMmGiIpFy8mNTQyNiROCCJZACxYCTlUKzpWGyleADBeBjRdGCxiCShlAEFcM0BeKDJmAzpmBCFwADxlIBt1BC9yBGpZW0NpMTtvDzttKkdqPid8AENxHD12DDh5AE9tPEZyJUV2Lzh/AF5rYD5+CEV+Fz+AGFxzT1h4LUx9NUaEAkCGA2dxYUqCEF91V1V8ME+AG0WHADuKCFl/RU+IIT2PG2l8XkqPAEuMJFmFREWTBVCRDzGcAHl6g2yBaEuWADybAEKZDkaaAHCHYnaCgneEeFCcA2WPR0ChB1qaA1ebFnuIbk2gCkSlAFCiAFegAF6fAFehD3ORXmueEXOWT26aQU+qBnCZV1inF3yUboCRhWWmBlmqCnuYa2OqAGGqDGOnJVevAF6tAEi0AG2sAF2vIYyXhomado2Ze1S2BmOyBHKpO1e3AGqxBVy1B1q0GXKwAG6sNEm9AH2tB3WrNYmfc22zAHumX2K4AH+maWO0NW61D2m4En60AHK4AGy6AHm3AIW0AHW2IYKsYoSrbnuzPW22S2u7JXS3NpKzBmDAG5CyGW66OI2ph3G7MIuyP4mteou5AHu/AIOzYXa7QpSpnKajqHu8M4O/AIG+EZy4AHe/K4m+AJytdZW8AIO4XnDCNp+ug429KaGrppG4YX+8dHzDUZnAHZ3CAJ/AJo7FK5O+c5+7cp7CP5jKJ5bIQpvAhqi8ia+6lYfLZ5PPHZrFbKHNDK/HVqnJcqHRPqDSTLvDq7TTN7jGubTLnMbRO8DTQ8TGw7DSjb/UVLDSmMTTZ7rYXbjWeMvVVNPSX8jZQbnfOMjYYcfbU7Xeb9XaTs/abt7XcMLjUMXhe8fficvbwdzV4czncNnb2NThwcnkztXlt+nr6OXy2Ozx9PLx6OP34vnv9e306fzx/vP35vL3+ff2/v/3/fj69//58v/76//6+PH/8/L///799P78//j/9Pb/+vn+//3//CH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAAHgASAAAI/gCJATpFKRIrTM5+YYpEadIoUNBkadLUJ5KhVfDe9cO3b58/doaodEGj5gwaYneQiDmzxgqmW0yy7LHjpgsmd/9y/rs37xwbNdeWIePSB1cXRtuY6VqyKlgVRtaWAXMSC96+fvb0+ZvnDMsfatmKSZF0a4iibNlqMRkEy4grsJua8Lq37x8/fzl5GXE0TtouJJA4IbHV7RmiJp8+MSlWzZuiI8o6/qs7790gJ666YbPVoxeYIbnGRUOUI1WYL7OE0UJDJNy+e/T2xe4HZMkwbtwsgYBGhIyxarXcBOEEBI0qU6SWhEnXzh8/ffvipduBZRq4b2tI+OKxJZEqT06m/hS6kQdVpUQ9xtDj19Gev33lUMTRFm2WlhqZYsAh1anRkDFp3IDHcYec8Mhk/8ADnTkpYHHJJYs4QUMgMnDRCCqL2OCFFzeo0UgnioQwh0f+6KOPOiMYIQiIYnDQCgtPNaJIE0WUQQIXiZRyiAtTrHOPP/nc888KMORBiiB2VBCKCUPkwYgnW5RgRgld8JFIHka0EE49WnWkRAiI5AEHGhnQoYMKbthxiBYdXPGDD3YgWQULydRFD3SvYIAGIWq4oYIQV2QQJx56cIBDGR4sogYhaJAgR0d40XOMBF3ogYYdPawQhQRouKGGHiHoYEYEe7iRRxsWPDFZR/uIs8EQY2KssYYTGkBxgRRdtFFHCjMkAUEbbVzqwQsK5nSPPBvAUMcbeFgRwQsfDFEHHnbkQAEOt77hRxspTICOTjmJIMACCSRgQAEPOAAAAQQEMMABDCAwbgEKHNCAKM2QQw469PwTEAA7"
        imgInRight = "R0lGODlhHgASAOf8ABcOChASDwkZDg8YBxcZCw8dDicUJhcdABkfCxgmBBApABwnDi4kLCsnJjJHICNUBCZUACxdBC5fAD5XKTFgEiRmATZeLUVcOTpiJDhnGStuADZrDzxpFEZlLjVvATxuASl0ADpyAEhpODtzGUxrQEpwHUlwJDp6AVFsXlVwLUp0Ll9rXTaACF5uSzOEADuCAFpzTFJ5LWprdEx+HEWEEkiGBVh3bkaGEzWNADyMClh/PD+NAEeMAESKJjiSEk2MG2GAWVGMLTmYAFqJOkOXAFmKQXCBXUqWAHd8fkmWC22EX1KWDk+aAE2aE0edFUqeBHuEf3iJfEmkAFCiAF6dE1ihAF+gAHmQXkynAGeaPEWqAn2OfHWSbmKfOH+Sc16nBViqCU2vAFCsG4STe2KqAGeoC1SuD2KnLnedVYCXfWynHF6uAFiwAHCpEIaXhWeuAHOrAHmhUmOtII6YdVS1BWavFVa2AIOea2mqQoGgZnCvBGSzB3mvAH+uAGyzC1O8AGuwOG+1AGm3AHGyKGS6AIOyAHm2AG26AHuwOo2jiWm2PHS6Ani3FXa1NYKsa3a3I4G4BX+3GJmjkm65N421BpCpeW69GnG6MIGxX3O7Jma/KJS1C3q+AHm4SG7DAIq7AI63I5W3IHO/QYS2aoO+IZW8AIG6Une9YH3DFnjCN4+6W6CvlpqxlqC/AJvBAJC7ZpbDDYvHDpK8cZe4jpq7a6DBIJ26dbK+JIvIN4vJLpzELprEN4jGd57EUbW4lZbGc6bJPpzIaJnJdpzLXaPMQL7KMqjJjJHVcKvOl7zIsLbNnrfUWsrOYbLQoMXWNMbUTsbVV8vWQNDTVLbZc7/aUcXaQdXOjbnfOMrMycHaWbfeaL/hZcfkNsffbdPfUd/bcMHld9XW4NnjdN/c4dHjxdzfz8ztf+Di38vvtvXm9enr6Oby3/Py6ev26vzz7Or63/b0+Pb2//f61e/76Pb49P/1++77/Pb7/vn/4Pf+8/X/+v/8+/78///+9fn///3/+yH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAAHgASAAAI/gD55fvH7969d50aTRp0yZKqZqIUZboE6FEwZJoUNWI46Vi/ffTu8ZOH6AmZOmDCOOGVSooaPV+0nPklpswaMmuedMGXr94/ffReHcnF7VkkJrRMVanlrNqiJsLOkCkW7VqZM+j+iYTXz1aOTNCi7eLxStURXNKqRUoiCw8WYNCktWnSbF8/fvT+KUvyaJs3YEJOYSJiiVo2UDgcYRKyC9o2Rkl43fP5k9yPKaVuwaKSZRSNMt3EEWuCxlYNUsy+4eIRJx+/ePfcvQvCJFarUmSCVPoBRhe0YVR6GHNRxxy4XkSKzOMHTx/zPDkMtfq0h8adLkcguaJkxYcvD3LA/lmbhmXGun/7/vX754iFn1Kl9rC4gmbHok2G1syoFAMLqmXa1PEBOesZxM8/c4DgSR+UrPECF1fwQEghlIDBQiIlMHFIKKA8McI5BxJ0YDpDuMBIH5xUMYIXOjwRCCWLPGHCLBJ8YUghhyTRgT30fESPa+WYsMQhehjChAppYPAFJ3r4sQMJrECwhiF8vHEECT3x048++eyTzAZMvBGIIDXoEEUGUwQCByEhAJHGB3vooUcYHijBj5b6/KOVGxx8cZMfGnixggdrBLLGGhVsscIJYfjhBxgcSJKXSAYascEea4BhhgRjwEDoGmyAEUEUIuQAxhtsNEFBMiL1E5I+ZOy0UAEddIBBxgNIwPBCSnUcEQEUFzTBxrA1TBDOnXqKxI4DKbBhBx1rPGCDBTXQEQYdS1iAAgRVhPEHGyxg0M6B6owTDjarKJBAAQIgAIABDBwwALsEAMBAAwsQcEACCwQgQ0AAOw=="

        imgOutLeft = "R0lGODlhHgASAOf7AAgiSgYlPA8nNQYrLRUnOhovUxwwRB0yNgA2eiIzPyoxQgA2jh46TR85Wik9Vz44TBM/jARElgdEnSI/gRFEihhEfipBcgBIrQBLpBBFtwBOmhZLkSlJeQBSnABUpQBWrghTxABWwyNPpCBTjRZXlxpWowdZvxRXtABetyVYjBdWzxdbpABgvwBd4ABd5wBg2wRjyhpevwRj0BpexSlawxtc2TFbpBtd0wBk5TFdnwplxQxk2QBn4ThfjxNk6ABtzABs2QBr5gBq9BNrtABr7RhozwFt4jlloU5kdB1o3kllhQpv3QBy3i9rnABz2QBy5Uxjohdwww5x2A9v6wB3zwB070NqjgF5xAB26gB34zRtrgB50QB1/wB74R504wZ76DBv7mVpjwB+6gp77yF16k1vp0NwwQB+/wCC7jx0ygCC9kd2pmJwoCt9w092og6D6lp2lx5/9R6A71N2tgSJ6CB//AiG/z961BaH4E940Fl6oACL/j994COH2j2Bz06AqiaG5gCQ9QCS4xiK+DOG0zaE30CA7gCS/1GBxW5/kwGW9R+O9R+P71GD222BpV6GoAeY8GaFmkmKvzOM7TKP4mCLsACh+TGV4Red74CGqVSQzUiT1TGX+EuS3nyLqlqS1nqOshOn6zOe6nCTqGGUzGWVwSel8EOe5XCVvGiV23GWt0yb/3OWy3WW4kqj62+frHyZyG+e3oaduiiz/nGj0o+bzoKe4Tiz8Uqt+3ai6UWx6mOq+6ehrGGx7IGp5DS+/Ea5/5Wo7pSsyl656kO//zrG4j/F6H2z5V27/DzG/VTB85uyw4G411HH/5a52KW5uH7A/2nN81HV/6jA0nTL/2fQ/2PU+X7P8ZjO4JTN+bzL36fQ7LjL8rDQ4MfNz9HUxNvX0sfj7tLo+N7m7+Tp7OTw5/Px9fL08dr7/vj07Pzy+fv14O73//H3+fr18+P+6P/19u387//2/Pj69/X88fD9/u3/+P/92v/6+fT++f/87f77//j9//j/7v7+9Pz/+yH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAAHgASAAAI/gDzpcM375+8d50GFbpD6dKmbX4MTWrDCE+uYIAA+QFEiRCzfPz87Ztnr1GRJ3WY8MDhyxARI1Kk4ACTa4oUKmdcvODD7hzIf/VouViU7NelGL0+oRCVjBidFrTaOPllbNaYNOL2/RPZz5mKQrqamTLRatOLU9KKyTFxLE+UW8qIXYnC7V7Ifeu6oYjTzBouE6lKgcA0TJooFbbm4MDUDFmdFs7a+VNXz1y5E0AghcKEIw8pHV+oVVsVQlOpF5eiUbsUopW+fPH08UOn5cUgS5CMFIE1REgoV8BmmImlow+0a51gSDo3st6+dH92iBmkKIsJVHNuLFKkCIgWWTGu/mTDtquFlnL89vXTSurEmEGHvnhQhSjEF0GQiNBANeQHp2HIZNGEOPKEhI859QizwBd0MDJGDGvAkkEdgtAxxQeVlFHDFm/Y8cMK4cDzDz3/8NOOOqx4sEUgYwBRghuasCBGF3ssUUItIkhhxxNo6NCEOfT4ww8/BrFjhQdYoPEFFiuM0sMOdnThxQ45vOIBEHiokUUISuTDXD5C+jPOESZ4oUYVMNiQyQZGvEGFGhc8kogEWXxRxRga6KHVOf/Y484+2pAAAxlfZAECFJ5Q8IQaTnCRQSSOXIBFFUt0cQEo6ezTjj377JPPMhTI8MUSQHzghioLtCCHEEJEkAgbdhegMQUQVUAwDZHp4ePPP6BIwIMQVTixQRiZaEDEFlm80EEkSnwgxBNAyFDBN/NoNY9I/CAxwQtGEIEDAnBw0MEORAghwwhKVMBCEEkAgUEK42hFDjjgePOMBQ0ckEABBOgbAAACDDAAAQ8owIABBDjQgAO8BAQAOw=="

        imgOutRight = "R0lGODlhHgASAOf7AAsjMAklQQYnOA8lNxAnPyAoOBosNRowPhUyRAoyfic1OgA4kRw3WCo3RABAmTA9SgNDoydAWRZBiABHnwBGsgtHjRtCkCxCYSREeQBJvgFOoAFNrRZIqQROpx5LeQ5OmgBQvSBQlwBWvRJVlQBWygRZuDBSfAVarAJX0wBbyB1YpQ5btQBd0Q1Z1SdYkwBhuQBhxwBf2xdcywBh4wJi1xhevjRcjBpexSRfnwhlxRtirgBnzB5e1DFfmx9itgBm7yhjnRFowSlmmgBr5hZl4gBs4ABr7SBpowBu1Bhn1Rhozxhn3EpkbUNjjhdsuABu6ABw4gBy0Ddolwpv3QBw8QBy3ght+FRjgCBp5gBx+Q5v5ABz7RBv7DxskgB36wB45RVz2gB64FJoqU1smAR82wB+1Rt21gB94T9wuWFqlAp69gB/6wCA5Td0vAB/+QCA80l1mRN960tytxN/3xZ98ih56DZ51TZ6zwCI5y559x2B6GF1mAaI7gWM3QCM8U55yyCF3i6D0DOA4gCP6iKH2hOI/TGD1xKJ90GCt1x8pmV8mUCB1wCR9ymH6E+Bv1d/vnB8lACV7GKBnC6I8DyH4z6H6l2CyAyX9gCb+TSO6T6N2yOU5m+Go0CQ2ACg+FOM0HeGpEuO13SHq2qLsjOY5X2Jol6Qy3mMpGePwhek4R+g8jKb7nKRrW6SsyKk7GKUz0aZ9Teg7XeU1nGYxUeh6HOax3qYx4SbuGue63ygtW6h2YOfwjOx/Xqg4W2m0ZmdrECx94qf0GKq4GCs74enw0y084Gn8GGx7Di9/4Kq5kq850W/9jzD842v5Ve/+WK891q+/4a240HJ/5a2xYu52VvG+Ke9r6y7zm3K/qW921fR/3jI/mXO/2zN+pLL95TP573J16vP2MfJxqrO69XZyNfZ1s/l7s/s6eDp8ejq59/v9uzx9Pbz+OT67P307ev4///09fb2//D69P32///2/Pb98vH+//r8+f/7+f/+4fX/+v78//j+///+7//+9f3//CH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAAHgASAAAI/gCjCcpESRAgQ82MUcJDiFKlQOM6acpkp9KkT/Lu7fOHb5++d4tazIhTBowRXHViaAEzxQglYzyMTKmzhUYlffs26uPn79ydLbyYIdMSyJcSPcikuYJhSliOPsykbUoyy94+fvXY7cs3LkgZaMuARfmTrAYfZdpi0QiFC4YqacUayaBWb9+/f/T+scsmI8+zaqtmWOrFglS3Z5FQoHpFAhg3Z3RKhOs3758/fpZlFebWTVWKWq9S0OKGrc6NWn+IeErFqIgPcxr9Xd0XD1EOWN22EVqhq00SXsBcUXEyKwkST57wxECjjt/Vuv/aoYkx7Ju3Lyt2HRnCB9MgGnJa/onYEumSHhKO5OHFtxMfOiFmnh1jhOSILR1GLvV5g35WhzOMHBKZKRr9I88+7phzAhKF4AEIC3KMsoEWjEQSRwa2wMFDGIMw4oUDxFylzz/4rCMFDHp4UQgSHwTzAXd8rAHDI4mcAEUcfpzRASo5jfhPPU2I8AUbeBQxQS42LPEGHl8kgQMrKjwxxxterNDFO3nhgw8/kmiwhRtrDKEBJ4ls8AUZYSwRQik97BBHHGqIAIQ6svGDjzu3mBlGFk9swIkiFGThRRhaVCCKGCKEwcYWLLgAzj7w/MPPPddYUAQUVXjBwR6QTDCEFWpMsQArY4BQRKZKVDCNbB7xQw4GaDyAocUPL3QhSQVFIBFGERCAksYHslqBhQOn6MMqP+uYsMETRgyRgwRXjFADFkbQoIEHiiSwRBFFEOEAE/f8c0+4//wSQQQPHIAAAg80MIAAAAwQAAENGEAAAwUowMAF1ohTTjnphBsQADs="
        self.phInLeft = PhotoImage(data=bytes(imgInLeft, 'latin1'))
        self.phInRight = PhotoImage(data=bytes(imgInRight, 'latin1'))
        self.phOutLeft = PhotoImage(data=bytes(imgOutLeft, 'latin1'))
        self.phOutRight = PhotoImage(data=bytes(imgOutRight, 'latin1'))

        self.updateUI()



    # Method that updates the current status, getting info from the file
    # Shall be called on receivment of SIGIUSR (sent by the GPIO class)
    def updateUI(self):
        self.canvas.delete("all")

        c = RawConfigParser()
        c.read(self.WORK_FILE)
            

        x = self.START_X

        y = self.START_Y

        for i in range(0,40):
            state = c.getint("pin"+str(i),"state")
            value = c.getint("pin"+str(i),"value")
            ident = 2*state+value

            self.currState[i] = state
            self.currValue[i]  = value

            e_x = x + self.PIN_SIZE
            e_y = y + self.PIN_SIZE

            self.canvas.create_oval(x, y, e_x, e_y, outline="black", fill=self.PIN_COLORS[ident], width=2, tags='pin'+str(i))

            self.canvas.tag_bind('pin'+str(i),'<Button>', self.click_cb(i) )

        

            if i%2==0: #LEFT COLUMN GPIOS
                self.canvas.create_window(x-70, y+10, window=Label(self.canvas, text=self.GPIO_NAMES[i], fg=self.TEXT_COLOR, bg= self.BG_COLOR)) 

                if ident==2:   #IN_LOW
                    self.canvas.create_window(x - 20, y+8, window=Label(self.canvas, image=self.phInLeft, bd=0))
                    #freccia e cliccabile(?)
                elif ident==3: #IN_HIGH
                    self.canvas.create_window(x - 20, y+8, window=Label(self.canvas, image=self.phInLeft, bd=0))
                    #freccia e cliccabile(?)
                elif state==self.STATE_GPIO_OUT: #OUT
                    self.canvas.create_window(x - 20, y+8, window=Label(self.canvas, image=self.phOutLeft, bd=0))



                x = e_x + self.PIN_DISTANCE
            else: #RIGHT COLUMN GPIOS
                self.canvas.create_window(e_x + 70, y+10, window=Label(self.canvas, text=self.GPIO_NAMES[i], fg=self.TEXT_COLOR, bg= self.BG_COLOR)) 

                

                if ident==2:   #IN_LOW
                    self.canvas.create_window(e_x + 22, y+8, window=Label(self.canvas, image=self.phInRight, bd=0))
                    #freccia e cliccabile(?)
                elif ident==3: #IN_HIGH
                    self.canvas.create_window(e_x + 22, y+8, window=Label(self.canvas, image=self.phInRight, bd=0))
                    #freccia e cliccabile(?)
                elif state==self.STATE_GPIO_OUT: #OUT
                    self.canvas.create_window(e_x + 22, y+8, window=Label(self.canvas, image=self.phOutRight, bd=0))

                


                y = e_y + self.PIN_DISTANCE
                x = self.START_X
        
        
        self.canvas.pack(fill=BOTH, expand=1)

    def updateFile(self):
        c = RawConfigParser()
        c.read(self.WORK_FILE)

        for i in range(0,40):
            c.set("pin"+str(i),"state",str(self.currState[i]))
            c.set("pin"+str(i),"value",str(self.currValue[i]))

        with open(self.WORK_FILE, 'w') as configfile:
            c.write(configfile)

    def simulateReboot(self, new=False):
        c = RawConfigParser()
        c.read(self.WORK_FILE)


        for i in range(0,40):
            if new:
                c.add_section("pin"+str(i))

            c.set("pin"+str(i),"state",str(self.GPIO_STATE_DEFAULT[i]))
            c.set("pin"+str(i),"value", "0")

        with open(self.WORK_FILE, 'w') as configfile:
            c.write(configfile)

        if not new:
            self.updateUI()

    def click_cb(self,x):
        return lambda y: self.click(x)

    def click(self,pin):
        #pin = clicked PIN

        if self.currState[pin]==self.STATE_GPIO_IN:

            self.currValue[pin] = int ( not bool(self.currValue[pin]))

            self.updateFile()

            self.updateUI()
Пример #47
0
class GUI():
    def __init__(self):
        self.root = ThemedTk(theme="radiance")
        INIT_WIDTH, INIT_HEIGHT = self.root.winfo_screenwidth(
        ), self.root.winfo_screenheight()
        boldStyle = ttk.Style()
        boldStyle.configure("Bold.TButton", font=('Sans', '12', 'bold'))
        #icon_loc = os.path.join(os.getcwd(),ICON_NAME)
        #img = ImageTk.PhotoImage(master = self.root, file=icon_loc)
        #self.root.wm_iconbitmap(img)
        #self.root.ttk.call('wm', 'iconphoto', self.root._w, img)
        self.root.title("Form Labeller")
        self.root.maxsize(INIT_WIDTH, INIT_HEIGHT)
        self.supported_formats = SUPPORTED_FORMATS

        self.left_frame = Frame(self.root, width=BUTTON_WIDTH)
        self.top_frame1 = Frame(self.left_frame,
                                width=BUTTON_WIDTH,
                                height=int(INIT_HEIGHT / 2))
        self.top_frame = Frame(self.left_frame,
                               width=BUTTON_WIDTH,
                               height=INIT_HEIGHT - int(INIT_HEIGHT / 2))
        self.bottom_frame = Frame(self.root,
                                  width=INIT_WIDTH - BUTTON_WIDTH,
                                  height=INIT_HEIGHT)

        self.load_image_directory_button = Button(self.top_frame1,
                                                  text='Open Folder',
                                                  command=self.load_directory,
                                                  width=int(BUTTON_WIDTH),
                                                  style="Bold.TButton")
        self.load_image_directory_button.grid(row=OPEN_FOLDER_ROW,
                                              columnspan=2,
                                              sticky=tk.W + tk.E)

        self.prev_img_button = Button(self.top_frame1,
                                      text='← Prev',
                                      command=self.previous_img,
                                      state=tk.DISABLED,
                                      width=int(BUTTON_WIDTH / 2),
                                      style="Bold.TButton")
        self.prev_img_button.grid(row=PREV_ROW, column=0, sticky=tk.W + tk.E)

        self.next_img_button = Button(self.top_frame1,
                                      text='Next → ',
                                      command=self.next_img,
                                      width=int(BUTTON_WIDTH / 2),
                                      style="Bold.TButton")
        self.next_img_button.grid(row=NEXT_COL, column=1, sticky=tk.W + tk.E)

        self.save_image_button = Button(self.top_frame1,
                                        text='Save ',
                                        command=self.saver,
                                        width=int(BUTTON_WIDTH),
                                        style="Bold.TButton")
        self.save_image_button.grid(row=SAVE_ROW,
                                    columnspan=2,
                                    sticky=tk.W + tk.E)

        self.delete_poly_button = Button(self.top_frame,
                                         text='Delete Selected',
                                         command=self.delete_selected,
                                         width=int(BUTTON_WIDTH),
                                         style="Bold.TButton")
        self.delete_poly_button.grid(row=DEL_SELECTED_ROW,
                                     columnspan=2,
                                     sticky=tk.W + tk.E)

        self.type_choices = TYPE_CHOICES
        self.variable = StringVar(self.top_frame)
        self.variable.set(self.type_choices[0])
        self.type_options = OptionMenu(self.top_frame,
                                       self.variable,
                                       *self.type_choices,
                                       style="Bold.TButton")
        self.type_options.config(width=int(BUTTON_WIDTH / 2))
        self.type_options.grid(row=DROP_DOWN_ROW, column=0)

        self.save_type_button = Button(self.top_frame,
                                       text='Save Type',
                                       command=self.save_type,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")
        self.save_type_button.grid(row=SAVE_TYPE_ROW,
                                   column=1,
                                   sticky=tk.W + tk.E)

        self.deselect_all_button = Button(self.top_frame,
                                          text='Deselect All',
                                          command=self.deselect_all,
                                          width=BUTTON_WIDTH,
                                          style="Bold.TButton")
        self.deselect_all_button.grid(row=DESELECT_ALL_ROW,
                                      columnspan=2,
                                      sticky=tk.W + tk.E)

        self.select_all_button = Button(self.top_frame,
                                        text='Select All',
                                        command=self.select_all,
                                        width=BUTTON_WIDTH,
                                        style="Bold.TButton")
        self.select_all_button.grid(row=SELECT_ALL_ROW,
                                    columnspan=2,
                                    sticky=tk.W + tk.E)

        self.draw_poly_button = Button(self.top_frame,
                                       text='Draw Poly',
                                       command=self.draw_poly_func,
                                       width=BUTTON_WIDTH,
                                       style="Bold.TButton")
        self.draw_poly_button.grid(row=DRAW_POLY_ROW,
                                   columnspan=2,
                                   sticky=tk.W + tk.E)

        self.draw_rect_button = Button(self.top_frame,
                                       text='Draw Rectangle',
                                       command=self.draw_rect_func,
                                       width=BUTTON_WIDTH,
                                       style="Bold.TButton")
        self.draw_rect_button.grid(row=DRAW_RECT_ROW,
                                   columnspan=2,
                                   sticky=tk.W + tk.E)

        self.delete_all_button = Button(self.top_frame,
                                        text='Delete All',
                                        command=self.delete_all,
                                        width=BUTTON_WIDTH,
                                        style="Bold.TButton")

        self.save_poly_button = Button(self.top_frame,
                                       text='Save Poly',
                                       command=self.save_drawing,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")

        self.discard_poly_button = Button(self.top_frame,
                                          text='Discard Poly',
                                          command=self.discard_drawing,
                                          width=int(BUTTON_WIDTH / 2),
                                          style="Bold.TButton")

        self.save_rect_button = Button(self.top_frame,
                                       text='Save Rect',
                                       command=self.save_drawing,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")

        self.discard_rect_button = Button(self.top_frame,
                                          text='Discard Rect',
                                          command=self.discard_drawing,
                                          width=int(BUTTON_WIDTH / 2),
                                          style="Bold.TButton")

        self.show_type_button = Button(self.top_frame,
                                       text='Show Type',
                                       command=self.show_type,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")
        self.show_type_button.grid(row=SHOW_TYPE_ROW,
                                   column=0,
                                   columnspan=1,
                                   sticky=tk.W + tk.E)

        self.hide_type_button = Button(self.top_frame,
                                       text='Hide Type',
                                       command=self.hide_type,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")
        self.hide_type_button.grid(row=HIDE_TYPE_ROW,
                                   columnspan=1,
                                   column=1,
                                   sticky=tk.W + tk.E)

        self.make_tight_button = Button(self.top_frame,
                                        text='Make Tight',
                                        command=self.make_tight,
                                        width=int(BUTTON_WIDTH / 2),
                                        style="Bold.TButton")
        self.make_tight_button.grid(row=MAKE_TIGHT_ROW,
                                    columnspan=2,
                                    column=0,
                                    sticky=tk.W + tk.E)

        self.threshold_scale = Scale(self.top_frame,
                                     from_=0,
                                     to=255,
                                     orient=HORIZONTAL,
                                     width=int(BUTTON_WIDTH / 2),
                                     label="Binary Threshold")
        self.threshold_scale.set(128)
        self.threshold_scale.grid(row=THRESHOLD_ROW,
                                  columnspan=2,
                                  column=0,
                                  sticky=tk.W + tk.E)

        self.tight_save_button = Button(self.top_frame,
                                        text='Accept Tight',
                                        command=self.save_tight)

        self.tight_discard_button = Button(self.top_frame,
                                           text='Discard Tight',
                                           command=self.discard_tight)

        self.canvas = Canvas(self.bottom_frame,
                             width=INIT_WIDTH - BUTTON_WIDTH,
                             height=INIT_HEIGHT,
                             borderwidth=1)
        self.image_name = None
        #self.image_path = os.path.join('imgs','img1.jpg')
        self.image_dir = None
        self.images_in_dir = None
        self.curr_idx = None
        self.img_cnv = None
        #self.img_cnv = ImageOnCanvas(self.root,self.canvas,self.image_path)
        self.drawing_obj = None
        self.tight_box_obj = None

        self.left_frame.pack(side=tk.LEFT)
        self.top_frame1.pack(side=tk.TOP)
        self.top_frame.pack(side=tk.BOTTOM)
        self.bottom_frame.pack(side=tk.LEFT)
        max_w, max_h = self.canvas.winfo_screenwidth(
        ), self.canvas.winfo_screenheight()
        self.hbar = Scrollbar(self.bottom_frame, orient=HORIZONTAL)
        self.hbar.pack(side=BOTTOM, fill=X)
        self.hbar.config(command=self.canvas.xview)
        self.vbar = Scrollbar(self.bottom_frame, orient=VERTICAL)
        self.vbar.pack(side=RIGHT, fill=Y)
        self.vbar.config(command=self.canvas.yview)
        max_w, max_h = self.canvas.winfo_width(), self.canvas.winfo_height()
        self.canvas.configure(
            #scrollregion=self.canvas.bbox('all'),
            scrollregion=(0, 0, max_w - BUTTON_WIDTH, max_h),
            yscrollcommand=self.vbar.set,
            xscrollcommand=self.hbar.set)
        self.canvas.pack()
        self.hide_buttons()
        self.load_image_directory_button.config(state="normal")

    def save_tight(self):
        self.tight_box_obj.save_tight_box()
        self.tight_save_button.grid_forget()
        self.tight_discard_button.grid_forget()
        self.make_tight_button.grid(row=MAKE_TIGHT_ROW,
                                    columnspan=2,
                                    sticky=tk.W + tk.E)
        self.show_buttons()
        self.tight_box_obj = None

    def discard_tight(self):
        self.tight_box_obj.discard_tight_box()
        self.tight_save_button.grid_forget()
        self.tight_discard_button.grid_forget()
        self.make_tight_button.grid(row=MAKE_TIGHT_ROW,
                                    columnspan=2,
                                    sticky=tk.W + tk.E)
        self.show_buttons()
        self.tight_box_obj = None

    def show_type(self):
        for poly in self.img_cnv.polygons:
            if poly.select_poly:
                poly.show_type()

    def hide_type(self):
        for poly in self.img_cnv.polygons:
            poly.unshow_type()

    def hide_buttons(self):
        self.load_image_directory_button.config(state=tk.DISABLED)
        self.save_image_button.config(state=tk.DISABLED)
        self.delete_poly_button.config(state=tk.DISABLED)
        self.save_type_button.config(state=tk.DISABLED)
        self.deselect_all_button.config(state=tk.DISABLED)
        self.select_all_button.config(state=tk.DISABLED)
        self.delete_all_button.config(state=tk.DISABLED)
        self.show_type_button.config(state=tk.DISABLED)
        self.hide_type_button.config(state=tk.DISABLED)
        self.make_tight_button.config(state=tk.DISABLED)

    def show_buttons(self):
        self.load_image_directory_button.config(state="normal")
        self.save_image_button.config(state="normal")
        self.delete_poly_button.config(state="normal")
        self.save_type_button.config(state="normal")
        self.deselect_all_button.config(state="normal")
        self.select_all_button.config(state="normal")
        self.delete_all_button.config(state="normal")
        self.show_type_button.config(state="normal")
        self.hide_type_button.config(state="normal")
        self.draw_poly_button.config(state="normal")
        self.draw_rect_button.config(state="normal")
        self.make_tight_button.config(state="normal")

    def select_all(self):
        for poly in self.img_cnv.polygons:
            poly.select_polygon()

    def deselect_all(self):
        self.hide_type()
        for poly in self.img_cnv.polygons:
            poly.deselect_poly()

    def delete_all(self):
        result = messagebox.askyesno("Confirm Delete All",
                                     "Delete All Annotations?")
        if not result:
            return
        self.select_all()
        self.delete_selected()
        #self.img_cnv.polygons_mutex.acquire()
        #for poly in self.img_cnv.polygons:
        #    poly.delete_self()
        #self.img_cnv.polygons_mutex.release()

    def save_type(self):
        selected_option = self.variable.get()
        self.img_cnv.polygons_mutex.acquire()
        for poly in self.img_cnv.polygons:
            if poly.select_poly == True:
                if selected_option == "None":
                    poly.poly_type = None
                else:
                    poly.poly_type = selected_option
                #poly.unshow_type()
                #poly.show_type()
        self.img_cnv.polygons_mutex.release()
        self.variable.set(self.type_choices[0])
        #self.deselect_all()

    def load_new_img(self):
        self.canvas.delete('all')
        self.img_cnv = None
        path = os.path.join(self.image_dir, self.image_name)
        self.img_cnv = ImageOnCanvas(self.root, self.bottom_frame, self.canvas,
                                     path)
        logger("LOADED: " + self.img_cnv.image_path)

    def load_directory(self):
        while True:
            selection = filedialog.askdirectory()
            if selection == () or selection == '':
                return
            self.root.directory = selection
            self.image_dir = self.root.directory
            file_names = os.listdir(self.image_dir)
            self.images_in_dir = []
            self.curr_idx = None
            self.image_name = None
            for name in file_names:
                if name.split('.')[-1] in self.supported_formats:
                    self.images_in_dir.append(name)
            if len(self.images_in_dir) == 0:
                self.pop_up("No supported images in the selected directory")
            else:
                break
        self.show_buttons()
        self.next_img()

    def pop_up(self, text):
        top = Toplevel()
        top.title("ERROR")
        msg = Message(top, text=text)
        msg.pack()
        button = Button(top, text="Dismiss", command=top.destroy)
        button.pack()

    def next_img(self):
        if self.curr_idx == None:
            self.curr_idx = -1
        self.curr_idx = self.curr_idx + 1
        if self.curr_idx >= len(self.images_in_dir):
            self.pop_up("Done with Images in this directory")
            self.curr_idx = self.curr_idx - 1
            return
        if self.curr_idx > 0:
            self.prev_img_button.config(state="normal")
        self.image_name = self.images_in_dir[self.curr_idx]
        self.load_new_img()
        self.root.title("Form Labeller - " + self.image_name + "(" +
                        str(self.curr_idx + 1) + "/" +
                        str(len(self.images_in_dir)) + ")")

    def previous_img(self):
        if self.curr_idx == 1:
            self.curr_idx = -1
            self.prev_img_button.config(state=tk.DISABLED)
        else:
            self.curr_idx = self.curr_idx - 2
        self.next_img()

    def delete_selected(self):
        to_be_deleted = []
        for i, poly in enumerate(self.img_cnv.polygons):
            if poly.select_poly == True:
                poly.delete_self()
                to_be_deleted.append(i)
        j = 0
        for idx in to_be_deleted:
            self.img_cnv.polygons.pop(idx - j)
            self.img_cnv.bbs.pop(idx - j)
            self.img_cnv.poly_type.pop(idx - j)
            j = j + 1

    def start_gui(self):
        self.root.mainloop()

    def saver(self):
        logger("Saving: " + self.img_cnv.image_path)
        self.save_image_button.config(state=tk.DISABLED)
        self.img_cnv.save_json(self.root.directory)
        self.save_image_button.config(state="normal")

    def draw_poly_func(self):
        self.deselect_all()
        self.img_cnv.drawing_polygon = True
        self.draw_poly_button.grid_forget()
        self.save_poly_button.grid(row=DRAW_POLY_ROW,
                                   column=0,
                                   sticky=tk.W + tk.E)
        self.discard_poly_button.grid(row=DRAW_POLY_ROW,
                                      column=1,
                                      sticky=tk.W + tk.E)
        self.hide_buttons()
        self.draw_rect_button.config(state=tk.DISABLED)
        self.drawing_obj = DrawPoly(self.bottom_frame, self.canvas,
                                    self.img_cnv, RADIUS)

    def draw_rect_func(self):
        self.deselect_all()
        self.img_cnv.drawing_polygon = True
        self.draw_rect_button.grid_forget()
        self.save_rect_button.grid(row=DRAW_RECT_ROW,
                                   column=0,
                                   sticky=tk.W + tk.E)
        self.discard_rect_button.grid(row=DRAW_RECT_ROW,
                                      column=1,
                                      sticky=tk.W + tk.E)
        self.hide_buttons()
        self.draw_poly_button.config(state=tk.DISABLED)
        self.drawing_obj = DrawRect(self.bottom_frame, self.canvas,
                                    self.img_cnv, RADIUS)

    def save_drawing(self):
        self.show_buttons()
        self.img_cnv.drawing_polygon = False
        new_poly_pts = self.drawing_obj.pt_coords
        print("Trying to save polygon with pts:", str(new_poly_pts))
        for pt in self.drawing_obj.points:
            self.canvas.delete(pt)
        if self.img_cnv.scale_factor != None:
            for i in range(len(new_poly_pts)):
                for j in range(2):
                    new_poly_pts[i][
                        j] = new_poly_pts[i][j] / self.img_cnv.scale_factor
        self.img_cnv.add_poly(new_poly_pts)
        #self.img_cnv.bbs.append(new_poly_pts)
        #self.img_cnv.draw_bbs([self.img_cnv.bbs[-1]])
        #debug (1, str(type(self.drawing_obj)))
        if isinstance(self.drawing_obj, DrawRect):
            self.save_rect_button.grid_forget()
            self.discard_rect_button.grid_forget()
            self.draw_rect_button.grid(row=DRAW_RECT_ROW,
                                       columnspan=2,
                                       sticky=tk.W + tk.E)
        elif isinstance(self.drawing_obj, DrawPoly):
            self.save_poly_button.grid_forget()
            self.discard_poly_button.grid_forget()
            self.draw_poly_button.grid(row=DRAW_POLY_ROW,
                                       columnspan=2,
                                       sticky=tk.W + tk.E)
        self.drawing_obj.delete_self()
        self.drawing_obj = None

    def discard_drawing(self):
        self.show_buttons()
        self.img_cnv.drawing_polygon = False
        #for pt in self.drawing_obj.points:
        #    self.canvas.delete(pt)
        self.drawing_obj.delete_self()
        if isinstance(self.drawing_obj, DrawRect):
            self.save_rect_button.grid_forget()
            self.discard_rect_button.grid_forget()
            self.draw_rect_button.grid(row=DRAW_RECT_ROW,
                                       columnspan=2,
                                       sticky=tk.W + tk.E)
        elif isinstance(self.drawing_obj, DrawPoly):
            self.save_poly_button.grid_forget()
            self.discard_poly_button.grid_forget()
            self.draw_poly_button.grid(row=DRAW_POLY_ROW,
                                       columnspan=2,
                                       sticky=tk.W + tk.E)
        self.drawing_obj = None

    def make_tight(self):
        self.hide_buttons()
        self.tight_box_obj = TightBox(self.root, self.img_cnv,
                                      self.threshold_scale.get())
        self.tight_box_obj.tight_box()
        self.make_tight_button.grid_forget()
        self.tight_save_button.grid(row=MAKE_TIGHT_ROW,
                                    column=0,
                                    columnspan=1,
                                    sticky=tk.W + tk.E)
        self.tight_discard_button.grid(row=MAKE_TIGHT_ROW,
                                       column=1,
                                       columnspan=1,
                                       sticky=tk.W + tk.E)
Пример #48
0
class text_canvas(Frame):

    def __init__(self, parent, font_size, input_handler, filename):
        Frame.__init__(self, parent)
        self.parent = parent
        self.text_font = tkFont.Font(
            family='Monaco', size=font_size, weight='bold'
        )
        self.filename = filename
        self.cheight, self.cwidth = font_size, self.text_font.measure('c')
        self.line_num_spacing = 50
        self.line_height = (
            (self.winfo_screenheight() - self.cheight)//(self.cheight + 2) - 4
        )
        self.init_UI(input_handler)

    def init_UI(self, input_handler):
        self.parent.title('')
        self.pack(fill=BOTH, expand=1)
        self.init_canvas(input_handler)

    def get_dimensions(self):
        """
        Getting the dimensions might be helpful
        for plugin writers
        """
        return {
            'cheight': self.cheight,
            'cwidth': self.cwidth,
            'line_num_spacing': self.line_num_spacing,
            'line_height': self.line_height,
            'screen_width': self.winfo_screenwidth(),
            'screen_height': self.winfo_screenheight()
        }

    def init_canvas(self, input_handler):
        self.canvas = Canvas(
            self, highlightthickness=0, width=self.winfo_screenwidth(),
            height=self.winfo_screenheight(), bg=options['background_color']
        )
        self.canvas.pack()
        self.canvas.focus_set()
        self.bind_events(input_handler)

    def clear_all(self):
        self.canvas.delete('all')

    def get_line_height(self):
        """
        return number of lines per page
        """
        return self.line_height

    def get_grid_y(self, y):
        """
        return character height * y
        in addition distane of the spaces inbetwen
        """
        return self.cheight * y + (y * 2)

    def write_line_grid(self, y, line):
        """
        Write to line of text on grid using tokens passed in
        """
        for token in line:
            self.write_text_grid(token[0], y, token[1], token[2])

    def write_text_grid(self, x, y, text, color=options['text_color']):
        """
        Write text to x, y location on grid
        """
        x_val = self.cwidth * x + self.line_num_spacing
        y_val = self.cheight * y + (y * 2)  # 2 pixel spacing between each line
        self.canvas.create_text(
            x_val, y_val, anchor='nw', text=text,
            font=self.text_font, fill=color
        )

    def write_status_line(
        self, text, textcolor=options['status_text_color'],
        backgroundcolor=options['status_background_color']
    ):
        """
        Writen a line of text to status line
        this function could take in different data if desired
        """
        y = self.line_height + 1
        self.canvas.create_rectangle(
            0, self.cheight * y + (y * 2), self.winfo_screenwidth(),
            self.cheight * y + (y * 2) + self.cheight + 4,
            fill=backgroundcolor, outline=backgroundcolor
        )
        self.write_text_grid(0, self.line_height + 1, text, textcolor)

    def draw_highlight_grid(
        self, y, x1, x2,
        highlightcolor=options['text_highlight_color']
    ):
        """
        Draw highlights onto text canvas
        i.e selections during visual mode
        """
        y_val = self.cheight * y + (y * 2)
        x1_val = self.cwidth * x1 + self.line_num_spacing
        x2_val = self.cwidth * x2 + self.line_num_spacing
        self.canvas.create_rectangle(
            x1_val, y_val, x2_val, y_val + self.cheight + 4,
            fill=highlightcolor, outline=highlightcolor
        )

    def draw_line_numbers(
        self, start,
        highlightcolor=options['line_num_highlight_color'],
        textcolor=options['line_num_text_color']
    ):
        self.canvas.create_rectangle(
            0, 0, self.line_num_spacing / 2,
            self.winfo_screenheight(),
            fill=highlightcolor, outline=highlightcolor
        )
        for i in range(self.line_height + 1):
            self.canvas.create_text(
                0, self.cheight * i + (i * 2), anchor='nw',
                text=str(start + i), font=self.text_font,
                fill=textcolor
            )

    def draw_cursor(
        self, x, y,
        highlightcolor=options['cursor_highlight_color'],
        cursorcolor=options['cursor_color']
    ):
        """
        draw cursor as well as line and column highlights
        TODO: users should have the option to disable line
        and column highlights
        """
        x_val = self.cwidth * x + self.line_num_spacing
        y_val = self.cheight * y + (y * 2)

        self.canvas.create_rectangle(
            0, y_val, self.winfo_screenwidth(),
            y_val + self.cheight + 4,
            fill=highlightcolor, outline=highlightcolor
        )
        self.canvas.create_rectangle(
            x_val, 0, x_val + self.cwidth,
            self.winfo_screenheight(), fill=highlightcolor,
            outline=highlightcolor
        )
        self.canvas.create_rectangle(
            x_val, y_val, x_val + self.cwidth,
            y_val + self.cheight + 4,
            fill=cursorcolor, outline=cursorcolor
        )

    def draw_rectangle_absolute(
        self, x1, y1, x2, y2, color
    ):
        """
        draw rectangle onto screen
        TODO: flesh out what this function should actually
        look like
        """
        self.canvas.create_rectangle(
            x1, y1, x2, y2,
            fill=color, outline=color
        )

    def bind_events(self, input_handler):
        """
        bind events for use in input_handler
        TODO: this should be cleaned up ideally into a separate handler list
        """
        input_handler.set_GUI_reference(self)
        self.canvas.bind('<Key>', input_handler.key)
        self.canvas.bind_all('<Escape>', input_handler.escape)
        self.canvas.bind_all('<Control-a>', input_handler.control_a)
        self.canvas.bind_all('<Control-b>', input_handler.control_b)
        self.canvas.bind_all('<Control-c>', input_handler.control_c)
        self.canvas.bind_all('<Control-d>', input_handler.control_d)
        self.canvas.bind_all('<Control-e>', input_handler.control_e)
        self.canvas.bind_all('<Control-f>', input_handler.control_f)
        self.canvas.bind_all('<Control-g>', input_handler.control_g)
        self.canvas.bind_all('<Control-h>', input_handler.control_h)
        self.canvas.bind_all('<Control-i>', input_handler.control_i)
        self.canvas.bind_all('<Control-j>', input_handler.control_j)
        self.canvas.bind_all('<Control-k>', input_handler.control_k)
        self.canvas.bind_all('<Control-l>', input_handler.control_l)
        self.canvas.bind_all('<Control-m>', input_handler.control_m)
        self.canvas.bind_all('<Control-n>', input_handler.control_n)
        self.canvas.bind_all('<Control-o>', input_handler.control_o)
        self.canvas.bind_all('<Control-p>', input_handler.control_p)
        self.canvas.bind_all('<Control-q>', input_handler.control_q)
        self.canvas.bind_all('<Control-r>', input_handler.control_r)
        self.canvas.bind_all('<Control-s>', input_handler.control_s)
        self.canvas.bind_all('<Control-t>', input_handler.control_t)
        self.canvas.bind_all('<Control-u>', input_handler.control_u)
        self.canvas.bind_all('<Control-v>', input_handler.control_v)
        self.canvas.bind_all('<Control-w>', input_handler.control_w)
        self.canvas.bind_all('<Control-x>', input_handler.control_x)
        self.canvas.bind_all('<Control-y>', input_handler.control_y)
        self.canvas.bind_all('<Control-z>', input_handler.control_z)
        self.canvas.bind_all("<MouseWheel>", input_handler.mouse_scroll)
        self.canvas.bind_all(
            '<Control-braceright>', input_handler.control_braceright
        )
        self.canvas.bind_all(
            '<Control-braceleft>', input_handler.control_braceleft
        )
Пример #49
0
class Visual(Frame):
    '''Class that takes a world as argument and present it graphically
    on a tkinter canvas.'''

    def __init__(self):
        '''
        Sets up a simulation GUI in tkinter.
        '''
        Frame.__init__(self)
        self.master.title("The Schelling Segregation Model in Python")
        self.master.wm_resizable(0, 0)
        self.grid()
        self.movement_possible = True

        # --------------------------------------- #
        # --------- FRAMES FOR GUI -------------- #
        # --------------------------------------- #

        # The pane for user values
        self._entryPane = Frame(self,
                                borderwidth=5,
                                relief='sunken')
        self._entryPane.grid(row=0, column=0, sticky='n')

        # The buttons pane
        self._buttonPane = Frame(self, borderwidth=5)
        self._buttonPane.grid(row=1, column=0, sticky='n')

        # A temp pane where graph is located, just for cosmetic reasons
        width, height = 425, 350
        self._graph = Canvas(self,
                             width=width,
                             height=height,
                             background="black")
        self._graph.configure(relief='sunken', border=2)
        self._graph.grid(row=3, column=0)

        # The pane where the canvas is located
        self._animationPane = Frame(self,
                                    borderwidth=5,
                                    relief='sunken')
        self._animationPane.grid(row=0, column=1,
                                 rowspan=4, pady=10,
                                 sticky="n")

        # --------------------------------------- #
        # --------- FILLING THE FRAMES ---------- #
        # --------------------------------------- #

        self._canvas()      # Create graphics canvas
        self._entry()       # Create entry widgets
        self._buttons()     # Create button widgets

    def _plot_setup(self, time):
        '''Method for crudely annotating the graph window.'''
        time = time

        # Main plot
        width, height = 425, 350
        y0 = -time/10
        self._graph = Canvas(self, width=width,
                             height=height,
                             background="black",
                             borderwidth=5)
        self._graph.grid(row=3, column=0)
        self.trans = Plotcoords(width, height, y0, -0.2, time, 1.3)

        x, y = self.trans.screen(time // 2, 1.2)
        x1, y1 = self.trans.screen(time // 2, 1.13)
        self._graph.create_text(x, y,
                                text="% Happy",
                                fill="green",
                                font="bold 12")
        
        self._graph.create_text(x1, y1,
                                text="% Unhappy",
                                fill="red",
                                font="bold 12")
 
        # Line x-axis
        x, y = self.trans.screen((-5 * (time / 100)), -0.05)
        x1, y = self.trans.screen(time, -0.05)
        self._graph.create_line(x, y, x1, y, fill="white", width=1.5)
         
        # Text x-axis
        x_text, y_text = self.trans.screen(time / 2, -0.15)
        self._graph.create_text(x_text, y_text,
                                text="Time",
                                fill="white",
                                font="bold 12")

        # Line y-axis
        x, y = self.trans.screen((-0.5 * (time / 100)), -0.05)
        x, y1 = self.trans.screen((-5 * (time / 100)), 1)
        self._graph.create_line(x, y, x, y1, fill="white", width=1.5)
 
    def _entry(self):
        '''Method for creating widgets for collecting user input.'''
         
        # N (no of turtles)
        dim = 30*30

        self.fill_label = Label(self._entryPane,
                                anchor='w',
                                justify='left',
                                text='Fill',
                                relief='raised',
                                width=12,
                                height=1,
                                font='italic 20')
        
        self.fill_label.grid(row=0, column=1, ipady=14)

        self.fill = Scale(self._entryPane,
                          from_=0,
                          to=1,
                          resolution=0.01,
                          bd=3,
                          relief='sunken',
                          orient='horizontal',
                          length=235,
                          tickinterval=20)
        self.fill.grid(row=0, column=2)
        self.fill.set(0.8)
                           
        self._N_label = Label(self._entryPane,
                              anchor='w',
                              justify='left',
                              text="N:",
                              relief='raised',
                              width=12,
                              height=1,
                              font="italic 20")
        self._N_label.grid(row=1, column=1, ipady=14)

        self._N = Scale(self._entryPane,
                        from_=0,
                        to=100,
                        resolution=1,
                        bd=3,
                        relief='sunken',
                        orient='horizontal',
                        length=235,
                        tickinterval=20)
        self._N.set(30)
        self._N.grid(row=1, column=2)

        # Ticks (length of simulation)
        self._Ticks_label = Label(self._entryPane,
                                  anchor='w',
                                  justify='left',
                                  text="Time:",
                                  relief='raised',
                                  width=12,
                                  height=1,
                                  font="bold 20")
        self._Ticks_label.grid(row=2, column=1, ipady=14)
 
        self._Ticks = Scale(self._entryPane,
                            from_=10,
                            to=1000,
                            resolution=1,
                            bd=3,
                            relief='sunken',
                            orient='horizontal',
                            length=235,
                            tickinterval=990)
        self._Ticks.set(500)
        self._Ticks.grid(row=2, column=2)
 
        # % similar wanted
        self._Similar_label = Label(self._entryPane,
                                    anchor='w',
                                    justify='left',
                                    text="Similar wanted:",
                                    relief='raised',
                                    width=12,
                                    height=1,
                                    font="bold 20")
         
        self._Similar_label.grid(row=3, column=1, ipady=14)
 
        self._Similar = Scale(self._entryPane,
                              from_=0.0,
                              to=1.0,
                              resolution=0.01,
                              bd=3,
                              relief='sunken',
                              orient='horizontal',
                              length=235,
                              tickinterval=0.5)
        self._Similar.set(0.76)
        self._Similar.grid(row=3, column=2)

        # Delay between steps
        self._delay_label = Label(self._entryPane,
                                  anchor='w',
                                  justify='left',
                                  text="Delay (s):",
                                  relief='raised',
                                  width=12,
                                  height=1,
                                  font="bold 20")
         
        self._delay_label.grid(row=4, column=1, ipady=14)
 
        self._delay = Scale(self._entryPane,
                            from_=0.0,
                            to=1.0,
                            resolution=0.01,
                            bd=3,
                            relief='sunken',
                            orient='horizontal',
                            length=235,
                            tickinterval=0.5)
        self._delay.set(0.15)
        self._delay.grid(row=4, column=2)

    def _buttons(self):
        '''Method for creating button widgets for setting up,
        running and plotting results from simulation.'''
        width = 7
        height = 1

        # The 'Setup' button
        self._setupButton = Button(self._buttonPane,
                                   text="Setup",
                                   command=self._setup,
                                   width=width,
                                   height=height,
                                   font="bold 30",
                                   relief='raised',
                                   borderwidth=5)
        self._setupButton.grid(row=0, column=0)

        # The 'Go' button
        self._goButton = Button(self._buttonPane,
                                text="Go",
                                command=self._go,
                                width=width,
                                height=height,
                                font="bold 30",
                                relief='raised',
                                borderwidth=5)
        self._goButton.grid(row=0, column=1)

        # The 'Quit' button
        self._quitButton = Button(self._buttonPane,
                                  text="Quit",
                                  command=self._quit,
                                  width=width,
                                  height=height,
                                  font="bold 30",
                                  relief='raised',
                                  borderwidth=5)
        self._quitButton.grid(row=1, column=0, columnspan=2)

    def _canvas(self):
        '''Creates the canvas on which everything happens.'''
        # The tick counter information
        self._Tick_counter = Label(self._animationPane,
                                   anchor='w',
                                   justify='left',
                                   text="Time:",
                                   width=5,
                                   font="bold 20")
        self._Tick_counter.grid(row=0, column=0, sticky="e")
        self._Tick_counter1 = Label(self._animationPane,
                                    justify='center',
                                    text="",
                                    relief='raised',
                                    width=5,
                                    font="bold 20")
        self._Tick_counter1.grid(row=0, column=1, sticky='w')
        self.canvas_w, self.canvas_h = 750, 750
        self.canvas = Canvas(self._animationPane,
                             width=self.canvas_w,
                             height=self.canvas_h,
                             background="black")

        self.canvas.grid(row=1, column=0, columnspan=2)

    def _setup(self):
        '''Method for 'Setup' button.'''
        # Clearing the canvas and reset the go button
        self.canvas.delete('all')
        self._goButton['relief'] = 'raised'
        self.N = int(self._N.get())
        self.Ticks = int(self._Ticks.get())
        self.similar = float(self._Similar.get())
        self.data = []
        self.tick_counter = 0
        self._Tick_counter1['text'] = str(self.tick_counter)
        self._plot_setup(self.Ticks)
        self.grid_size = self.N
        self.world = World(750, 750, self.grid_size)
        self.create_turtles()
        self.neighbouring_turtles()
        self.draw_turtles()

    def _go(self):
        '''Method for the 'Go' button, i.e. running the simulation.'''
        self._goButton['relief'] = 'sunken'
        if self.tick_counter <= self.Ticks:
            self._Tick_counter1['text'] = str(self.tick_counter)
            self.canvas.update()

            self._graph.update()
            self._graph.after(0)

            # Data collection
            turtles_unhappy = self.check_satisfaction()
            prop_happy, prop_unhappy = self.calc_prop_happy(self.tick_counter)

            self.data_collection(self.tick_counter, prop_happy, prop_unhappy)

            if self.tick_counter >= 1:

                # HAPPY values (%)
                x0 = self.tick_counter-1
                x1 = self.tick_counter

                # Collecting values from stored data
                y0 = self.data[self.tick_counter-1][1]
                y1 = self.data[self.tick_counter][1]

                # Transforming to tkinter
                x1, y1 = self.trans.screen(x1, y1)
                x0, y0 = self.trans.screen(x0, y0)
                self._graph.create_line(x0, y0, x1, y1,
                                        fill="green", width=1.3,
                                        tag="happy")  # Draw "happy lines

                # UNHAPPY values (%)
                x0 = self.tick_counter-1
                x1 = self.tick_counter

                # Collecting values from stored data
                y0 = self.data[self.tick_counter-1][2]
                y1 = self.data[self.tick_counter][2]

                # Transforming to tkinter
                x1, y1 = self.trans.screen(x1, y1)
                x0, y0 = self.trans.screen(x0, y0)
                self._graph.create_line(x0, y0, x1, y1,
                                        fill="red", width=1.1,
                                        tag="unhappy")  # Draw unhappy lines
             
            if prop_happy < 1:
                self.turtle_move(turtles_unhappy)
                time.sleep(self._delay.get())
                self.update_neighbours()
                self.tick_counter += 1
                self.canvas.after(0, self._go())

        self._goButton['relief'] = 'raised'

    def _quit(self):
        '''Method for the 'Quit' button.'''
        self.master.destroy()

    # ------------------------------------------------------ #
    # ---------- FUNCTIONS CALLED AT EACH TICK ------------- #
    # ------------------------------------------------------ #

    def turtle_move(self, unhappy_turtles):
        '''Moves all the unhappy turtles (randomly).'''
         
        while unhappy_turtles:
            i = random.randint(0, len(unhappy_turtles)-1)
            turtle = unhappy_turtles.pop(i)
            turtle.move(self)

    def update_neighbours(self):
        '''Updates the turtles neigbour attributes. Called
        after all turtles have moved.'''
        for turtle in self.turtles:
            turtle.update_neighbours()

    def check_satisfaction(self):
        '''Checks to see if turtles are happy or not.
        Returns a list of unhappy turtles, i.e. turtles
        that should move.

        Called before the move method.'''

        for turtle in self.turtles:
            turtle.is_happy()

        unhappy_turtles = []
        for element in self.turtles:
            if not element.happy:
                unhappy_turtles.append(element)

        return unhappy_turtles

    def calc_prop_happy(self, i):
        '''Calculates the proportion of happy turtles.'''
        happy = 0
        unhappy = 0

        for turtle in self.turtles:
            if turtle.happy:
                happy += 1
            else:
                unhappy += 1
        prop_happy = happy/len(self.turtles)
        prop_unhappy = unhappy/len(self.turtles)

        return prop_happy, prop_unhappy

    def data_collection(self, i, prop_happy, prop_unhappy):
        '''Method for collecting data at each tick.'''
        self.data.append((i, prop_happy, prop_unhappy))


# ------------------------------------------------------ #
# ---------- INITIALISATION FUNCTIONS ------------------ #
# ------------------------------------------------------ #

    def create_turtles(self):
        '''Method for creating a new list of turtles.

        Upon creation they are registered in the World object.'''
        if self.N*self.N <= self.grid_size*self.grid_size:
            counter = 0
            self.turtles = []
            while counter < self.N * self.N * self.fill.get():
                             
                s = "S"+str(counter)
                if counter <= int(self.N * self.N * self.fill.get() / 2):
                    color = "green"
                else:
                    color = "red"

                x = random.randint(0, self.grid_size-1)
                y = random.randint(0, self.grid_size-1)

                if not self.world.patch_list[x][y]:
                    new_turtle = Schelling(world=self.world,
                                           x=x,
                                           y=y,
                                           s=s,
                                           color=color,
                                           similar_wanted=self.similar)

                    self.world.register(new_turtle)
                    counter += 1
                    self.turtles.append(new_turtle)
        else:
            print("Number of turtles exceeds world!")

    def draw_turtles(self):
        '''Method for drawing turtles on canvas.

           Calls each turtle's own method for drawing.'''
        for turtle in self.turtles:
            turtle.draw(self.canvas)
 
    def neighbouring_turtles(self):
        '''Method for updating turtles' neighbours.

           Calls on each turtle's own method for updating neighbours.'''
        for turtle in self.turtles:
            turtle.get_neighbouring_patches()
Пример #50
0
def Classes(sbjBook, string):

	from tkinter import Tk
	from tkinter import Canvas
	import os

	master = Tk()

	w=1240
	h=1754
	m=120

	c = Canvas(master, width=1240, height=1754)
	c.pack()

	c.create_rectangle(0, 0, w, h, fill="#fff", outline="#fff")

	c.create_rectangle(m, 60, w-m, 180, fill="#9bbb59", outline="#cadba6")
	c.create_text(m+60, 90, fill="#fff", font=("Ubuntu","12", "bold") , text="SUBJECT")
	c.create_text(m+170, 90, fill="#fff", font=("Ubuntu","12", "bold") , text="CLASS")
	c.create_text(m+420, 90, fill="#fff", font=("Ubuntu","12", "bold") , text="SCHEDULE")
	c.create_text(m+720, 90, fill="#fff", font=("Ubuntu","12", "bold") , text="PROFESSOR")
	c.create_text(m+920, 90, fill="#fff", font=("Ubuntu","12", "bold") , text="OFFERED AS")	

	for i in range(13):
		c.create_rectangle(m, m+120*i, w-m, m+120*i+60, fill="#ebf1de", outline="#cadba6")
		c.create_rectangle(m, m+120*i+60, w-m, m+120*i+120, fill="#fff", outline="#cadba6")

	count = -1
	page = 0
	for i in sbjBook:
		if(i == -1):
			pass
		else:
			classroom = -1
			sameSche = [[],[],[]]
			scheRecord = [[],[],[]]
			for j in range(len(sbjBook[i])):
				classroom += 1
				count += 1
				period = sbjBook[i][j][1]
				hpw = sbjBook[i][j][2]
				professor = sbjBook[i][j][3]
				group = sbjBook[i][j][4]
				if(group==None):
					group = 'Elective'
				else:
					course_id = int(group/5)
					b26 = ''
					d = int(1)
					while(d<course_id):
						d = int(d*26)
					if(d>=26):d = int(d/26)
					else: pass
					while(d>=1):
						b26 = b26+chr(int(course_id/d) + ord('A'))
						course_id = course_id % d
						d = d/26
					group = str(group+1)+'-Year required subject\nfor course '+b26
				sche = sbjBook[i][j][5:]
		
				if(sche in scheRecord[period]):
					class_id = scheRecord[period].index(sche)
					class_idBK = scheRecord[period].index(sche)
					sameSche[period][class_id][0] += 1
				else:
					scheRecord[period].append(sche)
					sameSche[period].append([0])
					class_id = scheRecord[period].index(sche)
					class_idBK = scheRecord[period].index(sche)
			
				schedule = ""
				for k in sche:
					if(schedule==""):pass
					else: schedule = schedule + "\n"
				
					weekday = int((k+1)/2) + (k+1)%2
					if(weekday==1): weekday = 'Monday '
					elif(weekday==2): weekday = 'Tuesday '
					elif(weekday==3): weekday = 'Wednesday '
					elif(weekday==4): weekday = 'Thursday '
					else: weekday = 'Friday '
				
					if(k%2==0 and period==0): hour = "from 8:00 am to 10:00 am"
					elif(k%2==0 and period==1): hour = "from 2:00 pm to 4:00 pm"
					elif(k%2==0 and period==2): hour = "from 7:00 pm to 9:00 pm"
					elif(k%2==1 and period==0): hour = "from 10:00 am to 12:00 pm"
					elif(k%2==1 and period==1): hour = "from 4:00 pm to 6:00 pm"
					elif(k%2==1 and period==2): hour = "from 9:00 pm to 11:00 pm"
					
					try: schedule = schedule + weekday + hour
					except: print(k,period); raise
			
				b26 = ''
				div = int(1)
				while(div<class_id):
					div = int(div*26)
				if(div>=26):div = int(div/26)
				else: pass
				while(div>=1):
					b26 = b26+chr(int(class_id/div) + ord('A'))
					class_id = class_id % div
					div = div/26
		
				if(period==0): periodTX = " - morning"
				elif(period==1): periodTX = " - afternoon"
				else: periodTX = " - evening"
		
				if(count<=25): pass
				else:
					c.update()
					c.postscript(file = "classes-"+str(page)+".ps", pageheight="29.70c",x="0",y="0",height="1754",width="1240") 
					c.delete("lines")
					count = 0
					page += 1
				
				c.create_text(m+60, 150+60*count, fill="#000", font=("Ubuntu","10") , text=i, tags="lines") # Subject
				c.create_text(m+170, 150+60*count, fill="#000", font=("Ubuntu","10") , text=b26+str(sameSche[period][class_idBK][0]+1)+periodTX, tags="lines") # Class
				c.create_text(m+420, 150+60*count, fill="#000", font=("Ubuntu","10") , text=schedule, tags="lines") # Schedule
				c.create_text(m+720, 150+60*count, fill="#000", font=("Ubuntu","10") , text=professor, tags="lines") # Professor
				c.create_text(m+920, 150+60*count, fill="#000", font=("Ubuntu","10") , justify='center', text=group, tags="lines") # Group

	c.update()
	c.postscript(file = string+"-"+str(page)+".ps", pageheight="29.70c",x="0",y="0",height="1754",width="1240") 

	#Concatenate PS files and output a single PDF, then clear PS files
	os.system("convert -density 300 *.ps  "+string+".pdf")
	os.system("find . -name \*.ps -type f -delete")
Пример #51
0
class Visual(object):
    def __init__(self, width=800, height=600):
        root = Tk()
        self.root = root
        self.margin = 0.12*height
        self.width, self.height = width, height - self.margin
        self.cx, self.cy = width/2, (height - self.margin)/2
        self.toolbar = \
            Canvas(self.root, width=self.width, height=self.margin)
        self.toolbar.pack()
        self.canvas = Canvas(root, width=width, height=height - self.margin)
        self.canvas.pack()
        self.init_animation()
        root.bind("<Button-1>", lambda e: self.mouse_event(e))
        root.bind("<Key>", lambda e: self.key_event(e))
        root.mainloop()

    def draw_users(self):
        """Draw all users"""
        for user in self.users:
            user.draw()

    def draw_connections(self):
        """Draw all of user's connections"""
        for user in self.users:
            user.draw_students()

    def draw_start_screen(self):
        """Start screen text"""
        self.canvas.delete(ALL)
        cx, cy = self.width/2, self.height/2
        font = ("Impact", "128")
        self.canvas.create_text(cx, 0.8*cy, text="INFECTION", font=font)
        font = ("Impact", 32)
        self.canvas.create_text(cx, 1.5*cy, text="Press s to Begin", font=font)

    def draw_setup_screen(self):
        """User setup screen"""
        self.canvas.delete(ALL)
        cx, cy = self.width/2, self.height/2
        text = "Number of Users (1-{})".format(self.max_users)
        font = ("Impact", 24)
        self.canvas.create_text(cx, 0.4*cy, text=text, font=font)
        self.num_users_entry = Entry(self.canvas, justify=CENTER)
        self.canvas.create_window(cx, 0.5*cy, window=self.num_users_entry)
        self.num_users_entry.insert(0, str(self.default_users))

        text = "Number of Coaches"
        self.canvas.create_text(cx, 0.6*cy, text=text, font=font)
        self.num_coaches_entry = Entry(self.canvas, justify=CENTER)
        self.canvas.create_window(cx, 0.7*cy, window=self.num_coaches_entry)
        self.num_coaches_entry.insert(0, str(self.default_coaches))

        text = "Max Number of Students"
        self.canvas.create_text(cx, 0.8*cy, text=text, font=font)
        self.num_students_entry = Entry(self.canvas, justify=CENTER)
        self.canvas.create_window(cx, 0.9*cy, window=self.num_students_entry)
        self.num_students_entry.insert(0, str(self.default_students))

        self.button = Button(cx, 1.5*cy, 0.3*cx, 0.2*cy, "Begin")
        self.button.draw(self.canvas)

    def draw_toolbar(self):
        """Toolbar for main animation"""
        self.toolbar.create_text(self.cx, 0.1*self.cy, text="INFECTION",
                                 font=("Impact", 32))
        self.toolbar.create_text(self.cx*0.05, 0.1*self.cy,
                                 text="Total Infection: Click User",
                                 font=("Impact", 20), anchor="w")
        self.toolbar.create_text(self.cx*1.8, 0.1*self.cy,
                                 text="Limited Infection",
                                 font=("Impact", 20), anchor="e")
        self.limited_entry = Entry(self.toolbar, justify=CENTER, width=3)
        self.toolbar.create_window(self.cx*1.85, 0.1*self.cy,
                                   window=self.limited_entry)
        self.limited_entry.insert(0, str(self.default_users//2))
        cx, cy = self.cx*1.95, self.margin*0.35
        r = self.margin/5
        self.limited_button = (cx, cy, r)
        self.toolbar.create_oval((cx-r, cy-r, cx+r, cy+r), width=2, fill="RED")
        self.toolbar.create_text(cx, cy, text="X", font=("Courier Bold", 30))
        side = self.width/self.versions
        self.side = side
        y = 50
        self.gradient = (y, y+side)
        for col in range(int(self.versions)):
            fill = self.get_fill(col)
            width = 2 if col == self.version else 0
            self.toolbar.create_rectangle(col*side, y, (col+1)*side, y+side,
                                          fill=fill, width=width)
        self.select_version()

    def redraw_all(self):
        """Refresh frame for infection animation"""
        self.canvas.delete(ALL)
        # Draw connections first so circles get drawn on top of lines
        self.draw_connections()
        self.draw_users()

    def init_users(self):
        """Initializes list of VisualUser objects from users"""
        for user in self.raw_users:
            self.users.append(VisualUser(user, self))

    def update_locations(self):
        """Update locations of all users"""
        for user in self.users:
            user.update_location()

    def get_fill(self, v):
        """
        Convert version number into RGB hex value

        Creates gradient covering range of colors
        """
        if v is None:
            return "white"
        b = 0
        quarter = self.versions/4
        if v < quarter:  # Red -> Yellow
            r = 255
            g = int(255*min((v/quarter), 1))
        elif quarter <= v < 2*quarter:  # Yellow -> Green
            r = int(255*max(0, (1-(v-quarter)/quarter)))
            g = 255
        elif 2*quarter <= v < 3*quarter:  # Green -> Blue
            r = 0
            g = int(255*max(0, (1-(v-2*quarter)/quarter)))
            b = int(255*min(((v-2*quarter)/quarter), 1))
        else:  # Blue -> Purple
            g = 0
            r = int(255*min(((v-3*quarter)/quarter), 1))
            b = 255
        return "#{:02x}{:02x}{:02x}".format(r, g, b)

    def draw_random_point(self):
        """Draw randomly colored point on screen"""
        fill = self.get_fill(self.start_counter % 100)
        self.start_counter += 1
        x = random.randint(0, self.width)
        y = random.randint(0, self.height)
        self.canvas.create_rectangle(x, y, x+2, y+2, width=0, fill=fill)

    def timer_fired(self):
        """Called every frame refresh"""
        if self.mode == Mode.START:
            for _ in range(10):
                self.draw_random_point()
        if self.mode == Mode.MAIN and not self.paused:
            self.update_locations()
            self.redraw_all()

    def timer(self):
        """Setup timer loop"""
        self.timer_fired()
        self.canvas.after(self.timer_delay, self.timer)

    def init_animation(self):
        """Initialize or reset animation"""
        self.users = []
        self.timer_delay = 100
        self.start_counter = 0
        self.versions = 40
        self.default_users = 20
        self.default_coaches = 5
        self.default_students = 5
        self.max_users = 100
        self.version = None
        self.paused = False
        self.mode = Mode.START
        self.draw_start_screen()
        self.error_text = None
        self.error_font_size = 20
        self.version_select = None
        self.timer()

    def start_infection(self):
        """Initialize users and start infections"""
        num_users_text = self.num_users_entry.get()
        num_coaches_text = self.num_coaches_entry.get()
        num_students_text = self.num_students_entry.get()
        try:
            error = "Invalid Number of Users"
            num_users = int(num_users_text)
            if not (1 <= num_users <= self.max_users):
                raise ValueError
            num_coaches = int(num_coaches_text)
            error = "Invalid Number of Coaches"
            if not (1 <= num_coaches <= num_users):
                raise ValueError
            error = "Invalid Number of Students"
            num_students = int(num_students_text)
            if not (1 <= num_students <= num_users):
                raise ValueError
        except ValueError:
            if self.error_text:
                self.canvas.delete(self.error_text)
            self.error_text = \
                self.canvas.create_text(self.cx, 0.2*self.cy,
                                        text=error,
                                        font=("Impact", self.error_font_size))
            self.error_font_size += 2
            return
        self.infection = Infection(num_users=num_users, num_coaches=num_coaches,
                                   students=(1, num_students))
        self.num_users = num_users
        self.num_coaches = num_coaches
        self.num_students = num_students
        self.raw_users = self.infection.network.users
        self.init_users()
        self.draw_toolbar()
        self.mode = Mode.MAIN

    def limited_infection(self):
        size_text = self.limited_entry.get()
        try:
            size = int(size_text)
            if not (1 <= size <= self.num_users):
                raise ValueError
        except ValueError:
            print("Bad input")  # TODO: display to user
            return
        self.infection.limited_infection(size, self.version)
        print("Limited infection of size", size, self.num_users)

    def select_version(self):
        if self.version_select:  # Erase old selection
            self.toolbar.delete(self.version_select)
        if self.version is None:
            return
        y0, y1 = self.gradient
        x0, x1 = self.version*self.side, (self.version + 1)*self.side
        self.version_select = \
            self.toolbar.create_rectangle(x0, y0, x1, y1, width="2")

    def mouse_event(self, e):
        """Process click event"""
        x, y = e.x, e.y
        if self.mode == Mode.SETUP:
            if self.button.clicked(x, y):
                self.start_infection()
        if self.mode == Mode.MAIN:
            cx, cy, r = self.limited_button
            if distance(cx, cy, x, y) < r:
                self.limited_infection()
            elif self.gradient[0] <= y <= self.gradient[1]:
                print("gradient bar", x)
                self.version = int(x / self.side)
                print(self.versions, self.version)
                self.select_version()
            else:
                for user in self.users:
                    if user.clicked(x, y):
                        print("user clicked", user)
                        user.infect()
                        break

    def key_event(self, e):
        """Process keyboard event"""
        if e.keysym == 'r':
            self.init_animation()
            self.paused = False
        elif e.keysym == 'p':
            self.paused = not self.paused
        elif e.keysym == 's' and self.mode == Mode.START:
            self.mode = Mode.SETUP
            self.draw_setup_screen()
        elif e.keysym == 'b' and self.mode == Mode.SETUP:
            self.start_infection()
        elif e.keysym == 'q':
            self.root.destroy()
Пример #52
0
class CanvasRenderer(AbstractRenderer):
    """
    The CanvasRenderer can draw figures and grids on a canvas
    """

    def __init__(self, window):
        """
        Constructor
        :param window: Reference to the main window instance
        """

        super().__init__(window)

        self.canvas = Canvas(self.window)
        self.canvas.grid(row=0, column=0, padx=BOARD_CELL_SIZE, ipadx=10, ipady=10, sticky='nsew')
        self.path_sprites = set()

    def render_board(self, math_coords=False):
        """
        Renders the data
        """

        debug('CanvasRenderer.render_board() called')

        if not self.board:
            messagebox.showerror(
                'No Board',
                'No board has been selected, cannot render'
            )

        self.clear()
        payload = self.board.grid

        row_range = range(0, self.board_height)
        # If we are drawing using mathematical coordinates (Y-axis reversed)
        if math_coords:
            row_range = range(self.board_height - 1, -1, -1)

        # Iterate through all nodes, create sprite coords and determine fill color
        for y in row_range:
            for x in range(len(payload[y])):

                draw_y = y
                if math_coords:
                    draw_y = self.board_height - y

                coords = (
                    x * BOARD_CELL_SIZE + 1,
                    draw_y * BOARD_CELL_SIZE + 1,
                    x * BOARD_CELL_SIZE + BOARD_CELL_SIZE + 1,
                    draw_y * BOARD_CELL_SIZE + BOARD_CELL_SIZE + 1,
                )

                node = self.board.get_node(x, y)
                fill_color = '#FFFFFF'
                if not node.walkable:
                    fill_color = '#000000'
                elif node.is_start:
                    fill_color = '#4040FF'
                elif node.is_goal:
                    fill_color = '#40FF40'

                self.canvas.create_rectangle(
                    *coords,
                    fill=fill_color
                )

    def render_path(self, path, math_coords=False, **kwargs):
        """
        Renders path nodes on top of the map, after clearing previously rendered path nodes
        :param path: A list of Node objects
        """

        open_set = kwargs['open_set_size']
        closed_set = kwargs['closed_set_size']

        # Remove all previously rendered path sprites from canvas
        for sprite in self.path_sprites:
            self.canvas.delete(sprite)

        self.path_sprites.clear()

        if 'nonogram' in kwargs and kwargs['nonogram'] is not None:
            p = path[0].state
            for y in range(kwargs['nonogram'].total_rows):
                if len(p.nodes[y]) != 1:
                    continue
                for x in range(len(p.nodes[y][0][1])):
                    coords = (
                        x * BOARD_CELL_SIZE + 1,
                        y * BOARD_CELL_SIZE + 1,
                        x * BOARD_CELL_SIZE + BOARD_CELL_SIZE + 1,
                        y * BOARD_CELL_SIZE + BOARD_CELL_SIZE + 1
                    )

                    fill_color = '#FFFFFF'

                    if p.nodes[y][0][1][x]:
                        fill_color = '#22EE22'

                    # Create sprite and add to path sprite cache
                    self.path_sprites.add(
                        self.canvas.create_rectangle(
                            *coords,
                            fill=fill_color
                        )
                    )

            self.window.master.controller.references['path_length'].set(
                'Path length: %d' % (len(path) - 1)
            )
            self.window.master.controller.references['open_set_size'].set(
                'OpenSet size: %d' % open_set
            )
            self.window.master.controller.references['closed_set_size'].set(
                'ClosedSet size: %d' % (closed_set - 1)
            )
            self.window.master.controller.references['total_set_size'].set(
                'Total set size: %d' % (open_set + closed_set - 1)
            )

        else:
            # Add sprites for current path
            for node in reversed(path[:-1]):
                # If we are drawing using mathematical coordinates (y-reversed)
                y = node.y
                if math_coords:
                    y = self.board_height - node.y

                # Create the coordinates and dimension tuple
                coords = (
                    node.x * BOARD_CELL_SIZE + 1,
                    y * BOARD_CELL_SIZE + 1,
                    node.x * BOARD_CELL_SIZE + BOARD_CELL_SIZE + 1,
                    y * BOARD_CELL_SIZE + BOARD_CELL_SIZE + 1
                )

                fill_color = '#994499'

                # Create sprite and add to path sprite cache
                self.path_sprites.add(
                    self.canvas.create_rectangle(
                        *coords,
                        fill=fill_color
                    )
                )

                self.window.master.controller.references['path_length'].set(
                    'Path length: %d' % (len(path) - 1)
                )
                self.window.master.controller.references['open_set_size'].set(
                    'OpenSet size: %d' % open_set
                )
                self.window.master.controller.references['closed_set_size'].set(
                    'ClosedSet size: %d' % closed_set
                )
                self.window.master.controller.references['total_set_size'].set(
                    'Total set size: %d' % (open_set + closed_set)
                )

    def clear(self):
        """
        Clears the content area
        """

        self.canvas.delete('all')
        self.window.master.controller.clear_timers()
        self.window.master.controller.clear_stats()

    def destruct(self):
        """
        Destroys this canvas
        """

        self.window.master.controller.clear_timers()
        self.window.master.controller.clear_stats()
        self.canvas.destroy()
class RadiobuttonEntry(ttk.Frame):
    """State entry for all DMs, and controls for adding the infeasibles.

    Uses a set of RadioButtonSeries elements.
    """

    def __init__(self, master, conflict):
        """Initialize the widget."""
        ttk.Frame.__init__(self, master)

        self.conflict = conflict

        self.dmLookup = {dm.name: dm for dm in self.conflict.decisionMakers}
        dmNames = tuple(self.dmLookup.keys())
        self.activeDMname = StringVar(value=dmNames[0])
        self.activeDM = self.dmLookup[dmNames[0]]

        dmSelLabel = ttk.Label(self, text="Decision Maker")
        dmSelLabel.grid(column=0, row=0)

        self.dmSelector = ttk.Combobox(self, textvariable=self.activeDMname,
                                       values=dmNames, state='readonly')
        self.dmSelector.grid(column=1, row=0, sticky=NSEW)
        self.dmSelector.bind('<<ComboboxSelected>>', self.dmSel)

        self.rbeCanvas = Canvas(self)
        self.rdBtnFrame = ttk.Frame(self.rbeCanvas)
        self.scrollY = ttk.Scrollbar(self, orient=VERTICAL,
                                     command=self.rbeCanvas.yview)

        self.rbeCanvas.grid(column=0, row=1, columnspan=2, sticky=NSEW)
        self.scrollY.grid(column=2, row=1, sticky=NSEW)
        self.rbeCanvas.configure(yscrollcommand=self.scrollY.set)
        self.canvWindow = self.rbeCanvas.create_window(
            (0, 0), window=self.rdBtnFrame, anchor='nw')

        self.rowconfigure(1, weight=1)

        self.entryText = StringVar(value='')

        vcmd = self.register(self.onValidate)
        self.entryBx = ttk.Entry(self, textvariable=self.entryText,
                                 validate="key",
                                 validatecommand=(vcmd, '%S', '%P'))
        self.entryBx.grid(column=0, row=2, columnspan=2, sticky=NSEW)
        self.entryBx.bind('<Return>', self.generateAdd)

        self.warnText = StringVar(value='')

        self.addBtn = ttk.Button(self, text='Remove as Misperceived Condition',
                                 command=self.generateAdd)
        self.mutExBtn = ttk.Button(self,
                                   text='Perceived as Mutually Exclusive',
                                   command=self.generateMutEx)
        self.warnLab = ttk.Label(self, textvariable=self.warnText)
        self.warnLab.grid(column=0, row=3, sticky=NSEW)
        self.addBtn.grid(column=0, row=4, columnspan=2, sticky=NSEW)
        self.mutExBtn.grid(column=0, row=5, columnspan=2, sticky=NSEW)

        self.reloadOpts()

    def resize(self, event=None):
        """Resize the scroll region of the main canvas element."""
        self.rbeCanvas.configure(scrollregion=self.rbeCanvas.bbox("all"))
        self.rbeCanvas["width"] = self.rbeCanvas.bbox("all")[2]

    def generateAdd(self, *args):
        """Prompt response to addition of an infeasible state."""
        self.event_generate('<<addMisperceived>>')

    def generateMutEx(self, *args):
        """Prompt response to addition of a mutually exclusive set."""
        self.event_generate('<<AddMutEx>>')

    def reloadOpts(self):
        """Reload all options for all DMs."""
        self.rbeCanvas.delete(self.canvWindow)
        self.rdBtnFrame.destroy()
        self.rdBtnFrame = ttk.Frame(self.rbeCanvas)
        self.canvWindow = self.rbeCanvas.create_window(
            (0, 0), window=self.rdBtnFrame, anchor='nw')
        self.rdBtnFrame.bind('<<RdBtnChg>>', self.rdBtnChgCmd)
        self.rdBtnFrame.bind("<Configure>", self.resize)

        self.rdBtnSrs = []
        self.stringVarList = []

        for x, dm in enumerate(self.conflict.decisionMakers):
            a = RadiobuttonSeries(self.rdBtnFrame, dm)
            self.rdBtnSrs.append(a)
            a.setOpts(dm.options)
            a.grid(column=0, row=int(x), sticky=NSEW)
            self.stringVarList += a.stringVarList

        self.rdBtnChgCmd()

    def setStates(self, dashOne):
        """Change the condition selected on the radio buttons."""
        if len(dashOne) != len(self.stringVarList):
            raise Exception('string length does not match number '
                            'of options: {}'.format(dashOne))
        for x, y in enumerate(dashOne):
            self.stringVarList[x].set(y)
        self.entryText.set(dashOne)

    def getStates(self):
        """Get the condition selected on the radio buttons."""
        states = []
        for srs in self.rdBtnSrs:
            states.extend(srs.getStates())
        return states

    def onValidate(self, chg, res):
        """Validate manually entered condition characters and length."""
        if chg in ['Y', 'N', 'y', 'n', '-']:
            if len(res) < len(self.stringVarList):
                self.warnText.set('Entry too short')
                return True
            if len(res) == len(self.stringVarList):
                self.setStates(res.upper())
                self.warnText.set('')
                return True
        return False

    def rdBtnChgCmd(self, *args):
        """Set the entry box value to match the radiobuttons."""
        val = ''.join([x.get() for x in self.stringVarList])
        self.entryText.set(val)

    def dmSel(self, *args):
        """Prompt response to a different DM being selected."""
        dmName = self.activeDMname.get()
        self.activeDM = self.dmLookup[dmName]
        self.event_generate('<<ChangeDM>>')
Пример #54
0
class prgCanvas(Frame):
    def __init__(self,window=None,height=500,width=500,bg="grey"):
        Frame.__init__(self,window,height=height,width=width,bg=bg)
        self.canvas = Canvas(self, bg=bg, height=height, width=width)
        self.flagDescription = False
        self.setdefault(mashtab=True,reper=True,normalization=True)
        self.canvas.pack(expand='y',fill="both")
        self.field = None #данные, блоки групп, графические примитивы, точки, #графические примитивы, надписи
        self.fileprogram = None #имя файла для загрузки

        self.filter = None #фильтр, по которому определяется выделенный фрагмент

    def setdefault(self,mashtab=False,reper=False,normalization=False):
        if mashtab:
            self.mashtab = 1.00 #масштаб
        if reper:
            self.reper = [10.00,10.00] #смещение
        if normalization:
            self.normalization = [0.00,0.00] #коэффициент для нормализации координат
        
    def configure(self,file=None,filter= None):
        if file!=None:
            self.fileprogram = file
        self.filter=filter

    def setMashtab(self):
        '''Эта функция устанавливает текущий масштаб, так чтобы вся плата была в зоне видимости'''
        def findcoord(field):
            mX,mY = field[0][0],field[0][1]
            # sX,sY = field[0][0],field[0][1]
            sX,sY = 0, 0
            for c in field:
                if c[0]<sX: sX = c[0]
                elif c[0]>mX: mX = c[0]
                if c[1]<sY: sY = c[1]
                elif c[1]>mY: mY = c[1]
            return [sX,sY,mX,mY]
        sX,sY,mX,mY=findcoord(self.field)
        lX = int(self.canvas["width"])
        lY = int(self.canvas["height"])
        lengthX = abs(mX-sX)
        lengthY = abs(mY-sY)
        if lengthX>0 and lengthY>0:
            cX = lX/lengthX
            cY = lY/lengthY
        else:
            cX,cY=1.0,1.0
        print("MSH",cX,cY)
        
        self.normalization = [abs(sX),abs(sY)]
        self.mashtab = int(min(cX,cY)*0.9)
    
    def transform(self,x,y,a,etalon):
        """
        точка отсчета - в центре эталона
        """
        new = list()
        for item in etalon:
            ca = cos(a)
            sa = sin(a)
            x2,y2 = item[0]-x, item[1]-y
            
            new.append([x2*ca + y2*sa+x, x2*sa - y2*ca+y])
        return new
        
    def genfield(self):
        x,y,d=0,1,2
        
        self.canvas.delete("all")

        for c in self.field:
            cx = (c[x]+self.normalization[x])*self.mashtab+self.reper[x]
            cy = (c[y]+self.normalization[y])*self.mashtab+self.reper[y]

            print("filter",self.filter)
            
            if self.flagDescription and self.filter==None:
                tag = "BLACK"
                _color1,_color2 = "black","black"
                font = "Verdana 8"
                self.canvas.create_text(cx,cy,anchor="nw",text=str(c[d][1]), fill=_color1,font=font,tag=("DESC",tag))
            elif (not self.flagDescription) and self.filter==None:
                tag = "BLACK"
                _color1,_color2 = "black","black"
            elif self.flagDescription and self.filter!=None and self.filter(c[d][2]):
                _color1,_color2 = ["red","red"]
                tag = "RED"
                font = "Verdana 10 bold"
                self.canvas.create_text(cx,cy,anchor="nw",text=str(c[d][1]), fill=_color1,font=font,tag=("DESC",tag))
            elif self.flagDescription:
                _color1,_color2 = "black","black"
                tag = "BLACK"
                # font = "Verdana 8"
                # self.canvas.create_text(cx,cy,anchor="nw",text=str(c[d][1]), fill=_color1,font=font,tag=("DESC",tag))
                pass
                
            # здесь может быть выбор фигуры
            # здесь может быть угол поворота
            print("c",c)
            if c[-2][0]=="25":
                angle = radians(c[-1])
                pattern = [[-3,-5.0],[3,-5.0],[0.0,3.0],[-3.0,-5.0]]
                et = [[cx+item[0],cy+item[1]] for item in pattern]
                new = self.transform(cx,cy,angle,et)
                self.canvas.create_polygon(new,activefill="white",fill=_color2,tag=("FIG",tag))
            else:
                self.canvas.create_rectangle(cx-1,cy-1,cx+1,cy+1,outline=_color1,fill=_color2,tag=("FIG",tag))
        self.canvas.tag_lower("RED")
        
    def move(self,x,y):
        #в группы
        self.reper[0]+=x
        self.reper[1]+=y
        self.canvas.move("FIG",x,y)
        self.canvas.move("DESC",x,y)

    def load(self):
        _p = prg(self.fileprogram)
        _p.download()
        _p.extract()
        #вариант кода для загрузки информации о установке
        self.field = [x[1:4]+[x[0]] for x in _p.progdigit if ("25" in x[3]) or ("107" in x[3])]
        print(_p.progdigit)
        #вариант кода для загрузки информации о дозировании:
        # self.field.group = [x[1:4] for x in _p.progdigit if "107" in x[3]]
        # print(self.field)

    def paint(self):
        self.load()
        try:
            self.setMashtab()
            self.genfield()
        except ZeroDivisionError:
            print("Zero division")
        except IndexError:
            print("Index error")
            #рисуем надпись
            self.canvas.delete("all")
            x,y = int(self.canvas["width"]),int(self.canvas["height"])
            self.canvas.create_text(x//2,y//2,text="FILE IS CORRUPTED", font="Verdana 12 bold",fill="red",tag="del")
Пример #55
0
class TicTacToeGUI:

    ai = None

    def __init__(self, master):
        # Initial Frame
        self.frame = Frame(master)
        self.frame.pack(fill="both", expand=True)

        # Board canvas
        self.canvas = Canvas(self.frame, width=300, height=300)

        # Symbol selection buttons
        self.x_button = Button(self.frame, text='Play as X', height=4,
                               command=self.set_player_x, bg='white',
                               fg='black')
        self.o_button = Button(self.frame, text='Play as O', height=4,
                               command=self.set_player_o, bg='white',
                               fg='red')

        # Game start button and info box
        self.start_button = Button(self.frame, text="START", height=4,
                                   command=self.start, bg='white', fg='purple')
        self.info_box = Label(self.frame, text='Tic Tac Toe Game', height=4,
                              bg='white', fg='blue')

        self.clean_game_board()

    def start(self):
        """Sets up game board, starts a tic tac toe game,
        and a new AI if one doesn't exist. AI makes first move if
        playing as X
        """
        self.set_game_board()
        self.game = TicTacToe()
        self.game.start()
        if not self.ai:
            self.ai = TicTacToeAI()

        if self.ai_symbol == 'x':
            self.ai_action()

    def _board(self):
        """Draws tic tac toe board"""
        self.canvas.create_rectangle(0, 0, 300, 300, outline="black")
        self.canvas.create_rectangle(100, 300, 200, 0, outline="black")
        self.canvas.create_rectangle(0, 100, 300, 200, outline="black")

    def user_action(self, event):
        """Attempts to take action that matches user click. If the move is valid,
        then calls the AI to make the next move. If not, displays the error.
        """
        move_x = event.x // 100
        move_y = event.y // 100
        move_result = self.game.update(self.player_symbol, (move_x, move_y))
        if move_result == "Success":
            board_x = (200 * move_x + 100) / 2
            board_y = (200 * move_y + 100) / 2
            if self.player_symbol == 'x':
                self.draw_x(board_x, board_y)
            else:
                self.draw_o(board_x, board_y)
            if not self.completed():
                # Wait a bit before calling the ai, for visual style
                self.frame.after(500, self.ai_action)
        else:
            self.info_box['text'] = move_result

    def ai_action(self):
        """Gets the next move from the AI based on current game state,
        and plays.
        """
        state = self.game.get_board()
        move = self.ai.get_move(state)
        move_result = self.game.update(self.ai_symbol, move)
        if move_result == "Success":
            board_x = (200 * move[0] + 100) / 2
            board_y = (200 * move[1] + 100) / 2
            if self.ai_symbol == 'x':
                self.draw_x(board_x, board_y)
            else:
                self.draw_o(board_x, board_y)
            self.completed()

    def completed(self):
        """Checks the game status. If completed, displays the result,
        and asks whether the player would like to start another game.
        """
        status = self.game.done()
        if status == 'e':
            return False
        message = "Click to start a new game."
        if status == 't':
            message = "Tie game. " + message
        else:
            message = "Player " + status.upper() + " has won. " + message
        self.info_box.pack_forget()
        self.start_button.pack(fill="both", expand=True)
        self.start_button["text"] = message
        self.start_button["command"] = self.clean_game_board

    def draw_x(self, x, y):
        self.canvas.create_line(x + 20, y + 20, x - 20, y - 20, width=4,
                                fill="black")
        self.canvas.create_line(x - 20, y + 20, x + 20, y - 20, width=4,
                                fill="black")

    def draw_o(self, x, y):
        self.canvas.create_oval(x + 25, y + 25, x - 25, y - 25, width=4,
                                outline="red")

    def set_game_board(self):
        """Hides game start buttons, reveals the game board and info box."""
        self.start_button.pack_forget()
        self.x_button.pack_forget()
        self.o_button.pack_forget()
        self.canvas.delete(ALL)
        self.canvas.pack(fill="both", expand=True)
        self.info_box.pack(fill="both", expand=True)
        self.canvas.bind("<ButtonPress-1>", self.user_action)
        self._board()

    def clean_game_board(self):
        """Hides game board and label, reveals game start buttons."""
        self.canvas.pack_forget()
        self.info_box.pack_forget()
        self.start_button.pack_forget()
        self.x_button.pack(fill="both", expand=True)
        self.o_button.pack(fill="both", expand=True)

    def set_player_x(self):
        self.player_symbol = 'x'
        self.ai_symbol = 'o'
        self.start()

    def set_player_o(self):
        self.player_symbol = 'o'
        self.ai_symbol = 'x'
        self.start()
Пример #56
0
class Game:
    scale = 1

    @property
    def margin(self):
        return 10 * self.scale

    @property
    def cellSize(self):
        return 35 * self.scale

    @property
    def pentPadding(self):
        return 5 * self.scale

    # it's better if: cellSize % (dashBlack + dashWhite) == 0
    @property
    def dashBlack(self):
        return 3 * self.scale

    @property
    def dashWhite(self):
        return 2 * self.scale

    @property
    def canvasWidth(self):
        return 2 * self.margin + self.cols * self.cellSize

    @property
    def canvasHeight(self):
        return 2 * self.margin + self.rows * self.cellSize

    colors = {
        'idle'      : 'white',
        'free'      : 'yellow',
        'busy'      : '#F3C0BB',
        'pentomino' : '#D8B042',
        'pent_edit' : '#CB1222'
    }
    possibleRotations = 4
    numPieces = 5
    """For each rotation of the polyomino, it should be specified the
    "offset" from the center (0, 0) for every piece. The offset is a
    tuple (dx, dy). The center (0, 0) should appear somewhere in the
    list as well as other pieces. The order of pieces doesn't matter
    """
    pos = (
        ((2, 0),  (1, 0),  (0, 0), (0, 1),  (0, 2)),
        ((-2, 0), (-1, 0), (0, 0), (0, 1),  (0, 2)),
        ((-2, 0), (-1, 0), (0, 0), (0, -1), (0, -2)),
        ((2, 0),  (1, 0),  (0, 0), (0, -1), (0, -2))
    )
    """For each rotation and for each piece of the polyomino it should
    be specified a bitmask to instruct the program on how to draw that
    piece. Each piece of polyomino will be splitted in 9 subrectangles,
    according to the scheme:
        .___.___________.___.
        |   |           |   |
        | 0 |     1     | 2 |
        |___|___________|___|
        |   |           |   |
        |   |           |   |
        | 3 |           | 4 |
        |   |           |   |
        |___|___________|___|
        |   |           |   |
        | 5 |     6     | 7 |
        |___|___________|___|

    The middle rectangle will always be full.
    If you want the i-th rectangle to be full, then the i-th bit of the
    bitmask should be set. For example if you want to draw a CROSS piece
    then you will need to have 1-th, 3-th, 4-th and 6-th bits set: so
    the bitmask of the CROSS piece is (2**1)+(2**3)+(2**4)+(2**6)=90.
    For readability it's better to set explicitly every bit of the mask,
    like the pentomino's shape encoded in the "info" array, for example
    """
    info = (
        (
            ((0 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | (0 << 7)),
            ((0 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (0 << 4) | (0 << 5) | (1 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (0 << 3) | (1 << 4) | (0 << 5) | (1 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (1 << 3) | (1 << 4) | (0 << 5) | (0 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (1 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | (0 << 7))
        ),
        (
            ((0 << 0) | (0 << 1) | (0 << 2) | (0 << 3) | (0 << 4) | (0 << 5) | (1 << 6) | (0 << 7)),
            ((0 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (0 << 4) | (0 << 5) | (1 << 6) | (0 << 7)),
            ((0 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (1 << 4) | (0 << 5) | (0 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (1 << 3) | (1 << 4) | (0 << 5) | (0 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (1 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | (0 << 7))
        ),
        (
            ((0 << 0) | (0 << 1) | (0 << 2) | (0 << 3) | (0 << 4) | (0 << 5) | (1 << 6) | (0 << 7)),
            ((0 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (0 << 4) | (0 << 5) | (1 << 6) | (0 << 7)),
            ((0 << 0) | (1 << 1) | (0 << 2) | (1 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (1 << 3) | (1 << 4) | (0 << 5) | (0 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (0 << 3) | (1 << 4) | (0 << 5) | (0 << 6) | (0 << 7))
        ),
        (
            ((0 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (0 << 4) | (0 << 5) | (0 << 6) | (0 << 7)),
            ((0 << 0) | (1 << 1) | (0 << 2) | (0 << 3) | (0 << 4) | (0 << 5) | (1 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (1 << 3) | (0 << 4) | (0 << 5) | (1 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (1 << 3) | (1 << 4) | (0 << 5) | (0 << 6) | (0 << 7)),
            ((0 << 0) | (0 << 1) | (0 << 2) | (0 << 3) | (1 << 4) | (0 << 5) | (0 << 6) | (0 << 7))
        )
    )

    def __init__(self, num_rows, num_cols, best_possible):
        self.rows = num_rows
        self.cols = num_cols
        self.expectedBest = best_possible
        # create the root and the canvas
        root = Tk()
        # local function to bind/unbind events
        self.bind = root.bind
        self.unbind = root.unbind
        # local function to change title
        self.updateTitle = root.title
        # local function to change cursor
        self.updateCursor = lambda x: root.config(cursor=x)
        # local function to start game
        self.start = root.mainloop
        # get screen width and height
        ws = root.winfo_screenwidth()
        hs = root.winfo_screenheight()

        # fix scaling for higher resolutions
        if max(self.canvasWidth / ws, self.canvasHeight / hs) < 0.45:
            self.scale = 2

        self.canvas = Canvas(root, width=self.canvasWidth, height=self.canvasHeight)
        self.canvas.pack()
        # calculate position x, y
        x = (ws - self.canvasWidth) // 2
        y = (hs - self.canvasHeight) // 2
        root.geometry('%dx%d+%d+%d' % (self.canvasWidth, self.canvasHeight, x, y))
        root.resizable(width=0, height=0)
        self.init()
        # set up keypress events
        root.bind("<Key>", self.keyPressed)

    def gameOver(self):
        """Game over: clears background, unbinds events so the user can
        enjoy his result, updates title: "You won"
        """
        self.over = True
        self.correctPending()
        self.updateTitle("You won !!")
        self.unbind("<Motion>")
        self.unbind("<Leave>")
        self.unbind("<Button-1>")
        self.unbind("<Button-4>")
        self.unbind("<Button-5>")

    def refreshScore(self):
        """Visually updates the score reached by the user: actually it
        just changes the window title :P
        """
        self.updateTitle(str(self.onBoard) + " / " + str(self.expectedBest))

    def checkAvailable(self, x, y):
        """Checks if the cell at (x, y) is on the board AND is not busy
        """
        return 0 <= x < self.rows and 0 <= y < self.cols and not self.gridBusy[x][y]

    def checkFree(self, x, y):
        """Checks whether the position (x, y) is available or not.
        Returns the color to use for the background ('busy' or 'free')
        """
        for i in range(self.numPieces):
            new_x = x + self.pos[self.rotation][i][0]
            new_y = y + self.pos[self.rotation][i][1]
            if not self.checkAvailable(new_x, new_y):
                return self.colors['busy']
        return self.colors['free']

    def doPaint(self, x, y, color, pattern=""):
        """Does the actual painting: it paints with the specified color
        and pattern the background at (x, y). If a pattern isn't
        specified it won't be used
        """
        for i in range(self.numPieces):
            new_x = x + self.pos[self.rotation][i][0]
            new_y = y + self.pos[self.rotation][i][1]
            if 0 <= new_x < self.rows and 0 <= new_y < self.cols:
                for item in self.gridBG[new_x][new_y][0]:
                    self.canvas.itemconfigure(item, fill=color, stipple=pattern)

    def correctPending(self):
        """Restores to the normal state the last painted background
        """
        if self.lastPainted:
            self.doPaint(self.lastPainted[0], self.lastPainted[1], self.colors['idle'], "gray75")
            self.lastPainted = None

    def paintBackground(self, x, y, color):
        """Updates background to visually indicate whether the position
        (x, y) is available or not
        """
        self.correctPending()
        self.lastPainted = (x, y)
        self.doPaint(x, y, color)

    def mouseOut(self, event):
        """Catch mouseout in order to clean the last background painted
        when the cursor leaves the grid
        """
        if self.editMode and self.lastChanged:
            self.changeColor(self.lastChanged, self.colors['pentomino'])
            return
        self.correctPending()
        self.lastPosition = None

    def mouseOver(self, event):
        """Catch mouseover to paint the background accordingly to the
        availability of the pentomino space under the cursor
        """
        if self.editMode:
            self.setEditCursor(event)
            return
        x = (event.y - self.margin) // self.cellSize
        y = (event.x - self.margin) // self.cellSize
        if self.lastPosition == (x, y):
            return  # I've already drawn this
        if not (0 <= x < self.rows and 0 <= y < self.cols):
            return  # not on the grid
        self.lastPosition = (x, y)
        self.paintBackground(x, y, self.checkFree(x, y))

    def mouseClick(self, event):
        """Catch mouse click to confirm the insertion or removal (if in
        Edit mode) of a pentomino on the cell under the mouse pointer
        """
        if self.editMode:
            self.applyEditing(event)
            self.clearEditCursor(event)
            return
        x = (event.y - self.margin) // self.cellSize
        y = (event.x - self.margin) // self.cellSize
        if self.checkFree(x, y) == self.colors['busy']:
            return  # clicked busy position
        self.onBoard += 1
        self.refreshScore()
        self.history.append((
            self.setBusy(x, y),
            self.addPentomino(x, y)
        ))
        if self.onBoard == self.expectedBest:
            self.gameOver()

    def goBackInTime(self):
        """Removes the most recently inserted pentomino
        """
        if (len(self.history) == 0):
            return
        notBusy, notVisible = self.history.pop()
        for cell in notVisible:
            for item in cell[0] + cell[1]:
                self.canvas.delete(item)
        for x, y in notBusy:
            self.gridBusy[x][y] = 0
        self.onBoard -= 1
        self.refreshScore()

    def setBusy(self, x, y):
        """Sets as "busy" the cells occupied by a pentomino centered at
        (x, y) rotated as the current rotation stored in self.rotation
        """
        changes = []
        for i in range(self.numPieces):
            new_x = x + self.pos[self.rotation][i][0]
            new_y = y + self.pos[self.rotation][i][1]
            changes.append((new_x, new_y))
            self.gridBusy[new_x][new_y] = self.onBoard
        self.correctPending()
        return changes

    def addPentomino(self, x, y):
        """Adds a new pentomino with its center in the position (x, y)
        of the grid and returns the list of changes done. Each element
        of the list returned is a cell (that is the list of IDs of the
        new drawn items)
        """
        changes = []
        for i in range(self.numPieces):
            new_x = x + self.pos[self.rotation][i][0]
            new_y = y + self.pos[self.rotation][i][1]
            changes.append(self.drawCell(
                new_x, new_y, self.colors['pentomino'], self.info[self.rotation][i]
            ))
        return changes

    def doRotation(self, delta):
        """Sets the current rotation value to be rotated delta times by
        90 degrees CW. If delta is negative the rotation is CCW
        """
        self.correctPending()
        self.rotation = (self.rotation + delta) % self.possibleRotations

    def rollWheel(self, event):
        """Catch mousewheel scrolling to change the rotation
        """
        if event.num == 4:
            self.doRotation(-1)  # CCW rotation
        elif event.num == 5:
            self.doRotation(+1)  # CW rotation
        else:
            return
        x = (event.y - self.margin) // self.cellSize
        y = (event.x - self.margin) // self.cellSize
        self.paintBackground(x, y, self.checkFree(x, y))

    def rollWheelDelta(self, event):
        """Catch mousewheel scrolling to change the rotation: this is
        a version for newer mice (I think) because I had to add it to
        make the rotation work properly with a newer mouse. It would be
        nice to merge this routine with self.rollWheel()
        """
        if event.delta < 0:
            self.doRotation(-1)  # CCW rotation
        elif event.delta > 0:
            self.doRotation(+1)  # CW rotation
        else:
            return
        x = (event.y - self.margin) // self.cellSize
        y = (event.x - self.margin) // self.cellSize
        self.paintBackground(x, y, self.checkFree(x, y))

    def applyEditing(self, event):
        """Only called if in Edit mode: removes the pentomino that is
        currently under the mouse pointer. The pentomino is popped from
        history and every other (more recent) pentomino is updated with
        a new pentNumber (decreased by 1) to mantain the consistence of
        history ordering
        """
        self.lastChanged = None
        x = (event.y - self.margin) // self.cellSize
        y = (event.x - self.margin) // self.cellSize
        if not (0 <= x < self.rows and 0 <= y < self.cols):
            return
        if not self.gridBusy[x][y]:
            return
        assert len(self.history) >= self.gridBusy[x][y]
        for busy, items in self.history[self.gridBusy[x][y] : ]:
            for i, j in busy:
                self.gridBusy[i][j] -= 1
        notBusy, notVisible = self.history.pop(self.gridBusy[x][y] - 1)
        for cell in notVisible:
            for item in cell[0] + cell[1]:
                self.canvas.delete(item)
        for i, j in notBusy:
            self.gridBusy[i][j] = 0
        self.onBoard -= 1
        self.refreshScore()

    def setEditCursor(self, event):
        """Enters edit mode and sets the "X" cursor
        """
        self.editMode = True
        self.updateCursor("X_cursor")
        self.changeColor(self.lastChanged, self.colors['pentomino'])
        x = (event.y - self.margin) // self.cellSize
        y = (event.x - self.margin) // self.cellSize
        if not (0 <= x < self.rows and 0 <= y < self.cols):
            return
        if not self.gridBusy[x][y]:
            return
        assert len(self.history) >= self.gridBusy[x][y]
        self.lastChanged = self.gridBusy[x][y]
        self.changeColor(self.lastChanged, self.colors['pent_edit'])

    def clearEditCursor(self, event):
        """Exits from edit mode and restores the classic arrow cursor
        """
        self.editMode = False
        self.updateCursor("arrow")
        x = (event.y - self.margin) // self.cellSize
        y = (event.x - self.margin) // self.cellSize
        self.paintBackground(x, y, self.checkFree(x, y))

    def changeColor(self, pentNumber, color):
        """Updates the internal color of the pentNumber-th pentomino in
        the insertion history
        """
        if not pentNumber:
            return
        assert(len(self.history) >= pentNumber)
        for cell in self.history[pentNumber - 1][1]:
            for item in cell[0]:
                self.canvas.itemconfigure(item, fill=color)

    def keyPressed(self, event):
        """Catches when a key is pressed
        """
        if event.char == "r":
            self.init()
            return
        elif self.over:
            return
        elif event.char == ' ':
            if self.editMode:
                self.changeColor(self.lastChanged, self.colors['pentomino'])
                self.clearEditCursor(event)
                return
            self.correctPending()
            self.setEditCursor(event)
            return
        elif event.keysym == "BackSpace":
            self.goBackInTime()
        elif event.keysym == "Right":
            self.doRotation(+1)  # CW rotation
        elif event.keysym == "Left":
            self.doRotation(-1)  # CCW rotation
        else:
            return
        x = (event.y - self.margin) // self.cellSize
        y = (event.x - self.margin) // self.cellSize
        self.paintBackground(x, y, self.checkFree(x, y))

    def redrawAll(self):
        """Cleans the canvas and draws a new grid
        """
        self.canvas.delete(ALL)
        self.gridBG = []
        self.gridBusy = []
        for row in range(self.rows):
            self.gridBG.append([])
            self.gridBusy.append([])
            for col in range(self.cols):
                self.gridBG[row].append(self.drawCell(row, col, self.colors['idle'], bgPattern="gray75"))
                self.gridBusy[row].append(0)
        for row in range(self.rows + 1):
            self.canvas.create_line(
                self.margin,
                self.margin + row * self.cellSize,
                self.margin + self.cols * self.cellSize,
                self.margin + row * self.cellSize,
                dash=(self.dashBlack, self.dashWhite)
            )
        for col in range(self.cols + 1):
            self.canvas.create_line(
                self.margin + col * self.cellSize,
                self.margin,
                self.margin + col * self.cellSize,
                self.margin + self.rows * self.cellSize,
                dash=(self.dashBlack, self.dashWhite)
            )

    def drawCell(self, x, y, bgColor, closedSection=255, borderColor="", bgPattern=""):
        """Draws a new cell at position (x, y) of the grid. Returns a
        2-tuple of lists: the first list contains the rectangles (at
        most 9) and the second list contains the lines (at most 8).
        These rectangles and lines represent the cell's shape for this
        pentomino piece (as defined in "info" array)
        """
        left = self.margin + y * self.cellSize
        right = left + self.cellSize
        top = self.margin + x * self.cellSize
        bottom = top + self.cellSize
        adjustValue = self.cellSize - self.pentPadding
        # sections tuple = ([rectangles], [lines])
        sections = ([], [])
        # main section
        sections[0].append(self.canvas.create_rectangle(
            left + self.pentPadding,
            top + self.pentPadding,
            1 + right - self.pentPadding,
            1 + bottom - self.pentPadding,
            fill=bgColor, outline=borderColor, stipple=bgPattern
        ))
        # border sections
        if closedSection & (1 << 0):
            sections[0].append(self.canvas.create_rectangle(
                left,
                top,
                1 + right - adjustValue,
                1 + bottom - adjustValue,
                fill=bgColor, outline=borderColor, stipple=bgPattern
            ))
        if closedSection & (1 << 1):
            sections[0].append(self.canvas.create_rectangle(
                left + self.pentPadding,
                top,
                1 + right - self.pentPadding,
                1 + bottom - adjustValue,
                fill=bgColor, outline=borderColor, stipple=bgPattern
            ))
        if closedSection & (1 << 2):
            sections[0].append(self.canvas.create_rectangle(
                left + adjustValue,
                top,
                1 + right,
                1 + bottom - adjustValue,
                fill=bgColor, outline=borderColor, stipple=bgPattern
            ))
        if closedSection & (1 << 3):
            sections[0].append(self.canvas.create_rectangle(
                left,
                top + self.pentPadding,
                1 + right - adjustValue,
                1 + bottom - self.pentPadding,
                fill=bgColor, outline=borderColor, stipple=bgPattern
            ))
        if closedSection & (1 << 4):
            sections[0].append(self.canvas.create_rectangle(
                left + adjustValue,
                top + self.pentPadding,
                1 + right,
                1 + bottom - self.pentPadding,
                fill=bgColor, outline=borderColor, stipple=bgPattern
            ))
        if closedSection & (1 << 5):
            sections[0].append(self.canvas.create_rectangle(
                left,
                top + adjustValue,
                1 + right - adjustValue,
                1 + bottom,
                fill=bgColor, outline=borderColor, stipple=bgPattern
            ))
        if closedSection & (1 << 6):
            sections[0].append(self.canvas.create_rectangle(
                left + self.pentPadding,
                top + adjustValue,
                1 + right - self.pentPadding,
                1 + bottom,
                fill=bgColor, outline=borderColor, stipple=bgPattern
            ))
        if closedSection & (1 << 7):
            sections[0].append(self.canvas.create_rectangle(
                left + adjustValue,
                top + adjustValue,
                1 + right,
                1 + bottom,
                fill=bgColor, outline=borderColor, stipple=bgPattern
            ))
        # main section's borders
        if not closedSection & (1 << 1):
            sections[1].append(self.canvas.create_line(
                left + self.pentPadding,
                top + self.pentPadding,
                1 + right - self.pentPadding,
                bottom - adjustValue
            ))
        if not closedSection & (1 << 3):
            sections[1].append(self.canvas.create_line(
                left + self.pentPadding,
                top + self.pentPadding,
                right - adjustValue,
                1 + bottom - self.pentPadding
            ))
        if not closedSection & (1 << 4):
            sections[1].append(self.canvas.create_line(
                left + adjustValue,
                top + self.pentPadding,
                right - self.pentPadding,
                1 + bottom - self.pentPadding
            ))
        if not closedSection & (1 << 6):
            sections[1].append(self.canvas.create_line(
                left + self.pentPadding,
                top + adjustValue,
                1 + right - self.pentPadding,
                bottom - self.pentPadding
            ))
        # border sections' borders
        if (closedSection & (1 << 1)) and not (closedSection & (1 << 0)):
            sections[1].append(self.canvas.create_line(
                left + self.pentPadding,
                top,
                right - adjustValue,
                1 + bottom - adjustValue
            ))
        if (closedSection & (1 << 1)) and not (closedSection & (1 << 2)):
            sections[1].append(self.canvas.create_line(
                left + adjustValue,
                top,
                right - self.pentPadding,
                1 + bottom - adjustValue
            ))
        if (closedSection & (1 << 4)) and not (closedSection & (1 << 2)):
            sections[1].append(self.canvas.create_line(
                left + adjustValue,
                top + self.pentPadding,
                1 + right,
                bottom - adjustValue
            ))
        if (closedSection & (1 << 4)) and not (closedSection & (1 << 7)):
            sections[1].append(self.canvas.create_line(
                left + adjustValue,
                top + adjustValue,
                1 + right,
                bottom - self.pentPadding
            ))
        if (closedSection & (1 << 6)) and not (closedSection & (1 << 7)):
            sections[1].append(self.canvas.create_line(
                left + adjustValue,
                top + adjustValue,
                right - self.pentPadding,
                1 + bottom
            ))
        if (closedSection & (1 << 6)) and not (closedSection & (1 << 5)):
            sections[1].append(self.canvas.create_line(
                left + self.pentPadding,
                top + adjustValue,
                right - adjustValue,
                1 + bottom
            ))
        if (closedSection & (1 << 3)) and not (closedSection & (1 << 5)):
            sections[1].append(self.canvas.create_line(
                left,
                top + adjustValue,
                1 + right - adjustValue,
                bottom - self.pentPadding
            ))
        if (closedSection & (1 << 3)) and not (closedSection & (1 << 0)):
            sections[1].append(self.canvas.create_line(
                left,
                top + self.pentPadding,
                1 + right - adjustValue,
                bottom - adjustValue
            ))
        return sections

    def init(self):
        self.over = False
        self.onBoard = 0
        self.rotation = 0
        self.lastPosition = None
        self.lastPainted = None
        self.lastChanged = None
        self.editMode = False
        self.history = []
        self.redrawAll()
        self.refreshScore()
        # set up events
        self.bind("<Motion>", self.mouseOver)
        self.bind("<Leave>", self.mouseOut)
        self.bind("<Button-1>", self.mouseClick)
        self.bind("<Button-4>", self.rollWheel)
        self.bind("<Button-5>", self.rollWheel)
        self.bind("<MouseWheel>", self.rollWheelDelta)
Пример #57
0
class rmap():
    _var = [1]
    _nc = 0
    _nr = 0
    _r = 0
    _c = 0
    _size = 0
    _w = 0
    _d = 0
    _NoneUpdate = False
    _Nonelabel = False
    _Nonegettext = False
    _field = []
    _endPoint = (0,0)

    _robot = '' # рисунок Робота (синее кольцо)
    _park = ''

    _canvas = ''
    sleep = 0.5
    _task = ''
    _solve = ''
    _test = ''
    _res = ''
    _bum = 0

    m = []
    m.append('task1')
    m.append('task2')
    m.append('task3')
    m.append('task4')
    m.append('task5')

    m.append('task6')
    m.append('task7')
    m.append('task8')
    m.append('task9')
    m.append('task10')
    m.append('task11')
    m.append('task12')
    m.append('task13')

    class _v: # будет содержать изображение текста и квадратиков закраски и меток. Чтобы можно было "поднимать изображение"
        text = '' 
        label = '' 
        color = ''

    class _Tcell():
        color = ''
        text = ''
        label = '' # color
        wUp = False
        wLeft = False
        v = ''

    def help(self):
        """ Вывести список команд Робота
Примеры использования по команде r.help_full()
"""
        print("""
Пояснение по каждой команде: print команда.__doc__
Например:
print r.color.__doc__

---=: Команды перемещения :=---
r.rt() # Вправо
r.lt() # Влево
r.dn() # Вниз
r.up() # Вверх
r.jumpTo(r,c) # Прыжок в точку. Без особых указаний в задачах не использовать
-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=

---=: Команды изменения среды :=---
r.pt([цвет]) # Закрасить указанным цветом. По умолчанию зеленым
r.sw(направление) # Установить стену с указанной стороны
r.settext(тест) # Вписать в клетку текст
-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=

---=: Команды обратной связи :=---
r.cl() # Каким цветом закрашена клетка? r.color()
r.label() # Какого цвета метка в клетке?
r.gettext() # Какой текст в клетке?

r.getCoords() # Где Робот?
r.getCoordR() # В какой строке Робот?
r.getCoordС() # В каком столбце Робот?

r.fu() # Сверху свободно?
r.fd() # Снизу свободно?
r.fr() # Справа свободно?
r.fl() # Слева свободно?

r.wu() # Сверху стена?
r.wd() # Снизу стена?
r.wr() # Справа стена?
r.wl() # Слева стена?

r.isPark # Робот на парковке?
-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=

---=: Дополнительно :=---
r.sleep = 0.4 # Установить размер задержки после каждого хода. Меньше значение - быстрее Робот.
r._NoneUpdate = False # Отключить прорисовку поля
r._NoneUpdate = True # Включить прорисовку поля
r.demo() # Показать, что нужно сделать в текущей задаче
r.demoAll() # Показать все задачи (с решениями, по очереди)
r.randcolor() # Генерировать случайный цвет
-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=

""")

    def help_full(self):
        """ Примеры. Для получения списка команд r.help()
Примеры использования по команде r.help_full()
Больше информации по каждой команде: print команда.__doc__
Например:
print r.color.__doc__
"""
        print("""
Не реализовано в данной версии. 
Если нужно - пишите на [email protected] или на сайте progras.ru
""")

    def demo(self):
        """Показать выполнение задачи
Пример использования:
#-------------------
r.demo()
#-------------------

Для уcкорения использовать r.sleep = 0.01
В задании 10-3(4/5) можно отключить обновление экрана
#-------------------
r._NoneUpdate = True
r.demo()
r._NoneUpdate = False
#-------------------
"""
        global r
        r = self
        exec(self._solve)

    def demoAll(self):
        """Показать выполнение всех заданий в автоматическом режиме
Пример использования:

#-------------------
r.demoAll()
#-------------------

Для того, чтобы Робот двигался быстрее, используйте
#-------------------
r.sleep = 0 
r.demoAll()
#-------------------

"""
        global r
        r = self
        for x in r.m:
            r.lm(x)
            print(x)
            r.demo()
            r.pause()
          
    def __init__(self):
        self._w = 4 # толщина стен
        self._d = 4 # на столько меньше клетки закраска (с каждой стороны)
        self.sleep = 0.5 # замедление
        self._font_size = self._size // 2
        self._tk = Tk()
        self._tk.geometry('+0+0')
        x = (self._tk.winfo_screenwidth() - self._tk.winfo_reqwidth()) / 3
        y = (self._tk.winfo_screenheight() - self._tk.winfo_reqheight()) / 4
        self._tk.wm_geometry("+%d+%d" % (x, y))
        self._tk.title('Robot-hobot')
        self._canvas = Canvas(self._tk, width=(self._size*(self._nc+1)), height=(self._size*(self._nr+1)), bg="gray")

        buttons = Frame(self._tk)

        self.task = Label (self._tk, justify = 'left')
        self.res = Label (self._tk, justify = 'left')

        self._but_start = Button(buttons,text = 'start',width=10,height=1)
        self._but_start.bind('<ButtonRelease-1>',self.but1)

        self._but_demo = Button(buttons,text = 'demo',width=10,height=1)
        self._but_demo.bind('<ButtonRelease-1>',self.but_demo)

        self._but_reload = Button(buttons,text = 'reload',width=10,height=1)
        self._but_reload.bind('<ButtonRelease-1>',self.but_reload)

        self._but_load_next = Button(buttons,text = 'load next',width=10,height=1)
        self._but_load_next.bind('<ButtonRelease-1>',self.but_load_next)

        buttons.grid(row=0, column=0, sticky = "w") 
        self._canvas.grid(row=1, column=0, sticky = "e")
        self._but_start.pack(side = "left")
        self._but_demo.pack(side = "left")
        self._but_reload.pack(side = "left")
        self._but_load_next.pack(side = "left")
        self.task.grid(row=3, column=0, sticky = "w")
        self.res.grid(row=4, column=0, sticky = "w")

##        self.loadmap()
    def but_load_next(self,event):
        print ("load next")
        index = self.m.index(self._cur_map)
        if index < len(self.m)-1:
            self.lm(self.m[index+1])
        else:
            self.lm(self.m[0])

    	
    def but_demo(self,event):
        print ("demo")
        self.demo()

    def but1(self,event):
        print ('start')
        #self.lm(self._cur_map)
        self.solve_task()

    def but_reload(self,event):
        print ("reload")
        self.lm(self._cur_map)

            
    def clear (self):
        "Очистка данных (без перерисовки)"
        self._canvas.delete('all')
        self._field = []
        self._park = []
        self._Nonelabel = False
        self._NoneisPark = False
        self._Nonesettext = False
        self._test = ''
        self._res = ''
        self._bum = 0

        for r in range(1,self._nr+2):
            row = []
            for c in range(1,self._nc+2):
                row.append (self._Tcell())
            self._field.append(row)

        for r in range (1,self._nr):
            for c in range(1,self._nc):
                self._field[r][c].text = ''
                self._field[r][c].color = ''
                self._field[r][c].label = ''
                self._field[r][c].wUp = False
                self._field[r][c].wLeft = False
                self._field[r][c].v = self._v()
                
        for c in range (1,self._nc):
            self._field[1][c].wUp = True
            self._field[self._nr][c].wUp = True

        for r in range (1,self._nr):
            self._field[r][1].wLeft = True
            self._field[r][self._nc].wLeft = True

        self._solve = ''
        self._r = 1
        self._c = 1

    def _paintMap(self): 
        "Перерисовка  по имеющимся данным"
        remc = self._c
        remr = self._r
        size = self._size
        sleep = self.sleep
        self.sleep = 0

        self._bg = [self._canvas.create_rectangle(1,1,(size*(self._nc+1)), (size*(self._nr+1)), fill="gray")]
        # создать поле
        
        for r in range (1, self._nr+1):
            self._bg.append(self._canvas.create_line(size,r*size,self._nc*size,r*size))
            if r < self._nr: self._canvas.create_text(size/2,r*size+size/2,text=r)
        for c in range (1, self._nc+1):
            self._bg.append(self._canvas.create_line(c*size,size,c*size,self._nr*size))
            if c < self._nc: self._bg.append(self._canvas.create_text(c*size+size/2,size/2,text=c))
        # клетки и номера столбцов и строк

        for r in range (1,self._nr): 
            for c in range(1,self._nc):
                self._r = r
                self._c = c
                if  self._field[r][c].wUp: # стена сверху
                    self.setWall('up')
                if  self._field[r][c].wLeft: # стена слева
                    self.setWall('left')
                if  self._field[r][c].color != '' : # закраска
                    self.paint(self._field[r][c].color)
                if  self._field[r][c].label != '' : # метка0000
                    d = self._d 
                    x1 = self._size*(c)
                    x2 = self._size*(c+1)
                    y1 = self._size*(r)
                    y2 = self._size*(r+1)
                    self._canvas.delete(self._field[r][c].v.label)
                    self._field[r][c].v.label = self._canvas.create_rectangle(x1+d,y1+d,x2-d,y2-d, width = d-1, outline = self._field[r][c].label)
                    self._canvas.lift(self._robot)
                self.settext(self._field[r][c].text) # текст

        for self._c in range (1,self._nc): 
                if  self._field[self._nr][self._c].wUp: # стена сверху
                    self.setWall('down')

        for self._r in range (1,self._nr): 
                if  self._field[self._r][self._nc].wLeft: # стена слева
                    self.setWall('right')

        r = self._endPoint[0]
        c = self._endPoint[1]
        self._canvas.delete(self._park)
        if r > 0 and c > 0:
            self._park = self._canvas.create_oval (c*size+6,r*size+6, c*size+size-6,r*size+size-6, width = 3, outline = 'yellow')
        # конечная точка
        
        self.jumpTo((remr,remc))
        self._task = '\n'+self._task
        self.task.config(text = self._task)
        self.res.config()
        self._update()
        self.sleep = sleep
        #self.pause()

        
    def _update(self):
        "Обновить canvas"
        if not self._NoneUpdate:
            self._canvas.update()
            time.sleep(self.sleep)
        

    def start(self,fun):
        self.solve_task = fun
        self._tk.mainloop()


##Робот    

    def pause(self,t=1):
        """Приостановка выполнения программы. Пауза в секундах. 
#-------------------
r.pause() # пауза в одну секунду
#-------------------
r.pause(2) # пауза две секунды
#-------------------
"""
        time.sleep(t)
		
    def left(self, a = 1):
        """Шаг влево
#-------------------
r.left()
#-------------------
r.lt()
#-------------------
r.lt(3) 
#-------------------
"""
        if a == 1:
            if self.freeLeft():
                self._c -= 1
                self._canvas.move(self._robot,-self._size*a,0)
                self._update()
            else:
                self._stop()
        else :
            for z in range(0,a):
                self.left()

    def right(self, a = 1):
        """ Шаг вправо        
#-------------------
r.right()
#-------------------
r.rt()
#-------------------
r.rt(5)
#-------------------
"""        
        if a == 1:
            if self.freeRight():
                self._c += 1
                self._canvas.move(self._robot,self._size*a,0)
                self._update()
            else:
                self._stop()
                
        else :
            for z in range(0,a):
                self.right()
        
    def up(self, a = 1):
        """Шаг вверх
#-------------------
r.up()
#-------------------
r.up(3)
#-------------------
"""
        if a == 1:
            if self.freeUp():
                self._r -= 1
                self._canvas.move(self._robot,0,-self._size*a)
                self._update()
            else:
                self._stop()
        else :
            for z in range(0,a):
                self.up()
        
    def down(self, a = 1):
        """ Шаг вниз
#-------------------
r.down()
#-------------------
r.dn()
#-------------------
r.dn(4)
#-------------------
"""
        if a == 1:
            if self.freeDown():
                self._r += 1
                self._canvas.move(self._robot,0,self._size*a)
                self._update()
            else:
                self._stop()
        else :
            for z in range(0,a):
                self.down()
                
    def jumpTo(self,coord=(1,1)):
        """Прыжок в клетку с указанными координами. Через стены.
#-------------------
r.jumpTo((2,3)) # Робот окажется в третьем столбце второй строки
#-------------------
"""

        r = coord[0]
        c = coord[1]
        if ( 0 < r < self._nc) and (0 < c < self._nc):
            self._r = r
            self._c = c
            size = self._size
            self._canvas.coords(self._robot, c*size+4,r*size+4, c*size+size-4,r*size+size-4)
            self._canvas.lift(self._robot)
            self._update()
        else:
            print("Попытка переместиться за пределы поля. Отказано.")

    def paint (self, color = 'green'):
        """ Закрасить текущую клетку выбранным цветом. Если цвет не указан, то зеленым
#-------------------
r.paint() # Закрасит текущую клетку зеленым цветом
#-------------------
r.pt() # Закрасит текущую клетку зеленым цветом
#-------------------
r.pt('red') # Закрасит текущую клетку красным цветом
#-------------------
r.pt(r.randcolor()) # Закрасит текущую клетку случайным цветом
#-------------------
r.pt(r.label()) # Закрасит текущую клетку цветом метки в этой клетке
#-------------------
"""
        d = self._d+1
        self._field[self._r][self._c].color = color

        x1 = self._size*(self._c)
        x2 = self._size*(self._c+1)
        y1 = self._size*(self._r)
        y2 = self._size*(self._r+1)
        self._canvas.delete(self._field[self._r][self._c].v.color)
        self._field[self._r][self._c].v.color = self._canvas.create_rectangle(x1+d,y1+d,x2-d,y2-d, width = 0, fill = color)
        self._canvas.lift(self._field[self._r][self._c].v.text)
        self._canvas.lift(self._robot)
        self._canvas.lift(self._park)
        self._update()

    def setWall (self, target):
        """ Установить стену с указанной стороны
#-------------------
r.sw('up') # Установить стену сверху
#-------------------
r.sw('left') # Установить стену слева 
#-------------------
r.sw('down') # Установить стену снизу
#-------------------
r.sw('right') # Установить стену справа
#-------------------
"""
        size = self._size
        w = self._w
        if target == 'up':
            r = self._r
            c = self._c
            x1 = size*(c)-1
            x2 = size*(c+1)+1
            y1 = size*(r)
            y2 = size*(r+1)
            self._field[r][c].wUp = True
            self._canvas.create_line(x1,y1,x2,y1, width = w)
        elif target == 'left':
            r = self._r
            c = self._c
            x1 = size*(c)
            x2 = size*(c+1)
            y1 = size*(r)-1
            y2 = size*(r+1)+1
            self._field[r][c].wLeft = True
            self._canvas.create_line(x1,y1,x1,y2, width = w)
        elif target == 'down':
            r = self._r+1
            c = self._c
            x1 = size*(c)-1
            x2 = size*(c+1)+1
            y1 = size*(r)
            y2 = size*(r+1)
            self._field[r][c].wDown = True
            self._canvas.create_line(x1,y1,x2,y1, width = w)
        elif target == 'right':
            r = self._r
            c = self._c+1
            x1 = size*(c)
            x2 = size*(c+1)
            y1 = size*(r)-1
            y2 = size*(r+1)+1
            self._field[r][c].wRight = True
            self._canvas.create_line(x1,y1,x1,y2, width = 4)
        self._update()

    def wallUp (self):
        """ Возвращает истину, если сверху есть стена
#-------------------
if r.wallUp(): r.pt() # Закрасить, если сверху стена
#-------------------
if r.wu(): r.pt() # Закрасить, если сверху стена
#-------------------
if r.wu(): 
    r.pt() # Закрасить, если сверху стена
    r.rt() # Перейти вправо
#-------------------
while r.wu(): # Идти вправо, пока сверху есть стена
    r.rt()
"""
        return self._field[self._r][self._c].wUp 

    def wallDown (self):
        """ Возвращает истину, если снизу есть стена
#-------------------
if r.wallDown(): r.pt() # Закрасить, если снизу стена
#-------------------
if r.wd(): r.pt() # Закрасить, если снизу стена
#-------------------
if r.wd(): 
    r.pt() # Закрасить, если снизу стена
    r.rt() # Перейти вправо
#-------------------
while r.wd(): # Идти вправо, пока снизу есть стена
    r.rt()
"""
        return self._field[self._r+1][self._c].wUp 

    def wallLeft (self):
        """ Возвращает истину, если слева есть стена
#-------------------
if r.wallLeft(): r.pt() # Закрасить, если слева стена
#-------------------
if r.wl(): r.pt() # Закрасить, если слева стена
#-------------------
if r.wl(): 
    r.pt() # Закрасить, если слева стена
    r.dn() # Перейти вниз
#-------------------
while r.wl(): # Идти вниз, пока слева есть стена
    r.dn()
"""
        return self._field[self._r][self._c].wLeft

    def wallRight (self):
        """ Возвращает истину, если справа есть стена
#-------------------
if r.wallRight(): r.pt() # Закрасить, если справа стена
#-------------------
if r.wr(): r.pt() # Закрасить, если справа стена
#-------------------
if r.wr(): 
    r.pt() # Закрасить, если справа стена
    r.dn() # Перейти вниз
#-------------------
while r.wr(): # Идти вниз, пока справа есть стена
    r.dn()
"""
        return self._field[self._r][self._c+1].wLeft

    def freeUp (self):
        """ Возвращает истину, если сверху свободно (нет стены)
#-------------------
if r.freeUp(): r.pt() # Закрасить, если сверху свободно
#-------------------
if r.fu(): r.up() # Шагнуть вверх, если сверху свободно
#-------------------
if r.fu(): 
    r.up() # Шагнуть вверх
    r.pt() # Закрасить
    r.dn() # Перейти вниз
#-------------------
while r.fu(): # Идти вверх, пока сверху свободно
    r.up()
"""
        return not self._field[self._r][self._c].wUp 

    def freeDown (self):
        """ Возвращает истину, если снизу свободно (нет стены)
#-------------------
if r.freeDown(): r.pt() # Закрасить, если снизу свободно
#-------------------
if r.fd(): r.dn() # Шагнуть вверх, если снизу свободно
#-------------------
if r.fd(): 
    r.dn() # Шагнуть снизу
    r.pt() # Закрасить
    r.up() # Перейти вверх
#-------------------
while r.fd(): # Идти вниз, пока снизу свободно
    r.dn()
"""
        return not self._field[self._r+1][self._c].wUp 

    def freeLeft (self):
        """ Возвращает истину, если слева свободно (нет стены)
#-------------------
if r.freeLeft(): r.pt() # Закрасить, если слева свободно
#-------------------
if r.fl(): r.lt() # Шагнуть влево, если слева свободно
#-------------------
if r.fl(): 
    r.lt() # Шагнуть влево
    r.pt() # Закрасить
    r.rt() # Перейти вправо
#-------------------
while r.fl(): # Идти влево, пока слева свободно
    r.lt()
"""
        return not self._field[self._r][self._c].wLeft

    def freeRight (self):
        """ Возвращает истину, если снизу свободно (нет стены)
#-------------------
if r.freeDown(): r.pt() # Закрасить, если снизу свободно
#-------------------
if r.fd(): r.dn() # Шагнуть вверх, если снизу свободно
#-------------------
if r.fd(): 
    r.dn() # Шагнуть снизу
    r.pt() # Закрасить
    r.up() # Перейти вверх
#-------------------
while r.fd(): # Идти вниз, пока снизу свободно
    r.dn()
"""
        return not self._field[self._r][self._c+1].wLeft

    def getCoords(self):
        " Возвращает координаты в виде (row,column)"
        return (self._r,self._c)

    def getCoordR(self):
        " Возвращает номер строки, в которой находиться Робот"
        return self._r

    def getCoordC(self):
        " Возвращает номер столбца, в которой находиться Робот"
        return self._c

    def isPark (self):
        " Возвращает истину, если Робот находиться на парковке"
        if self._NoneisPark: self.null()
        else: return self._endPoint == self.getCoords()

    def color (self):
        """ Возвращает цвет, которым закрашена клетка
Можно использовать для проверки, закрашена ли клетка:
#-------------------
# Закрасить, если сверху закрашено
r.up()
if r.color():
    r.dn()
    r.pt()
else:
    r.dn()
#-------------------
if r.color() == 'red': r.rt() # Вправо, если закрашено красным
#-------------------
"""
        return self._field[self._r][self._c].color
    
    def randcolor (self):
        """ Возвращает случайный цвет
#-------------------
r.pt(r.randcolor()) # Закрасить случайным цветом
#-------------------
# Закрасить соседнюю клетку тем же цветом, что и текущая
x = r.color()
r.rt()
r.pt(x)
#-------------------
"""
        cr = rnd(1,255,10)
        cg = rnd(1,255,10)
        cb = rnd(1,255,10)
        color =  "#%02X%02X%02X" %(cr,cg,cb)
        return str(color)


    def label (self):
        """ Возвращает цвет метки текущей клетки
#-------------------
if r.label() == 'red': r.pt('red') # Закрасить клетку красным, если метка красная
#-------------------
"""
        if self._Nonelabel: self.null()
        else: return self._field[self._r][self._c].label
    
    def gettext(self):
        """ Возвращает текст, записанный в ячейке. 
#-------------------
if r.gettext() != '': r.rt() # Перейти вправо, если в ячейке есть какой-нибудь текст
#-------------------
if r.gettext() == '3': r.rt() # Перейти вправо, если в ячейке записано 3
#-------------------
n = r.gettext()
if n: r.rt(n) # Перейти вправо на количество шагов, указанное в клетке
#-------------------
"""
        if self._Nonegettext: self.null()
        else: return self._field[self._r][self._c].text
    
    def settext(self,text):
        """ Записать текст в клетку
#-------------------
r.settext(3)
#-------------------
"""
        self._field[self._r][self._c].text = text
        d = 1
        x1 = self._size*(self._c)
        x2 = self._size*(self._c+1)
        y1 = self._size*(self._r)
        y2 = self._size*(self._r+1)
        self._canvas.delete(self._field[self._r][self._c].v.text)
        self._field[self._r][self._c].v.text =  self._canvas.create_text(self._c*self._size+self._size/2,self._r*self._size+self._size/2,text =
                                 self._field[self._r][self._c].text, font = ('Helvetica', self._font_size,'bold'))
        self._update()

    def _stop (self):
        print ("Bum!")
        self._bum = 1
        self._canvas.delete(self._robot)
        x = self._c
        y = self._r
        
        self._robot = self._canvas.create_oval(
            x*self._size+2*self._d,y*self._size+2*self._d,
            x*self._size+self._size-2*self._d,y*self._size+self._size-2*self._d,
            fill = '#FF0000')

    def null (self, *args):
        print('Эта команда запрещена к использованию в данной задаче. Ищите другой способ')
        return ''


    def loadmap(self,mn=m[0],variant=0):
        """ Загрузить карту (задачу)
#-------------------
r.loadmap('task10-5')
#-------------------
r.lm('task10-5') # Загрузить задачу по названию
#-------------------
r.lm(r.m[5]) # Загрузить задачу по номеру
#-------------------
# Вывести полный список названий и номеров заданий
for x in r.m:
    print r.m.index(x),x
#-------------------
"""
        self._tk.title(mn)
        self._cur_map = mn
        self._NoneUpdate = False
        self._endPoint = (0, 0)
#        self._NoneUpdate = True

        if mn == 'task1':
            self._nc = 7
            self._nr = 5
            self._size = 30

            self.clear()
            self._r = 3
            self._c = 2

            self._solve = ''
            self._endPoint = (3,5)
            self._task = 'Необходимо перевести Робота по лабиринту\n' \
                         ' из начального положения в конечное.\n'

            self._field[2][2].wUp = True
            self._field[2][3].wUp = True
            self._field[2][4].wUp = True
            self._field[2][5].wUp = True

            self._field[4][2].wUp = True
            self._field[4][3].wUp = True
            self._field[4][4].wUp = True
            self._field[4][5].wUp = True

            self._field[2][4].wLeft = True
            self._field[3][3].wLeft = True
            self._field[3][5].wLeft = True

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task2':
            self._nc = 16
            self._nr = 4
            self._size = 30

            self.clear()
            self._r = 3
            self._c = 1

            self._solve = ''
            
            self._task = 'Составьте программу рисования узора.\n'

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task3':
            self._nc = 10
            self._nr = 5
            self._size = 30
            self.clear()
            self._r = 2
            self._c = 1

            self._endPoint = (2,9)
            self._solve = ''
            self._task = 'Необходимо провести Робота вдоль коридора\n' \
                         ' из начального положения в конечное,\n' \
                         ' заглядывая в каждый боковой коридор.'

            for i in range(2, 9):
                self._field[2][i].wUp = True
                if i%2 == 0:
                    self._field[3][i].wUp = True
                else:
                    self._field[4][i].wUp = True

                if i < 8:
                    self._field[3][i+1].wLeft = True

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task4':
            self._nc = 8
            self._nr = 12
            self._size = 30
            self.clear()
            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            for i in range(0, 5):
                for j in range(0, 3):
                    self._field[6+2*j-i][2+i].label = 'red'

            self._solve = ''
            self._task = 'Составьте программу закрашивания\n' \
                         ' клеток поля, отмеченных звездочкой.\n'

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task5':
            self._nc = 11
            self._nr = 10
            self._r = 1
            self._c = 1
            self._size = 30

            self.clear()
            self._solve = ''
            self._task = 'Составьте программу рисования узора.'

        ##--------------------------------------------------------------------------------------------
        ##--------------------------------------------------------------------------------------------
        elif mn == 'task6':
            self._nc = 25
            self._nr = 25
            self._r = 1
            self._c = 1
            self._size = 20
            self.clear()
            self._solve = ''
            self._task = 'Составьте программу рисования фигуры в виде буквы "Т".\n' \
                         ' Вертикальные и горизонтальные размеры пользователь вводит\n' \
                         ' с клавиатуры. Ввод данных можно осуществлять любым способом.\n'

        ##-------------------------------------------------------------------------------------------------------
        elif mn == 'task7':
            self._nc = 16
            self._nr = 11
            self._size = 25
                
            self.clear()

            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            self._field[3][2].wUp = True
            self._field[2][9].wUp = True
            self._field[3][12].wUp = True
            self._field[6][12].wUp = True
            self._field[7][3].wUp = True
            self._field[7][9].wUp = True
            self._field[8][6].wUp = True
            self._field[9][2].wUp = True
            self._field[9][11].wUp = True

            for i in range(0, 4):
                self._field[4][5+i].wUp = True
                self._field[5][5+i].wUp = True


            self._solve = ''
        
            self._task = 'Где-то в поле Робота находится горизонтальный коридор шириной в одну клетку\n' \
                         ' неизвестной длины. Робот из верхнего левого угла поля должен дойти до\n' \
                         ' коридора и закрасить клетки внутри него, как указано в задании. По полю\n' \
                         ' Робота в произвольном порядке располагаются стены, но расстояние \n' \
                         'между ними больше одной клетки.\n'
        ##--------------------------------------------------------------------------------------------
        elif mn == 'task8':
            self._nc = 16
            self._nr = 11
            self._size = 25

            self.clear()

            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            self._field[2][6].wLeft = True
            self._field[3][6].wLeft = True
            self._field[5][6].wLeft = True
            self._field[6][6].wLeft = True
            self._field[7][6].wLeft = True
            self._field[8][6].wLeft = True

            self._solve = ''
            self._task = 'Где-то в поле Робота находится вертикальная стена с отверстием в одну клетку,\n' \
                         ' размеры которой неизвестны. Робот из произвольной клетки должен дойти до\n' \
                         ' стены и закрасить клетки как показано в задании.\n'

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task9':
            self._nc = 20
            self._nr = 20
            self._size = 25

            self.clear()

            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            c = rnd(2,16)
            r = rnd(2,16)
            w = rnd(3,8)
            h = rnd(3,8)
            if c + w >= self._nc: w = self._nc-c
            if r + h >= self._nc: h = self._nr-r

            for rcount in range(0,h):
                for ccount in range(0,w):
                    self._field[r + rcount][c+ccount].label = 'green'

            self._solve = ''

            self._task = 'На поле находится квадрат из закрашенных клеток. Вычислить и вывести на экран площадь квадрата.\n'

        ##--------------------------------------------------------------------------------------------
        elif mn == 'task10':
            self._nc = 15
            self._nr = 11
            self._size = 30
            self.clear()
            self._r = 2
            self._c = 1

            self._field[2][1].wUp = True
            self._field[2][2].wUp = True
            self._field[2][4].wUp = True
            self._field[2][5].wUp = True
            self._field[2][6].wUp = True
            self._field[2][8].wUp = True
            self._field[2][9].wUp = True
            self._field[2][11].wUp = True
            self._field[2][12].wUp = True
            self._field[2][13].wLeft = True

            self._field[3][1].wUp = True
            self._field[3][2].wUp = True
            self._field[3][3].wUp = True
            self._field[3][4].wUp = True
            self._field[3][6].wUp = True
            self._field[3][7].wUp = True
            self._field[3][8].wUp = True
            self._field[3][10].wUp = True
            self._field[3][11].wUp = True
            self._field[3][12].wLeft = True

            self._field[4][3].wLeft = True
            self._field[4][3].wUp = True
            self._field[4][4].wUp = True
            self._field[4][5].wUp = True
            self._field[4][6].wUp = True
            self._field[4][8].wUp = True
            self._field[4][9].wUp = True
            self._field[4][10].wUp = True
            self._field[4][11].wUp = True
            self._field[4][13].wLeft = True

            self._field[5][3].wLeft = True
            self._field[5][4].wLeft = True
            self._field[5][4].wUp = True
            self._field[5][6].wUp = True
            self._field[5][7].wUp = True
            self._field[5][8].wUp = True
            self._field[5][10].wUp = True
            self._field[5][11].wUp = True
            self._field[5][12].wUp = True

            self._field[6][3].wLeft = True
            self._field[6][4].wUp = True
            self._field[6][5].wLeft = True

            self._field[7][3].wUp = True
            self._field[7][4].wLeft = True
            self._field[7][6].wUp = True
            self._field[7][7].wLeft = True

            self._field[8][4].wUp = True
            self._field[8][5].wUp = True
            self._field[8][6].wLeft = True
            self._field[8][7].wUp = True
            self._field[8][8].wLeft = True

            self._field[9][6].wUp = True
            self._field[9][7].wLeft = True
            self._field[9][8].wUp = True
            self._field[9][9].wUp = True
            self._field[9][10].wLeft = True

            self._field[10][7].wUp = True
            self._field[10][9].wLeft = True
            self._field[10][10].wLeft = True

            self._endPoint = (10,1)
            self._solve = """
"""

            self._task = 'Необходимо провести Робота по коридору шириной в одну клетку из начального положения до конца коридора, \n' \
                         'закрашивая при этом все клетки коридора, которые имеют выход. Выходы размером в одну клетку располагаются \n' \
                         'произвольно по всей длине коридора. Коридор заканчивается тупиком. Коридор имеет два горизонтальных и \n' \
                         'диагональный участки. Пример коридора показан на рисунке.\n'

        elif mn == 'task11':
            self._nc = 15
            self._nr = 11
            self._size = 30
            self.clear()

            self._r = rnd(1, self._nr)
            self._c = rnd(1, self._nc)

            for i in range(1,self._nr):
                for j in range(1,self._nc):
                    self._field[i][j].text = str(rnd(0, 10))

            self._task = 'На поле 10х15 каждой в каждой клетке записана цифра (от 0 до 9).\n Закрасить квадрат 2х2 с наименьшей суммой значений клеток.'

        elif mn == 'task12':
            self._nc = 15
            self._nr = 6
            self._size = 30
            self.clear()

            self._r = 2
            self._c = 13

            self._field[2][2].wUp = True
            self._field[2][3].wLeft = True
            self._field[3][3].wLeft = True
            self._field[4][3].wLeft = True
            self._field[5][3].wUp = True
            self._field[5][4].wUp = True
            self._field[4][5].wLeft = True
            self._field[3][5].wLeft = True
            self._field[2][5].wLeft = True
            self._field[2][5].wUp = True
            self._field[2][6].wLeft = True
            self._field[3][6].wLeft = True
            self._field[4][6].wLeft = True
            self._field[5][6].wUp = True
            self._field[5][7].wUp = True
            self._field[5][8].wUp = True
            self._field[4][9].wLeft = True
            self._field[3][9].wLeft = True
            self._field[2][9].wLeft = True
            self._field[2][9].wUp = True
            self._field[2][10].wUp = True
            self._field[2][11].wLeft = True
            self._field[3][11].wLeft = True
            self._field[4][11].wLeft = True
            self._field[5][11].wUp = True
            self._field[4][12].wLeft = True
            self._field[3][12].wLeft = True
            self._field[2][12].wLeft = True
            self._field[2][12].wUp = True
            self._field[2][13].wUp = True


            self._task = 'Робот движется вдоль стены, профиль которой показан на рисунке,\n' \
                         ' от начального положения до конца стены. Необходимо закрасить\n' \
                         ' все внутренние углы стены, как показано на примере. Размеры стены\n могут быть произвольны.'

        elif mn == 'task13':
            self._nc = 20
            self._nr = 20
            self._size = 25

            self.clear()

            self._r = rnd(self._nr/2, self._nr)
            self._c = rnd(self._nc/2, self._nc)

            col = rnd(2, self._nc/2)
            row = rnd(4, self._nr/2)
            height = rnd(4, self._nr-4)

            if row + height >= self._nr:
                height = self._nr - row-1

            for i in range(row, row+height):
                self._field[i][col].wLeft = True

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

        ##--------------------------------------------------------------------------------------------
# сделать прямое управление с демонстрацией датчиков и возможностей
# при запуске робота создавать task.py и справочник :)
# сделать робота без клеток !!!
        ##--------------------------------------------------------------------------------------------
        ##--------------------------------------------------------------------------------------------
        else:
            print(mn)
            self._task = "Нет задачи с таким номером"
            self._test = '-'

        self._canvas.config(
            width=(self._size*(self._nc+1)),
            height=(self._size*(self._nr+1)))
        x = y = 1
        d = self._d
        d = 6
        self._robot = self._canvas.create_oval(
            x*self._size+d,y*self._size+d,
            x*self._size+self._size-d,y*self._size+self._size-d,
            outline = '#4400FF', width = 3)

        self._paintMap()

    lm = loadmap
    lt = left
    rt = right
    dn = down
    pt = paint
    sw = setWall
    wu = wallUp
    wd = wallDown
    wl = wallLeft
    wr = wallRight
    fu = freeUp
    fd = freeDown
    fl = freeLeft
    fr = freeRight
    cl = color
Пример #58
0
class SkylineUI(Frame):
    """
    GUI for the skyline game
    """
    def __init__(self, parent, game):
        self.game = game
        self.parent = parent
        Frame.__init__(self, parent)

        self.row, self.col = 0, 0

        self.__initUI()

    def __initUI(self):
        self.parent.title("Skyline")
        self.pack(fill=BOTH, expand=1)
        self.canvas = Canvas(self,
                             width=WIDTH,
                             height=HEIGHT)
        self.canvas.pack(fill=BOTH, side=TOP)
        clear_button = Button(self,
                              text="Reset",
                              command=self.__clear_answers)
        clear_button.pack(fill=BOTH, side=BOTTOM)

        self.__draw_grid()
        self.__draw_game()

        self.canvas.bind("<Button-1>", self.__cell_clicked)
        self.canvas.bind("<Key>", self.__key_pressed)


    def __draw_grid(self):
        """
        Draws grid divided with blue lines into 3x3 squares
        """
        for i in range(self.game.size + 3):
            color = "blue" if i % 6 == 0 else "gray"
            if i == 1 or i == self.game.size + 1:
                color = "red"

            x0 = MARGIN + i * SIDE
            y0 = MARGIN
            x1 = MARGIN + i * SIDE
            y1 = HEIGHT - MARGIN
            self.canvas.create_line(x0, y0, x1, y1, fill=color)

            x0 = MARGIN
            y0 = MARGIN + i * SIDE
            x1 = WIDTH - MARGIN
            y1 = MARGIN + i * SIDE
            self.canvas.create_line(x0, y0, x1, y1, fill=color)


    def __draw_game(self):
        
        self.canvas.delete("numbers")
        for i in range(0, self.game.size):
            for j in range(0, self.game.size):
                answer = self.game.board[i][j]
                #if answer != 0:
                x = MARGIN + (j+1) * SIDE + SIDE / 2
                y = MARGIN + (i+1) * SIDE + SIDE / 2
                original = self.game.board_object.empty_board[i][j]
                color = "black" if answer == 0 else "sea green"
                self.canvas.create_text(
                    x, y, text=answer, tags="numbers", fill=color
                )
        self.__draw_hints()


    def __clear_answers(self):
        self.game.start()
        self.canvas.delete("victory")
        self.__draw_game()


    def __draw_cursor(self):
        self.canvas.delete("cursor")
        if self.row >= 0 and self.col >= 0:
            x0 = MARGIN + self.col * SIDE + 1
            y0 = MARGIN + self.row * SIDE + 1
            x1 = MARGIN + (self.col + 1) * SIDE - 1
            y1 = MARGIN + (self.row + 1) * SIDE - 1
            self.canvas.create_rectangle(
                x0, y0, x1, y1,
                outline="red", tags="cursor"
            )


    def __cell_clicked(self, event):
        if self.game.hasWon:
            return
        x, y = event.x, event.y
        if (MARGIN < x < WIDTH - MARGIN and MARGIN < y < HEIGHT - MARGIN):
            self.canvas.focus_set()

            # get row and col numbers from x,y coordinates
            row, col = (y - MARGIN) / SIDE, (x - MARGIN) / SIDE

            # if cell was selected already - deselect it
            if (row, col) == (self.row, self.col):
                self.row, self.col = -1, -1
            else:
                self.row, self.col = int(row), int(col)
        else:
            self.row, self.col = -1, -1

        self.__draw_cursor()


    def __key_pressed(self, event):
        if self.game.hasWon:
            return
        if self.row >= 0 and self.col >= 0 and event.char in "1234":
            self.game.board[self.row-1][self.col-1] = int(event.char)
            self.col, self.row = -1, -1
            self.__draw_game()
            self.__draw_cursor()
            if self.game.check_game():
                self.__draw_victory()


    def __draw_victory(self):
        # create text
        x = y = MARGIN + 3 * SIDE + SIDE / 2
        self.canvas.create_text(
            x, y,
            text="You win!", tags="victory",
            fill="orange", font=("Arial", 32)
        )


    def __draw_hints(self):

        #draw top hints:
        for i in range(0, self.game.size):
            color = "red"
            hint = self.game.hints_top[i]
            if hint == 0:
                color="white"
            x = SIDE + MARGIN + i * SIDE + SIDE / 2
            y = MARGIN + 0 * SIDE + SIDE / 2

            self.canvas.create_text(
                x, y, text=hint, tags="numbers", fill=color
            )

        #draw bottom hints:
        for i in range(0, self.game.size):
            color = "red"
            hint = self.game.hints_bottom[i]
            if hint == 0:
                color="white"
            x = SIDE + MARGIN + i * SIDE + SIDE / 2
            y = MARGIN + (self.game.size+1) * SIDE + SIDE / 2

            self.canvas.create_text(
                x, y, text=hint, tags="numbers", fill=color
            )     

        #draw left hints:
        for i in range(0, self.game.size):
            color = "red"
            hint = self.game.hints_left[i]
            if hint == 0:
                color="white"
            x =  MARGIN + 0 * SIDE + SIDE / 2
            y = MARGIN + (i+1) * SIDE + SIDE / 2

            self.canvas.create_text(
                x, y, text=hint, tags="numbers", fill=color
            )

        #draw right hints:
        for i in range(0, self.game.size):
            color = "red"
            hint = self.game.hints_right[i]
            if hint == 0:
                color="white"
            x =  MARGIN + (self.game.size+1) * SIDE + SIDE / 2
            y = MARGIN + (i+1) * SIDE + SIDE / 2

            self.canvas.create_text(
                x, y, text=hint, tags="numbers", fill=color
            )
Пример #59
-1
class TKinterDisplay(Display):
    '''
    classdocs
    '''
    
    
    '''
    Constructor
    '''
    def __init__(self, lineThickness=3, maxH=1920, maxW=1080):
        master = Tk()
        master.maxsize(maxH, maxW)
        self.localCanvas = Canvas(master, width=400, height=400)
        
        self.currentlyRenderedWindow = None
        self.lineThickness = lineThickness
        
        self.vsb = Scrollbar(master, orient="vertical", command=self.localCanvas.yview)
        self.hsb = Scrollbar(master, orient="horizontal", command=self.localCanvas.xview)
        
        self.localCanvas.configure(yscrollcommand=self.vsb.set)
        self.localCanvas.configure(xscrollcommand=self.hsb.set)
        
        master.bind("<Configure>", self.__eventOnFrameConfigure)
        self.hsb.pack(side="bottom", fill="x")
        self.vsb.pack(side="right", fill="y")
        self.localCanvas.pack()
        self.__sampleDraw()
        
        ''''''
    @abstractmethod    
    def drawSquare(self, xywhTuple, tags=None, colour=None, content=None):
        x2 = xywhTuple[0] + xywhTuple[2]
        y2 = xywhTuple[1] + xywhTuple[3]
        square = self.localCanvas.create_rectangle(xywhTuple[0], xywhTuple[1], x2, y2, width=self.lineThickness, tags=tags, fill=colour, activeoutline="white")
        def handler(event, self=self, content=content):
                return self.__eventOnClick(event, content)
        self.localCanvas.tag_bind(square, "<ButtonRelease-1>", handler)
        return square
    
    @abstractmethod
    def drawCircle(self, xywhTuple, tags=None , colour=None, content=None):
        x2 = xywhTuple[0] + xywhTuple[2]
        y2 = xywhTuple[1] + xywhTuple[3]
        circle = self.localCanvas.create_oval(xywhTuple[0], xywhTuple[1], x2, y2, width=self.lineThickness, tags=tags, fill=colour, activeoutline="white")
        
        def handler(event, self=self, content=content):
            return self.__eventOnClick(event, content)
        self.localCanvas.tag_bind(circle, "<ButtonRelease-1>", handler)
        return circle
    
    @abstractmethod
    def connectIdWithLine(self, id1, id2, tags=None, colour=None):
        
        # Gets the coordinates of id1 and then calulates centre point
        id1tuple = self.__getCoords(id1)
        x1 = id1tuple[0] + ((id1tuple[2] - id1tuple[0]) / 2)
        y1 = id1tuple[1] + ((id1tuple[3] - id1tuple[1]) / 2)
        
        # Gets the coordinates of id2 and then calulates centre point
        id2tuple = self.__getCoords(id2)
        x2 = id2tuple[0] + ((id2tuple[2] - id2tuple[0]) / 2)
        y2 = id2tuple[1] + ((id2tuple[3] - id2tuple[1]) / 2)
        
        # Calculates, using trig, the angle of the line at shape id1. This gives the radius of the ellipse
        opposite = y1 - y2
        adjacent = x1 - x2
        x1angle = 0
        x2angle = 0
        hyp = 0
        if adjacent != 0 and opposite != 0:
            hyp = math.sqrt(math.pow(opposite, 2) + math.pow(adjacent, 2))
            x1angle = math.tan(opposite / adjacent)
            x2angle = math.tan(adjacent / opposite)           
        else:
            
            if opposite == 0:
                hyp = adjacent
            else:
                hyp = opposite    
            x1angle = math.radians(90)
            x2angle = math.radians(270)
        
        a1 = (id1tuple[2] - id1tuple[0]) / 2
        b1 = (id1tuple[3] - id1tuple[1]) / 2
        
        a2 = (id2tuple[2] - id2tuple[0]) / 2
        b2 = (id2tuple[3] - id2tuple[1]) / 2
        
        r1 = a1 * b1 / (math.sqrt(((a1 * a1) * (math.pow(math.sin(x1angle), 2))) + ((b1 * b1) * math.pow(math.cos(x1angle), 2))))
        r2 = a2 * b2 / (math.sqrt(((a2 * a2) * (math.pow(math.sin(x2angle), 2))) + ((b2 * b2) * math.pow(math.cos(x2angle), 2))))
        
        x1 = x1 + ((r1 / hyp) * (x2 - x1))
        y1 = y1 + ((r1 / hyp) * (y2 - y1))
        
        #x2 = x2 + ((r2 / hyp) * (x1 - x2))
        #y2 = y2 - ((r2 / hyp) * (y1 - y2))
                    
        return self.__drawLine(x1, y1, x2, y2, tags, colour)
    
    @abstractmethod
    def renderTextInId(self, tagTocentreOn, tagsToAddTo, content, funcContent):
        id1tuple = self.__getCoords(tagTocentreOn)
        x1 = id1tuple[0] + ((id1tuple[2] - id1tuple[0]) / 2)
        y1 = id1tuple[1] + ((id1tuple[3] - id1tuple[1]) / 2)       
        txt = self.__renderText(x1, y1, (id1tuple[2] - id1tuple[0]), content, tagsToAddTo)
        
        def handler(event, self=self, content=funcContent):
            return self.__eventOnClick(event, content)
        
        self.localCanvas.tag_bind(txt, "<ButtonRelease-1>", handler)
        return txt
    
    @abstractmethod
    def move(self, tag, xamount, yamount):
        self.localCanvas.move(tag, xamount, yamount)

    @abstractmethod    
    def runDisplay(self):
        self.localCanvas.mainloop()
    
    
    def __hideId(self, objectId):
        self.localCanvas.itemconfigure(objectId, state="hidden")
        pass
        
    def __showId(self, objectId):
        self.localCanvas.itemconfigure(objectId, state="normal")
        pass
    
    def __sampleDraw(self):
        self.localCanvas.create_oval(0, 0, 0, 0, width=0)
    
    def __renderText(self, x, y, width, content, tag):
        val = self.localCanvas.create_text(x, y, width=width, text=content, tags=tag, justify="center", font="Helvetica 8 bold", anchor="center")
        self.localCanvas.tag_raise(val)
        return val
    
    def __drawLine(self, x1, y1, x2, y2, tags=None, colour="black"):
        line = self.localCanvas.create_line(x1, y1, x2, y2, tags=tags, width=self.lineThickness, arrow="first", arrowshape=(16,20,6),fill=colour, smooth=True)
        self.localCanvas.tag_lower(line)
        return  # line
    
    def __remove(self, num):
        self.localCanvas.delete(num)
    
    def __getCoords(self, ident):
        return self.localCanvas.coords(ident)
    
    def __eventOnFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        assert self.localCanvas
        coord_tuple = self.localCanvas.bbox("all")
        if not coord_tuple:
            logging.error("Frame reconfigure error on coordinate acquire.")
        else:
            reconWidth = coord_tuple[2] - coord_tuple[0]
            reconHeight = coord_tuple[3] - coord_tuple[1]
            self.localCanvas.configure(width=reconWidth)
            self.localCanvas.configure(height=reconHeight)
            self.localCanvas.configure(scrollregion=self.localCanvas.bbox("all"))
            self.localCanvas.update_idletasks()
    
    def __eventOnClick(self, event, content):
        self.__createWindowOnId(self.localCanvas.find_withtag(CURRENT), content)
        
    def __createWindowOnId(self, itemId, content):
        if self.currentlyRenderedWindow != None:
            self.currentlyRenderedWindow()
        # self.__remove(self.currentlyRenderedWindow)
        idtuple = self.localCanvas.coords(itemId)
        if idtuple:
            x = idtuple[0]
            y = idtuple[1]
            frm = Frame(self.localCanvas)
            frm.grid(row=0, column=0)
            canv = Canvas(frm)            
            
            vscroll = Scrollbar(frm, orient="vertical", command=canv.yview)
            vscroll.grid(row=0, column=1, sticky=N + S)
            
            canv.grid(row=0, column=0)
            
            canv["yscrollcommand"] = vscroll.set
            aframe = Frame(canv)
            aframe.grid(row=0, column=0)
            Label(aframe, text=content, anchor="center", background="#CCFFCC", borderwidth=6, relief="ridge", justify="left").grid(row=1, column=0)
            canvWindow = canv.create_window(x, y, window=aframe)
            canv.coords(canvWindow, x, y)
            self.localCanvas.update_idletasks()
            canv["scrollregion"] = canv.bbox("all")
            
            def destroyAll():
                self.__remove(canvWindow)
                canv.destroy()
                aframe.destroy()
                vscroll.destroy()
                frm.destroy()
                
            self.currentlyRenderedWindow = destroyAll 
            Button(frm, text="Close", command=lambda :  destroyAll()).grid(row=2, column=0)
Пример #60
-19
class IsometricViewer:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.wireframe = True
        self.drawables = []
        self.items = {}
        self.text = ""
        self.theta = 0
        self.phi = 0
        self.scale = 0
        self.x_offset = 0
        self.y_offset = 0
        self.canvas = Canvas(Tk(), width=self.width, height=self.height)
        self.reset_viewport()
        self.init_gui()
    @property
    def camera_coords(self):
        return Point3(math.cos(self.theta) * math.cos(self.phi), -math.sin(self.theta) * math.cos(self.phi), math.sin(self.phi))
    def reset_viewport(self):
        self.theta = math.pi / 8
        self.phi = math.pi / 16
        self.scale = 1
        self.x_offset = self.width / 2
        self.y_offset = self.height / 2
    def init_gui(self):
        self.canvas.pack()
        self.canvas.focus_set()
        self.canvas.bind("<Up>", self._callback_commandline_up)
        self.canvas.bind("<Down>", self._callback_commandline_down)
        self.canvas.bind("<Left>", self._callback_commandline_left)
        self.canvas.bind("<Right>", self._callback_commandline_right)
        self.canvas.bind("=", self._callback_commandline_equal)
        self.canvas.bind("-", self._callback_commandline_minus)
        self.canvas.bind("<Shift-Up>", self._callback_commandline_shift_up)
        self.canvas.bind("<Shift-Down>", self._callback_commandline_shift_down)
        self.canvas.bind("<Shift-Left>", self._callback_commandline_shift_left)
        self.canvas.bind("<Shift-Right>", self._callback_commandline_shift_right)
        self.canvas.bind("<Shift-Return>", self._callback_commandline_shift_return)
        self.canvas.bind("<Button-1>", self._callback_button_1)
        self.canvas.bind("<B1-Motion>", self._callback_button_1_motion)
    def add_drawable(self, drawable):
        assert isinstance(drawable, Drawable)
        self.drawables.append(drawable)
    def project(self, point):
        projected = point.rotate(self.theta, self.phi)
        return Point2(projected.y * self.scale + self.x_offset, -projected.z * self.scale + self.y_offset)
    def unproject(self, point):
        return point.rotate(0, -self.phi).rotate(-self.theta, 0)
    def move_camera(self, theta, phi):
        self.theta += theta
        if self.theta > 2 * math.pi:
            self.theta -= 2 * math.pi
        elif self.theta < 0:
            self.theta += 2 * math.pi
        if -math.pi / 2 <= self.phi + phi <= math.pi / 2:
            self.phi += phi
    def clear(self):
        for item in self.items:
            self.canvas.delete(item)
    def draw_line(self, owner, p1, p2, **kargs):
        assert isinstance(p1, Point3)
        assert isinstance(p2, Point3)
        p1 = self.project(p1)
        p2 = self.project(p2)
        item = self.canvas.create_line(p1.x, p1.y, p2.x, p2.y, **kargs)
        self.items[item] = owner
        return item
    def draw_ellipse(self, owner, corners, **kargs):
        assert all(isinstance(p, Point3) for p in corners)
        item = self.draw_polygon(owner, corners, outline="#000000", smooth=1, **kargs)
        self.items[item] = owner
        return item
    def draw_polygon(self, owner, pts, **kargs):
        assert all(isinstance(p, Point3) for p in pts)
        args = []
        for p in pts:
            p = self.project(p)
            args.extend((p.x, p.y))
        item = self.canvas.create_polygon(*args, **kargs)
        self.items[item] = owner
        return item
    def draw_wireframe(self):
        for drawable in self.drawables:
            drawable.draw_wireframe(self)
    def draw(self):
        for drawable in self.drawables:
            drawable.draw(self)
    def update(self):
        self.clear()
        header = [
            "(theta, phi): ({:.3f}, {:.3f})".format(self.theta, self.phi),
            "(x, y, z): {}".format(self.camera_coords),
        ]
        text = "\n".join(header) + "\n\n" + self.text
        item = self.canvas.create_text((10, 10), anchor="nw", text=text)
        self.items[item] = None
        if self.wireframe:
            self.draw_wireframe()
        else:
            self.draw()
    def display(self):
        self.update()
        mainloop()
    def _callback_commandline_up(self, event):
        self.move_camera(0, math.pi / 16)
        self.update()
    def _callback_commandline_down(self, event):
        self.move_camera(0, -math.pi / 16)
        self.update()
    def _callback_commandline_left(self, event):
        self.move_camera(math.pi / 16, 0)
        self.update()
    def _callback_commandline_right(self, event):
        self.move_camera(-math.pi / 16, 0)
        self.update()
    def _callback_commandline_equal(self, event):
        self.scale *= 1.2
        self.update()
    def _callback_commandline_minus(self, event):
        self.scale /= 1.2
        self.update()
    def _callback_commandline_shift_up(self, event):
        self.y_offset -= 10
        self.update()
    def _callback_commandline_shift_down(self, event):
        self.y_offset += 10
        self.update()
    def _callback_commandline_shift_left(self, event):
        self.x_offset -= 10
        self.update()
    def _callback_commandline_shift_right(self, event):
        self.x_offset += 10
        self.update()
    def _callback_commandline_shift_return(self, event):
        self.reset_viewport()
        self.update()
    def _callback_button_1(self, event):
        text = []
        closest = self.canvas.find_closest(event.x, event.y)[0]
        overlapping = self.canvas.find_overlapping(event.x, event.y, event.x+1, event.y+1)
        if closest in overlapping and closest in self.items and self.items[closest] is not None:
            text.append(self.items[closest].clicked(self, event, closest))
        self.text = "\n".join(text)
        self.update()
    def _callback_button_1_motion(self, event):
        pass