git_game_show 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,7 @@ module GitGameShow
17
17
  @players = []
18
18
  @game_state = :lobby # :lobby, :playing, :ended
19
19
  @current_timer_id = nil
20
+ @game_width = 80
20
21
  end
21
22
 
22
23
  def connect
@@ -27,7 +28,7 @@ module GitGameShow
27
28
  # For ngrok TCP tunnels, we should use regular ws:// since ngrok tcp doesn't provide SSL termination
28
29
  # Only use wss:// if the secure flag is explicitly set (for configured HTTPS endpoints)
29
30
  protocol = if @secure
30
- puts "Using secure WebSocket connection (wss://)".colorize(:cyan)
31
+ puts "Using secure WebSocket connection (wss://)".colorize(:light_blue)
31
32
  'wss'
32
33
  else
33
34
  'ws'
@@ -132,13 +133,13 @@ module GitGameShow
132
133
  clear_screen
133
134
 
134
135
  # Draw header with fancy box
135
- terminal_width = `tput cols`.to_i rescue 80
136
+ terminal_width = `tput cols`.to_i rescue @game_width
136
137
  terminal_height = `tput lines`.to_i rescue 24
137
138
 
138
139
  # Create title box
139
- puts "┏#{"" * (terminal_width - 2)}".colorize(:green)
140
- puts "┃#{" GIT GAME SHOW - WAITING ROOM ".center(terminal_width - 2)}".colorize(:green)
141
- puts "┗#{"" * (terminal_width - 2)}".colorize(:green)
140
+ puts "╭#{"" * (terminal_width - 2)}".colorize(:green)
141
+ puts "│#{" Git Game Show - Waiting Room ".center(terminal_width - 2)}".colorize(:green)
142
+ puts "╰#{"" * (terminal_width - 2)}".colorize(:green)
142
143
 
143
144
  # Left column width (2/3 of terminal) for main content
144
145
  left_width = (terminal_width * 0.65).to_i
@@ -148,20 +149,20 @@ module GitGameShow
148
149
  puts " Welcome to Git Game Show!".colorize(:yellow)
149
150
  puts " Test your knowledge about Git and your team's commits through fun mini-games.".colorize(:light_white)
150
151
  puts "\n"
151
- puts " 🔹 INSTRUCTIONS:".colorize(:cyan)
152
+ puts " 🔹 Instructions:".colorize(:light_blue)
152
153
  puts " • The game consists of multiple rounds with different question types".colorize(:light_white)
153
154
  puts " • Each round has a theme based on Git commit history".colorize(:light_white)
154
155
  puts " • Answer questions as quickly as possible for maximum points".colorize(:light_white)
155
156
  puts " • The player with the most points at the end wins!".colorize(:light_white)
156
157
  puts "\n"
157
- puts " 🔹 STATUS: Waiting for the host to start the game...".colorize(:light_yellow)
158
+ puts " 🔹 Status: Waiting for the host to start the game...".colorize(:light_yellow)
158
159
  puts "\n"
159
160
 
160
161
  # Draw player section in a box
161
162
  player_box_width = terminal_width - 4
162
- puts " ┏#{"" * player_box_width}".colorize(:cyan)
163
- puts " ┃#{" PLAYERS ".center(player_box_width)}".colorize(:cyan)
164
- puts " ┗#{"" * player_box_width}".colorize(:cyan)
163
+ puts ("╭#{"" * player_box_width}").center(terminal_width).colorize(:light_blue)
164
+ puts ("│#{" Players ".center(player_box_width)}").center(terminal_width).colorize(:light_blue)
165
+ puts ("╰#{"" * player_box_width}").center(terminal_width).colorize(:light_blue)
165
166
 
166
167
  # Display list of players in a nicer format
167
168
  if @players.empty?
@@ -255,9 +256,11 @@ module GitGameShow
255
256
 
256
257
  # Draw question header once
257
258
  if question_number && total_questions
