-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBoard.cpp
131 lines (105 loc) · 3.25 KB
/
Board.cpp
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
/*
* File: Board.cpp
* Author: Tomáš Čerevka, Adam Činčura
*
* Created on November 2, 2011, 10:19 AM
*/
#include <mpi.h>
#include "Board.h"
#include "Tower.h"
#include "Solver.h"
Board::Board(void) {
}
Board::Board(int _towersCount) : tokensCount(0) {
init(_towersCount);
}
Board::~Board() {
}
void Board::init(int _towersCount) {
if (_towersCount < 2) {
throw "Minimal number of towers is two!";
}
for (int i = 0; i < _towersCount; ++i) {
Tower tower;
towers.push_back(tower); // Kopirovani.
}
tokensCount = 0;
}
bool Board::isMoveCorrect(const Move& _move) const {
// Zdrojova vez je prazdna.
if (towers[_move.getFrom()].isEmpty()) {
return false;
}
// Cilova vez je prazda.
if (towers[_move.getTo()].isEmpty()) {
return true;
}
// Na obou vezich se nachazi token.
// Na zdrojove vezi musi byt mensi nez na cilove.
if (towers[_move.getFrom()].getTop() < towers[_move.getTo()].getTop()) {
return true;
}
return false;
}
void Board::doMove(const Move& _move) {
int token = towers[_move.getFrom()].removeTop();
towers[_move.getTo()].addTop(token);
}
void Board::addTowerTop(int _tower, int _value) {
towers[_tower].addTop(_value);
++tokensCount;
}
int Board::getTowerTop(int _tower) const {
if (towers[_tower].size() == 0) {
return 0;
}
return towers[_tower].getTop();
}
bool Board::isTowerComplete(int _tower) const {
if (towers[_tower].size() == tokensCount) {
return true;
}
return false;
}
int Board::getLowerBound(int _tower) const {
const Tower * const tower = &(towers[_tower]);
if (tower->size() == 0) return tokensCount;
int ok = 0;
for (int i = tokensCount; i > 0; --i) {
if ((tokensCount - i) >= tower->size()) continue;
if (tower->getToken(tokensCount - i) == i) ++ok;
}
return (tower->size() - ok) * 2 + tokensCount - tower->size();
}
void Board::serialize(char* _buffer, int& _position) const {
// Zabali se pocet tokenu na desce.
int data = tokensCount;
MPI_Pack(&data, 1, MPI_INT, _buffer, BUFFER_SIZE, &_position, MPI_COMM_WORLD);
// Zabali se velikost desky (pocet vezi).
data = size();
MPI_Pack(&data, 1, MPI_INT, _buffer, BUFFER_SIZE, &_position, MPI_COMM_WORLD);
// Zabali se vsechny veze na desce.
for (vector<Tower>::const_iterator it = towers.begin(); it < towers.end(); ++it) {
it->serialize(_buffer, _position);
}
}
void Board::deserialize(char* _buffer, int& _position) {
// Precte se pocet tokenu.
MPI_Unpack(_buffer, BUFFER_SIZE, &_position, &tokensCount, 1, MPI_INT, MPI_COMM_WORLD);
// Precte se velikost desky.
int size;
MPI_Unpack(_buffer, BUFFER_SIZE, &_position, &size, 1, MPI_INT, MPI_COMM_WORLD);
// Deserializuji se veze.
for (int i = 0; i < size; ++i) {
Tower tower;
tower.deserialize(_buffer, _position);
towers.push_back(tower); // Kopie.
}
}
ostream& operator<<(ostream& _ostream, const Board& _board) {
int order = 0;
for (vector<Tower>::const_iterator it = _board.towers.begin(); it != _board.towers.end(); ++it) {
_ostream << "Tower " << order++ << ": " << (*it) << endl;
}
return _ostream;
}