-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBaseVisualizer.py
More file actions
170 lines (141 loc) · 6.23 KB
/
BaseVisualizer.py
File metadata and controls
170 lines (141 loc) · 6.23 KB
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
168
169
170
import shutil
import sys
from typing import Any, List, Optional
from colorama import Fore, Style, init
# Initialize colorama for cross-platform color support
init()
class BaseVisualizer:
"""Base class for SAT solver visualization"""
def __init__(self):
self.step_count = 0
self.depth = 0
self.term_width, self.term_height = shutil.get_terminal_size()
def color_print(
self, text: str, color: str = Fore.WHITE, style: str = Style.NORMAL, end="\n"
):
"""Helper function to print colored text"""
print(f"{style}{color}{text}{Style.RESET_ALL}", end=end)
def center_text(self, text: str) -> str:
"""Center text based on terminal width"""
return text.center(self.term_width)
def create_box(self, text: str, padding: int = 1) -> List[str]:
"""Create a box around text with given padding"""
lines = text.split("\n")
width = max(len(line) for line in lines) + 2 * padding
top = "┌" + "─" * width + "┐"
bottom = "└" + "─" * width + "┘"
middle = [f"│{line.center(width)}│" for line in lines]
return [top, *middle, bottom]
def print_rule_box(
self, rule_name: str, description: str, color: str = Fore.YELLOW
):
"""Print a rule in a formatted box"""
box = self.create_box(f"{rule_name}\n{description}")
for line in box:
self.color_print(self.center_text(line), color)
def print_progress_bar(self, current: int, total: int, width: int = 40):
"""Print a progress bar showing algorithm progress"""
percentage = current / total
filled = int(width * percentage)
bar = "█" * filled + "░" * (width - filled)
self.color_print(f"\rProgress: |{bar}| {percentage:.1%}", Fore.CYAN, end="")
def print_step_counter(
self, current: int, depth: int, extra_info: Optional[str] = None
):
"""Print step counter in the top-right corner"""
# Save cursor position
print("\033[s", end="")
# Prepare counter text
counter_text = f"Step: {current} | Depth: {depth}"
if extra_info:
counter_text += f" | {extra_info}"
# Calculate box dimensions
box_width = len(counter_text) + 2 # Add 2 for padding
start_col = self.term_width - box_width - 2 # Subtract 2 for box borders
start_row = 2 # Start the box at row 2 instead of row 0
# Box drawing characters
top = f"╭{'─' * box_width}╮"
middle = f"│ {counter_text} │"
bottom = f"╰{'─' * box_width}╯"
# Move to positions and print each line
# Add start_row to each row position
print(f"\033[{start_row};{start_col}H", end="")
self.color_print(top, Fore.CYAN)
print(f"\033[{start_row + 1};{start_col}H", end="")
self.color_print(middle, Fore.CYAN)
print(f"\033[{start_row + 2};{start_col}H", end="")
self.color_print(bottom, Fore.CYAN)
# Restore cursor position
print("\033[u", end="")
sys.stdout.flush()
def clear_screen(self):
"""Clear the screen and move cursor to top"""
print("\033[2J\033[H", end="")
def print_welcome(self, title: str):
"""Print welcome message in a box"""
self.clear_screen()
welcome_box = self.create_box(title)
for line in welcome_box:
self.color_print(self.center_text(line), Fore.CYAN, Style.BRIGHT)
def print_legend(self):
"""Print color legend"""
self.color_print("\nColor Legend:", Fore.WHITE, Style.BRIGHT)
self.color_print("✓ GREEN: Success, TRUE assignments", Fore.GREEN)
self.color_print("✗ RED: Failure, FALSE assignments", Fore.RED)
self.color_print("→ BLUE: Decisions and branching", Fore.BLUE)
self.color_print("• YELLOW: Formulas and clauses", Fore.YELLOW)
self.color_print("• MAGENTA: Variable assignments", Fore.MAGENTA)
def get_parameters(self, default_n: int, default_ratio: float) -> tuple[int, float]:
"""Get problem parameters from user"""
self.color_print("\n" + "=" * self.term_width, Fore.CYAN)
self.color_print("\nConfiguration:", Fore.CYAN, Style.BRIGHT)
self.color_print(
f"\nUse default parameters (n={default_n}, ratio={default_ratio})? [Y/n]: ",
Fore.CYAN,
end="",
)
use_default = input().lower() != "n"
if use_default:
return default_n, default_ratio
while True:
try:
self.color_print(
"\nEnter number of variables (3-10 recommended): ",
Fore.CYAN,
end="",
)
n = int(input())
if n < 1:
self.color_print("❌ Number of variables must be positive", Fore.RED)
continue
if n > 10:
self.color_print(
"⚠️ Warning: Large values may be hard to follow", Fore.YELLOW
)
break
except ValueError:
self.color_print("❌ Please enter a valid number", Fore.RED)
while True:
try:
self.color_print(
"Enter clause/variable ratio (2.0-5.0 recommended): ",
Fore.CYAN,
end="",
)
ratio = float(input())
if ratio <= 0:
self.color_print("❌ Ratio must be positive", Fore.RED)
continue
break
except ValueError:
self.color_print("❌ Please enter a valid number", Fore.RED)
return n, ratio
def print_statistics(self, stats: List[tuple[str, Any]]):
"""Print statistics in a formatted box"""
stats_box = self.create_box("Algorithm Statistics")
for line in stats_box:
self.color_print(self.center_text(line), Fore.CYAN, Style.BRIGHT)
max_label_length = max(len(label) for label, _ in stats)
for label, value in stats:
centered_stat = self.center_text(f"{label:{max_label_length}}: {value}")
self.color_print(centered_stat, Fore.CYAN)