Numeric1 Posted Monday at 01:02 AM Posted Monday at 01:02 AM (edited) Taquin The Taquin is a solitary puzzle game, popular since the late 19th century, that challenges the player's logic and patience. This code implements a digital version of the Taquin, where the goal is to rearrange a set of 15 numbered tiles from 1 to 15 into ascending order by moving the tiles one at a time, in a frame of 16 spaces. The game is played on a simple and intuitive graphical interface. Goal of the Game The goal of Taquin is to rearrange the 15 tiles into numerical order (from 1 to 15), with an empty space, starting from a randomly shuffled configuration. The player must move the tiles using the empty space by clicking on tiles adjacent to the empty space. Game Features Graphical Interface (GUI): The game uses AutoIt to create a simple graphical interface, where the game board consists of 15 numbered tiles. The interface allows the user to see the tiles and easily move them to solve the puzzle. Game Mechanics: Tiles can only be moved if they are adjacent to the empty space. By clicking on a tile, it moves into the empty space, and the game updates the display after each move. Solution Verification: The game continuously checks if the tiles are in the correct order, and a victory notification is displayed when the tiles are correctly arranged. Random Shuffle: At the start of the game, the tiles are randomly arranged to create a different challenge with each game. Ease of Use: The game is designed to be simple to use, with controls based on mouse clicks to move the tiles. Game Rules Tile Movement: A player can move a tile by clicking on it if it is adjacent to the empty space. The objective is to move the tiles into ascending order. Solution: The game ends when the tiles are arranged in the following order: 1, 2, 3, ..., 15, with the empty space at the end. History of the Game The Taquin was invented in the United States around 1870, before being popularized in Europe and becoming widely recognized. The invention was claimed by Sam Loyd in 1891, when the game became a global phenomenon. It is now a classic among puzzle games. expandcollapse popup#include-once #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include <GUIConstantsEx.au3> #include <GDIPlus.au3> #include "AutoItObject.au3" #include <Array.au3> ; #INDEX# ======================================================================================================================= ; Title .........: Puzzle Game ; AutoIt Version : 3.3 ; AutoItObject Version : v1.2.8.2 ; Language ......: English ; Description ...: This script implements a puzzle game using AutoIt and AutoItObject.au3. ; Dependencies ..: AutoItObject.au3, GDIPlus.au3 ; Author ........: Numeric ; ======================================================================================================================= ; Game Overview: ; - The game consists of a grid of tiles. ; - The objective is to arrange the tiles in numerical order by swapping them. ; - The game ends when all tiles are correctly arranged. ; - Tiles are shuffled randomly at the start, and the player can interact with them via mouse clicks. ; Controls: ; - Mouse Click: Select a tile to move. ; - Tiles swap when an adjacent empty tile is clicked. ; Enjoy solving the puzzle! ; ======================================================================================================================= _AutoItObject_Startup() _GDIPlus_Startup() ; Classe Ligne Func CreateLine($startX, $startY, $endX, $endY, $color = 0xFF00FF00, $thickness = 1) If $color = Default Or $color = "" Or Not $color Then $color = 0xFF00FF00 Local $lineObject = _AutoItObject_Class() With $lineObject .AddProperty("StartX", $ELSCOPE_PUBLIC, $startX) .AddProperty("StartY", $ELSCOPE_PUBLIC, $startY) .AddProperty("EndX", $ELSCOPE_PUBLIC, $endX) .AddProperty("EndY", $ELSCOPE_PUBLIC, $endY) .AddProperty("Color", $ELSCOPE_PUBLIC, $color) .AddProperty("Thickness", $ELSCOPE_PUBLIC, $thickness) EndWith Return $lineObject.Object EndFunc ;==>CreateLine Func CreateTile($xPosition, $yPosition, $size, $color = 0xFFFFFFFF) Local $squareObject = _AutoItObject_Class() Local $radius = $size / 2 Local $lines[0] With $squareObject .Create() .AddProperty("Lines", $ELSCOPE_PUBLIC, $lines) .AddProperty("Type", $ELSCOPE_PUBLIC, "Square") .AddProperty("Number", $ELSCOPE_PUBLIC, 0) .AddProperty("X", $ELSCOPE_PUBLIC, $xPosition) .AddProperty("Y", $ELSCOPE_PUBLIC, $yPosition) .AddProperty("Size", $ELSCOPE_PUBLIC, $size) .AddProperty("Color", $ELSCOPE_PUBLIC, $color) .AddProperty("CircleRadius", $ELSCOPE_PUBLIC, $radius) .AddMethod("AddLine", "AddLineToSquare") .AddMethod("DisplayNumber", "DisplayNumberOnSquare") .AddMethod("Move", "MoveSquare") .AddMethod("Resize", "ResizeSquare") .AddMethod("CheckCollision", "CheckSquareCollision") .AddMethod("ContainsPoint", "PointInsideSquare") EndWith Return $squareObject.Object EndFunc ;==>CreateTile Func AddLineToSquare($this, $line) Local $lineArray = $this.Lines _ArrayAdd($lineArray, $line) $this.Lines = $lineArray EndFunc ;==>AddLineToSquare Func DisplayNumberOnSquare($this, $number) Local $lineArray[0] $this.Lines = $lineArray If $number = 0 Then $number = "" Local $segmentSize = $this.Size / 3 Local $centerX = $this.X + ($this.Size / 2) Local $centerY = $this.Y + ($this.Size / 2) Local $segmentPatterns[10][7] = [ _ [1, 1, 1, 1, 1, 1, 0], _ ; 0 [0, 1, 1, 0, 0, 0, 0], _ ; 1 [1, 1, 0, 1, 1, 0, 1], _ ; 2 [1, 1, 1, 1, 0, 0, 1], _ ; 3 [0, 1, 1, 0, 0, 1, 1], _ ; 4 [1, 0, 1, 1, 0, 1, 1], _ ; 5 [1, 0, 1, 1, 1, 1, 1], _ ; 6 [1, 1, 1, 0, 0, 0, 0], _ ; 7 [1, 1, 1, 1, 1, 1, 1], _ ; 8 [1, 1, 1, 1, 0, 1, 1] _ ; 9 ] Local $segmentCoords[7][4] = [ _ [-0.4, -0.4, 0.4, -0.4], _ ; Haut [0.4, -0.4, 0.4, 0.0], _ ; Haut-droite [0.4, 0.0, 0.4, 0.4], _ ; Bas-droite [-0.4, 0.4, 0.4, 0.4], _ ; Bas [-0.4, 0.0, -0.4, 0.4], _ ; Bas-gauche [-0.4, -0.4, -0.4, 0.0], _ ; Haut-gauche [-0.4, 0.0, 0.4, 0.0] _ ; Milieu ] Local $currentOffsetX = -($segmentSize * (StringLen($number) - 1) / 2) For $digitIndex = 0 To StringLen($number) - 1 Local $digit = Number(StringMid($number, $digitIndex + 1, 1)) For $segmentIndex = 0 To 6 If $segmentPatterns[$digit][$segmentIndex] Then Local $x1 = $centerX + $currentOffsetX + $segmentCoords[$segmentIndex][0] * $segmentSize Local $y1 = $centerY + $segmentCoords[$segmentIndex][1] * $segmentSize Local $x2 = $centerX + $currentOffsetX + $segmentCoords[$segmentIndex][2] * $segmentSize Local $y2 = $centerY + $segmentCoords[$segmentIndex][3] * $segmentSize $this.AddLine(CreateLine($x1, $y1, $x2, $y2, Default, 2)) EndIf Next $currentOffsetX += $segmentSize * 1.2 Next EndFunc ;==>DisplayNumberOnSquare Func PointInsideSquare($this, $pointX, $pointY) Return ($pointX >= $this.X And $pointX <= $this.X + $this.Size) And _ ($pointY >= $this.Y And $pointY <= $this.Y + $this.Size) EndFunc ;==>PointInsideSquare Func CheckSquareCollision($this, $otherSquare) If $this.Type = "Square" And $otherSquare.Type = "Square" Then Local $isAdjacentHorizontally = ($this.Y = $otherSquare.Y And $this.Size = $otherSquare.Size) And _ (($this.X + $this.Size = $otherSquare.X) Or ($this.X = $otherSquare.X + $otherSquare.Size)) Local $isAdjacentVertically = ($this.X = $otherSquare.X And $this.Size = $otherSquare.Size) And _ (($this.Y + $this.Size = $otherSquare.Y) Or ($this.Y = $otherSquare.Y + $otherSquare.Size)) Return $isAdjacentHorizontally Or $isAdjacentVertically EndIf Return False EndFunc ;==>CheckSquareCollision Func CreatePuzzleGame($backgroundColor = 0xFF0000FF) Local $window = GUICreate("Puzzle Game", 400, 400) GUISetState() Local $windowSize = WinGetClientSize($window) Local $windowWidth = $windowSize[0] Local $windowHeight = $windowSize[1] Local $graphicsContext[] $graphicsContext["Graphics"] = _GDIPlus_GraphicsCreateFromHWND($window) $graphicsContext["Bitmap"] = _GDIPlus_BitmapCreateFromGraphics($windowWidth, $windowHeight, $graphicsContext["Graphics"]) $graphicsContext["GraphicsObject"] = _GDIPlus_ImageGetGraphicsContext($graphicsContext["Bitmap"]) $graphicsContext["BackgroundBrush"] = _GDIPlus_BrushCreateSolid($backgroundColor) Local $tileSize = Int($windowWidth / 4) Local $tiles[] Local $index = 0 Local $numbers[16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 14, 15] _ArrayShuffle($numbers) For $row = 0 To 3 For $col = 0 To 3 Local $tile = CreateTile($col * $tileSize, $row * $tileSize, $tileSize) $tile.Number = $numbers[$index] $tile.DisplayNumber($tile.Number) $index += 1 $tiles[$index] = $tile Next Next Local $game = _AutoItObject_Class() With $game .Create() .AddProperty("Tiles", $ELSCOPE_PUBLIC, $tiles) .AddProperty("GraphicsContext", $ELSCOPE_PUBLIC, $graphicsContext) .AddProperty("Window", $ELSCOPE_PUBLIC, $window) .AddProperty("WindowWidth", $ELSCOPE_PUBLIC, $windowWidth) .AddProperty("WindowHeight", $ELSCOPE_PUBLIC, $windowHeight) .AddMethod("Render", "RenderPuzzle") .AddMethod("Reset", "ResetPuzzle") .AddMethod("CheckVictory", "VerifyWinCondition") .AddMethod("Run", "StartGameLoop") .AddMethod("HandleClick", "ProcessMouseClick") .AddMethod("GetTileAtPosition", "FindTileAtCoordinates") .AddMethod("GetEmptyAdjacentTile", "FindEmptyNeighbor") .AddMethod("SwapTiles", "ExchangeTiles") .AddMethod("UpdateDisplay", "RefreshDisplay") .AddDestructor("ReleaseResources") EndWith Return $game.Object EndFunc ;==>CreatePuzzleGame Func StartGameLoop($this) Local $msg While 1 $msg = GUIGetMsg(1) Switch $msg[0] Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_PRIMARYDOWN $this.HandleClick($msg[3], $msg[4]) $this.Render() EndSwitch $this.Render() WEnd EndFunc ;==>StartGameLoop ; Gestion des clics de souris Func ProcessMouseClick($this, $x, $y) Local $clickedTileIndex = $this.GetTileAtPosition($x, $y) If Not $clickedTileIndex Then Return Local $emptyTileIndex = $this.GetEmptyAdjacentTile($clickedTileIndex) If $emptyTileIndex Then $this.SwapTiles($clickedTileIndex, $emptyTileIndex) $this.UpdateDisplay() If $this.CheckVictory() Then MsgBox(0, "Congratulations!", "You have solved the puzzle") $this.Reset() EndIf EndIf EndFunc ;==>ProcessMouseClick ; Trouve une tuile à une position donnée Func FindTileAtCoordinates($this, $x, $y) For $tileKey In MapKeys($this.Tiles) Local $tile = $this.Tiles[$tileKey] If $tile.ContainsPoint($x, $y) Then Return $tileKey EndIf Next Return Null EndFunc ;==>FindTileAtCoordinates ; Trouve une tuile vide adjacente Func FindEmptyNeighbor($this, $tileKey) Local $currentTile = $this.Tiles[$tileKey] Local $tileKeys = MapKeys($this.Tiles) For $key In $tileKeys Local $neighbor = $this.Tiles[$key] If $neighbor.Number = 0 And _ $neighbor <> $currentTile And _ $currentTile.CheckCollision($neighbor) Then Return $key EndIf Next Return Null EndFunc ;==>FindEmptyNeighbor ; Échange les numéros entre deux tuiles Func ExchangeTiles($this, $tile1Key, $tile2Key) Local $tiles = $this.Tiles Local $temp = $tiles[$tile1Key].Number $tiles[$tile2Key].Number = $temp $tiles[$tile1Key].Number = 0 $this.Tiles = $tiles EndFunc ;==>ExchangeTiles ; Met à jour l'affichage des tuiles Func RefreshDisplay($this) For $tile In $this.Tiles $tile.DisplayNumber($tile.Number) Next EndFunc ;==>RefreshDisplay ; Affiche le plateau de jeu Func RenderPuzzle($this) Local $graphicsContext = $this.GraphicsContext Local $graphics = $graphicsContext["GraphicsObject"] Local $pen = _GDIPlus_PenCreate(0xFFFF0000, 2) _GDIPlus_GraphicsClear($graphics, 0xFF000000) Local $tiles = $this.Tiles For $tile In $tiles _GDIPlus_GraphicsDrawRect($graphics, $tile.X, $tile.Y, $tile.Size, $tile.Size, $pen) For $line In $tile.Lines Local $linePen = _GDIPlus_PenCreate($line.Color, $line.Thickness) _GDIPlus_GraphicsDrawLine($graphics, $line.StartX, $line.StartY, $line.EndX, $line.EndY, $linePen) _GDIPlus_PenDispose($linePen) Next Next _GDIPlus_PenDispose($pen) _GDIPlus_GraphicsDrawImageRect($graphicsContext["Graphics"], $graphicsContext["Bitmap"], 0, 0, $this.WindowWidth, $this.WindowHeight) EndFunc ;==>RenderPuzzle Func ResetPuzzle($this) Local $numbers[16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 14, 15] _ArrayShuffle($numbers) Local $tiles = $this.Tiles For $i = 0 To UBound($tiles) - 1 $tiles[$i].Number = $numbers[$i] $tiles[$i].DisplayNumber($tiles[$i].Number) Next EndFunc ;==>ResetPuzzle ; Vérifie la condition de victoire Func VerifyWinCondition($this) Local $tiles = $this.Tiles For $i = 1 To UBound($tiles) - 1 ; Les cases doivent être triées de 1 à 15, avec la dernière case vide (0) If $tiles[$i].Number <> $i Then Return False EndIf Next Return True EndFunc ;==>VerifyWinCondition ; Libère les ressources Func ReleaseResources($this) Local $graphicsContext = $this.GraphicsContext _GDIPlus_BrushDispose($graphicsContext["BackgroundBrush"]) _GDIPlus_GraphicsDispose($graphicsContext["Graphics"]) _GDIPlus_BitmapDispose($graphicsContext["Bitmap"]) GUIDelete($graphicsContext["BoardWindow"]) _GDIPlus_Shutdown() EndFunc ;==>ReleaseResources Global $game = CreatePuzzleGame() $game.Run() $game = 0 Have fun! Edited Monday at 07:53 AM by Numeric1 Danyfirex and ioa747 2
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now