-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbot.cpp
More file actions
91 lines (75 loc) · 2.74 KB
/
Copy pathbot.cpp
File metadata and controls
91 lines (75 loc) · 2.74 KB
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
#include "bot.h"
#include "point.h"
#include "settings.h"
#include <omp.h>
#include <limits.h>
#include <vector>
namespace {
int CountScore(const Field& field) {
int score = 0;
for (int y = 0; y < field.GetFirstEmptyRow(); y++) {
for (int x = 0; x < field.GetSize().x; x++) {
if (field[y][x] != 0) {
score += y + 1;
} else if (y + 1 < field.GetSize().y && field[y + 1][x]) {
score += (y + 2) * field.GetSize().x;
}
}
}
return score;
}
std::vector<PiecePosition> GetAllPiecePositions(const Field& field, PieceType type) {
std::vector<PiecePosition> allPiecePositions;
for (unsigned int rot = 0; rot < GetRotationCount(type); rot++) {
int n = field.GetSize().x - GetPieceWidth(type, rot) + 1;
int m = std::min(field.GetSize().y - GetPieceHeight(type, rot), field.GetFirstEmptyRow()) + 1;
for (int x = 0; x < n; x++) {
for (int y = m - 1; y >= 0; y--) {
PiecePosition currPiecePosition{Point(x, y), type, rot};
if (field.CanPut(currPiecePosition)) {
allPiecePositions.push_back(currPiecePosition);
break;
}
}
}
}
return allPiecePositions;
}
void GetBestScore(Field& field, std::deque<PieceType>& nextPieces, int& bestScore) {
if (nextPieces.empty()) {
bestScore = std::min(bestScore, CountScore(field));
return;
}
PieceType type = nextPieces.front();
nextPieces.pop_front();
for (const auto& piecePosition : GetAllPiecePositions(field, type)) {
field.PutAndClearFilledLines(piecePosition);
GetBestScore(field, nextPieces, bestScore);
field.EraseLastAddedPiece();
}
nextPieces.push_front(type);
}
}
PiecePosition Bot::GetBestPiecePosition(
Field field,
PieceType type,
std::deque<PieceType> nextPieces
) {
int bestScore = INT_MAX;
PiecePosition bestPiecePosition;
#pragma omp parallel for firstprivate(field, nextPieces)
for (const auto& piecePosition : GetAllPiecePositions(field, type)) {
int currScore = INT_MAX;
field.PutAndClearFilledLines(piecePosition);
GetBestScore(field, nextPieces, currScore);
field.EraseLastAddedPiece();
#pragma omp critical
{
if (currScore < bestScore) {
bestScore = currScore;
bestPiecePosition = piecePosition;
}
}
}
return bestPiecePosition;
}