Tic Tac Toe mit KI

  • noch ein altes stück code eine schlichte variante von Tic Tac Toe mit anschaltbarer KI. Zur Entspannung für den frustrierten Programmierer.

    €: musste schlichte streichen nach Andys post

    [autoit]

    #include <WindowsConstants.au3>
    #include <guiConstants.au3>
    Global $i_counter = 0
    Global $a_s_TicTacToe_logic[9] = ["124836", "0247", "016458", "0645", "18172635", "2834", "037842", "1468", "250467"]
    Global $a_s_TicTacToe_sieg[8] = ["012", "345", "678", "036", "147", "258", "048", "246"]
    Global $b_KI = 0
    $h_GUI_TicTacToe = GUICreate("TicTacToe", 356, 500)
    GUISetBkColor(0x000000)
    $id_BUTTON_Neustart = GUICtrlCreateButton("Neustart", 20, 400, 75, 25)
    $id_BUTTON_ComputerZeichen = GUICtrlCreateButton("KI Zeichen", 20, 440, 150, 20)
    $id_BUTTON_KiStart = GUICtrlCreateButton("KI Start", 200, 440, 100, 20)
    $id_BUTTON_KiStop = GUICtrlCreateButton("KI Stop", 200, 460, 100, 20, $WS_DISABLED)
    GUISetFont(30, 500, "", "Comic Sans", $h_GUI_TicTacToe, 5)
    Global $a_id_BUTTON_Field[9], $a_s_Field[9]
    $i_counter = 0
    For $i1 = 1 To 3
    For $i2 = 1 To 3
    $a_id_BUTTON_Field[$i_counter] = GUICtrlCreateButton("", 120 * ($i2 - 1), 128 * ($i1 - 1), 115, 121);erzeuge spielfeld 0=oben links
    $i_counter += 1
    Next
    Next
    $i_counter = 0;counter widerverwendet für spielzüge
    GUICtrlSetDefBkColor(0x000000, $h_GUI_TicTacToe)
    GUICtrlSetDefColor(0xFFFFFF, $h_GUI_TicTacToe)
    Global $h_LABEL_NextesZeichen = GUICtrlCreateLabel("X", 260, 390, 50, 50);
    $h_LABEL_KiZeichen = GUICtrlCreateLabel("O", 75, 460, 50, 50)
    GUISetState(@SW_SHOW, $h_GUI_TicTacToe)
    While 1
    $hMsg = GUIGetMsg()
    Switch $hMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $id_BUTTON_KiStart
    $b_KI = 1
    GUICtrlSetState($id_BUTTON_KiStop, $GUI_ENABLE)
    GUICtrlSetState($id_BUTTON_KiStart, $GUI_DISABLE)
    Case $id_BUTTON_KiStop
    $b_KI = 0
    GUICtrlSetState($id_BUTTON_KiStart, $GUI_ENABLE)
    GUICtrlSetState($id_BUTTON_KiStop, $GUI_DISABLE)
    Case $id_BUTTON_Neustart
    For $i1 = 0 To 8;Buttons zurücksetzen
    GUICtrlSetData($a_id_BUTTON_Field[$i1], "")
    GUICtrlSetState($a_id_BUTTON_Field[$i1], $GUI_ENABLE)
    $a_s_Field[$i1] = ""
    Next
    $i_counter = Random(0, 1, 1);zufälliger Start
    GUICtrlSetData($h_LABEL_NextesZeichen, Mod($i_counter, 2) ? "O" : "X");Anzeige nextes Zeichen
    Case $a_id_BUTTON_Field[0] To $a_id_BUTTON_Field[8]; nacheinander erstellte buttons haben aufsteigende IDs
    GUICtrlSetState($hMsg, $GUI_DISABLE);gedrückter Button ausgrauen
    GUICtrlSetData($hMsg, Mod($i_counter, 2) ? "O" : "X")
    $i_counter += 1;zähler erhöhen
    GUICtrlSetData($h_LABEL_NextesZeichen, Mod($i_counter, 2) ? "O" : "X");Anzeige nextes Zeichen
    _test_win()
    Case $id_BUTTON_ComputerZeichen
    GUICtrlSetData($h_LABEL_KiZeichen, GUICtrlRead($h_LABEL_KiZeichen) = "O" ? "X" : "O");KI Zeichen setzen
    EndSwitch
    If GUICtrlRead($h_LABEL_KiZeichen) = (Mod($i_counter, 2) ? "O" : "X") And $b_KI = 1 Then;KI zug
    $s__Temp01 = (Mod($i_counter, 2) ? "O" : "X")
    For $i1 = 0 To 8
    If $a_s_Field[$i1] = "" Then
    For $i2 = 1 To StringLen($a_s_TicTacToe_logic[$i1]) - 1 Step 2
    If $a_s_Field[StringMid($a_s_TicTacToe_logic[$i1], $i2, 1)] == $s__Temp01 And $a_s_Field[StringMid($a_s_TicTacToe_logic[$i1], $i2 + 1, 1)] == $s__Temp01 Then;wenn 2 felder so belegt sind das das spiel von der KI gewonnen werden kann
    _KI_Button($i1)
    ExitLoop 2
    EndIf
    Next
    EndIf
    Next
    If GUICtrlRead($h_LABEL_KiZeichen) = (Mod($i_counter, 2) ? "O" : "X") Then;noch nichts gemacht
    $s__Temp01 = (Mod($i_counter + 1, 2) ? "O" : "X");spieler Zeichen
    For $i1 = 0 To 8
    If $a_s_Field[$i1] = "" Then
    For $i2 = 1 To StringLen($a_s_TicTacToe_logic[$i1]) - 1 Step 2
    If $a_s_Field[StringMid($a_s_TicTacToe_logic[$i1], $i2, 1)] == $s__Temp01 And $a_s_Field[StringMid($a_s_TicTacToe_logic[$i1], $i2 + 1, 1)] == $s__Temp01 Then;wenn 2 felder so belegt sind das das spiel vom spieler gewonnen werden kann (vereiteln)
    _KI_Button($i1)
    ExitLoop 2
    EndIf
    Next
    EndIf
    Next
    EndIf
    If GUICtrlRead($h_LABEL_KiZeichen) = (Mod($i_counter, 2) ? "O" : "X") Then;noch nichts gemacht
    Select
    Case $a_s_Field[1] = "" And $a_s_Field[7] = "" And $a_s_Field[4] = (Mod($i_counter, 2) ? "O" : "X");vorzugsweise in das feld setzen in dem der Spieler noch gewinnen kann
    _KI_Button(1)
    Case $a_s_Field[3] = "" And $a_s_Field[5] = "" And $a_s_Field[4] = (Mod($i_counter, 2) ? "O" : "X");vorzugsweise in das feld setzen in dem der Spieler noch gewinnen kann
    _KI_Button(3)
    Case $a_s_Field[4] = "";mitte frei
    _KI_Button(4)
    Case $a_s_Field[0] = "";oben links frei
    _KI_Button(0)
    Case $a_s_Field[2] = "";oben rechts frei
    _KI_Button(2)
    Case $a_s_Field[6] = "";unten links frei
    _KI_Button(6)
    Case $a_s_Field[8] = "";unten rechts frei
    _KI_Button(8)
    Case $a_s_Field[3] = ""
    _KI_Button(3)
    Case $a_s_Field[1] = ""
    _KI_Button(1)
    Case $a_s_Field[5] = ""
    _KI_Button(5)
    Case $a_s_Field[7] = ""
    _KI_Button(7)
    EndSelect
    EndIf
    EndIf
    WEnd
    Func _KI_Button($i_Index)
    GUICtrlSetState($a_id_BUTTON_Field[$i_Index], $GUI_DISABLE);gedrückter Button ausgrauen
    GUICtrlSetData($a_id_BUTTON_Field[$i_Index], Mod($i_counter, 2) ? "O" : "X");Zeichen Anzeigen
    $i_counter += 1;zähler erhöhen
    GUICtrlSetData($h_LABEL_NextesZeichen, Mod($i_counter, 2) ? "O" : "X");Anzeige nextes Zeichen
    _test_win();schauen ob wer gewonnen hat
    EndFunc ;==>_KI_Button
    Func _test_win()
    For $i1 = 0 To 8
    $a_s_Field[$i1] = GUICtrlRead($a_id_BUTTON_Field[$i1]);button infos holen
    Next
    $s__Temp01 = (Mod($i_counter, 2) ? "O" : "X")
    $s__Temp02 = (Mod($i_counter + 1, 2) ? "O" : "X")
    For $i1 = 0 To 7;test auf sieg
    If $a_s_Field[StringMid($a_s_TicTacToe_sieg[$i1], 1, 1)] == $s__Temp01 And $a_s_Field[StringMid($a_s_TicTacToe_sieg[$i1], 2, 1)] == $s__Temp01 And $a_s_Field[StringMid($a_s_TicTacToe_sieg[$i1], 3, 1)] == $s__Temp01 Then _TicTacToe_Win($s__Temp01)
    If $a_s_Field[StringMid($a_s_TicTacToe_sieg[$i1], 1, 1)] == $s__Temp02 And $a_s_Field[StringMid($a_s_TicTacToe_sieg[$i1], 2, 1)] == $s__Temp02 And $a_s_Field[StringMid($a_s_TicTacToe_sieg[$i1], 3, 1)] == $s__Temp02 Then _TicTacToe_Win($s__Temp02)
    Next
    EndFunc ;==>_test_win
    Func _TicTacToe_Win($s_win)
    MsgBox(0, "", $s_win & " gewinnt")
    For $i1 = 0 To 8;Buttons zurücksetzen
    GUICtrlSetData($a_id_BUTTON_Field[$i1], "")
    GUICtrlSetState($a_id_BUTTON_Field[$i1], $GUI_ENABLE)
    Next
    $i_counter = Random(0, 1, 1);zufälliger anfang
    GUICtrlSetData($h_LABEL_NextesZeichen, Mod($i_counter, 2) ? "O" : "X");Anzeige nextes Zeichen
    EndFunc ;==>_TicTacToe_Win

    [/autoit]

    Einmal editiert, zuletzt von bollen (24. Mai 2015 um 22:49)

  • noch ein altes stück code eine schlichte variante von Tic Tac Toe

    erinnert mich an einen Freund, der 1984 mit ein bisschen Fädeldraht und einem 32 BYTE großen "Ram"-Chip aus einem Casio FX82 einen "programmierbaren" Taschenrechner bastelte. Auf diesem Gerät konnte man tatsächlich ein lernfähiges TiCTacToe spielen. In 32 Byte Ram! Man hat das "Programm" gestartet und konnte durch eine Taste auswählen ob der Rechner anfängt oder der Spieler. Das Spielfeld war aus den Ziffern 1-9 auf der Taschenrechnertastatur aufgebaut....
    Nach einigen Runden Spielen hat der Computer immer mindestens ein unentschieden erreicht!

    Daran muss ich immer denken, wenn ich den Begriff KI im Zusammenhang mit TicTacToe lese^^