Skip to content

Commit

Permalink
Add ranking into Scores, and textual output
Browse files Browse the repository at this point in the history
  • Loading branch information
iangray001 committed Nov 8, 2024
1 parent 8fc09f3 commit ecceb88
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 19 deletions.
26 changes: 18 additions & 8 deletions Quiz Server/Quiz Server/ControllerWindow.xib
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<outlet property="numbersAllowAnswers" destination="7kj-Da-9HS" id="zaT-Ku-pY6"/>
<outlet property="numbersTeamGuesses" destination="6GF-Mg-VR7" id="ZiO-7c-liM"/>
<outlet property="quieterBuzzes" destination="EOs-rc-2CU" id="OZm-0m-IfW"/>
<outlet property="scoresOutput" destination="mxH-b9-Xel" id="EPU-wf-phZ"/>
<outlet property="scoresText" destination="nUs-YF-jmA" id="MjU-mf-Kk6"/>
<outlet property="tabView" destination="SaY-do-P3f" id="ldq-kO-31n"/>
<outlet property="tabitemBuzzers" destination="zkE-YU-uHw" id="tqo-kG-iLP"/>
Expand Down Expand Up @@ -1193,7 +1194,7 @@ Answers</string>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZRL-oQ-wuX">
<rect key="frame" x="11" y="117" width="179" height="37"/>
<rect key="frame" x="11" y="117" width="206" height="62"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="bevel" title="Parse and Reset Anim" bezelStyle="regularSquare" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="GJl-RS-z86">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
Expand All @@ -1204,7 +1205,7 @@ Answers</string>
</connections>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CsS-SV-AdW">
<rect key="frame" x="24" y="167" width="153" height="37"/>
<rect key="frame" x="11" y="212" width="125" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="bevel" title="Initialise Text" bezelStyle="regularSquare" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ffG-wy-qsL">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
Expand All @@ -1215,7 +1216,7 @@ Answers</string>
</connections>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="69L-09-a9U">
<rect key="frame" x="51" y="59" width="98" height="37"/>
<rect key="frame" x="11" y="20" width="206" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="bevel" title="Show Next" bezelStyle="regularSquare" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="22l-Ch-6fu">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
Expand All @@ -1226,17 +1227,17 @@ Answers</string>
</connections>
</button>
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iPM-on-FTo">
<rect key="frame" x="333" y="17" width="546" height="221"/>
<rect key="frame" x="282" y="18" width="235" height="221"/>
<autoresizingMask key="autoresizingMask"/>
<clipView key="contentView" drawsBackground="NO" id="Fag-Ir-clm">
<rect key="frame" x="0.0" y="0.0" width="531" height="221"/>
<rect key="frame" x="0.0" y="0.0" width="220" height="221"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView wantsLayer="YES" importsGraphics="NO" richText="NO" verticallyResizable="YES" spellingCorrection="YES" smartInsertDelete="YES" id="nUs-YF-jmA">
<rect key="frame" x="0.0" y="0.0" width="531" height="221"/>
<rect key="frame" x="0.0" y="0.0" width="220" height="221"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="531" height="221"/>
<size key="minSize" width="220" height="221"/>
<size key="maxSize" width="555" height="10000000"/>
</textView>
</subviews>
Expand All @@ -1246,10 +1247,19 @@ Answers</string>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" horizontal="NO" id="CgK-hw-DLP">
<rect key="frame" x="531" y="0.0" width="15" height="221"/>
<rect key="frame" x="220" y="0.0" width="15" height="221"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mxH-b9-Xel">
<rect key="frame" x="573" y="24" width="291" height="210"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" borderStyle="border" title="No score data" id="ksy-Pe-smM">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
</tabViewItem>
Expand Down
4 changes: 4 additions & 0 deletions Quiz Server/Quiz Server/ControllerWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class ControllerWindowController: NSWindowController, NSWindowDelegate, NSTabVie
@IBOutlet weak var numbersAllowAnswers: NSButton!
@IBOutlet weak var numbersActualAnswer: NSTextField!

@IBOutlet var scoresOutput: NSTextField!
@IBOutlet var scoresText: NSTextView!

