feat: new tower and similiarity socre calc

This commit is contained in:
raiot 2024-11-06 02:16:57 +08:00
parent 0f758396a7
commit 0f784cecc7
1 changed files with 51 additions and 14 deletions

View File

@ -12,7 +12,7 @@ pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("积木塔仿真")
pygame.display.set_caption("Stack Simulation")
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
@ -341,7 +341,9 @@ class Tower:
temp_tower.add_block(new_block)
if temp_tower.check_stability():
distance = np.sqrt((x - ideal_x)**2 + (y - ideal_y)**2) + abs(angle - ideal_angle)
similarity_score = 100 * (1 - distance / (np.sqrt(WIDTH**2 + HEIGHT**2) + 360))
# 方案1使用指数函数
ratio = distance / (np.sqrt(WIDTH**2 + HEIGHT**2) + 360)
similarity_score = 100 * (1 - np.power(ratio, 0.5)) # 使用0.5次方增加敏感度
if distance < min_distance:
min_distance = distance
@ -455,7 +457,7 @@ def show_tower_selection(screen):
# 添加标题
font = pygame.font.Font(None, 36)
title = font.render("选择塔型", True, BLACK)
title = font.render("Select Tower Type", True, BLACK)
title_rect = title.get_rect(center=(SCREEN_WIDTH // 2, 50))
screen.blit(title, title_rect)
@ -528,9 +530,26 @@ def get_tower_blueprint_1():
def get_tower_blueprint_2():
# 使用极坐标定义第二种塔型的蓝图
return [
[polar_to_cartesian(20, 180, 90), polar_to_cartesian(20, 0, 90)], # (20, 0, 90)
[polar_to_cartesian(20, 90, 0), polar_to_cartesian(20, 270, 0)], # (0, -20, 0)
[polar_to_cartesian(20, 165, 75), polar_to_cartesian(20, -15, 75)],
[(-30, 0, 90), (30, 0, 90)],
[(-3, 30, -5), (3, -30, -5)],
[(-29, -5, 80), (29, 5, 80)],
[(-8, 29, -15), (8, -29, -15)],
[(-28, -10, 70), (28, 10, 70)],
[(-13, 27, -25), (13, -27, -25)],
[(-27, -13, 60), (27, 13, 60)],
[(-18, 25, -35), (18, -25, -35)],
[(-26, -18, 50), (26, 18, 50)],
[(-21, 23, -45), (21, -23, -45)],
[(-25, -21, 40), (25, 21, 40)],
[(-22, 20, -55), (22, -20, -55)],
[(-24, -22, 30), (24, 22, 30)],
[(-20, 19, -65), (20, -19, -65)],
[(-23, -20, 20), (23, 20, 20)],
[(-19, 18, -75), (19, -18, -75)],
[(-22, -19, 10), (22, 19, 10)],
[(-17, 17, -85), (17, -17, -85)],
[(-21, -17, 0), (21, 17, 0)],
[(-16, 16, -95), (16, -16, -95)],
]
def get_tower_blueprint_3():
@ -553,7 +572,7 @@ def get_tower_blueprint_3():
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("积木塔仿真")
pygame.display.set_caption("Stack Simulation")
# 加载塔型图片
tower_images = [
@ -591,9 +610,27 @@ def main():
elif event.type == pygame.MOUSEMOTION:
if current_block:
current_block.x, current_block.y = pygame.mouse.get_pos()
# 实时计算当前位置的相似性评分
ideal_positions = tower.ideal_positions[tower.current_layer]
blocks_in_current_layer = sum(1 for block in tower.blocks if block.layer == tower.current_layer)
if blocks_in_current_layer < len(ideal_positions):
ideal_x, ideal_y, ideal_angle = ideal_positions[blocks_in_current_layer]
distance = np.sqrt((current_block.x - ideal_x)**2 + (current_block.y - ideal_y)**2) + abs(current_block.angle - ideal_angle)
# similarity_score = 100 * (1 - distance / (np.sqrt(WIDTH**2 + HEIGHT**2) + 360))
ratio = distance / (np.sqrt(WIDTH**2 + HEIGHT**2) + 360)
similarity_score = 100 * (1 - np.power(ratio, 0.5)) # 使用0.5次方增加敏感度
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1 and current_block:
# 计算最终放置位置的相似性评分
ideal_positions = tower.ideal_positions[tower.current_layer]
blocks_in_current_layer = sum(1 for block in tower.blocks if block.layer == tower.current_layer)
if blocks_in_current_layer < len(ideal_positions):
ideal_x, ideal_y, ideal_angle = ideal_positions[blocks_in_current_layer]
distance = np.sqrt((current_block.x - ideal_x)**2 + (current_block.y - ideal_y)**2) + abs(current_block.angle - ideal_angle)
similarity_score = 100 * (1 - distance / (np.sqrt(WIDTH**2 + HEIGHT**2) + 360))
if tower.add_block_from_sim(current_block):
print(f"Block placed with similarity score: {similarity_score:.2f}")
current_block = None
else:
print("CANNOT place block here, there is already a block there.")
@ -607,12 +644,12 @@ def main():
auto_block, new_similarity_score = tower.auto_place_block()
if auto_block:
if tower.add_block_from_sim(auto_block):
print(f"成功放置积木在 ({auto_block.x}, {auto_block.y}) 角度为 {auto_block.angle}")
similarity_score = new_similarity_score # 更新相似性评分
print(f"Successfully placed block at ({auto_block.x}, {auto_block.y}) with angle {auto_block.angle}")
similarity_score = new_similarity_score
else:
print("无法放置积木")
print("Cannot place block")
else:
print("无法找到合适的放置位置")
print("Cannot find suitable position")
elif event.key == pygame.K_n: # 按 'N' 键自动放置新的一层
tower.auto_place_layer()
elif event.key == pygame.K_s: # 按 'S' 键扫描当前层
@ -624,9 +661,9 @@ def main():
if current_block:
current_block.draw(screen)
# 显示相似性评分,将 Y 坐标从 10 改为 50
# 显示相似性评分
score_text = font.render(f"Similarity Score: {similarity_score:.2f}", True, (0, 0, 0))
screen.blit(score_text, (10, 50)) # 这里将 Y 坐标从 10 改为 50
screen.blit(score_text, (10, 50))
# 计算并绘制当前层的重心
current_centroid = tower.calculate_current_layer_centroid()
@ -647,7 +684,7 @@ def main():
screen.blit(text, (WIDTH // 2 - text.get_width() // 2, 20))
font = pygame.font.Font(None, 36)
layer_text = font.render(f"Current layer: {tower.current_layer + 1}", True, BLACK)
layer_text = font.render(f"Current Layer: {tower.current_layer + 1}", True, BLACK)
screen.blit(layer_text, (10, 10))
tower.draw_tower_image(screen)