Skip to content

Commit

Permalink
Added multithreading optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
AnasImloul committed Oct 31, 2023
1 parent aa3136d commit 590a447
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 31 deletions.
10 changes: 8 additions & 2 deletions grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,16 @@ void grid::show() {
long long value = (tiles[i * SIZE + j] != 0 ? (1 << tiles[i * SIZE + j]) : 0);
std::cout << value << std::string(maxLength1 - length(value), ' ') << " ";
}
for (int i = 0; i < 1 + maxLength1 / 3; i++)
if (i + 1 == SIZE) {
std::cout << std::endl;
} else {
for (int i = 0; i < 1 + maxLength1 / 3; i++)
std::cout << std::endl;
}
}
std::cout << std::endl;
std::cout << "Score: " << score << std::endl;


}

bool grid::up() {
Expand Down
6 changes: 3 additions & 3 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ void fastIO() {
}

int main() {
std::srand(std::time(nullptr));
// std::srand(std::time(nullptr));
fastIO();

grid g;

int move;
do {
move = move::bestMove(g, 8);
move = move::bestMove(g, 12);
g.move(move);
g.show();
std::cout << "Score: " << g.getScore() << std::endl;
std::cout << std::endl;
} while (move != -1);

}
76 changes: 51 additions & 25 deletions move.cpp
Original file line number Diff line number Diff line change
@@ -1,47 +1,73 @@
//
// Created by user on 29/10/2023.
//

#include "move.h"
#include <iostream>
#include <thread>
#include <vector>
#include <atomic>

#define max(a, b) ((a) > (b) ? (a) : (b))

namespace move {
int bestMove(grid& g, int depth) {
int64_t bestScore = 0;
int bestDir = -1, calls = 0;
bestMoveHelper(g, depth, bestScore, bestDir, -1, calls);
std::cout << "calls: " << calls << std::endl;
std::vector<std::thread> threads;
int64_t scores[16];
for (int i = 0; i < 16; i++) scores[i] = -1;

for (int first : DIRECTIONS) {
for (int second : DIRECTIONS) {
threads.emplace_back([&](int dir) {
grid g1(g);
if (g1.move(dir / 4)) {
grid g2(g1);
if (g2.move(dir % 4)) {
int64_t score = -1;
bestScore(g2, depth - 2, score);
scores[dir] = score;
} else {
int64_t score = evaluate(g1) >> depth;
scores[dir] = score;
}
}
}, first * 4 + second);
}
}

for (auto& thread : threads) {
thread.join();
}

int bestDir = -1;
int64_t _bestScore = -1;

for (int i = 0; i < 16; i++) {
int64_t score = scores[i];

if (score > _bestScore) {
_bestScore = score;
bestDir = i / 4;
}
}

return bestDir;

}

inline int64_t evaluate(grid& g) { return (g.getEmpty() << 16) + g.getScore(); }

namespace {
int bestMoveHelper(const grid& g, int depth, int &bestScore, int &bestDir, int move) {
if (depth == 0 || g.isBlocked()) {
return evaluate(g);
}
void bestScore(grid& g, int depth, int64_t& currentBestScore) {

if (move == -1) {
// if the move is -1, we are at the root of the tree
// we will have dynamic depth based on the number of empty tiles
// the less empty tiles, the more depth
depth = max(depth * (SIZE - g.getEmpty() / SIZE) / SIZE, 4);
}
int64_t score = evaluate(g) >> depth;
currentBestScore = max(currentBestScore, score);

if (depth == 0)
return;

for (int dir : DIRECTIONS) {
grid g1(g);
g1.move(dir);
int score = bestMoveHelper(g1, depth - 1, bestScore, bestDir, (move == -1 ? dir : move));
if (score > bestScore) {
bestScore = score;
bestDir = move;
if (g1.move(dir)) {
bestScore(g1, depth - 1, currentBestScore);
}
}

return bestScore;
}
}

Expand Down
2 changes: 1 addition & 1 deletion move.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace move {
inline int64_t evaluate(grid &g);

namespace {
void bestMoveHelper(grid& g, int depth, int64_t &bestScore, int &bestDir, int move, int& calls);
void bestScore(grid& g, int depth, int64_t& currentBestScore);
}

}

0 comments on commit 590a447

Please sign in to comment.