Kleines Spiel - Denksport ^^

  • Hey ihr Lieben! :D
    Ich habe mir ein kleines Spiel ausgedacht welches eure Gehirnzellen ein wenig anstrengen soll. Ziel ist es, etwas zu sortieren. Ihr bekommt nach der Reihe (verdeckt) entweder die Zahl 1 oder 0. Ihr müsst versuchen nacheinander die Zahlen in einem langen String irgendwo einzufügen, sodass möglichst viele Nullen auf der einen Seite und Einsen auf der anderen Seite zu finden sind. Wo ihr die Zahl einfügt dürft ihr euch aussuchen. Die Schwierigkeit ist halt, dass ihr nicht wisst um was für eine Zahl es sich dabei handelt, diese wird euch erst hinterher bekannt gegeben. Es geht also darum möglichst intelligent die Zahlen zu verteilen ohne zu wissen welche Zahl ihr an eurer gewünschten Stelle einfügt. ^^

    Hier einmal ein kleines Skript zur Veranschaulichung:

    [autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit][autoit][/autoit][autoit]

    #include <Array.au3>
    #include <String.au3>
    #include <StringConstants.au3>

    [/autoit][autoit][/autoit][autoit]

    Global Const $g_eNumb = 100
    Global Const $g_eRound = 100

    [/autoit][autoit][/autoit][autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit][autoit][/autoit][autoit]

    Global $iFor, $iNum, $sStr, $iPt

    [/autoit][autoit][/autoit][autoit]

    For $iFor = 1 To $g_eRound
    $sStr = _GameRound(0, $iNum, True)

    [/autoit][autoit][/autoit][autoit]

    While $iNum
    $sStr = _GameRound(Random(0, StringLen($sStr), 1), $iNum)
    WEnd

    [/autoit][autoit][/autoit][autoit]

    $iPt += _GetPoints($sStr)
    Next

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite('Punkte im Durchschnitt: ' & Round($iPt / $g_eRound) & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit][autoit][/autoit][autoit]

    Func _GameRound($iPos, ByRef $iNumb, $bReset = False)
    Local Static $sStr = Null

    [/autoit][autoit][/autoit][autoit]

    If $bReset Or IsKeyword($sStr) Then
    $sStr = __GetNextNumb(True)
    $iNum = 1
    EndIf

    [/autoit][autoit][/autoit][autoit]

    If Not IsInt($iPos) Or $iPos < 0 Or $iPos > StringLen($sStr) Or Not $iNumb Then Return SetError(1)

    [/autoit][autoit][/autoit][autoit]

    $sStr = _StringInsert($sStr, __GetNextNumb(), $iPos)
    $iNumb = $g_eNumb - StringLen($sStr)

    [/autoit][autoit][/autoit][autoit]

    Return $sStr
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _GetPoints($sStr)
    Local $iP, $i, $iT, $sT

    [/autoit][autoit][/autoit][autoit]

    For $i = 1 To StringLen($sStr) -1
    $iT = __GetPoints($sStr, $i)
    If $iT > $iP Then $iP = $iT
    Next

    [/autoit][autoit][/autoit][autoit]

    Return $iP
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit][autoit][/autoit][autoit]

    Func __GetNextNumb($bReset = False)
    Local Static $aiNumb[$g_eNumb]
    Local $i

    [/autoit][autoit][/autoit][autoit]

    If $bReset Then
    ReDim $aiNumb[$g_eNumb]
    For $i = 0 To $g_eNumb -1
    $aiNumb[$i] = String(($i < $g_eNumb / 2) ? 1 : 0)
    Next
    _ArrayShuffle($aiNumb)
    EndIf

    [/autoit][autoit][/autoit][autoit]

    Return _ArrayPop($aiNumb)
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func __GetPoints($sStr, $iPos)
    Local $asSplit = StringSplit(_StringInsert($sStr, '|', $iPos), '|', $STR_NOCOUNT)
    Local $iPoints

    [/autoit][autoit][/autoit][autoit]

    $sStr = StringReplace($asSplit[0], '0', '') & StringReplace($asSplit[1], '1', '')
    $iPoints = StringLen($sStr)
    $sStr = StringReplace($asSplit[0], '1', '') & StringReplace($asSplit[1], '0', '')

    [/autoit][autoit][/autoit][autoit]

    Return (($iPoints > StringLen($sStr)) ? $iPoints : StringLen($sStr))
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit]

    In erster Linie ist für euch nur die Funktion _GameRound() und _GetPoints() interessant. Mit _GameRound() führt ihr eine Spielrunde aus. Beim ersten Aufruf (oder wenn ihr das Spiel mit dem dritten Parameter resettet) werden euch lediglich 2 Anfangszahlen vorgegeben. Diese können 00, 01, 10 oder auch 11 sein (wird von der Funktion returnt). Danach könnt ihr im ersten Parameter angeben wo ihr eure nächste Zahl hinsetzen möchtet. Die Zahl 0 steht dabei für den Anfang des Strings. Im 2ten Parameter wird euch eine Zahl zurückgegeben, welche die noch verbleibende Anzahl an Runden enthält. Ist diese auf 0 gesunken, so ist das Spiel vorbei und ihr könnt eure Punktzahl mithilfe von _GetPoints() ermitteln. Diese teilt den String auf und schaut, wie viele Einsen auf der einen und wie viele Nullen auf der anderen Seite ist. Dabei wird nicht exakt in der Mitte geteilt, sondern dort wo ihr die meisten Punkte mit bekommen könnt. Es spielt auch keine Rolle ob ihr die Einsen eher nach links als nach rechts sortiert, das Beste Ergebnis wird euch errechnet.

    Noch ein kleiner Tipp: Es sind so viele Einsen wie auch Nullen im Spiel vorhanden. Ich wünsche euch viel Erfolg! Mal schau'n wer die beste Punktzahl heraus bekommt, es bieten sich da einige Möglichkeiten an. ^^

    Falls Fragen auftauchen, immer her damit. Ach ja, wenn ich am WE Zeit finde dann versuche ich mal das Skript zu optimieren sodass es schneller läuft. Hab dazu gerade keine Zeit mehr. Und wer die Master Lösung herausfindet (*g* ^^) behält sie bitte erstmal für sich, ja? :D