// Shape matching utility (define "IfThisRotationDo" // compiles but sometimes misses (if (= 0 (size Array (difference (results from:(sites Group at:#4) to:(from) (+ (+ (* 32 #1) (#2)) (+ (max (results from:(sites Group at:#4) to:(from) (- (* 32 #1)) ) ) (max (results from:(sites Group at:#4) to:(from) (- (#2)) ) ) ) ) ) (results from:(sites) to:(from) (value Piece at:(from)) ) ) ) ) #3 ) ) (define "DRow" (/ (value Piece at:(from)) 32)) (define "DCol" (% (value Piece at:(from)) 32)) (define "IsSameSizeAsShapeAtValue" (= (size Array (array (sites))) (size Array (array (sites Group at:#1)))) ) (define "IfShapessMatchDo" (if ("IsSameSizeAsShapeAtValue" #2) (priority { ("IfThisRotationDo" ("DRow") ("DCol") #1 #2) ("IfThisRotationDo" ("DRow") (- "DRow" "DCol") #1 #2) ("IfThisRotationDo" (- "DRow" "DCol") ("DRow") #1 #2) ("IfThisRotationDo" ("DCol") ("DRow") #1 #2) ("IfThisRotationDo" (- "DCol") (- "DRow" "DCol") #1 #2) ("IfThisRotationDo" (- "DCol" "DRow") ("DCol") #1 #2) ("IfThisRotationDo" (- "DRow") (- "DCol") #1 #2) ("IfThisRotationDo" (- "DRow") (- "DCol" "DRow") #1 #2) ("IfThisRotationDo" (- "DCol" "DRow") (- "DRow") #1 #2) ("IfThisRotationDo" (- "DCol") (- "DRow") #1 #2) ("IfThisRotationDo" ("DCol") (- "DCol" "DRow") #1 #2) ("IfThisRotationDo" (- "DRow" "DCol") (- "DCol") #1 #2) } ) ) ) //---------------------------------------------- (define "RecordShapeVectorsAsValues" (set Var "LastRow" (row of:(max (array (sites Group at:(last To))))) (then (set Var "LastCol" (max (results from:(sites Group at:(last To)) to:(from) (column of:(from)))) (then (forEach Site (sites Group at:(last To)) (set Value at:(site) (+ (* 32 (- (var "LastRow") (row of:(site)))) (- (var "LastCol") (column of:(site))) ) ) ) ) ) ) ) ) //---------------------------------- // For each mover group find out how many matching groups there are and if that is less then the group multiply it by the group size and add to the score, otherwise square the group size and add it to the score (define "GroupSize" (size Group at:(var "KeySite")) ) (define "BroodSize" (count Value (var "KeySite") in:(values Remembered "ShapeCount")) ) (define "ManifoldBroodSize" (+ (count Value (var "KeySite") in:(values Remembered "ShapeCount")) (count Value (+ 1000 (var "KeySite")) in:(values Remembered "ShapeCount")) ) ) (define "RecordMultiplier" (if (= 0 "BroodSize") (set State at:(var "KeySite") (* (% "ManifoldBroodSize" 2) (- 2 (% "GroupSize" 2)))) (set State at:(var "KeySite") 0) ) ) (define "CountShapesOf" (forEach Value (values Remembered) (and { (set Var "KeySite" (value) (then (forEach Group if:(= #1 (who at:(to))) ("IfShapessMatchDo" (remember Value "ShapeCount" (+ (if (> (var "KeySite") (regionSite (sites) index:0)) 0 1000) (var "KeySite") ) ) (var "KeySite") ) ) ) ) } (then ("RecordMultiplier")) ) (then (forget Value All)) ) ) (define "ScorePlayer" (forEach Group if:(= #1 (who at:(to))) (remember Value (regionSite (sites) index:0) unique:True) (then (and { ("CountShapesOf" #1) (set Score Mover 0 (then (forEach Piece (addScore Mover (state at:(from)))) ) ) } ) ) ) ) (define "PlaceHex" (do (forEach Site (sites Occupied by:Mover) (set State at:(site) 0) ) next:(move Add (piece (id "Hex" Mover)) (to (sites Empty)) (then ("RecordShapeVectorsAsValues")) ) (then ("ScorePlayer" (mover))) ) ) //--------------------------------------------------------- (game "Manifold" (players 2) (equipment { (board use:Cell) (piece "Hex" Each maxState:7 maxValue:1023) // 32rows * 32columns for recording vectors (piece "Disc" Neutral) }) (rules (play (if (or (= 0 (count Moves)) (!= 0 (count MovesThisTurn))//("SameTurn") ) ("PlaceHex") (or (move Pass) (and { ("PlaceHex") } (then (moveAgain)) ) ) (then (forget Value All)) ) ) (end (if (all Passed) (byScore) ) ) ) ) //--------------- (option "Board Size" args:{ } { (item "4" <(hex Hexagon 4)> "A board of size 4 is currently selected.") (item "5" <(hex Hexagon 5)> "A board of size 5 is currently selected.")* (item "6" <(hex Hexagon 6)> "A board of size 6 is currently selected.") (item "7" <(hex Hexagon 7)> "A board of size 7 is currently selected.") (item "8" <(hex Hexagon 8)> "A board of size 8 is currently selected.") (item "9" <(hex Hexagon 9)> "A board of size 9 is currently selected.") } ) (option "Brood Values" args:{ } { (item "Hide" <> "Nothing is currently printed on the pieces.")* (item "Show" <(show Piece State "Hex" Middle)> "Each brood currently has one piece that shows how many points it is worth.") } ) //--------------- (metadata (info { (description "Manifold is a polyhex building game for two players – Black and White – played on an initially empty hexhex board. Michael Amundsen invented Manifold in May 2022.") (rules "Definitions: 1 A group is a stone along with all stones one can reach from it through a series of steps onto adjacent stones of the same color. 1.1 The size of a group is the number of stones in it. 2 A brood is a group along with all other groups of identical color, size and shape. Shapes are considered identical across rotational and mirror-symmetries. 2.1 The size of a brood is the number of groups in it. 2.2 The order of a brood is the size of the groups in it. Play: On the very first turn of the game, Black places one stone of their color on any hex. After, that – starting with White – take turns doing one of the following: • Pass. • Place two stones of your color on empty hexes. When the players pass consecutively, the winner is the player with the higher score. Scoring: For each of your odd-sized broods, you score 1 point if its order is odd and 2 points if its order is even.") (id "1997") (version "1.3.12") (classification "board/space/group") (author "Michael Admundsen") (credit "Dale Walton") (date "2022") } ) (graphics { (board Colour Phase0 (colour 100 200 250 120)) (board Colour OuterEdges (colour Black)) (board Colour InnerEdges (colour Black)) (board StyleThickness OuterEdges 1.5) (board StyleThickness InnerEdges 0.4) (board StyleThickness InnerVertices 0.4) (board StyleThickness OuterVertices 0.4) (player Colour P1 (colour Black)) (player Colour P2 (colour Cream)) (player Colour Neutral (colour 72 144 160 190)) (piece Scale Neutral .6) (piece Foreground P1 state:1 image:"1" edgeColour:(colour White) scale:.3) (piece Foreground P2 state:1 image:"1" edgeColour:(colour Black) scale:.3) (piece Foreground P1 state:2 image:"2" edgeColour:(colour White) scale:.3) (piece Foreground P2 state:2 image:"2" edgeColour:(colour Black) scale:.3) } ) (ai "Manifold_ai" ) )