66)
77from PyQt5 .QtGui import QFont , QBrush , QColor , QPen , QTextCursor
88from PyQt5 .QtCore import Qt , QPointF , QTimer
9-
9+ from matplotlib .backends .backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
10+ from matplotlib .figure import Figure
1011from ui .node_item import NodeItem
1112
1213class BaseLevel (QWidget ):
@@ -59,6 +60,17 @@ def __init__(self, level_name, parent_selector, max_rounds=3, auto_mode=False, a
5960 self .commit_btn .clicked .connect (self .commit_colors )
6061 self .challenge_btn .clicked .connect (self .challenge_edge_once )
6162 self .reset_btn .clicked .connect (self .reset_game )
63+ self .figure = Figure (figsize = (5 , 2.5 ))
64+ self .canvas = FigureCanvas (self .figure )
65+ self .ax = self .figure .add_subplot (111 )
66+ self .success_rates = []
67+ self .round_numbers = []
68+
69+ self .ax .set_title ("ZKP Success Rate Over Rounds" )
70+ self .ax .set_xlabel ("Rounds" )
71+ self .ax .set_ylabel ("Success %" )
72+ self .ax .set_ylim (0 , 100 )
73+ self .layout .addWidget (self .canvas )
6274
6375 self .buttons_layout .addWidget (self .commit_btn )
6476 self .buttons_layout .addWidget (self .challenge_btn )
@@ -123,7 +135,20 @@ def commit_colors(self, auto_trigger=False):
123135 self .committed = True
124136 if not auto_trigger :
125137 self .update_narration ("🔒 Commitments made. Verifier, choose an edge to challenge!" )
126-
138+ def update_success_chart (self ):
139+ total = self .valid_proofs + self .invalid_proofs
140+ if total == 0 :
141+ return
142+ success = (self .valid_proofs / total ) * 100
143+ self .round_numbers .append (self .rounds )
144+ self .success_rates .append (success )
145+ self .ax .clear ()
146+ self .ax .plot (self .round_numbers , self .success_rates , marker = 'o' , color = 'lime' )
147+ self .ax .set_title ("ZKP Success Rate Over Rounds" )
148+ self .ax .set_xlabel ("Rounds" )
149+ self .ax .set_ylabel ("Success %" )
150+ self .ax .set_ylim (0 , 100 )
151+ self .canvas .draw ()
127152 def challenge_edge_once (self , auto = False ):
128153 if not self .committed :
129154 if not auto :
@@ -155,6 +180,7 @@ def challenge_edge_once(self, auto=False):
155180 QTimer .singleShot (1500 , self .prompt_next_round )
156181 else :
157182 QTimer .singleShot (1500 , self .finish_level )
183+ self .update_success_chart ()
158184
159185 def auto_run_verification (self ):
160186 if self .rounds >= self .auto_total_rounds :
@@ -180,8 +206,13 @@ def show_final_report(self):
180206
181207 msg = QMessageBox ()
182208 msg .setWindowTitle ("📊 Simulation Summary" )
183- msg .setText (f"✅ Valid Proofs: { self .valid_proofs } \n ❌ Invalid Proofs: { self .invalid_proofs } \n \n "
184- f"🎯 Success Probability: { success_rate :.2f} %" )
209+ msg .setText (
210+ f"📊 Final Round Report:\n \n "
211+ f"✅ You passed { self .valid_proofs } out of { total } rounds.\n "
212+ f"❌ You failed { self .invalid_proofs } times.\n "
213+ f"🎯 Estimated Trust Level: { success_rate :.2f} %\n \n "
214+ f"{ '🟢 Verifier is likely convinced.' if success_rate >= 75 else '🔴 Verifier remains skeptical.' } "
215+ )
185216 msg .exec_ ()
186217 self .finish_level ()
187218
@@ -194,7 +225,31 @@ def prompt_next_round(self):
194225 self .reset_game (preserve_round = True )
195226
196227 def finish_level (self ):
197- self .parent_selector .update_trust_points (points_earned = 3 )
228+ total = self .valid_proofs + self .invalid_proofs
229+ success_rate = (self .valid_proofs / total ) * 100 if total > 0 else 0
230+
231+ # Award logic (adjust as needed)
232+ if success_rate >= 90 :
233+ points = 5
234+ message = "🌟 Outstanding! The verifier is truly convinced."
235+ elif success_rate >= 75 :
236+ points = 3
237+ message = "✅ Good job! You earned trust."
238+ elif success_rate >= 50 :
239+ points = 1
240+ message = "⚠️ Partial success. Try again for full trust."
241+ else :
242+ points = 0
243+ message = "❌ Verifier is not convinced. Try again."
244+
245+ self .parent_selector .update_trust_points (points_earned = points )
246+
247+ QMessageBox .information (
248+ self ,
249+ "🎉 Level Complete" ,
250+ f"{ message } \n \n You earned { points } trust point(s) for this level."
251+ )
252+
198253 self .close ()
199254 self .parent_selector .show ()
200255
@@ -220,4 +275,15 @@ def reset_game(self, preserve_round=False):
220275 self .update_narration ("🔁 Game reset. Recolor and start again!" )
221276 self .log_box .clear ()
222277 else :
223- self .update_narration ("🎨 Prover: Please recolor the graph for the next round." )
278+ self .update_narration ("🎨 Prover: Please recolor the graph for the next round." )
279+ def show_education_modal (self ):
280+ QMessageBox .information (
281+ self ,
282+ "📘 Level Introduction" ,
283+ f"Welcome to { self .level_name } !\n \n "
284+ "Your goal is to convince the verifier using Zero-Knowledge Proof.\n "
285+ "Step 1: Secretly color each node.\n "
286+ "Step 2: Commit to your colors.\n "
287+ "Step 3: Let the verifier challenge an edge.\n \n "
288+ "Make sure adjacent nodes have different colors!"
289+ )
0 commit comments