Exit Full View
Up

/Games/JigsawSuits.foocad

JigsawSuits

A tricky puzzle. Place the pieces in a 3x3 grid.

Flipping the pieces over isn't allowed (so I suggest swapping colors half way through).

FooCAD Source Code
import static uk.co.nickthecoder.foocad.changefilament.v1.ChangeFilament.*
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*

class JigsawSuits : Model {
    
    var pieceSize = 60
    var cornerRadius = 3
    var thickness = 3.0
    var slack = 0.5

    // Pieces are chamfered. The bottom chamfer is larger to account for elephant foot on the first layer.
    var chamfer1 = 0.9
    var chamfer2 = 0.6

    fun piece() = Square( pieceSize -slack ).center().roundAllCorners( cornerRadius )
    fun extrude( piece : Shape2d ) = piece.chamferedExtrude( thickness, chamfer1, chamfer2 )
    fun hole( shape : Shape2d ) = shape.translateY(-pieceSize).mirrorY().offset(slack)

    var heart : Shape2d = Square(1)
    var spade : Shape2d = Square(1)
    var club : Shape2d = Square(1)

    @Custom
    var pauseHalfWay = true

    init {
        val svg = SVGParser().parseFile( "JigsawSuits.svg" )
        heart = svg.shapes["heart"]
            .leftTo(-0.1).mirrorX().also()
            .frontTo(-4)
        spade = svg.shapes["spade"]
            .leftTo(-0.01).mirrorX().also()
            .frontTo(-3)
        club = svg.shapes["club"]
            .leftTo(-0.1).mirrorX().also()
            .frontTo(-3)
    }

    fun heart() : Shape2d {
        return heart.scale( pieceSize * 0.33 / heart.size.x )
            .translateY( pieceSize/2 )
    }

    fun spade() : Shape2d {
        return spade.scale( pieceSize * 0.33 / spade.size.x )
            .translateY( pieceSize/2 )
    }

    fun club() : Shape2d {
        return club.scale( pieceSize * 0.33 / club.size.x )
            .translateY( pieceSize/2 )
    }

    fun diamond() : Shape2d {
        val size = pieceSize * 0.17
        
        val diamond = Circle( size ).sides(4).translateY(size/2+2)
        val withSquare = (diamond + Circle( diamond.size.x ).sides(4)
            .scale(1,0.1).center().backTo(0))
            .roundCorner( 4, 2 )
            .roundCorner( 0, 2 )


        return withSquare.translateY( pieceSize/2 )
    }
    

    fun at( piece : Shape3d, x : double, y : double ) =
            piece.translate( x * pieceSize*1.4, y * pieceSize*1.4, 0 )

    fun piece( top : Shape2d, left : Shape2d, bottom : Shape2d, right : Shape2d ) =
        extrude(
            piece() + top + left.rotate(90) - hole( bottom ).rotate(180) - hole( right ).rotate(-90)
        )

    @Piece
    fun pieceA() = piece( heart(), club(), heart(), spade() )

    @Piece
    fun pieceB() = piece( diamond(), spade(), diamond(), heart() )

    @Piece
    fun pieceC() = piece( spade(), spade(), club(), heart() )

    @Piece
    fun pieceD() = piece( diamond(), heart(), heart(), diamond() )

    @Piece
    fun pieceE() = piece( heart(), club(), club(), diamond() )

    @Piece
    fun pieceF() = piece( diamond(), spade(), heart(), spade() )

    @Piece
    fun pieceG() = piece( spade(), heart(), club(), spade() )

    @Piece
    fun pieceH() = piece( club(), diamond(),diamond(), club() )

    @Piece
    fun pieceI() = piece( diamond(), heart(), club(), club() )

    @Piece
    fun row1() = pieceA() + at( pieceB(), 1, 0 ) + at( pieceC(), 2, 0 )

    @Piece
    fun row2() = at( pieceD(), 0, -1 ) + at( pieceE(), 1, -1 ) + at( pieceF(), 2, -1 )

    @Piece
    fun row3() = at( pieceG(), 0, -2 ) + at( pieceH(), 1, -2 ) + at( pieceI(), 2, -2 )
    
    @Piece
    fun holder() : Shape3d {
        val stack = layoutZ( 0.2, pieceA(), pieceB(), pieceC(), pieceD(), pieceE(), pieceF(), pieceG(), pieceH(), pieceI() )
        
        val base = piece().extrude(thickness)
        val corner = Square( base.size.x/2 + thickness ).roundCorner( 2, cornerRadius )
            .translate(-thickness, -thickness)
        val wall = (corner.translate( thickness, thickness ) - corner)
            .extrude( stack.size.z + thickness )
            .color("Green")
        val peg = (Circle(3).sides(12) hull Circle(3).sides(12).translateX(5.5))
            .rotate(120).also()
            .extrude( wall.size.z )
            .rightTo(wall.right)
            .color("Orange")
        val pegs = peg.mirrorX().rotateZ(-90).also(2)

        return base + pegs + wall + stack.rotateZ(90).bottomTo( thickness ).previewOnly()
    }

    override fun build() = row1() + row2() + row3()

    /*
    override fun postProcess(pieceName : String, gcode : GCode) {
        if (pieceName != "holder" && pauseHalfWay) {
            pauseAtHeight( gcode, thickness/2, "Change Filament" )
        }
    }
    */

}