258
- puts "\n ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓".colorize(:cyan)
259
- puts " ┃#{"QUESTION #{question_number} of #{total_questions}".center(45)}┃".colorize(:cyan)
260
- puts " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛".colorize(:cyan)
259
+ box_width = 42
260
+ puts ""
261
+ puts ("" + "─" * box_width + "╮").center(@game_width).colorize(:light_blue)
262
+ puts ("│#{'Question #{question_number} of #{total_questions}'.center(box_width-2)}│").center(@game_width).colorize(:light_blue)
263
+ puts ("╰" + "─" * box_width + "╯").center(@game_width).colorize(:light_blue)
261
264
  end
262
265
 
263
266
  # Draw the main question text once
@@ -271,17 +274,12 @@ module GitGameShow
271
274
  puts " • Selected items move with cursor when you press ↑/↓".colorize(:white)
272
275
  puts " • Navigate to Submit and press ENTER when finished".colorize(:white)
273
276
 
274
- # Draw the header for the list content once
275
- puts "\n CURRENT ORDER:".colorize(:light_blue)
276
-
277
277
  # Calculate where the list content starts on screen
278
278
  content_start_line = question_number ? 15 : 12
279
279
 
280
280
  # Draw the list content (this will be redrawn repeatedly)
281
281
  draw_ordering_list(current_order, cursor_index, selected_index, content_start_line, num_options)
282
282
 
283
- # Initialize variables
284
-
285
283
  # Main interaction loop
286
284
  loop do
287
285
  # Read a single keypress
@@ -544,14 +542,15 @@ module GitGameShow
544
542
  clear_screen
545
543
 
546
544
  # Display a fun "Game Starting" animation
545
+ box_width = 40
547
546
  puts "\n\n"
548
- puts " ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓".colorize(:green)
549
- puts " ┃ GAME STARTING...".colorize(:green)
550
- puts " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛".colorize(:green)
547
+ puts ("" + "─" * box_width + "╮").center(@game_width).colorize(:green)
548
+ puts ("│" + "Game starting...".center(box_width) + "│").center(@game_width).colorize(:green)
549
+ puts ("" + "─" * box_width + "╯").center(@game_width).colorize(:green)
551
550
  puts "\n\n"
552
551
 
553
- puts " Total rounds: #{@total_rounds}".colorize(:cyan)
554
- puts " Players: #{@players.join(', ')}".colorize(:cyan)
552
+ puts " Total rounds: #{@total_rounds}".colorize(:light_blue)
553
+ puts " Players: #{@players.join(', ')}".colorize(:light_blue)
555
554
  puts "\n\n"
556
555
  puts " Get ready for the first round!".colorize(:yellow)
557
556
  puts "\n\n"
@@ -573,21 +572,22 @@ module GitGameShow
573
572
  end
574
573
  else
575
574
  # During gameplay, just show a notification without disrupting the game UI
576
- terminal_width = `tput cols`.to_i rescue 80
575
+ terminal_width = `tput cols`.to_i rescue @game_width
577
576
 
578
577
  # Create a notification box that won't interfere with ongoing gameplay
579
- puts "\n┏#{"━" * (terminal_width - 2)}┓".colorize(:cyan)
578
+ puts ""
579
+ puts "╭#{"─" * (terminal_width - 2)}╮".colorize(:light_blue)
580
580
 
581
581
  if data['type'] == 'player_joined'
582
- puts "┃#{" 🟢 #{data['name']} has joined the game ".center(terminal_width - 2)}".colorize(:green)
582
+ puts "│#{" 🟢 #{data['name']} has joined the game ".center(terminal_width - 2)}".colorize(:green)
583
583
  else
584
- puts "┃#{" 🔴 #{data['name']} has left the game ".center(terminal_width - 2)}".colorize(:yellow)
584
+ puts "│#{" 🔴 #{data['name']} has left the game ".center(terminal_width - 2)}".colorize(:yellow)
585
585
  end
586
586
 
587
587
  # Don't show all players during gameplay - can be too disruptive
588
588
  # Just show the total count
589
- puts "┃#{" Total players: #{data['players'].size} ".center(terminal_width - 2)}".colorize(:cyan)
590
- puts "┗#{"" * (terminal_width - 2)}".colorize(:cyan)
589
+ puts "│#{" Total players: #{data['players'].size} ".center(terminal_width - 2)}".colorize(:light_blue)
590
+ puts "╰#{"" * (terminal_width - 2)}".colorize(:light_blue)
591
591
  end
