~ubuntu-branches/ubuntu/raring/qgo/raring

« back to all changes in this revision

Viewing changes to src/matrix.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin A. Godisch
  • Date: 2005-01-01 23:07:10 UTC
  • Revision ID: james.westby@ubuntu.com-20050101230710-fhng6yidm47xlb2i
Tags: upstream-1.0.0-r2
ImportĀ upstreamĀ versionĀ 1.0.0-r2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* matrix.cpp
 
3
*/
 
4
 
 
5
#include "matrix.h"
 
6
#include <stdlib.h>
 
7
#ifndef NO_DEBUG
 
8
#include <iostream.h>
 
9
#endif
 
10
 
 
11
Matrix::Matrix(int s)
 
12
: size(s)
 
13
{
 
14
        ASSERT(size > 0 && size <= 36);
 
15
        
 
16
        init();
 
17
}
 
18
 
 
19
Matrix::Matrix(const Matrix &m)
 
20
{
 
21
        size = m.getSize();
 
22
        ASSERT(size > 0 && size <= 36);
 
23
        
 
24
        init();
 
25
        
 
26
        for (int i=0; i<size; i++)
 
27
                for (int j=0; j<size; j++)
 
28
                        matrix[i][j] = m.at(i, j);
 
29
}
 
30
 
 
31
Matrix::~Matrix()
 
32
{
 
33
        ASSERT(size > 0 && size <= 36);
 
34
        
 
35
        for (int i=0; i<size; i++)
 
36
                delete [] matrix[i];
 
37
        delete [] matrix;
 
38
        
 
39
        delete markTexts;
 
40
}
 
41
 
 
42
void Matrix::init()
 
43
{
 
44
        matrix = new short*[size];
 
45
        CHECK_PTR(matrix);
 
46
        
 
47
        for (int i=0; i<size; i++)
 
48
        {
 
49
                matrix[i] = new short[size];
 
50
                CHECK_PTR(matrix[i]);
 
51
                
 
52
                for (int j=0; j<size; j++)
 
53
                        matrix[i][j] = stoneNone;
 
54
        }
 
55
        
 
56
        markTexts = NULL;
 
57
}
 
58
 
 
59
void Matrix::initMarkTexts()
 
60
{
 
61
        markTexts = new QStringList();
 
62
        CHECK_PTR(markTexts);
 
63
}
 
64
 
 
65
void Matrix::clear()
 
66
{
 
67
        ASSERT(size > 0 && size <= 36);
 
68
        
 
69
        for (int i=0; i<size; i++)
 
70
                for (int j=0; j<size; j++)
 
71
                        matrix[i][j] = stoneNone;
 
72
}
 
73
 
 
74
#ifndef NO_DEBUG
 
75
void Matrix::debug() const
 
76
{
 
77
        ASSERT(size > 0 && size <= 36);
 
78
        
 
79
        int i, j;
 
80
        
 
81
        cout << "\n  ";
 
82
        for (i=0; i<size; i++)
 
83
                cout << (i+1)%10 << " ";
 
84
        cout << endl;
 
85
        
 
86
        for (i=0; i<size; i++)
 
87
        {
 
88
                cout << (i+1)%10 << " ";
 
89
                for (j=0; j<size; j++)
 
90
                {
 
91
#if 1
 
92
                        switch (abs(matrix[j][i]))
 
93
                        {
 
94
                        case stoneNone:
 
95
                        case stoneErase: cout << ". "; break;
 
96
                        case stoneBlack: cout << "B "; break;
 
97
                        case stoneWhite: cout << "W "; break;
 
98
                        case markSquare*10: cout << "[ "; break;
 
99
                        case markCircle*10: cout << "O "; break;
 
100
                        case markTriangle*10: cout << "T "; break;
 
101
                        case markCross*10: cout << "X "; break;
 
102
                        case markText*10: cout << "A "; break;
 
103
                        case markNumber*10: cout << "1 "; break;
 
104
                        case markSquare*10+stoneBlack: cout << "S "; break;
 
105
                        case markCircle*10+stoneBlack: cout << "C "; break;
 
106
                        case markTriangle*10+stoneBlack: cout << "D "; break;
 
107
                        case markCross*10+stoneBlack: cout << "R "; break;
 
108
                        case markText*10+stoneBlack: cout << "A "; break;
 
109
                        case markNumber*10+stoneBlack: cout << "N "; break;
 
110
                        case markSquare*10+stoneWhite: cout << "s "; break;
 
111
                        case markCircle*10+stoneWhite: cout << "c "; break;
 
112
                        case markTriangle*10+stoneWhite: cout << "d "; break;
 
113
                        case markCross*10+stoneWhite: cout << "r "; break;
 
114
                        case markText*10+stoneWhite: cout << "a "; break;
 
115
                        case markNumber*10+stoneWhite: cout << "n "; break;
 
116
                        default: cout << "? ";
 
117
                        }
 
118
#else
 
119
                        cout << matrix[j][i] << " ";
 
120
#endif
 
121
                }
 
122
                cout << (i+1)%10 << endl;
 
123
        }
 
124
        
 
125
        cout << "  ";
 
126
        for (i=0; i<size; i++)
 
127
                cout << (i+1)%10 << " ";
 
128
        cout << endl;
 
129
        
 
130
        if (markTexts != NULL && !markTexts->isEmpty())
 
131
        {
 
132
                cout << markTexts->count() << " mark texts in the storage.\n";
 
133
                for (QStringList::Iterator it=markTexts->begin(); it != markTexts->end(); ++it)
 
134
                        cout << (QString)(*it) << endl;
 
135
        }
 
136
}
 
