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