592
592
  end
593
593
 
@@ -604,27 +604,17 @@ module GitGameShow
604
604
 
605
605
  # Box is drawn with exactly 45 "━" characters for the top and bottom borders
606
606
  # The top and bottom including borders are 48 characters wide
607
- box_top = " ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
608
- box_bottom = " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
609
-
610
- # Get the text to center
611
- round_text = "ROUND #{round_num} of #{total_rounds}"
612
-
613
- # Find exact box width by measuring the top border
614
- box_width = box_top.length # Should be 48 with Unicode characters
615
-
616
- # The inner width is the box width minus the borders
617
- inner_width = box_width - (" ┃".length + "┃".length)
618
-
619
- # Simply use Ruby's built-in center method for reliable centering
620
- box_middle = " ┃" + round_text.center(inner_width) + "┃"
607
+ box_width = 42
608
+ box_top = ("" + "─" * (box_width - 2) + "╮").center(@game_width)
609
+ box_bottom = ("╰" + "─" * (box_width - 2) + "╯").center(@game_width)
610
+ box_middle = "│#{"Round #{round_num} of #{total_rounds}".center(box_width - 2)}│".center(@game_width)
621
611
 
622
612
  # Output the box
623
613
  puts box_top.colorize(:green)
624
614
  puts box_middle.colorize(:green)
625
615
  puts box_bottom.colorize(:green)
626
616
  puts "\n"
627
- puts " Mini-game: #{mini_game}".colorize(:cyan)
617
+ puts " Mini-game: #{mini_game}".colorize(:light_blue)
628
618
  puts " #{description}".colorize(:light_blue)
629
619
  puts "\n"
630
620
 
@@ -657,16 +647,15 @@ module GitGameShow
657
647
  puts "\n"
658
648
 
659
649
  # Draw a simple box for the question header
660
- box_top = " ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
661
- box_bottom = " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
662
- question_text = "QUESTION #{question_num} of #{total_questions}"
663
- inner_width = box_top.length - (" ┃".length + "┃".length)
664
- box_middle = " ┃" + question_text.center(inner_width) + "┃"
650
+ box_width = 42
651
+ box_top = ("" + "─" * (box_width - 2) + "╮").center(@game_width)
652
+ box_bottom = ("╰" + "─" * (box_width - 2) + "╯").center(@game_width)
653
+ box_middle = "│#{"Question #{question_num} of #{total_questions}".center(box_width - 2)}│".center(@game_width)
665
654
 
666
655
  # Output the question box
667
- puts box_top.colorize(:cyan)
668
- puts box_middle.colorize(:cyan)
669
- puts box_bottom.colorize(:cyan)
656
+ puts box_top.colorize(:light_blue)
657
+ puts box_middle.colorize(:light_blue)
658
+ puts box_bottom.colorize(:light_blue)
670
659
  puts "\n"
671
660
 
672
661
  # Display question
@@ -681,12 +670,6 @@ module GitGameShow
681
670
  # Create a unique timer ID for this question
682
671
  timer_id = SecureRandom.uuid
683
672
  @current_timer_id = timer_id
684
- start_time = Time.now
685
- end_time = start_time + timeout
686
-
687
- # Static deadline info
688
- puts " Deadline: #{end_time.strftime('%I:%M:%S %p')}".colorize(:light_blue)
689
- puts "\n"
690
673
 
691
674
  # Initialize remaining time for scoring
692
675
  @time_remaining = timeout
@@ -888,32 +871,31 @@ module GitGameShow
888
871
 
889
872
  # Box is drawn with exactly 45 "━" characters for the top and bottom borders
890
873
  # The top and bottom including borders are 48 characters wide
891
- box_top = " ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
892
- box_bottom = " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
893
-
894
- # Get the text to center
895
- result_text = "ROUND RESULTS"
896
-
897
- # Find exact box width by measuring the top border
898
- box_width = box_top.length # Should be 48 with Unicode characters
899
-
900
- # The inner width is the box width minus 2 characters for the borders
901
- inner_width = box_width - (" ┃".length + "┃".length)
902
-
903
- # Simply use Ruby's built-in center method for reliable centering
904
- box_middle = " ┃" + result_text.center(inner_width) + "┃"
874
+ box_width = 40
875
+ box_top = ("" + "─" * box_width + "╮").center(@game_width)
876
+ box_bottom = ("╰" + "─" * box_width + "╯").center(@game_width)
877
+ box_middle = "│#{'Round Results'.center(box_width)}│".center(@game_width)
905
878
 