137
#endif
 
138
 
 
139
void Matrix::insertStone(int x, int y, StoneColor c, GameMode mode)
 
140
{
 
141
        ASSERT(x > 0 && x <= size &&
 
142
                y > 0 && y <= size);
 
143
        
 
144
        matrix[x-1][y-1] = abs(matrix[x-1][y-1] / 10 * 10) + c;
 
145
        if (mode == modeEdit)
 
146
                matrix[x-1][y-1] *= -1;
 
147
}
 
148
 
 
149
void Matrix::removeStone(int x, int y)
 
150
{
 
151
        ASSERT(x > 0 && x <= size &&
 
152
                y > 0 && y <= size);
 
153
        
 
154
        matrix[x-1][y-1] = abs(matrix[x-1][y-1] / 10 * 10);
 
155
}
 
156
 
 
157
void Matrix::eraseStone(int x, int y)
 
158
{
 
159
        ASSERT(x > 0 && x <= size &&
 
160
                y > 0 && y <= size);
 
161
        
 
162
        matrix[x-1][y-1] = (abs(matrix[x-1][y-1] / 10 * 10) + stoneErase) * -1;
 
163
}
 
164
 
 
165
short Matrix::at(int x, int y) const
 
166
{
 
167
        ASSERT(x >= 0 && x < size &&
 
168
                y >= 0 && y < size);
 
169
        
 
170
        return matrix[x][y];
 
171
}
 
172
 
 
173
void Matrix::set(int x, int y, int n)
 
174
{
 
175
        ASSERT(x >= 0 && x < size &&
 
176
                y >= 0 && y < size);
 
177
        
 
178
        matrix[x][y] = n;
 
179
}
 
180
 
 
181
void Matrix::insertMark(int x, int y, MarkType t)
 
182
{
 
183
        //ASSERT(x > 0 && x <= size && y > 0 && y <= size);
 
184
        if (!(x > 0 && x <= size && y > 0 && y <= size))
 
185
    return;
 
186
    
 
187
        matrix[x-1][y-1] = (abs(matrix[x-1][y-1]) + 10*t) * (matrix[x-1][y-1] < 0 ? -1 : 1);
 
188
}
 
189
 
 
190
void Matrix::removeMark(int x, int y)
 
191
{
 
192
        ASSERT(x > 0 && x <= size &&
 
193
                y > 0 && y <= size);
 
194
        
 
195
        matrix[x-1][y-1] %= 10;
 
196
        
 
197
        if (markTexts != NULL && !markTexts->isEmpty())
 
198
        {
 
199
                QStringList::Iterator it = getMarkTextIterator(x, y);
 
200
                if (it != NULL)
 
201
                        markTexts->remove(it);
 
202
        }
 
203
}
 
204
 
 
205
void Matrix::clearAllMarks()
 
