Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 19.02.2018
Сообщений: 30
1

При перемещении дисков, диски на другом стержне сдвигаются

18.05.2018, 17:36. Показов 968. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Это ханойские башни. При перемещении дисков, диски на другом стержне сдвигаются в некоторых случаях. Дело, если я правильно понял, в переменной dx. Но как исправить, не приходит в голову

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import pygame
import sys
 
SIZE = (900, 300)
AMOUNT_OF_RINGS = 3
MIN_WIDTH_OF_RING = 20
MAX_WIDTH_OF_RING = 290
STEP_OF_CHANGE_OF_WIDTH = int((MAX_WIDTH_OF_RING - MIN_WIDTH_OF_RING) / AMOUNT_OF_RINGS)
HEIGHT_OF_RING = int((SIZE[1] - 20) / AMOUNT_OF_RINGS)
 
 
class Hanoi:
    def __init__(self):
        self.current_tower = 0
        self.screen = pygame.display.set_mode(SIZE)
        self.towers = [
            [3, 2, 1],
            [],
            []
        ]
 
    def Run(self):
        while True:
            self.CheckEvents()
            self.Draw()
            pygame.display.flip()
 
    def CheckEvents(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
 
            if event.type == pygame.MOUSEBUTTONDOWN:
                mx, my = event.pos
                # print mx, my
                if 0 <= mx <= 300:
                    self.current_tower = 1
                if 300 <= mx <= 600:
                    self.current_tower = 2
                if 600 <= mx <= 900:
                    self.current_tower = 3
            if event.type == pygame.MOUSEBUTTONUP:
                if self.current_tower > 0:
                    mx, my = event.pos
                    if 0 <= mx <= 300:
                        self.MoveRing(self.current_tower, 1)
                    if 300 <= mx <= 600:
                        self.MoveRing(self.current_tower, 2)
                    if 600 <= mx <= 900:
                        self.MoveRing(self.current_tower, 3)
                    self.current_tower = 0
 
    def MoveRing(self, first, second):
        if self.towers[first - 1] != []:
            if self.towers[second - 1] != []:
                if self.towers[first - 1][-1] < self.towers[second - 1][-1]:
                    self.towers[second - 1].append(self.towers[first - 1][-1])
                    self.towers[first - 1] = self.towers[first - 1][:-1]
            else:
                self.towers[second - 1].append(self.towers[first - 1][-1])
                self.towers[first - 1] = self.towers[first - 1][:-1]
 
    def Draw(self):
        bg = pygame.Surface(SIZE)
        bg.fill(pygame.Color("Gray"))
        self.screen.blit(bg, (0, 0))
        t = pygame.Surface((10, SIZE[1] - 10))
        t.fill(pygame.Color("black"))
        self.screen.blit(t, (145, 10))
        self.screen.blit(t, (145 + 300, 10))
        self.screen.blit(t, (145 + 600, 10))
        x = 5
        dx = 0
        y = SIZE[1] - HEIGHT_OF_RING
        for tower in self.towers:
            for ring in tower:
                r = pygame.Surface((MIN_WIDTH_OF_RING + STEP_OF_CHANGE_OF_WIDTH * ring, HEIGHT_OF_RING))
                r.fill(pygame.Color("Green"))
                self.screen.blit(r, (dx + x, y))
                y -= HEIGHT_OF_RING + 2
                dx += STEP_OF_CHANGE_OF_WIDTH // 2
            x += 300
            y = SIZE[1] - HEIGHT_OF_RING
 
 
h = Hanoi()
h.Run()
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.05.2018, 17:36
Ответы с готовыми решениями:

Сдвигаются элементы при Draggable перемещении
Есть блоки. Они перемещаться, но когда я удаляю один из них, то остальные сдвигаються( Что делать?...

Из списка компакт-дисков из файла выбрать только музыкальные диски, диски в формате МР3
Составить программу, которая по-зволяет из списка компакт-дисков из файла, выбрать только...

При установке программ в окне выбора дисков не отображаются сетевые диски
Есть сеть из 3х ноутбуков: на 1ом и 2ом стоит 7ка на 3ем - 8ка. На первом ноуте одна из папок...

Создать массив структур «Диски», метод для вывода дисков по типу, поиска по флагу, вывода всех дисков. Вывести 3 диска
Не могу сделать массив структур. Задание: Салон проката содержит список CD/DVD дисков. Создайте...

6
1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
18.05.2018, 20:06 2
Лучший ответ Сообщение было отмечено DJuice как решение

Решение

Проблема в следующем, для отрисовки блоков у каждого должен быть определенный dx у 1-90, у 2-45, у 3-0, а в цикле нет проверки какой блок обрабатывается, просто первому попавшемуся назначается 0, второму 45, третьему 90, и если порядок блоков отличается от 3 2 1, то dx будет неправильный

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import pygame
import sys
 
SIZE = (900, 300)
AMOUNT_OF_RINGS = 3
MIN_WIDTH_OF_RING = 20
MAX_WIDTH_OF_RING = 290
STEP_OF_CHANGE_OF_WIDTH = int((MAX_WIDTH_OF_RING - MIN_WIDTH_OF_RING) / AMOUNT_OF_RINGS)
HEIGHT_OF_RING = int((SIZE[1] - 20) / AMOUNT_OF_RINGS)
 
 
class Hanoi:
    def __init__(self):
        self.current_tower = 0
        self.screen = pygame.display.set_mode(SIZE)
        self.towers = [
            [3, 2, 1],
            [],
            []
        ]
        self.dx = {1:90, 2:45, 3:0}
        
    def Run(self):
        while True:
            self.CheckEvents()
            self.Draw()
            pygame.display.flip()
 
    def CheckEvents(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
 
            if event.type == pygame.MOUSEBUTTONDOWN:
                mx, my = event.pos
                # print mx, my
                if 0 <= mx <= 300:
                    self.current_tower = 1
                if 300 <= mx <= 600:
                    self.current_tower = 2
                if 600 <= mx <= 900:
                    self.current_tower = 3
            if event.type == pygame.MOUSEBUTTONUP:
                if self.current_tower > 0:
                    mx, my = event.pos
                    if 0 <= mx <= 300:
                        self.MoveRing(self.current_tower, 1)
                    if 300 <= mx <= 600:
                        self.MoveRing(self.current_tower, 2)
                    if 600 <= mx <= 900:
                        self.MoveRing(self.current_tower, 3)
                    self.current_tower = 0
 
    def MoveRing(self, first, second):
        if self.towers[first - 1] != []:
            if self.towers[second - 1] != []:
                if self.towers[first - 1][-1] < self.towers[second - 1][-1]:
                    self.towers[second - 1].append(self.towers[first - 1][-1])
                    self.towers[first - 1] = self.towers[first - 1][:-1]
            else:
                self.towers[second - 1].append(self.towers[first - 1][-1])
                self.towers[first - 1] = self.towers[first - 1][:-1]
 
    def Draw(self):
        bg = pygame.Surface(SIZE)
        bg.fill(pygame.Color("Gray"))
        self.screen.blit(bg, (0, 0))
        t = pygame.Surface((10, SIZE[1] - 10))
        t.fill(pygame.Color("black"))
        self.screen.blit(t, (145, 10))
        self.screen.blit(t, (145 + 300, 10))
        self.screen.blit(t, (145 + 600, 10))
        x = 5
        dx = 0
        y = SIZE[1] - HEIGHT_OF_RING
        for tower in self.towers:
            for ring in tower:
                r = pygame.Surface((MIN_WIDTH_OF_RING + STEP_OF_CHANGE_OF_WIDTH * ring, HEIGHT_OF_RING))
                r.fill(pygame.Color("Green"))
                dx = self.dx[ring]
                self.screen.blit(r, (dx + x, y))
                y -= HEIGHT_OF_RING + 2
                # dx += STEP_OF_CHANGE_OF_WIDTH // 2
            x += 300
            y = SIZE[1] - HEIGHT_OF_RING
 
 
h = Hanoi()
h.Run()
1
0 / 0 / 0
Регистрация: 19.02.2018
Сообщений: 30
18.05.2018, 21:31  [ТС] 3
Ещё небольшой вопрос: как можно автоматически добавить вычисление dx, если количество колец меняется пользователем?
Python
1
2
3
4
5
6
7
8
9
10
class Hanoi:
* * def __init__(self):
* * * * self.current_tower = 0
* * * * self.screen = pygame.display.set_mode(SIZE)
* * * * self.towers = [
* * * * * * [i for i in range(AMOUNT_OF_RINGS, 0, -1)],
* * * * * * [],
* * * * * * []
* * * * ]
* * * * self.dx = {1:90, 2:45, 3:0}
0
1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
18.05.2018, 21:51 4
Лучший ответ Сообщение было отмечено DJuice как решение

Решение

Можно в класс добавить метод, который задает количества колец, вроде такого

Python
1
2
def set_rings(self,num):
    self.dx = {i: a * 45 for i,a in enumerate(range(num-1,-1,-1), start=1)}
1
0 / 0 / 0
Регистрация: 19.02.2018
Сообщений: 30
18.05.2018, 23:06  [ТС] 5
Я немного интерфейса сделал, поменял разрешение. Не смог решить проблемы с координатами. Тут он автоматически собирает, но суть одна и та же
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
from Tkinter import *
import pygame
import sys
import time
 
root = Tk()
root.title("Главное меню")
root.geometry("300x180")
 
 
 
col = IntVar()
am = IntVar()
col.set(0)
am.set(3)
l_amount=Label(root,text="Количество")
l_color=Label(root,text="Цвет")
r_amount1 = Radiobutton(root, text = "3", variable = am, value = 3)
r_amount2 = Radiobutton(root, text = "5", variable = am, value = 5)
r_amount3 = Radiobutton(root, text = "9", variable = am, value = 9)
r_amount4 = Radiobutton(root, text = "12", variable = am, value = 12)
r_color1 = Radiobutton(root, text = "синий", variable = col, value = 0)
r_color2 = Radiobutton(root,text = "зелёный", variable = col, value = 1)
r_color3 = Radiobutton(root, text = "жёлтый", variable = col, value = 2)
 
 
btn1 = Button(root,text="Auto", width=10)
btn2 = Button(root,text="User Mode", width=10)
 
 
 
 
l_amount.grid(row=0,column = 0,columnspan=2,sticky=W)
l_color.grid(row=0,column = 7,columnspan=2,sticky=W)
r_amount1.grid(row = 1, column = 0, sticky = W, padx = 5)
r_amount2.grid(row = 2, column = 0, sticky = W, padx = 5)
r_amount3.grid(row = 3, column = 0, sticky = W, padx = 5)
r_amount4.grid(row = 4, column = 0, sticky = W, padx = 5)
r_color1.grid(row=1,column=7,sticky=W,padx=5)
r_color2.grid(row=2,column=7,sticky=W,padx=5)
r_color3.grid(row=3,column=7,sticky=W,padx=5)
btn1.grid(row=6,column=0,padx=10,pady=5)
btn2.grid(row=6,column=7,padx=10,pady=5)
 
 
SIZE = (1024, 512)
MIN_WIDTH_OF_RING = 20
MAX_WIDTH_OF_RING = 290
 
 
 
 
class Hanoi:
    def __init__(self):
        self.current_tower = 0
        self.screen = pygame.display.set_mode(SIZE)
        pygame.display.set_caption("Ханойские башни")
        AMOUNT_OF_RINGS = am.get()
        self.towers = [
            [i for i in range(AMOUNT_OF_RINGS, 0, -1)],
            [],
            []
        ]
        self.dx = {i: a * 50 for i, a in enumerate(range(AMOUNT_OF_RINGS - 1, -1, -1), start=1)}
 
 
 
 
    def Run(self):
        while True:
            self.CheckEvents()
            self.Draw()
            pygame.display.flip()
 
    def CheckEvents(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
 
            if event.type == pygame.MOUSEBUTTONDOWN:
                mx, my = event.pos
                if 0 <= mx <= 300:
                    self.current_tower = 1
                if 300 <= mx <= 600:
                    self.current_tower = 2
                if 600 <= mx <= 900:
                    self.current_tower = 3
            if event.type == pygame.MOUSEBUTTONUP:
                if self.current_tower > 0:
                    mx, my = event.pos
                    if 0 <= mx <= 300:
                        self.MoveRing(self.current_tower, 1)
                    if 300 <= mx <= 600:
                        self.MoveRing(self.current_tower, 2)
                    if 600 <= mx <= 900:
                        self.MoveRing(self.current_tower, 3)
                    self.current_tower = 0
 
    def Hanoi1(self, n, src, dst, tmp):
        if n == 0:
            pass
        else:
            print n, src, dst, tmp
            self.Hanoi1(n - 1, src, tmp, dst)
            self.MoveRing(src, dst)
            self.Hanoi1(n - 1, tmp, dst, src)
        self.Draw()
        pygame.display.flip()
        time.sleep(0.3)
 
    def MoveRing(self, first, second):
        if self.towers[first - 1] != []:
            if self.towers[second - 1] != []:
                if self.towers[first - 1][-1] < self.towers[second - 1][-1]:
                    self.towers[second - 1].append(self.towers[first - 1][-1])
                    self.towers[first - 1] = self.towers[first - 1][:-1]
            else:
                self.towers[second - 1].append(self.towers[first - 1][-1])
                self.towers[first - 1] = self.towers[first - 1][:-1]
 
    def Draw(self):
        AMOUNT_OF_RINGS = am.get()
        STEP_OF_CHANGE_OF_WIDTH = int((MAX_WIDTH_OF_RING - MIN_WIDTH_OF_RING) / AMOUNT_OF_RINGS)
        HEIGHT_OF_RING = int((SIZE[1] - 20) / AMOUNT_OF_RINGS)
        bg = pygame.Surface(SIZE)
        bg.fill(pygame.Color("Gray"))
        self.screen.blit(bg, (0, 0))
        t = pygame.Surface((10, SIZE[1] - 10))
        t.fill(pygame.Color("black"))
        self.screen.blit(t, (170, 10))
        self.screen.blit(t, (170 + 340, 10))
        self.screen.blit(t, (170 + 680, 10))
        x1 = 30
        dx = 0
        y = SIZE[1] - HEIGHT_OF_RING
        c = col.get()
        for tower in self.towers:
            for ring in tower:
                r = pygame.Surface((MIN_WIDTH_OF_RING + STEP_OF_CHANGE_OF_WIDTH * ring, HEIGHT_OF_RING))
                if c == 0:
                    r.fill(pygame.Color("blue"))
                elif c == 1:
                    r.fill(pygame.Color("green"))
                elif c == 2:
                    r.fill(pygame.Color("yellow"))
                dx = self.dx[ring]
                self.screen.blit(r, (dx + x1, y))
                y -= HEIGHT_OF_RING + 2
            x1 += 340
            y = SIZE[1] - HEIGHT_OF_RING
 
 
def Autogame(event):
    AMOUNT_OF_RINGS = am.get()
    h = Hanoi()
    h.Hanoi1(AMOUNT_OF_RINGS, 1, 3, 2)
    # h.Run()
 
    while True:
        h.Draw()
        pygame.display.flip()
 
btn1.bind('<Button-1>', Autogame)
btn2.bind('<Button-1>', Autogame)
 
 
root.mainloop()
0
1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
18.05.2018, 23:29 6
Лучший ответ Сообщение было отмечено DJuice как решение

Решение

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
class Hanoi:
    def __init__(self):
        self.current_tower = 0
        self.screen = pygame.display.set_mode(SIZE)
        pygame.display.set_caption("Ханойские башни")
        AMOUNT_OF_RINGS = am.get()
        self.towers = [
            [i for i in range(AMOUNT_OF_RINGS, 0, -1)],
            [],
            []
        ]
        x = int((MAX_WIDTH_OF_RING - MIN_WIDTH_OF_RING) / AMOUNT_OF_RINGS) // 2
        self.dx = {i: a * x for i, a in enumerate(range(AMOUNT_OF_RINGS - 1, -1, -1), start=1)}
Только с 12 колец не выйдет, так как 270 / 12 = 22,5
1
0 / 0 / 0
Регистрация: 19.02.2018
Сообщений: 30
18.05.2018, 23:48  [ТС] 7
Огромное спасибо!!!
0
18.05.2018, 23:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.05.2018, 23:48
Помогаю со студенческими работами здесь

Рекурсивная задача о перемещении дисков
Легенда гласит, что, в Великом храме города Бенарас, под собором, отмечающим середину мира,...

Вылазиет 0x0000007b при запуске жёстких дисков с windows 7 или windows 7 home premium на другом пк
---p.s.---- первый диск поделён на два раздела C: и D:, и на D: стоит windows 7 home premium...

Дисковод не читает диски, кроме дисков с Windows.
Доброго времени суток. У меня вот такая проблема дисковод не читает диски, кроме диска на котором...

дисков нет в посмотреть диски в управлении виндоус
из-за чего может не быть дисков там где можно посмотреть диски в виндоус ? речь про виндоус 7...

Загрузочный сектор CD\DVD дисков (загрузочные диски)
Приветик всем знатокам! Обращаюсь за помощью по следующему вопросу: необходимо сделать (или...

Почему продают Жесткие диски в основном 500 Гб, а 512 Гб дисков меньше
На самом деле у меня больше вопросов, типо, почему продают Жесткие диски в основном 500 Гб, а 512...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru