summaryrefslogtreecommitdiffstats
path: root/examples/life/life.cpp
blob: 24379e67c5f94f6da823862ee3f957b53216ae4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/****************************************************************************
**
** Copyright (C) 1992-2008 Trolltech ASA.  All rights reserved.
**
** This file is part of an example program for Qt.  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, QWidget *parent, const char *name )
    : QFrame( 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( QResizeEvent * 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 QPoint &pos )
{
    int i = pos2index( pos.x() );
    int j = pos2index( pos.y() );
    setPoint( i, j );
}


void LifeWidget::mouseMoveEvent( QMouseEvent *e )
{
    mouseHandle( e->pos() );
}


void LifeWidget::mousePressEvent( QMouseEvent *e )
{
    if ( e->button() == QMouseEvent::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( QPaintEvent * 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;

    QPainter 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 );
}