206
{
 
207
        ASSERT(size > 0 && size <= 36);
 
208
        
 
209
        for (int i=0; i<size; i++)
 
210
                for (int j=0; j<size; j++)
 
211
                        matrix[i][j] %= 10;
 
212
                
 
213
                if (markTexts != NULL)
 
214
                {
 
215
                        delete markTexts;
 
216
                        markTexts = NULL;
 
217
                }
 
218
}
 
219
 
 
220
void Matrix::clearTerritoryMarks()
 
221
{
 
222
        ASSERT(size > 0 && size <= 36);
 
223
        
 
224
        int data;
 
225
        
 
226
        for (int i=0; i<size; i++)
 
227
                for (int j=0; j<size; j++)
 
228
                        if ((data = abs(matrix[i][j] / 10)) == markTerrBlack ||
 
229
                                data == markTerrWhite)
 
230
                                matrix[i][j] %= 10;
 
231
}
 
232
 
 
233
void Matrix::absMatrix()
 
234
{
 
235
        ASSERT(size > 0 && size <= 36);
 
236
        
 
237
        for (int i=0; i<size; i++)
 
238
        {
 
239
                for (int j=0; j<size; j++)
 
240
                {
 
241
                        matrix[i][j] = abs(matrix[i][j]);
 
242
                        if (matrix[i][j] == stoneErase)
 
243
                                matrix[i][j] = stoneNone;
 
244
                        if (matrix[i][j] % 10 == stoneErase)
 
245
                                matrix[i][j] = matrix[i][j] / 10 * 10;
 
246
                }
 
247
        }
 
248
}
 
249
 
 
250
void Matrix::setMarkText(int x, int y, const QString &txt)
 
251
{
 
252
        ASSERT(x > 0 && x <= size &&
 
253
                y > 0 && y <= size);
 
254
        
 
255
        // We only create the markTexts list if we really need it.
 
256
        if (markTexts == NULL)
 
257
                initMarkTexts();
 
258
        
 
259
        QStringList::Iterator it = getMarkTextIterator(x, y);
 
260
        if (it != NULL)  // Mark already exists at this position, remove old text.
 
261
                markTexts->remove(it);
 
262
        
 
263
        QString tmp = QString::number(coordsToKey(x, y)) + "#" + txt;
 
264
        markTexts->append(tmp);
 
265
}
 
266
 
 
267
QStringList::Iterator Matrix::getMarkTextIterator(int x, int y)
 
268
{
 
269
        if (markTexts == NULL)
 
270
                return NULL;
 
271
        
 
272
        QString s, tmp;
 
273
        int pos, tmpX, tmpY, counter=0;
 
274
        bool check = false;
 
275
        long key;
 
276
        QStringList::Iterator it;
 
277
        
 
278
        for (it=markTexts->begin(); it != markTexts->end(); ++it)
 
279
        {
 
280
                s = (QString)(*it);
 
281
                
 
282
                // Get the splitting '#', everything left of it is our key.
 
283
                pos = s.find('#');
 
284
                if (pos == -1)  // Whoops
 
285
                {
 
286
                        qWarning("   *** Corrupt text marks in matrix! ***");
 
287
                        continue;
 
288
                }
 
289
                
 
290
                // Transform key to coordinates
 
291
                tmp = s.left(pos);
 
292
                key = tmp.toLong(&check);
 
293
                if (!check)
 
294
                {
 
295
                        qWarning("   *** Corrupt text marks in matrix! ***");
 
296
                        continue;
 
297
                }
 
298
                keyToCoords(key, tmpX, tmpY);
 
299
                
 
300
                // This is our hit?
 
301
                if (tmpX == x && tmpY == y)
 
302
                        return it;
 
303
                
 
304
                // Nope, wasn't
 
305
                counter++;
 
306
        }
 
307
        return NULL;
 
308
}
 
309
 
 
310
const QString Matrix::getMarkText(int x, int y)
 
311
{
 
312
        // We didn't store any texts in this matrix.
 
313
        if (markTexts == NULL || markTexts->isEmpty())
 
314
                return NULL;
 
315
        
 
316
        QStringList::Iterator it = getMarkTextIterator(x, y);
 
317
        if (it == NULL)  // Nope, this entry does not exist.
 
318
                return NULL;
 
319
        
 
320
        QString s = (QString)(*it);
 
321
        s = s.right(s.length() - s.find('#') - 1);
 
322
        
 
323
        return s;
 
324
}
 
