Hi
ich nutze eine random Funktion die aus einer .txt datei eine Zeile auswählt und diese an eine Variable übergibt
Nun such eich eine Möglichkeit die eine bereits ausgewählte Zeile nicht wiederholt
button1:
loop,10
{
gosub, funktion
sleep, 100000
}
tooltip, end
return
funktion:
MouseClick, left, 947, 667 ;chatklick
loop, 1
{
Random, num, 1, 30
FileReadLine, line, chat1.txt, %num%
sendinput, %line%
sleep, 1000
}
Sleep, 100
send, {enter}
Sleep, 1500
return
random - no repeat Topic is solved
Moderator: jNizM
Re: random - no repeat
Moin,
wenn die Datei nicht zu groß ist, würde ich Folgendes vorschlagen:
wenn die Datei nicht zu groß ist, würde ich Folgendes vorschlagen:
- Datei komplett einlesen, z.B. mit FileRead, DateiInhalt, ....
- Eingelesene Datei 'zufällig' sortieren, z.B. Sort, DateiInhalt, Random.
- Den zufällig sortierten Inhalt in ein Array übertragen, z.B. ZeilenArray := StrSplit(DateiInhalt, ...).
- Bei Bedarf immer die letzte Zeile aus dem Array auslesen und entfernen, z.B. Zeile := ZeilenArray.Pop().
- Wenn das ZeilenArray vollständig abgearbeitet ist (ZeilenArray.Length() = 0) ab 2. wiederholen. Alternativ auch ab 1., falls Du den DateiInhalt freigegeben/gelöscht hast
Re: random - no repeat
Hallo,
diese Randomfunktion gibt statt einem bereits früher gegebenen Wert, "Wiederholung" zurück:
diese Randomfunktion gibt statt einem bereits früher gegebenen Wert, "Wiederholung" zurück:
Code: Select all
q::ToolTip,% Random(1,10)
Random(Min,Max)
{
Static
Random, Random, Min, Max
IF Random%Random%
Return, "Wiederholung"
Random%Random% := True
Return, Random
}
Re: random - no repeat
Hi Rohwedder,
die von Dir eingestellte Funktion scheint mir wenig benutzerfreundlich und verwendet überholte Syntax. Wenn die Funktion prüft, ob der Wert schon einmal erzeugt wurde, sollte sie meiner Meinung nach intern weitersuchen, bis sie einen neuen Wert gefunden hat. Mit dem Rückgabewert Wiederholung lässt sich nichts anfangen. Das führt dann zu Konstrukten wieIch finde das nicht prickelnd.
Außerdem kann es bei größeren Wertebereichen nach vielen Aufrufen schon mal dauern, bis die Funktion endlich einen unbenutzten Wert findet.
die von Dir eingestellte Funktion scheint mir wenig benutzerfreundlich und verwendet überholte Syntax. Wenn die Funktion prüft, ob der Wert schon einmal erzeugt wurde, sollte sie meiner Meinung nach intern weitersuchen, bis sie einen neuen Wert gefunden hat. Mit dem Rückgabewert Wiederholung lässt sich nichts anfangen. Das führt dann zu Konstrukten wie
Code: Select all
Loop
R := Random(Min, Max)
Until (R <> "Wiederholung")
Außerdem kann es bei größeren Wertebereichen nach vielen Aufrufen schon mal dauern, bis die Funktion endlich einen unbenutzten Wert findet.
Re: random - no repeat
Hallo just me,
Pseudo Arrays werden zwar nicht empfohlen, sind jedoch Ausdruck-Syntax - nicht Altmodisch-Syntax!
Vorteil und Nachteil von Objekt Arrays ist ihre Initialisierung.
Vorteilhaft wenn man es will (auf einen Schlag alle Elemente löschen),
eher von Nachteil, daß man es anfänglich machen muß und es auch ungewollt passieren kann:
Ich finde, Pseudo Arrays und Objekt Arrays haben beide ihre Existenzberechtigung,
ziehe aber erstere vor.
Pseudo Arrays werden zwar nicht empfohlen, sind jedoch Ausdruck-Syntax - nicht Altmodisch-Syntax!
Vorteil und Nachteil von Objekt Arrays ist ihre Initialisierung.
Vorteilhaft wenn man es will (auf einen Schlag alle Elemente löschen),
eher von Nachteil, daß man es anfänglich machen muß und es auch ungewollt passieren kann:
Code: Select all
q::
A := [] ;Array A muß initialisiert werden
A[1] := 1
MsgBox,% A[1]
a := 2 ;initialisiert (ungewollt) Array A
MsgBox,% A[1]
Return
ziehe aber erstere vor.
Re: random - no repeat
Deine Pseudo arrays sorgen hier dafür, dass deine Funktion schlechte Optimierung hat und nur einmal verwendet werden kann.
Objekt arrays haben durch die Initialisierung keinen eigenen Nachteil.
Ich sehe ehrlich gesagt keinerlei Grund Pseudo Arrays in AHK zu verwenden.
Für mich haben sie keinerlei Existenzberechtignung.
Objekt arrays haben durch die Initialisierung keinen eigenen Nachteil.
Ich sehe ehrlich gesagt keinerlei Grund Pseudo Arrays in AHK zu verwenden.
Für mich haben sie keinerlei Existenzberechtignung.
Recommends AHK Studio
Re: random - no repeat
Danke für die Antworten
@just me kannst du mal ein beispiel zeigen wie der code aussehen soll, besonders punkt 5 verstehe ich nicht
@Rohwedder
thx für deine Mühe, leider bekomme ich bei deinem code immer "Wiederholung" und verstehe zudem überhaupt nicht wie ich das in meine funktion einbauen sollte
@just me kannst du mal ein beispiel zeigen wie der code aussehen soll, besonders punkt 5 verstehe ich nicht
@Rohwedder
thx für deine Mühe, leider bekomme ich bei deinem code immer "Wiederholung" und verstehe zudem überhaupt nicht wie ich das in meine funktion einbauen sollte
Re: random - no repeat
Hallo,
ich habe die Randomfunktion selbstresetend gemacht.
Sie gibt jetzt solange nicht wiederholende Zufallszahlen zurück bis sie keine mehr findet und stattdessen den Reset meldet.
ich habe die Randomfunktion selbstresetend gemacht.
Sie gibt jetzt solange nicht wiederholende Zufallszahlen zurück bis sie keine mehr findet und stattdessen den Reset meldet.
Code: Select all
q::ToolTip,% Random(1,5)
Random(Min,Max)
{
Static R
If R.MaxIndex() = ""
R := []
Random, Random, Min, Max
IF R[Random]
Loop,% Max-Min
{
If (++Random > Max)
Random := Min
}
Until !R[Random]
If R[Random]
Return, "Reset" R := []
R[Random] := True
Return, Random
}
Last edited by Rohwedder on 23 Mar 2019, 03:13, edited 1 time in total.
Re: random - no repeat
Moin,
ich verstehe nicht, welchen Code ich Dir zeigen soll. Die Anweisungen, mit denen man das machen kann, stehen ja schon am Ende der Zeilen der Schritt-für-Schritt-Anleitung.
Zu Pkt. 5 ist muss man sich die Doku zu Object.Pop() ansehen. Die Methode "entfernt das letze Array-Element und gibt es zurück". Daraus folgt, dass das Array nach einer bestimmten Anzahl von Aufrufen leer ist (keine Elemente mehr enthält). Array.Length() liefert dann 0. Wenn man dann noch weitermachen will, muss man das Array neu erstellen. Dazu wäre es gut, wenn das Erstellen des Arrays in eine Funktion oder Subroutine ausgelagert ist, die wiederholt aufgerufen werden kann.
Mit Arrays lassen sich auch alternative Lösungen einfach umsetzen.
ich verstehe nicht, welchen Code ich Dir zeigen soll. Die Anweisungen, mit denen man das machen kann, stehen ja schon am Ende der Zeilen der Schritt-für-Schritt-Anleitung.
Zu Pkt. 5 ist muss man sich die Doku zu Object.Pop() ansehen. Die Methode "entfernt das letze Array-Element und gibt es zurück". Daraus folgt, dass das Array nach einer bestimmten Anzahl von Aufrufen leer ist (keine Elemente mehr enthält). Array.Length() liefert dann 0. Wenn man dann noch weitermachen will, muss man das Array neu erstellen. Dazu wäre es gut, wenn das Erstellen des Arrays in eine Funktion oder Subroutine ausgelagert ist, die wiederholt aufgerufen werden kann.
Mit Arrays lassen sich auch alternative Lösungen einfach umsetzen.
Re: random - no repeat
Moin Rohwedder,
mir gefällt Deine letzte Version deutlich besser!
mir gefällt Deine letzte Version deutlich besser!
Re: random - no repeat
thx Rohwedder für deine zeit und mühe
Ich habe das jetzt schon anders (vll auch besser) gelöst damit es auch mit mehreren dateien funktioniert
Mein script poste ich mal vll hat jemand irgendwann das gleiche problem und sucht eine schnelle lösung
Ich habe das jetzt schon anders (vll auch besser) gelöst damit es auch mit mehreren dateien funktioniert
Mein script poste ich mal vll hat jemand irgendwann das gleiche problem und sucht eine schnelle lösung
Code: Select all
Gui, Add, Button, x6 y7 w90 h20 gbutton1, button1
Gui, Show, w177 h204, New GUI Window
Return
button1:
gosub, funktionchat1
sleep, 100
loop,10
{
gosub, randomsend1
sleep, 1000
}
tooltip, 1-done
gosub, funktionchat2
sleep, 100
loop,10
{
gosub, randomsend2
sleep, 1000
}
tooltip, 2-done
return
;---------------------------------------
funktionchat1:
Loop, read, chat1.txt
{
question%A_index% := A_LoopReadLine
maxquestion := A_index
}
ObjectCreate1:
Obj:=[]
Loop, %maxquestion%
Obj.Push(A_Index)
return
randomsend1:
Random, item, 1, % Obj.MaxIndex()
number:=Obj[item]
Obj.Delete(number)
If Obj.MaxIndex()=0
GoSub, ObjectCreate1
tooltip % question%number%
return
;---------------------------------------
funktionchat2:
Loop, read, chat2.txt
{
question%A_index% := A_LoopReadLine
maxquestion := A_index
}
ObjectCreate2:
Obj:=[]
Loop, %maxquestion%
Obj.Push(A_Index)
return
randomsend2:
Random, item, 1, % Obj.MaxIndex()
number:=Obj[item]
Obj.Delete(number)
If Obj.MaxIndex()=0
GoSub, ObjectCreate2
tooltip % question%number%
return
;---------------------------------------
Re: random - no repeat
Hallo tn6464,
die Idee ist an sich nicht schlecht. Ich glaube aber nicht, dass das so funktioniert.
die Idee ist an sich nicht schlecht. Ich glaube aber nicht, dass das so funktioniert.
- Du verwendest für beide Chatroutinen dieselbe Variable Obj als Array für die Zeilennummern.
- Obj.Delete(number) verändert Obj.MaxIndex() nur dann, wenn number zufällig den maximalen Index des Arrays enthält. Was Du machen willst, ist wohl eher Obj.RemoveAt(number).
Re: random - no repeat
Meine Idee:
Du hast eine Urne in der du alle Sätze die möglich sind hinzufügst.
Wenn du einen Satz brauchst ziehst du einen zufälligen aus der Urne.
Als Urne verwenden wir ein Array:
Um dem array Bälle aus einer datei hinzuzufügen verwenden wir:
Hier passiert ne Menge in einer Zeile:
FileOpen(textDatei,"r`n") Öffnet eine Datei fürs lesen und gibt ein file objekt zurück. Der Name der Datei wird durch die variable textDatei bestimmt.
….Read() liest den Text eines FileObjektes und gibt ihn ganz zurück.
Per StrSplit(…,"`n") erzeugen wir aus dem Text einen Array der bei jeder Zeile getrennt ist.
Und als letztes fügen wir dieses Array per Urne.push(…*) diesen Array dem Urnen Array hinzu.
Als letztes brauch man nur eine Möglichkeit einen zufälligen Satz zu ziehen und diesen aus der Urne zu entfernen.
Wobei dann satzText den text des gezogenen Satzes enthält.
Du hast eine Urne in der du alle Sätze die möglich sind hinzufügst.
Wenn du einen Satz brauchst ziehst du einen zufälligen aus der Urne.
Als Urne verwenden wir ein Array:
Code: Select all
urne := []
Code: Select all
urne.push(StrSplit(FileOpen(textDatei,"r`n").Read(),"`n")*)
FileOpen(textDatei,"r`n") Öffnet eine Datei fürs lesen und gibt ein file objekt zurück. Der Name der Datei wird durch die variable textDatei bestimmt.
….Read() liest den Text eines FileObjektes und gibt ihn ganz zurück.
Per StrSplit(…,"`n") erzeugen wir aus dem Text einen Array der bei jeder Zeile getrennt ist.
Und als letztes fügen wir dieses Array per Urne.push(…*) diesen Array dem Urnen Array hinzu.
Als letztes brauch man nur eine Möglichkeit einen zufälligen Satz zu ziehen und diesen aus der Urne zu entfernen.
Code: Select all
Random, gezogenerSatz, 1, % urne.length()
satzText := urne.removeAt(gezogenerSatz)
Recommends AHK Studio
Re: random - no repeat
@just me
also bisher funktionierts so
also bisher funktionierts so
Re: random - no repeat
@tm6464: Dann funktioniert es aber anders, als Du ursprünglich gefordert hast. Ich kann nue von dem Code ausgehen, den Du eingestellt hast. Wenn ich den hier mit folgender Datei für Chat1 und Chat2 laufen lasse
produziert er beispielhaft folgende Ausgaben:Fällt Dir etwas auf?
Code: Select all
Zeile 1
Zeile 2
Zeile 3
Zeile 4
Zeile 5
Zeile 6
Zeile 7
Zeile 8
Zeile 9
Zeile 10
Code: Select all
---------------------------
Test.ahk
---------------------------
Chat1..........:
Zeile 8
Zeile 5
Zeile 4
Zeile 2
Zeile 10
Zeile 7
Zeile 1
..........1 done
Chat2..........:
Zeile 3
Zeile 5
Zeile 7
Zeile 8
Zeile 10
Zeile 4
Zeile 2
..........2 done
---------------------------
OK
---------------------------
Re: random - no repeat
@just me da hast du sicher recht, das script ist nicht perfekt für meine anwendung gehts hald so auch
wenn du weisst wie kannst du es gerne so anpassen das es perfekt ist , ich bin dazu nicht in der lage und froh das überhaupt jetzt so geht
wenn du weisst wie kannst du es gerne so anpassen das es perfekt ist , ich bin dazu nicht in der lage und froh das überhaupt jetzt so geht
Re: random - no repeat Topic is solved
Hallo,
das folgende Codeschnipsel enthält zwei Funktionen, die für Deine Aufgabe taugen sollten:
Du musst nun pro Chatdatei am Anfang des Skripts einmal die Funktion FileToArray() aufrufen und ein zunächst leeres Zeilennummernarray anlegen, z.B.
Die Routine, die die zufälligen Zeilen ausgibt, könnte dann so aussehen:
das folgende Codeschnipsel enthält zwei Funktionen, die für Deine Aufgabe taugen sollten:
- FileToArray(FileName)
liest eine Datei und gibt die Zeilen als Array zurück. - RandomArray(SimpleArray)
baut aus diesem Array ein zufällig sortiertes Array mit den Zeilennummern auf und gibt es zurück.
Code: Select all
FileToArray(FileName) {
If !(FileHandle := FileOpen(FileName, "r"))
Throw "Die Datei " . FileName . " konnte nicht geöffnet werden!"
FileContent := FileHandle.Read()
FileHandle.Close()
Return StrSplit(RTrim(FileContent, "`n`r"), "`n", "`r")
}
RandomArray(SimpleArray) {
SortVar := ""
For Index In SimpleArray
SortVar .= Index . "`n"
Sort, SortVar, Random
Return StrSplit(RTrim(SortVar, "`n"), "`n")
}
Code: Select all
Chat1FileArray := FileToArray("Chat1.txt")
Chat1RandArray := []
Code: Select all
Chat1Label:
If (Chat1RandArray.Length() = 0)
Chat1RandArray := RandomArray(Chat1FileArray)
Rand := Chat1RandArray.Pop()
MsgBox, 0, #%Rand%, % Chat1FileArray[Rand]
Return
Re: random - no repeat
wow respekt, funktioniert wirklich perfekt
ich verstehe nicht jede deiner zeilen aber habe das mal so eingefügt, hoffe es passt so
ich verstehe nicht jede deiner zeilen aber habe das mal so eingefügt, hoffe es passt so
Code: Select all
Mbutton::
Chat1FileArray := FileToArray("Chat1.txt")
Chat1RandArray := []
loop, 3
{
gosub, Chat1Label
sleep, 1000
}
Chat1FileArray := FileToArray("Chat2.txt")
Chat1RandArray := []
loop, 5
{
gosub, Chat1Label
sleep, 1000
}
tooltip, end
return
Chat1Label:
If (Chat1RandArray.Length() = 0)
Chat1RandArray := RandomArray(Chat1FileArray)
Rand := Chat1RandArray.Pop()
tooltip, % Chat1FileArray[Rand]
Return
FileToArray(FileName) {
If !(FileHandle := FileOpen(FileName, "r"))
Throw "Die Datei " . FileName . " konnte nicht geöffnet werden!"
FileContent := FileHandle.Read()
FileHandle.Close()
Return StrSplit(RTrim(FileContent, "`n`r"), "`n", "`r")
}
RandomArray(SimpleArray) {
SortVar := ""
For Index In SimpleArray
SortVar .= Index . "`n"
Sort, SortVar, Random
Return StrSplit(RTrim(SortVar, "`n"), "`n")
}
Re: random - no repeat
Eine Frage:
Warum arbeitest du nicht mit einer Funktion statt mit goSub?
In den Doks steht:
Grüße
Warum arbeitest du nicht mit einer Funktion statt mit goSub?
In den Doks steht:
Ich selbst bin überhaupt kein Fan von goSub und goto.Obwohl Gosub für einfache, allgemeine Subroutinen nützlich ist, wäre es ratsam, für komplexere Anliegen Funktionen zu verwenden.
Grüße
Please use [code][/code] when posting code!
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09
Who is online
Users browsing this forum: gero and 55 guests