906
879
  # Output the box
907
- puts box_top.colorize(:cyan)
908
- puts box_middle.colorize(:cyan)
909
- puts box_bottom.colorize(:cyan)
880
+ puts box_top.colorize(:light_blue)
881
+ puts box_middle.colorize(:light_blue)
882
+ puts box_bottom.colorize(:light_blue)
910
883
  puts "\n"
911
884
 
912
885
  # Show question again
913
886
  puts " Question: #{data['question'][:question]}".colorize(:light_blue)
914
- puts " Correct answer: #{data['correct_answer']}".colorize(:green)
915
887
 
916
- puts "\n All player results:".colorize(:cyan)
888
+ # Handle different display formats for correct answers
889
+ if data['question'][:question_type] == 'ordering' && data['correct_answer'].is_a?(Array)
890
+ puts " Correct order (oldest to newest):".colorize(:green)
891
+ data['correct_answer'].each do |item|
892
+ puts " #{item}".colorize(:green)
893
+ end
894
+ else
895
+ puts " Correct answer: #{data['correct_answer']}".colorize(:green)
896
+ end
897
+
898
+ puts "\n All player results:".colorize(:light_blue)
917
899
 
918
900
  # Debug data temporarily removed
919
901
 
@@ -931,11 +913,33 @@ module GitGameShow
931
913
  points_str = "(+#{points} points)"
932
914
  player_str = player == name ? "#{player} (You)" : player
933
915
 
934
- player_output = " #{player_str.ljust(20)} #{points_str.ljust(15)} #{answer} #{status}"
935
- if correct
936
- puts player_output.colorize(:green)
916
+ # For ordering questions with array answers, show them with numbers
917
+ if data['question'][:question_type] == 'ordering' && answer.is_a?(Array)
918
+ # First display player name and points
919
+ header = " #{player_str.ljust(20)} #{points_str.ljust(15)} #{status}"
920
+
921
+ # Color according to correctness
922
+ if correct
923
+ puts header.colorize(:green)
924
+ puts " Submitted order:".colorize(:green)
925
+ answer.each_with_index do |item, idx|
926
+ puts " #{idx + 1}. #{item}".colorize(:green)
927
+ end
928
+ else
929
+ puts header.colorize(:red)
930
+ puts " Submitted order:".colorize(:red)
931
+ answer.each_with_index do |item, idx|
932
+ puts " #{idx + 1}. #{item}".colorize(:red)
933
+ end
934
+ end
937
935
  else
938
- puts player_output.colorize(:red)
936
+ # Standard display for non-ordering questions
937
+ player_output = " #{player_str.ljust(20)} #{points_str.ljust(15)} #{answer} #{status}"
938
+ if correct
939
+ puts player_output.colorize(:green)
940
+ else
941
+ puts player_output.colorize(:red)
942
+ end
939
943
  end
940
944
  else
941
945
  # Fallback for unexpected result format
@@ -983,10 +987,11 @@ module GitGameShow
983
987
  # Always start with a clean screen for the scoreboard
984
988
  clear_screen
985
989
 
986
- puts "\n"
987
- puts " ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓".colorize(:yellow)
988
- puts " ┃ SCOREBOARD ┃".colorize(:yellow)
989
- puts " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛".colorize(:yellow)
990
+ box_width = 40
991
+ puts ""
992
+ puts ("" + "─" * box_width + "╮").center(@game_width).colorize(:yellow)
993
+ puts "│#{'Scoreboard'.center(box_width)}┃".center(@game_width).colorize(:yellow)
994
+ puts ("╰" + "─" * box_width + "╯").center(@game_width).colorize(:yellow)
990
995
  puts "\n"
991
996
 
992
997
  # Get player positions
@@ -1021,7 +1026,7 @@ module GitGameShow
1021
1026
  end
