//----------------------------------------------------- // utilities (define "QtyAround" (count Pieces Next in:(sites Around #1 "LoSDirection") ) ) (define "LoSAt" (count Pieces Next in:(sites LineOfSight Piece at:#1 "LoSDirection") ) ) (define "SitesControlledBy" (sites (results from:(sites Occupied by:#1) to:(sites LineOfSight Empty at:(from) "LoSDirection") (to) ) ) ) (define "Placement" (move Add (piece (mover)) (to (difference (sites Empty) ("SitesControlledBy" Next) ) ) ) ) (define "Movement" (forEach Piece (do (and (set Var "LoSFrom" ("LoSAt" (from))) (set Var "QtyAroundFrom" ("QtyAround" (from))) ) next:(move Slide "LoSDirection") ifAfterwards:(or (> ("QtyAround" (last To)) (var "QtyAroundFrom")) (and (= ("QtyAround" (last To)) (var "QtyAroundFrom")) (> ("LoSAt" (last To)) (var "LoSFrom")) ) ) ) #1 ) ) (define "MPScoring" (set Score #1 (+ (size Array (array (sites From ("Movement" #1) ) ) ) (count Sites in:(difference ("SitesControlledBy" #1) ("SitesControlledBy" #2) ) ) ) ) ) (define "ScoreTerritory" (and ("MPScoring" Mover Next) ("MPScoring" Next Mover))) //------------------------------------------------- (game "Epoxy" (players 2) (equipment { "BoardUsed" (piece "Ball" Each (move Slide)) }) (rules (start (set Score Each 0)) (play (or { ("Placement") ("Movement" Mover) (if (and (not (is Prev Next)) (< 0 (counter)) ) (move Pass) ) } (then (if (is Prev Next) (moveAgain) ("ScoreTerritory") ) ) ) ) (end "PassEnd") ) ) //-------------------------- // ending rules: (define "PassEnd" (if (and ("SameTurn") (no Moves Next) ) (result Mover Win) )) //------------------------------------------------------- (define "LoSDirection" Orthogonal) (define "BoardUsed" ) //------------------------------------------------------- // Board definitions (define "Jungle" (poly { { -3.5 -11.75 } { -10.0 -5.25 } { -6.75 12.0 } { 1.25 14.75 } { 15.25 3.25 } { 14.0 -5.75 } })) (define "Perf2" (board (dual (remove (hex 4 5) cells:{0 1 15 20 25 32 36 39 44 })) use:Vertex)) (define "Perf3" (board (dual (remove (hex 5 6) cells:{0 1 2 3 4 5 6 7 11 12 13 14 21 25 30 37 42 53 63 64 65 69 70 71 72 73 74})) use:Vertex)) (define "Perf4" (board (dual (remove (hex 6) cells:{0 1 5 12 17 23 30 37 40 45 50 53 60 67 73 78 85 89 90})) use:Vertex)) (define "Perf5" (board (dual (remove (hex 7 8) cells:{0 1 2 3 4 5 6 7 8 9 10 11 12 16 17 18 19 26 27 34 38 43 50 53 60 63 64 71 76 77 82 89 92 99 108 116 123 130 131 132 136 137 138 139 140 141 142 143 144 145 146})) use:Vertex)) (define "Perf6" (board (dual (remove (hex 8) cells:{0 4 5 6 7 8 13 17 20 27 28 35 44 49 54 61 62 65 72 76 77 84 91 92 96 103 106 107 114 119 124 133 140 141 148 151 155 160 161 162 163 164 168})) use:Vertex)) (define "Perf7" (board (dual (remove (hex "Jungle") cells:{12 25 34 41 50 57 66 75 82 91 98 107 116 123 131 144 150 161})) use:Vertex)) (option "Size" args:{} { (item "XS (39)" <"Perf2"> "Extra small board (39 nodes) as a filler game and for learning how to play")** (item "S (48)" <"Perf3"> "Small board (48 nodes)") (item "M (72)" <"Perf4"> "Medium board (72 nodes)") (item "L (96)" <"Perf5"> "Large board (96 nodes)") (item "XL (126)" <"Perf6"> "Extra large board (126 nodes)") (item "XXL (156)" <"Perf7"> "XXL board (156 nodes)") } ) //------------------------------------------------ (metadata (info { (description "Epoxy is a version of 'Shaka' (my ancestor game a few other games including my game Situ.) Shaka was a territorial lines-of-sight game based on out-of-sight entry, sliding moves, increasing stone contact, capture by enclosure and double-pass ending. Epoxy does not involve capture, and is a survival game. It is played on a special, 'perforated' triangular grid that makes the game more manageable than pure Shaka by limiting the lines of sight and movement. Both Epoxy and Situ improve the balance and opening stability of Shaka by using a '12* double-move protocol' (that is, after the first placement, players alternate taking double turns.)Epoxy differs from Situ in having no capture, but having movement. Movement is controlled by adjacency to the opponent's stones, effectively locking stones in place as they neighbour more and more opponent's stones. This creates territories that can be filled, as well as dead-zones for movement and/or placement. Due to this territorial nature, unlike Situ, turns may be partially passed, but a full pass is by definition a resignation.Territory equates to the availability of future placements when other movement is no longer possible, and the goal is to be the last to play.") (rules "Use Options to select a board size. Goal: Be the last to play. Then the first player (Maroon) places a stone, after which the players alternate, taking up to two moves per turn. To move, either: 1. Add a stone to an empty space that is not in line-of-sight of any opponent's stone. -Or, 2. Slide a stone along a straight line to a new position, with the following restriction: Either -- A. The new location must have a greater number of opponent's stones adjacent to it, or -- B. The new location must have more sight-lines to opponent's stones than the old location, while keeping number of adjacent opponent's stones the same. To avoid forfeiting the game, a player must move at least once on a turn. The second move can be voluntarily skipped. The winner is last to play. The score shown is a count of the available moves at the beginning of a player's turn for use by the AI.") (id "1762") (version "1.3.12") (classification "board/space/blocking") (author "Dale W. Walton") (credit "Dale W. Walton") (date "05-12-2020") } ) (graphics { (player Colour P1 (colour 120 36 0)) (player Colour P2 (colour Cream)) (piece Background image:"Disc" fillColour:(colour 0 0 0 120) edgeColour:(colour 0 0 0 0) scale:.97 offsetX:.26 offsetY:.3) (board StyleThickness InnerEdges 0.4) (board StyleThickness OuterEdges 0.6) (board StyleThickness InnerVertices 0.45) (board StyleThickness OuterVertices 0.45) (board Colour InnerVertices (colour Grey)) (board Colour OuterVertices (colour Grey)) (board Colour InnerEdges (colour Black)) (board Colour OuterEdges (colour Black)) (board Background fillColour:(colour HumanLight) edgeColour:(colour Grey) scale:1.3) (show Edges Diagonal Hidden (colour DarkGrey)) } ) (ai "Epoxy_ai" ) )