2048 is a game that appeared in 2014 and quickly became a popular time killer. Simple rules of the game only push players to create clones, bots and winning strategies. Including on Habré. ( Clone , bot , strategy ) This article tells about a handy tool for evaluating game strategies and examples of how it works on several bots.
The tool itself consists of three parts. The first is the C ++ engine. You can play with it manually in the console. It works according to the following algorithm:
Selects two random cells on the playing field, places two for each of them and displays the coordinates of these cells.
Until the player makes a dead-end move (the turn after which the playing field does not change) the engine performs a cycle:
To simulate the playing field, the engine uses a class from board.hpp . Announcement of this class with comments.
template<int n> class A{ // n private: int left_adder(int&, int); // 16 move int left_compressor(int&, int); // namespace int left_move_row(int); // 4 int left_move(); // , int right_adder(int&, int); // int right_compressor(int&, int); // int right_move_row(int); // int right_move(); // int up_adder(int&, int); // int up_compressor(int&, int); // int up_move_column(int); // int up_move(); // int down_adder(int&, int); // int down_compressor(int&, int); // int down_move_column(int); // int down_move(); // std::pair<int,int> random(); // 2 4 void out() const; // a. move(0) unsigned score = 0; // bool deadlock = false; // static std::mt19937 rand; // std::array<std::array<int,n>,n> a; // public: A(); // std::vector<int> init(); // std::vector<int> move(int); // unsigned get_score() const; // };
The second is a bot whose strategy needs to be evaluated. He reads what the engine displays (for synchronizing the game fields of the engine and the bot), and displays the move that the strategy under test considers best. Bot can be written in any language. The only restriction is that you cannot make a move in a dead end direction.
And the third part is a simple bash script that "connects" the first two components and displays the statistics in a readable form.
All 4 bots are written in python using the board module and differ only in the evaluation function. One argument is passed to the evaluation function - the current state of the playing field. To determine the available moves, the playing field has a deadlock method. The main function communicates with the engine.
1. Random selection
Bot makes a random available move. This bot is made only to compare its effectiveness with the effectiveness of other bots.
Medium Result: 1250
import random import board def f(a): l = [1, 2, 3, 4] ans = random.choice(l) while a.deadlock(ans) and l != []: ans = random.choice(l) del l[l.index(ans)] if l == [] and a.deadlock(ans): ans = 0 return ans board.main(f)
2. Moving in a circle
With its first move, the bot makes a move up, and then selects the next move clockwise skipping dead ends.
Median result: 2900
import board def f(a): global h ans = h % 4 + 1 while a.deadlock(ans) and ans != h: ans = ans % 4 + 1 h = ans return h h = 0 board.main(f)
3. Everything in one corner
The bot makes its first move up. After each move up, selects the move to the right, and after each move to the right, move up. If the selected move is a dead end, the bot repeats the previous move. If the previous move is a dead end, then the bot tries to move to the left and at the most, move down.
Medium Result: 3900
import board def f(a): global h if h == 1: l = [2, 1] else: l = [1, 2] l += [4, 3, 0] while a.deadlock(l[0]) and l[0] != 0: l = l[1:] h = l[0] return h h = 0 board.main(f)
4. Maximum points
This bot checks the moves in all four directions and selects the one that brings the maximum points.
Median result: 4000
import board def f(a): max = 0 ans = 0 for i in range(1, 5): if not a.deadlock(i): b = a.copy() t = b.move(i) if (t >= max): ans = i max = t return ans board.main(f)
All bots were tested 1000 times under the same conditions.
Bot number | Average Steps | Min Steps | Max. Steps | Average score | Min score | Max. score | Average time | Min time | Max. time |
---|---|---|---|---|---|---|---|---|---|
one | 131 | 50 | 266 | 1259 | 240 | 3216 | 90 | 60 | 242 |
2 | 233 | 57 | 647 | 2885 | 292 | 11296 | 108 | 52 | 234 |
3 | 311 | 98 | 859 | 3905 | 740 | 14700 | 155 | 78 | 363 |
four | 317 | 70 | 826 | 4027 | 412 | 13292 | 776 | 116 | 2692 |
All sources on github
Source: https://habr.com/ru/post/317370/
All Articles