Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <vector>
- #include <algorithm>
- #include <float.h>
- #include <limits.h>
- using namespace std;
- const int WIDTH = 7;
- const int HEIGHT = 7;
- const int MAX_PLAYERS = 2;
- enum class MoveType
- {
- Push = 0,
- Move = 1,
- Pass = -1 // non existant in input, so just - 1
- };
- enum Direction
- {
- Up = 1 << 3,
- Right = 1 << 2,
- Down = 1 << 1,
- Left = 1 << 0
- };
- struct vec2
- {
- int x;
- int y;
- bool insideMap()
- {
- return x >= 0 && y >= 0 && x <= WIDTH - 1 && y <= HEIGHT - 1;
- }
- vec2 operator-(vec2 b)
- {
- return vec2{ x - b.x, y - b.y };
- }
- vec2 operator+(vec2 b)
- {
- return vec2{ x + b.x, y + b.y };
- }
- void operator+=(vec2 b)
- {
- x += b.x;
- y += b.y;
- }
- void operator-=(vec2 b)
- {
- x -= b.x;
- y -= b.y;
- }
- bool operator==(vec2 b)
- {
- return x == b.x && y == b.y;
- }
- };
- struct Move
- {
- vec2 vel;
- Direction from;
- Direction to;
- };
- //vec2 UP = { 0, -1 }, DOWN = { 0, 1 }, LEFT = { -1, 0 }, RIGHT = { 1, 0 };
- Move
- UP = { {0, -1}, Direction::Down, Direction::Up },
- DOWN = { {0, 1}, Direction::Up, Direction::Down },
- LEFT = { {-1, 0}, Direction::Right, Direction::Left },
- RIGHT = { {1, 0}, Direction::Left, Direction::Right };
- Move availableMoves[4] = { UP, DOWN, LEFT, RIGHT };
- struct Grid
- {
- int type; // binary type
- vec2 pos;
- int item; // 0 if mine, 1 if enemy, -1 if none
- };
- struct Player
- {
- int type;
- vec2 pos;
- int questN;
- bool holdingItem; // in hand
- };
- struct Item
- {
- string name;
- vec2 pos;
- int playerId;
- };
- struct Quest
- {
- string name;
- int playerId;
- };
- struct State
- {
- MoveType moveType;
- Grid grid[HEIGHT][WIDTH];
- Player players[MAX_PLAYERS];
- vector<Item> items;
- vector<Quest> quests;
- void clear()
- {
- items.clear();
- quests.clear();
- }
- bool availableCell(vec2 fromPos, vec2 toPos, Move move)
- {
- return (grid[fromPos.y][fromPos.x].type & move.to) && (grid[toPos.y][toPos.x].type & move.from);
- }
- vector<vec2> getAvailableMoves(vec2 pos)
- {
- vector<vec2> moves;
- for (int i = 0; i < 4; i++)
- {
- vec2 futurePos = pos + availableMoves[i].vel;
- if (!futurePos.insideMap()) continue;
- if (availableCell(pos, futurePos, availableMoves[i]))
- {
- moves.push_back({ availableMoves[i].vel });
- }
- }
- return moves;
- }
- };
- struct Action
- {
- MoveType moveType;
- int id = -1; // if id == -1 then moveType is move
- vector<Direction> directionMoves;
- void clear()
- {
- directionMoves.clear();
- }
- string getString(int index)
- {
- switch (directionMoves[index])
- {
- case Up:
- return "UP";
- case Down:
- return "DOWN";
- case Left:
- return "LEFT";
- case Right:
- return "RIGHT";
- }
- return "NULL";
- }
- };
- struct Agent
- {
- State state;
- Action bestAction;
- float bestScore = -FLT_MAX;
- void read()
- {
- state.clear();
- // game loop
- int turnType;
- cin >> turnType; cin.ignore();
- state.moveType = (MoveType)turnType;
- for (int i = 0; i < 7; i++) {
- for (int j = 0; j < 7; j++) {
- string tile;
- cin >> tile; cin.ignore();
- int binaryNum = 0;
- for (int k = 3; k >= 0; k--)
- {
- if (tile[k] == '1')
- {
- binaryNum |= 1 << k;
- }
- }
- state.grid[j][i].pos.x = j;
- state.grid[j][i].pos.y = i;
- state.grid[j][i].type = binaryNum;
- state.grid[j][i].item = -1;
- }
- }
- for (int i = 0; i < 2; i++) {
- int numPlayerCards; // the total number of quests for a player (hidden and revealed)
- int playerX;
- int playerY;
- string playerTile;
- cin >> numPlayerCards >> playerX >> playerY >> playerTile; cin.ignore();
- Player & player = state.players[i];
- player.pos.x = playerX;
- player.pos.y = playerY;
- player.questN = numPlayerCards;
- int binaryNum = 0;
- for (int k = 3; k >= 0; k--)
- {
- if (playerTile[k] == '1')
- {
- binaryNum |= 1 << k;
- }
- }
- player.type = binaryNum;
- player.holdingItem = false;
- }
- int numItems; // the total number of items available on board and on player tiles
- cin >> numItems; cin.ignore();
- for (int i = 0; i < numItems; i++) {
- string itemName;
- int itemX;
- int itemY;
- int itemPlayerId;
- cin >> itemName >> itemX >> itemY >> itemPlayerId; cin.ignore();
- state.items.push_back({ itemName, vec2{itemX, itemY}, itemPlayerId });
- state.grid[itemY][itemX].item = itemPlayerId;
- if (itemX == -1 && itemPlayerId == 0)
- {
- state.players[0].holdingItem = true;
- }
- }
- int numQuests; // the total number of revealed quests for both players
- cin >> numQuests; cin.ignore();
- for (int i = 0; i < numQuests; i++) {
- string questItemName;
- int questPlayerId;
- cin >> questItemName >> questPlayerId; cin.ignore();
- state.quests.push_back({ questItemName, questPlayerId });
- }
- }
- void think()
- {
- bestScore = -FLT_MAX;
- // heuristic stuff
- if (state.moveType == MoveType::Move)
- {
- auto moves = state.getAvailableMoves(state.players[0].pos);
- for (auto move : moves)
- {
- }
- // for now just pass
- bestAction.moveType = MoveType::Pass;
- }
- else
- {
- bestAction.moveType = MoveType::Push;
- if (state.players[0].holdingItem)
- {
- Player & player = state.players[0];
- if (player.pos.x == 0)
- {
- bestAction.clear();
- bestAction.directionMoves.push_back({ Left });
- bestAction.id = player.pos.y;
- return;
- }
- else if (player.pos.x == 6)
- {
- bestAction.clear();
- bestAction.directionMoves.push_back({ Right });
- bestAction.id = player.pos.y;
- return;
- }
- else if (player.pos.y == 0)
- {
- bestAction.clear();
- bestAction.directionMoves.push_back({ Up });
- bestAction.id = player.pos.x;
- return;
- }
- else if (player.pos.y == 6)
- {
- bestAction.clear();
- bestAction.directionMoves.push_back({ Down });
- bestAction.id = player.pos.x;
- return;
- }
- }
- // find best push
- for (auto & item : state.items)
- {
- bool quested = false;
- if (item.playerId != 0 || item.pos.x < 0) continue;
- for (auto & quest : state.quests)
- {
- if (quest.name == item.name && quest.playerId == 0)
- {
- quested = true;
- break;
- }
- }
- if (!quested) continue;
- float avrg = (float)WIDTH / 2.0f;
- // LEFT RIGHT
- if (item.pos.x < avrg)
- {
- int d = -item.pos.x;
- if (d > bestScore)
- {
- bestScore = d;
- bestAction.id = item.pos.y;
- bestAction.clear();
- bestAction.directionMoves.push_back(Left);
- }
- }
- else
- {
- int d = -WIDTH + 1 + item.pos.x;
- if (d > bestScore)
- {
- bestScore = d;
- bestAction.id = item.pos.y;
- bestAction.clear();
- bestAction.directionMoves.push_back(Right);
- }
- }
- if (item.pos.y < avrg)
- {
- int d = -item.pos.y;
- if (d > bestScore)
- {
- bestScore = d;
- bestAction.id = item.pos.x;
- bestAction.clear();
- bestAction.directionMoves.push_back(Up);
- }
- }
- else
- {
- int d = -HEIGHT + 1 + item.pos.y;
- if (d > bestScore)
- {
- bestScore = d;
- bestAction.id = item.pos.x;
- bestAction.clear();
- bestAction.directionMoves.push_back(Down);
- }
- }
- }
- }
- }
- void output()
- {
- if (bestAction.moveType == MoveType::Push)
- {
- cout << "PUSH " << bestAction.id << " " << bestAction.getString(0) << endl;
- }
- else
- {
- cout << "PASS" << endl;
- }
- }
- };
- int main()
- {
- Agent agent;
- while (1)
- {
- agent.read();
- agent.think();
- agent.output();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement