All computer source code presented on this page, unless it includes attribution to another author, is provided by Ed Halley under the Artistic License. Use such code freely and without any expectation of support. I would like to know if you make anything cool with the code, or need questions answered.
python/
    bindings.py
    boards.py
    buzz.py
    caches.py
    cards.py
    constraints.py
    csql.py
    english.py
    getch.py
    getopts.py
    gizmos.py
    goals.py
    improv.py
    interpolations.py
    namespaces.py
    nihongo.py
    nodes.py
    octalplus.py
    patterns.py
    physics.py
    pids.py
    pieces.py
    quizzes.py
    recipes.py
    relays.py
    romaji.py
    ropen.py
    sheets.py
    stores.py
    strokes.py
    subscriptions.py
    svgbuild.py
    testing.py
    things.py
    timing.py
    ucsv.py
    useful.py
    uuid.py
    vectors.py
    weighted.py
java/
    CSVReader.java
    CSVWriter.java
    GlobFilenameFilter.java
    RegexFilenameFilter.java
    StringBufferOutputStream.java
    ThreadSet.java
    Throttle.java
    TracingThread.java
    Utf8ConsoleTest.java
    droid/
        ArrangeViewsTouchListener.java
        DownloadFileTask.java
perl/
    CVQM.pm
    Kana.pm
    Typo.pm
cxx/
    CCache.h
    equalish.cpp
Download boards.py
# boards - a "things" library space that supports board games and toys

import vectors ; from vectors import *
import things ; from things import *
import pieces ; from pieces import *
import goals ; from goals import *

#----------------------------------------------------------------------------

class Board (Space):

    def __init__(self, board=None):
        super(Board, self).__init__(VectorContext())
        if not board: board = "board-800x480.png"
        image = App.resource(board).convert()
        self.board = pygame.transform.scale(image, (720, 420))
        self.players = [ ]
        self.player = 0
        self.rules = { }
        self.phase = None

    def background(self, surface):
        surface.blit( self.board, (0,0) )

    def next_player(self):
        if not self.players:
            self.players.append('you')
        self.players = (self.players + 1) % len(self.players)

    def can_drag(self, thing):
        return True

    def zone_drop(self, zone, what):
        pass

    def get_zones(self):
        followers = self.followers()
        zones = [ zone for zone in followers if isinstance(zone, Zone) ]
        return zones

    def nearest_zone(self, where, test=None):
        '''Find the zone that's closest, or the closest empty zone.'''
        zones = self.get_zones()
        if callable(test):
            zones = [ zone for zone in zones if test(zone) ]
        if not zones:
            return None
        places = [ zone.xform.translation() for zone in zones ]
        (which, nearest) = (0, where.distance(places[0]))
        for i in range(1, len(zones)):
            d = where.distance(places[i])
            if d < nearest:
                (which, nearest) = (i, d)
        return (zones[which], V())

    def nearest_drop(self, thing, where):
        where = V(where[0], where[1], 0)
        return (self, where)

#----------------------------------------------------------------------------

class Zone (Piece):

    def __init__(self, name, image=None, size=1.0):
        super(Zone, self).__init__()
        self.name = name
        self.set_image(image, size)

    def set_image(self, image, size=1.0):
        if isinstance(image, str):
            image = App.resource(image)
        if image is not None and size != 1.0:
            image = pygame.transform.rotozoom(image, 0, size)
        self.image = image

    def get_image(self):
        return self.image

    def get_image(self):
        return self.image

    def xevent(self, event):
        # do not call super's version
        pass

#----------------------------------------------------------------------------

class _SampleBoard (Board):

    cards = { 'kawa': 0x5ddd,
              'chii.sai': 0x5c0f,
              'mizu': 0x6c34,
              'kokoro':0x5fc3,
              'ba.keru':0x5316,
              'ki.ru':0x5207, }

    def __init__(self, board=None):
        super(_SampleBoard, self).__init__()
        self.die = Die()
        self.die.follow(self)
        self.die.move( V(100, 275, self.die.height) )

        self.unknown = Zone('unknown',
                            App.resource('zone-blue.png'),
                            size=0.75)
        self.unknown.follow(self)
        self.unknown.move( V(100, 100, 0) )

        self.correct = Zone('correct',
                            App.resource('zone-green-o.png'),
                            size=0.75)
        self.correct.follow(self)
        self.correct.move( V(600, 100, 0) )

        self.mistake = Zone('mistake',
                            App.resource('zone-red-x.png'),
                            size=0.75)
        self.mistake.follow(self)
        self.mistake.move( V(600, 275, 0) )

        self.make_deck(self.unknown)

    def nearest_drop(self, thing, where):
        if isinstance(thing, Card):
            zones = [ zone.get_topmost() for zone in
                      [ self.unknown, self.correct, self.mistake ] ]
            places = [ zone.xform.translation() for zone in zones ]
            (which, nearest) = (0, where.distance(places[0]))
            for i in range(1, len(zones)):
                d = where.distance(places[i])
                if d < nearest:
                    nearest = d
                    which = i
            return (zones[which], V())
        return super(_SampleBoard, self).nearest_drop(thing, where)

    def event(self, event):
        super(_SampleBoard, self).event(event)
        if event.type == KEYDOWN:
            if event.key == K_SPACE:
                if self.die.is_idle():
                    self.die.append_goal(QuakeGoal(self.die, amount=20))
                    self.die.append_goal(QuakeGoal(self.die, cycles=3, amount=20))

    def make_deck(self, zone=None):
        self.deck = []
        self.font = App.resource('epkgobld.ttf', 36)
        follow = zone
        if not follow: follow = self
        for i in range(10):
            front = random.choice(_SampleBoard.cards.keys())
            back = unichr( _SampleBoard.cards[front] )
            card = Card( (front, back), font=self.font, size=0.75 )
            card.follow(follow)
            card.set_style('pickable')
            self.deck.append(card)
            follow = card

if __name__ == '__main__':
    app = App('Boardgame', (720, 420))
    Piece._shadows = True
    app.space = _SampleBoard()
    app.run()


Contact Ed Halley by email at ed@halley.cc.
Text, code, layout and artwork are Copyright © 1996-2013 Ed Halley.
Copying in whole or in part, with author attribution, is expressly allowed.
Any references to trademarks are illustrative and are controlled by their respective owners.
Make donations with PayPal - it's fast, free and secure!