1022
1027
  end
1023
1028
 
1024
- puts "\n Next round coming up soon...".colorize(:cyan)
1029
+ puts "\n Next round coming up soon...".colorize(:light_blue)
1025
1030
  end
1026
1031
 
1027
1032
  def handle_game_end(data)
@@ -1043,34 +1048,37 @@ module GitGameShow
1043
1048
  winner = data['winner']
1044
1049
 
1045
1050
  # ASCII trophy art
1046
- trophy = <<-TROPHY
1047
- ___________
1048
- '._==_==_=_.'
1049
- .-\\: /-.
1050
- | (|:. |) |
1051
- '-|:. |-'
1052
- \\::. /
1053
- '::. .'
1054
- ) (
1055
- _.' '._
1056
- TROPHY
1057
-
1051
+ trophy = [
1052
+ "___________",
1053
+ "'._==_==_=_.'",
1054
+ ".-\\: /-.",
1055
+ "| (|:. |) |",
1056
+ "'-|:. |-'",
1057
+ "\\::. /",
1058
+ "'::. .'",
1059
+ ") (",
1060
+ "_.' '._"
1061
+ ]
1062
+
1063
+ box_width = 40
1058
1064
  puts "\n\n"
1059
- puts trophy.colorize(:yellow)
1065
+ trophy.each{|line| puts line.center(@game_width).colorize(:yellow)}
1060
1066
  puts "\n"
1061
- puts " ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓".colorize(:green)
1062
- puts " ┃ GAME OVER ┃".colorize(:green)
1063
- puts " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛".colorize(:green)
1067
+ puts ("" + "─" * box_width + "╮").center(@game_width).colorize(:green)
1068
+ puts "│#{'Game Over'.center(box_width)}│".center(@game_width).colorize(:green)
1069
+ puts ("" + "─" * box_width + "╯").center(@game_width).colorize(:green)
1064
1070
  puts "\n"
1065
1071
 
1066
1072
  winner_is_you = winner == name
1067
1073
  if winner_is_you
1068
- puts " 🎉 Congratulations! You won! 🎉".colorize(:light_yellow)
1074
+ puts "🎉 Congratulations! You won! 🎉".center(@game_width).colorize(:light_yellow)
1069
1075
  else
1070
- puts " Winner: #{winner}! 🏆".colorize(:light_yellow)
1076
+ puts "Winner: #{winner}! 🏆".center(@game_width).colorize(:light_yellow)
1071
1077
  end
1072
1078
 
1073
- puts "\n Final Scores:".colorize(:cyan)
1079
+ puts ""
1080
+ puts "Final Scores".center(@game_width).colorize(:light_blue)
1081
+ puts ""
1074
1082
 
1075
1083
  # Get player positions
1076
1084
  position = 1
@@ -1089,23 +1097,29 @@ module GitGameShow
1089
1097
  score_str = "#{score} points"
1090
1098
 
1091
1099
  # Add emoji for top 3
1100
+ scores_width = @game_width - 30
1092
1101
  case position
1093
1102
  when 1
1094
1103
  position_str = "🥇 #{position_str}"
1095
- puts " #{position_str.ljust(5)} #{player_str.ljust(25)} #{score_str}".colorize(:light_yellow)
1104
+ left_string = (position_str.rjust(5) + ' ' + player_str).ljust(scores_width - score_str.length)
1105
+ puts "#{left_string}#{score_str}".center(@game_width).colorize(:light_yellow)
1096
1106
  when 2
1097
1107
  position_str = "🥈 #{position_str}"
1098
- puts " #{position_str.ljust(5)} #{player_str.ljust(25)} #{score_str}".colorize(:light_blue)
1108
+ left_string = (position_str.rjust(5) + ' ' + player_str).ljust(scores_width - score_str.length)
1109
+ puts "#{left_string}#{score_str}".center(@game_width).colorize(:light_blue)
1099
1110
  when 3
1100
1111
  position_str = "🥉 #{position_str}"
1101
- puts " #{position_str.ljust(5)} #{player_str.ljust(25)} #{score_str}".colorize(:light_magenta)
1112
+ left_string = (position_str.rjust(5) + ' ' + player_str).ljust(scores_width - score_str.length)
1113
+ puts "#{left_string}#{score_str}".center(@game_width).colorize(:light_magenta)
1102
1114
  else
1103
- puts " #{position_str.ljust(5)} #{player_str.ljust(25)} #{score_str}"
1115
+ left_string = " " + (position_str.rjust(5) + ' ' + player_str).ljust(scores_width - score_str.length)
1116
+ puts "#{left_string}#{score_str}".center(@game_width)
1104
1117
  end
1105
1118
  end
1106
1119
 
1107
- puts "\n\n Thanks for playing Git Game Show!".colorize(:green)
1108
- puts " Waiting for the host to start a new game...".colorize(:cyan)
1120
+ puts "\n"
1121
+ puts " Thanks for playing Git Game Show!".colorize(:green)
1122
+ puts " Waiting for the host to start a new game...".colorize(:light_blue)
1109
1123
  puts " Press Ctrl+C to exit, or wait for the next game".colorize(:light_black)
1110
1124
 
1111
1125
  # Keep client ready to receive a new game start or reset message
@@ -1138,8 +1152,8 @@ module GitGameShow
1138
1152
  display_waiting_room
1139
1153
 
1140
1154
  # Show a prominent message that we're back in waiting room mode
1141
- puts "\n 🔄 The game has been reset by the host. Waiting for a new game to start...".colorize(:cyan)
1142
- puts " You can play again or press Ctrl+C to exit.".colorize(:cyan)
1155
+ puts "\n 🔄 The game has been reset by the host. Waiting for a new game to start...".colorize(:light_blue)
1156
+ puts " You can play again or press Ctrl+C to exit.".colorize(:light_blue)
1143
1157
  end
1144
1158
 
1145
1159
  def handle_chat(data)
@@ -61,14 +61,14 @@ module GitGameShow
61
61
  # Clear the terminal for better visibility
62
62
  puts "\n\n"
63
63
 
64
- puts "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓".colorize(:cyan)
65
- puts " UPDATE AVAILABLE FOR GIT GAME SHOW ".colorize(:cyan)
66
- puts "┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫".colorize(:cyan)
67
- puts " ".colorize(:cyan)
68
- puts " Current version: #{current_version.ljust(44)}".colorize(:cyan)
69
- puts " Latest version: #{latest_version.ljust(44)}".colorize(:cyan)
70
- puts " ".colorize(:cyan)
71
- puts "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛".colorize(:cyan)
64
+ puts "╭―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――╮".colorize(:cyan)
65
+ puts " UPDATE AVAILABLE FOR GIT GAME SHOW ".colorize(:cyan)
66
+ puts "├―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――┤".colorize(:cyan)
67
+ puts " ".colorize(:cyan)
68
+ puts " Current version: #{current_version.ljust(44)}".colorize(:cyan)
69
+ puts " Latest version: #{latest_version.ljust(44)}".colorize(:cyan)
70
+ puts " ".colorize(:cyan)
71
+ puts "╰―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――╯".colorize(:cyan)
72
72
  puts "\n"
73
73
 
74
74
  update_now = prompt.yes?("Would you like to update now?")
@@ -1,4 +1,4 @@
1
1
  module GitGameShow
2
2
  # Current version of Git Game Show
3
- VERSION = "0.1.4"
3
+ VERSION = "0.1.6"
4
4
  end
@@ -179,29 +179,68 @@ module GitGameShow
179
179
  def evaluate_answers(question, player_answers)
180
180
  results = {}
181
181
 
182
+ # Safety check for nil or empty responses
183
+ return results if player_answers.nil? || player_answers.empty?
184
+ return results unless question && question[:correct_answer]
185
+
186
+ # Get total number of items in the correct answer
187
+ total_items = question[:correct_answer].size
188
+
182
189
  player_answers.each do |player_name, answer_data|
190
+ # Skip nil entries
191
+ next unless player_name && answer_data
192
+
193
+ # Extract player's answer with defensive checks
183
194
  player_answer = answer_data[:answer]
184
195
  time_taken = answer_data[:time_taken] || 20
185
196
 
186
- # For the ordering quiz, we allow partial credit
187
- correct_positions = 0
197
+ # Initialize points
198
+ points = 0
188
199
 
189
- # Count how many items are in the correct position
190
- question[:correct_answer].each_with_index do |item, index|
191
- if player_answer && index < player_answer.size && player_answer[index] == item
192
- correct_positions += 1
200
+ # New scoring system: checks positions relative to each other item
201
+ if player_answer && !player_answer.empty?
202
+ # Create a mapping from item to its position in player's answer
203
+ item_positions = {}
204
+ player_answer.each_with_index do |item, index|
205
+ item_positions[item] = index if item # Skip nil items
206
+ end
207
+
208
+ # Create mapping from item to correct position
209
+ correct_positions = {}
210
+ question[:correct_answer].each_with_index do |item, index|
211
+ correct_positions[item] = index if item # Skip nil items
212
+ end
213
+
214
+ # For each item, calculate points based on relative positions
215
+ question[:correct_answer].each_with_index do |item, correct_index|
216
+ # Skip if the item isn't in the player's answer
217
+ next unless item && item_positions.key?(item)
218
+
219
+ player_index = item_positions[item]
220
+
221
+ # Check position relative to other items
222
+ question[:correct_answer].each_with_index do |other_item, other_correct_index|
223
+ next if !other_item || item == other_item || !item_positions.key?(other_item)
224
+
225
+ other_player_index = item_positions[other_item]
226
+
227
+ # If this item should be before the other item
228
+ if correct_index < other_correct_index
229
+ points += 1 if player_index < other_player_index
230
+ # If this item should be after the other item
231
+ elsif correct_index > other_correct_index
232
+ points += 1 if player_index > other_player_index
233
+ end
234
+ end
193
235
  end
194
236
  end
195
237
 
196
- # Calculate points: full credit for all correct, partial for some correct
197
- total_items = question[:correct_answer].size
198
- points = (correct_positions.to_f / total_items * 10).round
238
+ # Bonus points for perfect answer
239
+ perfect_score = total_items * (total_items - 1)
240
+ perfect_score = 1 if perfect_score <= 0 # Prevent division by zero
241
+ fully_correct = points == perfect_score
199
242
 
200
- # Fully correct gets bonus points
201
- if correct_positions == total_items
202
- # Base bonus for fully correct answer
203
- points += 3
204
-
243
+ if fully_correct
205
244
  # Additional time-based bonus (faster answers get more points)
206
245
  if time_taken < 8 # Really fast (under 8 seconds)
207
246
  points += 4
@@ -210,17 +249,35 @@ module GitGameShow
210
249
  end
211
250
  end
212
251
 
213
- # Create feedback with date info for displaying in results
214
- feedback = "#{correct_positions}/#{total_items} positions correct"
252
+ # Create detailed feedback
253
+ max_possible = total_items * (total_items - 1)
254
+ max_possible = 1 if max_possible <= 0 # Prevent division by zero
255
+ feedback = "#{points}/#{max_possible} points (based on relative ordering)"
215
256
  if question[:commit_dates]
216
- feedback += "\n\nActual dates:\n" + question[:commit_dates]
257
+ feedback += "\n\nActual dates:"
258
+ # Split by newlines and add them as separate lines for better readability
259
+ question[:commit_dates].to_s.split("\n").each do |date_line|
260
+ feedback += "\n • #{date_line}"
261
+ end
217
262
  end
218
263
 
264
+ # Ensure we return all required fields
265
+ results[player_name] = {
266
+ answer: player_answer || [],
267
+ correct: fully_correct || false,
268
+ points: points || 0,
269
+ partial_score: feedback || ""
270
+ }
271
+ end
272
+
273
+ # Return a default result if somehow we ended up with empty results
274
+ if results.empty? && !player_answers.empty?
275
+ player_name = player_answers.keys.first
219
276
  results[player_name] = {
220
- answer: player_answer,
221
- correct: correct_positions == total_items,
222
- points: points,
223
- partial_score: feedback
277
+ answer: [],
278
+ correct: false,
279
+ points: 0,
280
+ partial_score: "Error calculating score"
224
281
  }
225
282
  end
226
283
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_game_show
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Paulson