var quizScreen: NSScreen?
Expand Down Expand Up @@ -103,6 +104,9 @@ class ControllerWindowController: NSWindowController, NSWindowDelegate, NSTabVie
override func windowDidLoad() {
super.windowDidLoad()

//Connect any output UI elements
quizView.scoresScene.output = scoresOutput

//Connect to Node server
print("Connect to Node server...")
socket.delegate = self
Expand Down
76 changes: 65 additions & 11 deletions Quiz Server/Quiz Server/Scores.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ class ScoresScene: SKScene {
var numTeams = 15
var webSocket: WebSocket?

var scores : [(Int, Int)] = []
var scores : [(Int, Int, Int)] = []
var teamBoxes = [ScoreNode]()
var displayIndex = 0

var scoreSounds = [SKAction]()
var lastScoreSound = 0
let topScoreNoise = SKAction.playSoundFileNamed("topscore", waitForCompletion: false)
let simpleScoreNoise = SKAction.playSoundFileNamed("score5", waitForCompletion: false)

let snow1 = SKEmitterNode(fileNamed: "ScoresBackground")!

var output : NSTextField!

func setUpScene(size: CGSize, numTeams: Int, webSocket: WebSocket?) {
if setUp {
return
Expand All @@ -34,7 +37,7 @@ class ScoresScene: SKScene {

self.size = size
self.numTeams = numTeams
self.webSocket = webSocket;
self.webSocket = webSocket

let bgImage = SKSpriteNode(imageNamed: "abstract-dark")
bgImage.zPosition = 0
Expand Down Expand Up @@ -85,6 +88,7 @@ class ScoresScene: SKScene {

lastScoreSound = 0
scoreSounds.shuffle()
output.stringValue = "Ready"
}


Expand All @@ -95,12 +99,16 @@ class ScoresScene: SKScene {

func parseStringToPairs(_ input: String) -> [(Int, Int)]? {
var pairs = [(Int, Int)]()

let lines = input.split(separator: "\n")

let lines = input.replacingOccurrences(of: "\r", with: "").split(separator: "\n")
for line in lines {
do {
let components = line.split(separator: ",")
//Split on either tab or comma
var components : [Substring.SubSequence]
if line.split(separator: ",").count != 2 {
components = line.split(separator: "\t")
} else {
components = line.split(separator: ",")
}

if components.count == 2 {
guard let x = Int(components[0].trimmingCharacters(in: .whitespaces)),
Expand All @@ -111,30 +119,75 @@ class ScoresScene: SKScene {
}
} catch {
print("Error parsing line '\(line)': \(error)")
output.stringValue = "Error parsing line '\(line)': \(error)"
return nil
}
}

print("Number of teams with valid scores: \(pairs.count)")
output.stringValue = "Number of teams with valid scores: \(pairs.count)"
return pairs
}

func parseAndReset(scoreText : String) {
if let res = parseStringToPairs(scoreText) {
scores = res.sorted { $0.1 < $1.1 }
print(scores)

//Determine ranks
var rankedScores : [(Int, Int, Int)] = []
var lastScore = -1
var currentRank = 0
var skipped = 1
for i in res.sorted(by: { $0.1 > $1.1 }) {
if i.1 != lastScore {
lastScore = i.1
currentRank += skipped
skipped = 1
} else {
skipped += 1
}
rankedScores.append((currentRank, i.0, i.1))
}

scores = rankedScores.sorted { $0.0 > $1.0 }
output.stringValue = scores.map({"\($0): Team \($1) (\($2))"}).joined(separator: "\n")

} else {
print("Failed to parse input.")
}
displayIndex = 0
}

func numberAsEmoji(_ n: Int) -> String {
func conv(_ n: Int) -> String {
switch n {
case 0: return "0️⃣"
case 1: return "1️⃣"
case 2: return "2️⃣"
case 3: return "3️⃣"
case 4: return "4️⃣"
case 5: return "5️⃣"
case 6: return "6️⃣"
case 7: return "7️⃣"
case 8: return "8️⃣"
case 9: return "9️⃣"
default: return ""
}
}
if n > 10 {
return conv(n/10) + conv(n%10)
} else {
return conv(n)
}
}


func next() {

if displayIndex < scores.count {
//Add a team box
//BuzzerTeamNode expects team number to be zero based
let box = ScoreNode(team: scores[displayIndex].0 - 1, width: 1000, height: 150, fontSize: 80, addGlow: true, altText: "Team \(scores[displayIndex].0): \(scores[displayIndex].1) points")
let s = scores[displayIndex]
let box = ScoreNode(team: s.1 - 1, width: 1000, height: 150, fontSize: 80, addGlow: true, altText: "\(numberAsEmoji(s.0)) Team \(s.1): \(s.2) points")
box.position = CGPoint(x: self.centrePoint.x, y: self.size.height - 200)
box.zPosition = 1
teamBoxes.append(box)
Expand All @@ -144,14 +197,15 @@ class ScoresScene: SKScene {
if displayIndex == scores.count - 1 {
self.run(topScoreNoise)
} else {
if scoreSounds.count > 1 {
/*if scoreSounds.count > 1 {
if lastScoreSound > scoreSounds.count - 1 {
lastScoreSound = 0
scoreSounds.shuffle()
}
self.run(scoreSounds[lastScoreSound])
lastScoreSound += 1
}
}*/
self.run(simpleScoreNoise)
}

//LEDs expect zero based team ids
Expand Down

0 comments on commit ecceb88

Please sign in to comment.