From 8628fafd2b26ec9b11a8161a1840d38063bd79be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=B6hler=2C=20Marcel?= <mkoehler@student.tugraz.at>
Date: Wed, 16 Apr 2025 09:04:17 +0200
Subject: [PATCH] Upload New File

---
 TicTacToe/TicTacToe.py | 247 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 247 insertions(+)
 create mode 100644 TicTacToe/TicTacToe.py

diff --git a/TicTacToe/TicTacToe.py b/TicTacToe/TicTacToe.py
new file mode 100644
index 0000000..e2b249b
--- /dev/null
+++ b/TicTacToe/TicTacToe.py
@@ -0,0 +1,247 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@author: imp
+"""
+
+import wx
+import wx.lib.buttons as buttons
+import random
+
+
+# generate Class for the Tic Tac Toe Panel
+class TicPanel(wx.Panel):
+    """
+    Panel Object for the Tic Tac Toe game
+    """
+
+    def __init__(self, parent):
+        # init Panel
+        wx.Panel.__init__(self, parent)
+
+        self.toggled = False
+        self.playerWon = False
+
+        self.LayoutWidgets()
+
+    def CheckWin(self, computer=False):
+
+        for button1, button2, button3 in self.winConditions:
+            if button1.GetLabel() == button2.GetLabel() and \
+               button2.GetLabel() == button3.GetLabel() and \
+               button1.GetLabel() != "":
+                print("Player has won!")
+                self.playerWon = True
+                button1.SetBackgroundColour("Green")
+                button2.SetBackgroundColour("Green")
+                button3.SetBackgroundColour("Green")
+                self.Layout()
+
+                if not computer:
+                    dlg = wx.MessageDialog(
+                        None, "You Won!", "Winner!", wx.YES_NO | wx.ICON_WARNING)
+                    result = dlg.ShowModal()
+                    if result == wx.ID_YES:
+                        wx.CallAfter(self.restart)
+                    dlg.Destroy()
+                    break
+                else:
+                    return True
+
+    def LayoutWidgets(self):
+        """
+        create the window layout for the Buttons
+        """
+        sizer = wx.BoxSizer(wx.VERTICAL)
+        self.fgSizer = wx.FlexGridSizer(rows=3, cols=3, vgap=5, hgap=5)
+        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        size = (75, 75)
+        # create the buttons
+        self.button1 = buttons.GenToggleButton(
+            self, size=size, name="button1")
+        self.button2 = buttons.GenToggleButton(
+            self, size=size, name="button2")
+        self.button3 = buttons.GenToggleButton(
+            self, size=size, name="button3")
+        self.button4 = buttons.GenToggleButton(
+            self, size=size, name="button4")
+        self.button5 = buttons.GenToggleButton(
+            self, size=size, name="button5")
+        self.button6 = buttons.GenToggleButton(
+            self, size=size, name="button6")
+        self.button7 = buttons.GenToggleButton(
+            self, size=size, name="button7")
+        self.button8 = buttons.GenToggleButton(
+            self, size=size, name="button8")
+        self.button9 = buttons.GenToggleButton(
+            self, size=size, name="button9")
+        self.normalBtnColour = self.button1.GetBackgroundColour()
+
+        self.widgets = [self.button1, self.button2, self.button3,
+                        self.button4, self.button5, self.button6,
+                        self.button7, self.button8, self.button9]
+
+        font = wx.Font(22, wx.FONTFAMILY_DEFAULT,
+                       wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
+        for button in self.widgets:
+            button.SetFont(font)
+            button.Bind(wx.EVT_BUTTON, self.OnToggle)
+
+        # insert buttons
+        self.fgSizer.AddMany(self.widgets)
+        sizer.Add(self.fgSizer, 0, wx.ALL | wx.CENTER, 5)
+
+        self.endTurnButton = wx.Button(self, label="End turn")
+        self.endTurnButton.Bind(wx.EVT_BUTTON, self.EndTurn)
+        self.endTurnButton.Disable()
+        buttonSizer.Add(self.endTurnButton, 0, wx.ALL | wx.CENTER, 5)
+
+        restartButton = wx.Button(self, label="restart")
+        restartButton.Bind(wx.EVT_BUTTON, self.restart)
+        buttonSizer.Add(restartButton, 0, wx.ALL | wx.CENTER, 5)
+        sizer.Add(buttonSizer, 0, wx.CENTER)
+
+        self.winConditions = [(self.button1, self.button4, self.button7),        # vertical win conditions
+                              (self.button2, self.button5, self.button8),
+                              (self.button3, self.button6, self.button9),
+                              # horizontal win conditions
+                              (self.button1, self.button2, self.button3),
+                              (self.button4, self.button5, self.button6),
+                              (self.button7, self.button8, self.button9),
+                              # diagonal win conditions
+                              (self.button1, self.button5, self.button9),
+                              (self.button3, self.button5, self.button7)]
+
+        self.SetSizer(sizer)
+
+    def EnableButtons(self):
+
+        for button in self.widgets:
+            if button.GetLabel() == "":
+                button.Enable()
+        self.Refresh()
+        self.Layout()
+
+    def EndTurn(self, event):
+        self.toggled = False
+
+        # Disable all occupied buttons
+        for button in self.widgets:
+            if button.GetLabel():
+                button.Disable()
+
+    # Check if computer can win immediately
+        mustPlays = []
+        possiblePlays = [b for b in self.widgets if not b.GetLabel()]
+
+        # check if any win condition is possible
+        for button1, button2, button3 in self.winConditions:
+            if button1.GetLabel() == button2.GetLabel() and button3.GetLabel() == "":
+                if button1.GetLabel() == button2.GetLabel() == "X":
+                    mustPlays.append(button3)
+            elif button2.GetLabel() == button3.GetLabel() and button1.GetLabel() == "":
+                if button2.GetLabel() == button3.GetLabel() == "X":
+                    mustPlays.append(button1)
+            elif button1.GetLabel() == button3.GetLabel() and button2.GetLabel() == "":
+                if button1.GetLabel() == button3.GetLabel() == "X":
+                    mustPlays.append(button2)
+
+        if mustPlays:
+            button = random.choice(mustPlays)
+            button.SetLabel("O")
+            button.Disable()
+            self.CheckWin(computer=True)
+
+        if not mustPlays and possiblePlays:
+            button = random.choice(possiblePlays)
+            button.SetLabel("O")
+            button.Disable()
+            self.CheckWin(computer=True)  # Final win check
+
+        # Enable buttons for player's next turn
+        self.EnableButtons()
+        self.endTurnButton.Disable()  # Critical fix here
+
+    # Check for draw after computer move
+        if all(b.GetLabel() for b in self.widgets):
+            self.ShowDrawDialog()
+
+    def Surrender(self):
+        msg = "I give up!"
+        dlg = wx.MessageDialog(None, msg, "Game Over!",
+                               wx.YES_NO | wx.ICON_WARNING)
+
+        result = dlg.ShowModal()
+        if result == wx.ID_YES:
+            self.restart()
+        else:
+            wx.CallAfter(self.GetParent().Close)
+        dlg.Destroy()
+
+    def OnToggle(self, event):
+        button = event.GetEventObject()
+        button.SetLabel("X")
+        buttonId = button.GetId()
+
+        self.CheckWin()
+        if not self.toggled:
+            self.toggled = True
+            self.endTurnButton.Enable()
+
+            for button in self.widgets:
+                if buttonId != button.GetId():
+                    button.Disable()
+        else:
+            self.toggled = False
+            self.endTurnButton.Disable()
+            button.SetLabel("")
+            self.EnableButtons()
+
+        # is it a draw?
+        if not self.playerWon:
+            label = [True if button.GetLabel(
+            ) else False for button in self.widgets]
+            if False not in label:
+                msg = "Draw, nobody won"
+                dlg = wx.MessageDialog(
+                    None, msg, "Game Over!", wx.YES_NO | wx.ICON_WARNING)
+                result = dlg.ShowModal()
+                if result == wx.ID_YES:
+                    self.restart()
+                dlg.Destroy()
+
+    def restart(self, event):
+        for button in self.widgets:
+            button.SetLabel("")
+            button.SetValue(False)
+            button.SetBackgroundColour(self.normalBtnColour)
+            self.toggled = False
+            self.playerWon = False
+            self.endTurnButton.Disable()
+            self.EnableButtons()
+
+
+class TicFrame(wx.Frame):
+
+    def __init__(self):
+        style = wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX
+        wx.Frame.__init__(self, parent=None, title="",
+                          size=(400, 400), style=style)
+
+        self.SetTitle("Tic-Tac-Toe")
+
+        panel = TicPanel(self)
+
+        self.CenterOnScreen(wx.BOTH)
+        self.Show()
+
+
+def main():
+    app = wx.App(False)
+    frame = TicFrame()
+    app.MainLoop()
+
+
+if __name__ == '__main__':
+    main()
-- 
GitLab