325
 
 
326
const QString Matrix::saveMarks()
 
327
{
 
328
        ASSERT(size > 0 && size <= 36);
 
329
        
 
330
        QString txt, sSQ = "", sCR = "", sTR = "", sMA = "", sLB = "", sTB = "", sTW = "";
 
331
        int i, j, colw = 0, colb = 0;
 
332
        
 
333
        for (i=0; i<size; i++)
 
334
        {
 
335
                for (j=0; j<size; j++)
 
336
                {
 
337
                        switch (abs(matrix[i][j] / 10))
 
338
                        {
 
339
                        case markSquare:
 
340
                                if (sSQ.isEmpty())
 
341
                                        sSQ += "SQ";
 
342
                                sSQ += "[" + coordsToString(i, j) + "]";
 
343
                                break;
 
344
                        case markCircle:
 
345
                                if (sCR.isEmpty())
 
346
                                        sCR += "CR";
 
347
                                sCR += "[" + coordsToString(i, j) + "]";
 
348
                                break;
 
349
                        case markTriangle:
 
350
                                if (sTR.isEmpty())
 
351
                                        sTR += "TR";
 
352
                                sTR += "[" + coordsToString(i, j) + "]";
 
353
                                break;
 
354
                        case markCross:
 
355
                                if (sMA.isEmpty())
 
356
                                        sMA += "MA";
 
357
                                sMA += "[" + coordsToString(i, j) + "]";
 
358
                                break;
 
359
                        case markText: 
 
360
                        case markNumber:
 
361
                                if (sLB.isEmpty())
 
362
                                        sLB += "LB";
 
363
                                sLB += "[" + coordsToString(i, j);
 
364
                                sLB += ":";
 
365
                                txt = getMarkText(i+1, j+1);
 
366
                                if (txt.isNull() || txt.isEmpty())
 
367
                                        sLB += "?";  // Whoops
 
368
                                else
 
369
                                        sLB += txt;
 
370
                                sLB += "]";
 
371
                                break;
 
372
                        case markTerrBlack:
 
373
                                if (sTB.isEmpty())
 
374
                                {
 
375
                                        sTB += "\nTB";
 
376
                                        colb = 0;
 
377
                                }
 
378
                                sTB += "[" + coordsToString(i, j) + "]";
 
379
                                if (++colb % 15 == 0)
 
380
                                        sTB += "\n  ";
 
381
                                break;
 
382
                        case markTerrWhite:
 
383
                                if (sTW.isEmpty())
 
384
                                {
 
385
                                        sTW += "\nTW";
 
386
                                        colw = 0;
 
387
                                }
 
388
                                sTW += "[" + coordsToString(i, j) + "]";
 
389
                                if (++colw % 15 == 0)
 
390
                                        sTW += "\n  ";
 
391
                                break;
 
392
                        default: continue;
 
393
                        }
 
394
                }
 
395
        }
 
396
        
 
397
        return sSQ + sCR + sTR + sMA + sLB + sTB + sTW;
 
398
}
 
399
 
 
400
const QString Matrix::saveEditedMoves(Matrix *parent)
 
401
{
 
402
        ASSERT(size > 0 && size <= 36);
 
403
        
 
404
        QString sAB="", sAW="", sAE="";
 
405
        int i, j;
 
406
        
 
407
        for (i=0; i<size; i++)
 
408
        {
 
409
                for (j=0; j<size; j++)
 
410
                {
 
411
                        switch (matrix[i][j] % 10)
 
412
                        {
 
413
                        case stoneBlack * -1:
 
414
                                if (parent != NULL &&
 
415
                                        parent->at(i, j) == stoneBlack)
 
416
                                        break;
 
417
                                if (sAB.isEmpty())
 
418
                                        sAB += "AB";
 
419
                                sAB += "[" + coordsToString(i, j) + "]";
 
420
                                break;
 
421
                                
 
422
                        case stoneWhite * -1:
 
423
                                if (parent != NULL &&
 
424
                                        parent->at(i, j) == stoneWhite)
 
425
                                        break;
 
426
                                if (sAW.isEmpty())
 
427
                                        sAW += "AW";
 
428
                                sAW += "[" + coordsToString(i, j) + "]";
 
429
                                break;
 
430
                                
 
431
                        case stoneErase * -1:
 
432
                                if (parent != NULL &&
 
433
                                        (parent->at(i, j) == stoneNone ||
 
434
                                        parent->at(i, j) == stoneErase))
 
435
                                        break;
 
436
                                if (sAE.isEmpty())
 
437
                                        sAE += "AE";
 
438
                                sAE += "[" + coordsToString(i, j) + "]";
 
439
                                break;
 
440
                        }
 
441
                }
 
442
        }
 
443
        
 
444
        return sAB + sAW + sAE;
 
445
}
 
