diff options
Diffstat (limited to 'examples/life')
-rw-r--r-- | examples/life/life.cpp | 136 | ||||
-rw-r--r-- | examples/life/life.doc | 27 | ||||
-rw-r--r-- | examples/life/life.h | 58 | ||||
-rw-r--r-- | examples/life/life.pro | 13 | ||||
-rw-r--r-- | examples/life/lifedlg.cpp | 162 | ||||
-rw-r--r-- | examples/life/lifedlg.h | 64 | ||||
-rw-r--r-- | examples/life/main.cpp | 44 | ||||
-rw-r--r-- | examples/life/patterns.cpp | 383 |
8 files changed, 887 insertions, 0 deletions
diff --git a/examples/life/life.cpp b/examples/life/life.cpp new file mode 100644 index 000000000..413a7db40 --- /dev/null +++ b/examples/life/life.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "life.h" + +#include <qpainter.h> +#include <qdrawutil.h> +#include <qcheckbox.h> +#include <qevent.h> +#include <qapplication.h> + +// The main game of life widget + +LifeWidget::LifeWidget( int s, TQWidget *parent, const char *name ) + : TQFrame( parent, name ) +{ + SCALE = s; + + maxi = maxj = 50; + setMinimumSize( MINSIZE * SCALE + 2 * BORDER, + MINSIZE * SCALE + 2 * BORDER ); + setMaximumSize( MAXSIZE * SCALE + 2 * BORDER, + MAXSIZE * SCALE + 2 * BORDER ); + setSizeIncrement( SCALE, SCALE); + + clear(); + resize( maxi * SCALE + 2 * BORDER , maxj * SCALE + 2 * BORDER ); + +} + + +void LifeWidget::clear() +{ + current = 0; + for ( int t = 0; t < 2; t++ ) + for ( int i = 0; i < MAXSIZE + 2; i++ ) + for ( int j = 0; j < MAXSIZE + 2; j++ ) + cells[t][i][j] = FALSE; + + repaint(); +} + + +// We assume that the size will never be beyond the maximum size set +// this is not in general TRUE, but in practice it's good enough for +// this program + +void LifeWidget::resizeEvent( TQResizeEvent * e ) +{ + maxi = (e->size().width() - 2 * BORDER) / SCALE; + maxj = (e->size().height() - 2 * BORDER) / SCALE; +} + + +void LifeWidget::setPoint( int i, int j ) +{ + if ( i < 1 || i > maxi || j < 1 || j > maxi ) + return; + cells[current][i][j] = TRUE; + repaint( index2pos(i), index2pos(j), SCALE, SCALE, FALSE ); +} + + +void LifeWidget::mouseHandle( const TQPoint &pos ) +{ + int i = pos2index( pos.x() ); + int j = pos2index( pos.y() ); + setPoint( i, j ); +} + + +void LifeWidget::mouseMoveEvent( TQMouseEvent *e ) +{ + mouseHandle( e->pos() ); +} + + +void LifeWidget::mousePressEvent( TQMouseEvent *e ) +{ + if ( e->button() == TQMouseEvent::LeftButton ) + mouseHandle( e->pos() ); +} + + +void LifeWidget::nextGeneration() +{ + for ( int i = 1; i <= MAXSIZE; i++ ) { + for ( int j = 1; j <= MAXSIZE; j++ ) { + int t = cells[current][i - 1][j - 1] + + cells[current][i - 1][j] + + cells[current][i - 1][j + 1] + + cells[current][i][j - 1] + + cells[current][i][j + 1] + + cells[current][i + 1][j - 1] + + cells[current][i + 1][j] + + cells[current][i + 1][j + 1]; + + cells[!current][i][j] = ( t == 3 || + t == 2 && cells[current][i][j] ); + } + } + current = !current; + repaint( FALSE ); // repaint without erase +} + + +void LifeWidget::paintEvent( TQPaintEvent * e ) +{ + int starti = pos2index( e->rect().left() ); + int stopi = pos2index( e->rect().right() ); + int startj = pos2index( e->rect().top() ); + int stopj = pos2index( e->rect().bottom() ); + + if (stopi > maxi) + stopi = maxi; + if (stopj > maxj) + stopj = maxj; + + TQPainter paint( this ); + for ( int i = starti; i <= stopi; i++ ) { + for ( int j = startj; j <= stopj; j++ ) { + if ( cells[current][i][j] ) + qDrawShadePanel( &paint, index2pos( i ), index2pos( j ), + SCALE - 1, SCALE - 1, colorGroup() ); + else if ( cells[!current][i][j] ) + erase(index2pos( i ), index2pos( j ), SCALE - 1, SCALE - 1); + } + } + drawFrame( &paint ); +} diff --git a/examples/life/life.doc b/examples/life/life.doc new file mode 100644 index 000000000..cd935cfbc --- /dev/null +++ b/examples/life/life.doc @@ -0,0 +1,27 @@ +/* +*/ +/*! \page life-example.html + + \ingroup examples + \title Conway's Game of Life + + + <hr> + + Header file: + + \include life/life.h + + <hr> + + Implementation: + + \include life/life.cpp + + <hr> + + Main: + + \include life/main.cpp +*/ + diff --git a/examples/life/life.h b/examples/life/life.h new file mode 100644 index 000000000..578044068 --- /dev/null +++ b/examples/life/life.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef LIFE_H +#define LIFE_H + +#include <qframe.h> + + +class LifeWidget : public TQFrame +{ + Q_OBJECT +public: + LifeWidget( int s = 10, TQWidget *parent = 0, const char *name = 0 ); + + void setPoint( int i, int j ); + + int maxCol() { return maxi; } + int maxRow() { return maxj; } + +public slots: + void nextGeneration(); + void clear(); + +protected: + virtual void paintEvent( TQPaintEvent * ); + virtual void mouseMoveEvent( TQMouseEvent * ); + virtual void mousePressEvent( TQMouseEvent * ); + virtual void resizeEvent( TQResizeEvent * ); + void mouseHandle( const TQPoint &pos ); + +private: + enum { MAXSIZE = 50, MINSIZE = 10, BORDER = 5 }; + + bool cells[2][MAXSIZE + 2][MAXSIZE + 2]; + int current; + int maxi, maxj; + + int pos2index( int x ) + { + return ( x - BORDER ) / SCALE + 1; + } + int index2pos( int i ) + { + return ( i - 1 ) * SCALE + BORDER; + } + + int SCALE; +}; + + +#endif // LIFE_H diff --git a/examples/life/life.pro b/examples/life/life.pro new file mode 100644 index 000000000..cc9d22fa9 --- /dev/null +++ b/examples/life/life.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = life + +CONFIG += qt warn_on release +DEPENDPATH = ../../include + +REQUIRES = medium-config + +HEADERS = life.h \ + lifedlg.h +SOURCES = life.cpp \ + lifedlg.cpp \ + main.cpp diff --git a/examples/life/lifedlg.cpp b/examples/life/lifedlg.cpp new file mode 100644 index 000000000..1f9af427c --- /dev/null +++ b/examples/life/lifedlg.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "lifedlg.h" +#include <qapplication.h> +#include <qpushbutton.h> +#include <qlabel.h> +#include <qslider.h> +#include <qcombobox.h> +#include <qdatetime.h> +#include <stdlib.h> + +#include "patterns.cpp" + + +// A simple timer which has a pause and a setSpeed slot + +LifeTimer::LifeTimer( TQWidget *parent ) : TQTimer( parent ), interval( 500 ) +{ + start( interval ); +} + + +void LifeTimer::pause( bool stopIt ) +{ + if ( stopIt ) + stop(); + else + start( interval ); +} + + +void LifeTimer::setSpeed( int speed ) +{ + interval = MAXSPEED - speed; + if ( isActive() ) + changeInterval( interval ); +} + + +// A top-level container widget to organize the others + +LifeDialog::LifeDialog( int scale, TQWidget * parent, const char * name ) + : TQWidget( parent, name ) +{ + qb = new TQPushButton( "Quit!", this ); + cb = new TQComboBox( this, "comboBox" ); + life = new LifeWidget(scale, this); + life->move( SIDEBORDER, TOPBORDER ); + + + connect( qb, SIGNAL(clicked()), qApp, SLOT(tquit()) ); + qb->setGeometry( SIDEBORDER, SIDEBORDER, qb->sizeHint().width(), 25 ); + timer = new LifeTimer( this ); + + connect( timer, SIGNAL(timeout()), life, SLOT(nextGeneration()) ); + pb = new TQPushButton( "Pause", this ); + pb->setToggleButton( TRUE ); + connect( pb, SIGNAL(toggled(bool)), timer, SLOT(pause(bool)) ); + pb->resize( pb->sizeHint().width(), 25 ); + pb->move( width() - SIDEBORDER - pb->width(), SIDEBORDER ); + + sp = new TQLabel( "Speed:", this ); + sp->adjustSize(); + sp->move( SIDEBORDER, 45 ); + scroll = new TQSlider( 0, LifeTimer::MAXSPEED, 50, + LifeTimer::MAXSPEED / 2, + TQSlider::Horizontal, this ); + connect( scroll, SIGNAL(valueChanged(int)), + timer, SLOT(setSpeed(int)) ); + + scroll->move( sp->width() + 2 * SIDEBORDER, 45 ); + scroll->resize( 200, 15 ); + + life->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + life->show(); + + srand( TQTime(0,0,0).msecsTo(TQTime::currentTime()) ); + int sel = rand() % NPATS; + getPattern( sel ); + + cb->move( 2*SIDEBORDER + qb->width(), SIDEBORDER); + cb->insertItem( "Glider Gun " ); + cb->insertItem( "Figure Eight " ); + cb->insertItem( "Pulsar " ); + cb->insertItem( "Barber Pole P2 " ); + cb->insertItem( "Achim P5 " ); + cb->insertItem( "Hertz P4 " ); + cb->insertItem( "Tumbler " ); + cb->insertItem( "Pulse1 P4" ); + cb->insertItem( "Shining Flower P5 " ); + cb->insertItem( "Pulse2 P6 " ); + cb->insertItem( "Pinwheel, Clock P4 " ); + cb->insertItem( "Pentadecatholon " ); + cb->insertItem( "Piston " ); + cb->insertItem( "Piston2 " ); + cb->insertItem( "Switch Engine " ); + cb->insertItem( "Gears (Gear, Flywheel, Blinker) " ); + cb->insertItem( "Turbine8 " ); + cb->insertItem( "P16 " ); + cb->insertItem( "Puffer " ); + cb->insertItem( "Escort " ); + cb->insertItem( "Dart Speed 1/3 " ); + cb->insertItem( "Period 4 Speed 1/2 " ); + cb->insertItem( "Another Period 4 Speed 1/2 " ); + cb->insertItem( "Smallest Known Period 3 Spaceship Speed 1/3 " ); + cb->insertItem( "Turtle Speed 1/3 " ); + cb->insertItem( "Smallest Known Period 5 Speed 2/5 " ); + cb->insertItem( "Sym Puffer " ); + cb->insertItem( "], Near Ship, Pi Heptomino " ); + cb->insertItem( "R Pentomino " ); + cb->setAutoResize( FALSE ); + cb->setCurrentItem( sel ); + cb->show(); + connect( cb, SIGNAL(activated(int)), SLOT(getPattern(int)) ); + + TQSize s; + s = life->minimumSize(); + setMinimumSize( s.width() + 2 * SIDEBORDER, + s.height() + TOPBORDER + SIDEBORDER ); + s = life->maximumSize(); + setMaximumSize( s.width() + 2 * SIDEBORDER, + s.height() + TOPBORDER + SIDEBORDER ); + s = life->sizeIncrement(); + setSizeIncrement( s.width(), s.height() ); + + resize( TQMIN(512, qApp->desktop()->width()), + TQMIN(480, qApp->desktop()->height()) ); +} + + +void LifeDialog::resizeEvent( TQResizeEvent * e ) +{ + life->resize( e->size() - TQSize( 2 * SIDEBORDER, TOPBORDER + SIDEBORDER )); + pb->move( e->size().width() - SIDEBORDER - pb->width(), SIDEBORDER ); + scroll->resize( e->size().width() - sp->width() - 3 * SIDEBORDER, + scroll->height() ); + cb->resize( width() - 4*SIDEBORDER - qb->width() - pb->width() , 25 ); +} + + +// Adapted from xlock, see pattern.cpp for copyright info. + +void LifeDialog::getPattern( int pat ) +{ + life->clear(); + int i = pat % NPATS; + int col; + int * patptr = &patterns[i][0]; + while ( (col = *patptr++) != 127 ) { + int row = *patptr++; + col += life->maxCol() / 2; + row += life->maxRow() / 2; + life->setPoint( col, row ); + } +} diff --git a/examples/life/lifedlg.h b/examples/life/lifedlg.h new file mode 100644 index 000000000..4ff4b195c --- /dev/null +++ b/examples/life/lifedlg.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef LIFEDLG_H +#define LIFEDLG_H + +#include <qtimer.h> +#include <qwidget.h> + +class TQSlider; +class TQPushButton; +class TQLabel; +class TQComboBox; + +#include "life.h" + + +class LifeTimer : public TQTimer +{ + Q_OBJECT +public: + LifeTimer( TQWidget *parent ); + enum { MAXSPEED = 1000 }; + +public slots: + void setSpeed( int speed ); + void pause( bool ); + +private: + int interval; +}; + + +class LifeDialog : public TQWidget +{ + Q_OBJECT +public: + LifeDialog( int scale = 10, TQWidget *parent = 0, const char *name = 0 ); +public slots: + void getPattern( int ); + +protected: + virtual void resizeEvent( TQResizeEvent * e ); + +private: + enum { TOPBORDER = 70, SIDEBORDER = 10 }; + + LifeWidget *life; + TQPushButton *qb; + LifeTimer *timer; + TQPushButton *pb; + TQComboBox *cb; + TQLabel *sp; + TQSlider *scroll; +}; + + +#endif // LIFEDLG_H diff --git a/examples/life/main.cpp b/examples/life/main.cpp new file mode 100644 index 000000000..7505e0f28 --- /dev/null +++ b/examples/life/main.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "lifedlg.h" +#include <qapplication.h> +#include <stdlib.h> + +void usage() +{ + qWarning( "Usage: life [-scale scale]" ); +} + +int main( int argc, char **argv ) +{ + TQApplication a( argc, argv ); + + int scale = 10; + + for ( int i = 1; i < argc; i++ ){ + TQString arg = argv[i]; + if ( arg == "-scale" ) + scale = atoi( argv[++i] ); + else { + usage(); + exit(1); + } + } + + if ( scale < 2 ) + scale = 2; + + LifeDialog *life = new LifeDialog( scale ); + a.setMainWidget( life ); + life->setCaption("TQt Example - Life"); + life->show(); + + return a.exec(); +} diff --git a/examples/life/patterns.cpp b/examples/life/patterns.cpp new file mode 100644 index 000000000..4203adcd6 --- /dev/null +++ b/examples/life/patterns.cpp @@ -0,0 +1,383 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +/**************************************************************************** + * + * Patterns for life. Adapted from xlock; original copyright notice below. + * + * Copyright (c) 1988-91 by Patrick J. Naughton. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + *****************************************************************************/ + +//#include <qglobal.h> + + +#define NUMPTS 63 +/* Patterns have < NUMPTS pts (and should have a size of <= 32x32, + the Gun is an exception) */ +static int patterns[][2 * NUMPTS + 1] = { + { /* GLIDER GUN */ + 6, -4, + 5, -3, 6, -3, + -6, -2, -5, -2, 8, -2, 9, -2, 16, -2, + -7, -1, 8, -1, 9, -1, 10, -1, 16, -1, 17, -1, + -18, 0, -17, 0, -8, 0, 8, 0, 9, 1, + -17, 1, -8, 1, 5, 1, 6, 1, + -8, 2, 6, 2, + -7, 3, + -6, 4, -5, 4, + 127 + }, + { /* FIGURE EIGHT */ + -3, -3, -2, -3, -1, -3, + -3, -2, -2, -2, -1, -2, + -3, -1, -2, -1, -1, -1, + 0, 0, 1, 0, 2, 0, + 0, 1, 1, 1, 2, 1, + 0, 2, 1, 2, 2, 2, + 127 + }, + { /* PULSAR */ + -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, + -2, 0, 2, 0, + 127 + }, + { /* BARBER POLE P2 */ + -6, -6, -5, -6, + -6, -5, -4, -5, + -4, -3, -2, -3, + -2, -1, 0, -1, + 0, 1, 2, 1, + 2, 3, 4, 3, + 5, 4, + 4, 5, 5, 5, + 127 + }, + { /* ACHIM P5 */ + -6, -6, -5, -6, + -6, -5, + -4, -4, + -4, -3, -2, -3, + -2, -1, 0, -1, + 0, 1, 2, 1, + 2, 3, 3, 3, + 5, 4, + 4, 5, 5, 5, + 127 + }, + { /* HERTZ P4 */ + -2, -5, -1, -5, + -2, -4, -1, -4, + -7, -2, -6, -2, -2, -2, -1, -2, 0, -2, 1, -2, 5, -2, 6, -2, + -7, -1, -5, -1, -3, -1, 2, -1, 4, -1, 6, -1, + -5, 0, -3, 0, -2, 0, 2, 0, 4, 0, + -7, 1, -5, 1, -3, 1, 2, 1, 4, 1, 6, 1, + -7, 2, -6, 2, -2, 2, -1, 2, 0, 2, 1, 2, 5, 2, 6, 2, + -2, 4, -1, 4, + -2, 5, -1, 5, + 127 + }, + { /* TUMBLER */ + -2, -3, -1, -3, 1, -3, 2, -3, + -2, -2, -1, -2, 1, -2, 2, -2, + -1, -1, 1, -1, + -3, 0, -1, 0, 1, 0, 3, 0, + -3, 1, -1, 1, 1, 1, 3, 1, + -3, 2, -2, 2, 2, 2, 3, 2, + 127 + }, + { /* PULSE1 P4*/ + 0, -3, 1, -3, + -2, -2, 0, -2, + -3, -1, 3, -1, + -2, 0, 2, 0, 3, 0, + 0, 2, 2, 2, + 1, 3, + 127 + }, + { /* SHINING FLOWER P5 */ + -1, -4, 0, -4, + -2, -3, 1, -3, + -3, -2, 2, -2, + -4, -1, 3, -1, + -4, 0, 3, 0, + -3, 1, 2, 1, + -2, 2, 1, 2, + -1, 3, 0, 3, + 127 + }, + { /* PULSE2 P6 */ + 0, -4, 1, -4, + -4, -3, -3, -3, -1, -3, + -4, -2, -3, -2, 0, -2, 3, -2, + 1, -1, 3, -1, + 2, 0, + 1, 2, 2, 2, + 1, 3, 2, 3, + 127 + }, + { /* PINWHEEL, CLOCK P4 */ + -2, -6, -1, -6, + -2, -5, -1, -5, + -2, -3, -1, -3, 0, -3, 1, -3, + -3, -2, -1, -2, 2, -2, 4, -2, 5, -2, + -3, -1, 1, -1, 2, -1, 4, -1, 5, -1, + -6, 0, -5, 0, -3, 0, 0, 0, 2, 0, + -6, 1, -5, 1, -3, 1, 2, 1, + -2, 2, -1, 2, 0, 2, 1, 2, + 0, 4, 1, 4, + 0, 5, 1, 5, + 127 + }, + { /* PENTADECATHOLON */ + -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, + 127 + }, + { /* PISTON */ + 1, -3, 2, -3, + 0, -2, + -10, -1, -1, -1, + -11, 0, -10, 0, -1, 0, 9, 0, 10, 0, + -1, 1, 9, 1, + 0, 2, + 1, 3, 2, 3, + 127 + }, + { /* PISTON2 */ + -3, -5, + -14, -4, -13, -4, -4, -4, -3, -4, 13, -4, 14, -4, + -14, -3, -13, -3, -5, -3, -4, -3, 13, -3, 14, -3, + -4, -2, -3, -2, 0, -2, 1, -2, + -4, 2, -3, 2, 0, 2, 1, 2, + -14, 3, -13, 3, -5, 3, -4, 3, 13, 3, 14, 3, + -14, 4, -13, 4, -4, 4, -3, 4, 13, 4, 14, 4, + -3, 5, + 127 + }, + { /* SWITCH ENGINE */ + -12, -3, -10, -3, + -13, -2, + -12, -1, -9, -1, + -10, 0, -9, 0, -8, 0, + 13, 2, 14, 2, + 13, 3, + 127 + }, + { /* GEARS (gear, flywheel, blinker) */ + -1, -4, + -1, -3, 1, -3, + -3, -2, + 2, -1, 3, -1, + -4, 0, -3, 0, + 2, 1, + -2, 2, 0, 2, + 0, 3, + + 5, 3, + 3, 4, 4, 4, + 5, 5, 6, 5, + 4, 6, + + 8, 0, + 8, 1, + 8, 2, + 127 + }, + { /* TURBINE8 */ + -4, -4, -3, -4, -2, -4, -1, -4, 0, -4, 1, -4, 3, -4, 4, -4, + -4, -3, -3, -3, -2, -3, -1, -3, 0, -3, 1, -3, 3, -3, 4, -3, + 3, -2, 4, -2, + -4, -1, -3, -1, 3, -1, 4, -1, + -4, 0, -3, 0, 3, 0, 4, 0, + -4, 1, -3, 1, 3, 1, 4, 1, + -4, 2, -3, 2, + -4, 3, -3, 3, -1, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, + -4, 4, -3, 4, -1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4, + 127 + }, + { /* P16 */ + -3, -6, 1, -6, 2, -6, + -3, -5, 0, -5, 3, -5, + 3, -4, + -5, -3, -4, -3, 1, -3, 2, -3, 5, -3, 6, -3, + -6, -2, -3, -2, + -6, -1, -3, -1, + -5, 0, 5, 0, + 3, 1, 6, 1, + 3, 2, 6, 2, + -6, 3, -5, 3, -2, 3, -1, 3, 4, 3, 5, 3, + -3, 4, + -3, 5, 0, 5, 3, 5, + -2, 6, -1, 6, 3, 6, + 127 + }, + { /* PUFFER */ + 1, -9, + 2, -8, + -2, -7, 2, -7, + -1, -6, 0, -6, 1, -6, 2, -6, + -2, -2, + -1, -1, 0, -1, + 0, 0, + 0, 1, + -1, 2, + 1, 5, + 2, 6, + -2, 7, 2, 7, + -1, 8, 0, 8, 1, 8, 2, 8, + 127 + }, + { /* ESCORT */ + 3, -8, + 4, -7, + -2, -6, 4, -6, + -1, -5, 0, -5, 1, -5, 2, -5, 3, -5, 4, -5, + -5, -1, -4, -1, -3, -1, -2, -1, -1, -1, 0, -1, + 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, + -6, 0, 6, 0, + 6, 1, + 5, 2, + 3, 4, + 4, 5, + -2, 6, 4, 6, + -1, 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, + 127 + }, + { /* DART SPEED 1/3 */ + 3, -7, + 2, -6, 4, -6, + 1, -5, 2, -5, + 4, -4, + 0, -3, 4, -3, + -3, -2, 0, -2, + -4, -1, -2, -1, 1, -1, 2, -1, 3, -1, 4, -1, + -5, 0, -2, 0, + -4, 1, -2, 1, 1, 1, 2, 1, 3, 1, 4, 1, + -3, 2, 0, 2, + 0, 3, 4, 3, + 4, 4, + 1, 5, 2, 5, + 2, 6, 4, 6, + 3, 7, + 127 + }, + { /* PERIOD 4 SPEED 1/2 */ + -3, -5, + -4, -4, -3, -4, -2, -4, -1, -4, 0, -4, + -5, -3, -4, -3, 0, -3, 1, -3, 3, -3, + -4, -2, 4, -2, + -3, -1, -2, -1, 1, -1, 3, -1, + -3, 1, -2, 1, 1, 1, 3, 1, + -4, 2, 4, 2, + -5, 3, -4, 3, 0, 3, 1, 3, 3, 3, + -4, 4, -3, 4, -2, 4, -1, 4, 0, 4, + -3, 5, + 127 + }, + { /* ANOTHER PERIOD 4 SPEED 1/2 */ + -4, -7, -3, -7, -1, -7, 0, -7, 1, -7, 2, -7, 3, -7, 4, -7, + -5, -6, -4, -6, -3, -6, -2, -6, 5, -6, + -6, -5, -5, -5, + -5, -4, 5, -4, + -4, -3, -3, -3, -2, -3, 0, -3, + -2, -2, + -2, -1, + -1, 0, + -2, 1, + -2, 2, + -4, 3, -3, 3, -2, 3, 0, 3, + -5, 4, 5, 4, + -6, 5, -5, 5, + -5, 6, -4, 6, -3, 6, -2, 6, 5, 6, + -4, 7, -3, 7, -1, 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, + 127 + }, + { /* SMALLEST KNOWN PERIOD 3 SPACESHIP SPEED 1/3 */ + 0, -8, + -1, -7, 1, -7, + -1, -6, 1, -6, + -1, -5, + -2, -3, -1, -3, + -1, -2, 1, -2, + -2, -1, 0, -1, + -2, 0, -1, 0, 0, 0, + -1, 2, 1, 2, + -1, 3, 0, 3, + 0, 4, + 0, 5, 2, 5, + 0, 6, 2, 6, + 1, 7, + 127 + }, + { /* TURTLE SPEED 1/3 */ + -4, -5, -3, -5, -2, -5, 6, -5, + -4, -4, -3, -4, 0, -4, 2, -4, 3, -4, 5, -4, 6, -4, + -2, -3, -1, -3, 0, -3, 5, -3, + -4, -2, -1, -2, 1, -2, 5, -2, + -5, -1, 0, -1, 5, -1, + -5, 0, 0, 0, 5, 0, + -4, 1, -1, 1, 1, 1, 5, 1, + -2, 2, -1, 2, 0, 2, 5, 2, + -4, 3, -3, 3, 0, 3, 2, 3, 3, 3, 5, 3, 6, 3, + -4, 4, -3, 4, -2, 4, 6, 4, + 127 + }, + { /* SMALLEST KNOWN PERIOD 5 SPEED 2/5 */ + 1, -7, 3, -7, + -2, -6, 3, -6, + -3, -5, -2, -5, -1, -5, 4, -5, + -4, -4, -2, -4, + -5, -3, -4, -3, -1, -3, 0, -3, 5, -3, + -4, -2, -3, -2, 0, -2, 1, -2, 2, -2, 3, -2, 4, -2, + -4, 2, -3, 2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, + -5, 3, -4, 3, -1, 3, 0, 3, 5, 3, + -4, 4, -2, 4, + -3, 5, -2, 5, -1, 5, 4, 5, + -2, 6, 3, 6, + 1, 7, 3, 7, + 127 + }, + { /* SYM PUFFER */ + 1, -4, 2, -4, 3, -4, 4, -4, + 0, -3, 4, -3, + 4, -2, + -4, -1, -3, -1, 0, -1, 3, -1, + -4, 0, -3, 0, -2, 0, + -4, 1, -3, 1, 0, 1, 3, 1, + 4, 2, + 0, 3, 4, 3, + 1, 4, 2, 4, 3, 4, 4, 4, + 127 + }, + { /* ], NEAR SHIP, PI HEPTOMINO */ + -2, -1, -1, -1, 0, -1, + 1, 0, + -2, 1, -1, 1, 0, 1, + 127 + }, + { /* R PENTOMINO */ + 0, -1, 1, -1, + -1, 0, 0, 0, + 0, 1, + 127 + } +}; + +#define NPATS (sizeof patterns / sizeof patterns[0]) |