Exit Full View
Up

/Games/GameTiles.foocad

GameTiles

Playing tiles for various games, including Qwirkle. [https://en.wikipedia.org/wiki/Qwirkle]

These can be weighted with a penny (or a washer). See Custom [weight]. All plastic tiles feel cheap, the added heft makes a big difference.

Versions

I origionally used hearts,clubs,diamonds,spades symbols. However, symetric symbols are better.

Colors Used

In case reprints are needed.

  • 3DQF Matt Black (Base)
  • 3DQF Sky Blue,
  • Filamentive Cosmic Gold
  • Copymaster Bloody Red,
  • PrimaSelect Nebula Purple
  • Cheap (unbranded) Pink
  • 3DQF British Racing Greeen
FooCAD Source Code
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*
import static uk.co.nickthecoder.foocad.changefilament.v1.ChangeFilament.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*

class GameTiles : Model, PostProcessor {

    @Custom
    var size = Vector3(24,24,3.2)

    @Custom
    var cornerRadius = 4

    @Custom
    var patternThickness = 1.0

    @Custom( about="Diameter and thickness of a void which holds a washer or coin (to add weight)" )
    var weight = Vector2( 21, 2.0 )

    @Custom
    var spacing = 8
    
    fun tile() : Shape3d {
        val tile = Square( size.x, size.y ).center()
            .roundAllCorners( cornerRadius )
            .chamferedExtrude( size.z, 0.6, 0.4 )
        if ( weight.x > 0 && weight.y > 0 ) {
            val hole = Cylinder( weight.y , weight.x /2 )
                .bottomTo( (size.z - weight.y) / 2 )
            return tile - hole
        } else {
            return tile
        }
    }

    fun tile( pattern : Shape2d ) : Shape3d {
        val plain = tile()
        val top = pattern.extrude( patternThickness )
            .bottomTo(plain.top)
            .color( "Green")
        return plain + top
    }

    @Piece
    fun plain() = tile()

    @Piece
    fun disk() = tile( Circle( size.x/2 - 3 ) ) 

    @Piece
    fun rect() = tile( Square( size.x - 8 ).center() ) 

    @Piece
    fun heart() : Shape3d {
        val half = Circle( 5.5 ).translate( 4, 3 ) hull Circle( 1 ).translate(0, -8)
        val heart = half.mirrorX().also()
        return tile( heart )
    }
    
    @Piece
    fun club() : Shape3d {
        val circle = Circle( 4 )
        val three = circle.repeatX( 3, 4.5 ).translateY(-1).centerX() +
            circle.translateY( 5 )
        val tail = Triangle( 9 ).translateY(-9)
    
        return tile( three + tail )
    }

    @Piece
    fun diamond() = tile( Square( size.x * 0.6 ).center().rotate(45) ) 


    @Piece
    fun spade() : Shape3d {
        val half = Circle( 4 ).translate( 4, -1 ) hull Circle( 1 ).translate(0, 8)
        val tail = Triangle( 9 ).translateY(-9)
        val spade = half.mirrorX().also() + tail
        return tile( spade )
    }
    
    @Piece
    fun cross() : Shape3d {
        val leg = Circle( 3 ).translateX(7) hull ( Circle( 1 ) )
        val cross = leg.rotate(45).mirrorX().also().mirrorY().also()
        return tile ( cross )
    }

    @Piece
    fun fourBlob() : Shape3d {
        val blob = Circle( 4 )
        val blobs = blob + blob.translateX(4).repeatAround( 4 )
        return tile( blobs )
    }

    @Piece
    fun diamond2() : Shape3d {
        val size = 8
        val foo = 1.5
        val quarter = Square( size ) - Circle( size * foo ).translate(size*foo,size*foo) +
            Circle( 1.5 ).translateX( size )

        return tile( quarter.repeatAround(4) )
    }

    @Piece
    fun dots() : Shape3d {
        val dot = Circle( 4 )
        val dots = dot.tileX( 2, 1.5 ).tileY( 2, 1.5 ).center()
        return tile( dots )
    }

    @Piece
    fun set() : Shape3d {
        val a = disk()
        val b = rect().leftTo( a.right + spacing )
        val c = cross().leftTo( b.right + spacing )
        val d = fourBlob().leftTo( c.right + spacing )
        val e = diamond2().leftTo( d.right + spacing )
        val f = dots().leftTo( e.right + spacing )

        return a + b + c + d + e + f
    }

    @Piece
    fun oldSet() : Shape3d {
        val a = disk()
        val b = rect().leftTo( a.right + spacing )
        val c = heart().leftTo( b.right + spacing )
        val d = club().leftTo( c.right + spacing )
        val e = diamond().leftTo( d.right + spacing )
        val f = spade().leftTo( e.right + spacing )

        return a + b + c + d + e + f
    }

    @Piece
    fun oldThreeSets() = oldSet().tileY(3, spacing)

    @Piece
    fun threeSets() = set().tileY(3, spacing)

    // These pieces failed to print, so I'm printing extra copies!
    @Piece
    fun bodge() : Shape3d {
        val a = disk().tileX(3,2)
        val b = spade().tileX(3,2)
        return b //a + b.frontTo( a.back + 2 )
    }

    override fun postProcess(gcode : GCode ) {
        if ( weight.x > 0 && weight.y > 0 ) {
            pauseAtHeight( gcode, size.z - (size.z - weight.y) / 2, "Insert weights" )
        }

        pauseAtHeight( gcode, size.z, "Change Filament" )
    }

    override fun postProcess(pieceName : String, gcode : GCode ) {
        postProcess(gcode)
    }

    override fun build() : Shape3d {
        return set()
    }
}