446
 
 
447
const QString Matrix::printMe(ASCII_Import *charset)
 
448
{
 
449
        ASSERT(size > 0 && size <= 36);
 
450
        
 
451
#if 0
 
452
        qDebug("BLACK STONE CHAR %c\n"
 
453
                "WHITE STONE CHAR %c\n"
 
454
                "STAR POINT  CHAR %c\n"
 
455
                "EMPTY POINT CHAR %c\n",
 
456
                charset->blackStone,
 
457
                charset->whiteStone,
 
458
                charset->starPoint,
 
459
                charset->emptyPoint);
 
460
#endif
 
461
        
 
462
        int i, j;
 
463
        QString str;
 
464
        
 
465
        str = "\n    ";
 
466
        for (i=0; i<size; i++)
 
467
                str += QString(QChar(static_cast<const char>('A' + (i<8?i:i+1)))) + " ";
 
468
        str += "\n   +";
 
469
        for (i=0; i<size-1; i++)
 
470
                str += "--";
 
471
        str += "-+\n";
 
472
        
 
473
        for (i=0; i<size; i++)
 
474
        {
 
475
                if (size-i < 10) str += " ";
 
476
                str += QString::number(size-i) + " |";
 
477
                for (j=0; j<size; j++)
 
478
                {
 
479
                        switch (abs(matrix[j][i] % 10))
 
480
                        {
 
481
                        case stoneBlack: str += QChar(charset->blackStone); str += " "; break;
 
482
                        case stoneWhite: str += QChar(charset->whiteStone); str += " "; break;
 
483
                        default:
 
484
                                // Check for starpoints
 
485
                                if (size > 9)  // 10x10 or larger
 
486
                                {
 
487
                                        if ((i == 3 && j == 3) ||
 
488
                                                (i == size-4 && j == 3) ||
 
489
                                                (i == 3 && j == size-4) ||
 
490
                                                (i == size-4 && j == size-4) ||
 
491
                                                (i == (size+1)/2 - 1 && j == 3) ||
 
492
                                                (i == (size+1)/2 - 1 && j == size-4) ||
 
493
                                                (i == 3 && j == (size+1)/2 - 1) ||
 
494
                                                (i == size-4 && j == (size+1)/2 - 1) ||
 
495
                                                (i == (size+1)/2 - 1 && j == (size+1)/2 - 1))
 
496
                                        {
 
497
                                                str += QChar(charset->starPoint);
 
498
                                                str += " ";
 
499
                                                break;
 
500
                                        }
 
501
                                }
 
502
                                else  // 9x9 or smaller
 
503
                                {
 
504
                                        if ((i == 2 && j == 2) ||
 
505
                                                (i == 2 && j == size-3) ||
 
506
                                                (i == size-3 && j == 2) ||
 
507
                                                (i == size-3 && j == size-3))
 
508
                                        {
 
509
                                                str += QChar(charset->starPoint);
 
510
                                                str += " ";
 
511
                                                break;
 
512
                                        }
 
513
                                }
 
514
                                
 
515
                                str += QChar(charset->emptyPoint);
 
516
                                str += " ";
 
517
                                break;
 
518
                        }
 
519
                }
 
520
                str = str.left(str.length()-1);
 
521
                str += "| ";
 
522
                if (size-i < 10) str += " ";
 
523
                str += QString::number(size-i) + "\n";
 
524
        }
 
525
        
 
526
        str += "   +";
 
527
        for (i=0; i<size-1; i++)
 
528
                str += "--";
 
529
        str += "-+\n    ";
 
530
        for (i=0; i<size; i++)
 
531
                str += QString(QChar(static_cast<const char>('A' + (i<8?i:i+1)))) + " ";
 
532
        str += "\n";
 
533
        
 
534
        return str;
 
535
}