Highscore-Liste (kreieren/sortieren/aktualisieren)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
diceman
Beiträge: 347
Registriert: 06.07.2017 12:24
Kontaktdaten:

Highscore-Liste (kreieren/sortieren/aktualisieren)

Beitrag von diceman »

Braucht jemand eine Highscore-Liste? :)
Das besondere bei dieser Implementierung: es werden nicht einfach Scores verglichen und Listenelemente neu sortiert, sondern am Anfang wird eine "Default-Liste" mit vorbelegten Scores kreiert, damit der Spieler gleich zu Beginn etwas zu knacken hat. Beim Sortieren muß dann jeweils berücksichtig werden, ob ein neuer Eintrag eingeschoben, oder lediglich ein Default-Eintrag ersetzt wird.
Der Code ist gut verständlich denke ich, habe ihn auch ausreichend kommentiert, und kann leicht in eigene Projekte eingepflegt werden. Bitte beachten, daß immer ein Null-Element in der Score-Liste existiert, welches den aktuell erzielten Punktestand repräsentiert und ggf. beim aktualisieren der Liste an eine neue Position geschoben wird. Beim Einschieben fällt immer zugleich ein anderes Listenelement heraus, welches zum neuen Null-Element wird. Wenn ein Default-Score geknackt wird, bleibt das Null-Element bestehen.
Das Null-Element wird bei jedem neuen Spiel mit den aktuellen Daten gefüttert (Spielername + erzielte Punkte).

Code: Alles auswählen

EnableExplicit

Declare updateScores()
Declare showScores()
Declare refreshPointer()

Structure SCORE_LIST
	name.s
	score.i
EndStructure
Global NewList scoreList.SCORE_LIST()
Global *current.SCORE_LIST		;Pointer auf aktuell erzielten Score (Null-Element)
Global *best.SCORE_LIST			;Pointer auf höchsten Score (Highscore)


Global defaultName$ = "..."
#maxScore = 10					;Anzahl der Positionen in Scoreliste
Global a						;unspezifische Laufvariable


;Default-Scores kreieren
For a = 0 To #maxScore
	AddElement(scoreList())
	scoreList()\name = defaultName$
	If a > 0
		scoreList()\score = ((#maxScore+1)-a)*100
	EndIf
Next
refreshPointer()	;Zeiger aktualisieren



;Einige Spiele simulieren, und jedesmal die Scoreliste aktualisieren
#maxPlayer = 4
Global Dim player$(#maxPlayer)
player$(0) = "diceman"
player$(1) = "xxxKillzXXX"
player$(2) = "LadyLuna"
player$(3) = "MrPansen"
player$(4) = "t3h_Master666"
showScores()	;Zu Beginn Default-Scoreliste anzeigen
For a = 1 To 10		;10 Spiele simulieren
	*current\name = player$(Random(#maxPlayer))	;Spieler bestimmen
	*current\score = Random(*best\score*1.5,1)	;Score auswürfeln, der höher als der gegenwärtige Highscore sein kann
	updateScores()		;Scores neu sortieren
	showScores()		;Scores anzeigen
	refreshPointer()	;Zeiger ggf. aktualisieren
Next
End






Procedure refreshPointer()
	;Pointer auf Null-Element und den besten Score-Eintrag aktualisieren (WICHTIG!)
	FirstElement(scoreList())
	*current = @scoreList()
	SelectElement(scoreList(),1)
	*best = @scoreList()
EndProcedure




Procedure showScores()
	Debug ""
	Debug ""
	Debug ""
	;Aktuellen Spieler + Ergebnis anzeigen
	If *current\name <> defaultName$	:	Debug "Player: "+*current\name+" ("+*current\score+")"	:	EndIf
	Debug ""
	ForEach scoreList()
		If ListIndex(scoreList()) > 0
			Debug Str(ListIndex(scoreList()))+". "+scoreList()\name+"   "+Str(scoreList()\score)
		EndIf
	Next
EndProcedure



Procedure updateScores()
	Define *relative.SCORE_LIST
	Define curPosition
	
	ForEach scoreList()
		If ListIndex(scoreList()) > 0
			;Die Liste von oben herab durchsuchen, bis man auf einen Score-Eintrag stößt ...
			If scoreList()\score < *current\score		;... der kleiner als der aktuell erzielte ist
				If scoreList()\name = defaultName$
					;Wenn es sich um einen Default-Eintrag handelt, Werte überschreiben
					scoreList()\name = *current\name
					scoreList()\score = *current\score
				Else
					;Ansonsten Position merken, als Referenz fürs Einschieben
					*relative = @scoreList()
				EndIf
				Break
			EndIf
		EndIf
	Next
	
	;Wenn ein Referenzpunkt existiert ...
	If *relative <> #Null
		;... aktuellen Score bevor neu gefundener Position einschieben
		ChangeCurrentElement(scoreList(),*current)
		MoveElement(scoreList(),#PB_List_Before,*relative)
		;Zwischenspeichern der Listenposition (als Referenz fürs Aufschieben)
		curPosition = ListIndex(scoreList())
		
		;Nächstes "freies" (default) Listenelement unterhalb aktueller Position löschen
		;... spätestens aber letztes Element
		ForEach scoreList()
			If (ListIndex(scoreList()) > curPosition And scoreList()\name = defaultName$) Or ListIndex(scoreList()) = #maxScore
				;zu löschender Eintrag wird neues Null-Element
				MoveElement(scoreList(),#PB_List_First)	
				Break
			EndIf
		Next
	EndIf
EndProcedure
Zuletzt geändert von diceman am 07.06.2019 14:40, insgesamt 1-mal geändert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Highscore-Liste (kreieren/sortieren/aktualisieren)

Beitrag von RSBasic »

:allright:
diceman hat geschrieben:Braucht jemand eine Highscore-Liste? :)
Online-Highscore-Liste immer.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
diceman
Beiträge: 347
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Highscore-Liste (kreieren/sortieren/aktualisieren)

Beitrag von diceman »

Mit Online-Funktionalität habe ich mich leider nie beschäftigt; also auf externe Quellen zugreifen und diese zu manipulieren ...
das geht (momentan noch) über meinen Verstand. /:-> :coderselixir:
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Antworten