Compare commits

10 Commits
master ... play

Author SHA1 Message Date
4a1bae3f87 Add memory header for building project
Some checks failed
BattleCap test mode / Build BattleCap (push) Failing after 18s
2025-09-03 23:50:48 +03:00
c68e8c6bb1 Find the current path of gitea runner
Some checks failed
BattleCap test mode / Build BattleCap (push) Failing after 21s
2025-09-03 23:48:02 +03:00
140c814135 Install cmake package
Some checks failed
BattleCap test mode / Build BattleCap (push) Failing after 20s
2025-09-03 23:46:29 +03:00
b7c9f24bba Test workflow again
Some checks failed
BattleCap test mode / Build BattleCap (push) Failing after 1m18s
2025-09-03 23:43:10 +03:00
41a56730c4 New workflow for project
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m14s
2025-09-03 17:23:06 +03:00
e63d3030ea Edit enemy's logic for step 2025-08-30 17:24:23 +03:00
d4d30ae1fa Player's turn complete 2025-07-09 17:27:51 +03:00
5577f14f5b First attempts for moving player's unit 2025-07-08 18:23:27 +03:00
136215cd1e Remve debug infotmation after init 2025-07-07 23:42:10 +03:00
ee925cebc9 Highlight selected unit
Debug information about selected unit
2025-07-07 23:34:42 +03:00
7 changed files with 240 additions and 48 deletions

View File

@@ -0,0 +1,24 @@
name: BattleCap test mode
run-name: ${{ gitea.actor }} is testing out Gitea Actions
on: [push]
jobs:
Build BattleCap:
runs-on: ubuntu-latest
steps:
- run: echo "Ubuntu machine succesfully started!"
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: Install cmake package
run: sudo apt update -y && sudo apt install cmake -y
- name: Cmake prepare part
run: mkdir build && cd build && cmake ..
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- name: Build project
run: cd build && make
- run: echo "🍏 This job's status is ${{ job.status }}."

View File

@@ -6,6 +6,7 @@
constexpr auto SIZE = 10;
constexpr auto SIZE_FOR_ARRAY = SIZE - 1;
constexpr auto ARMY = 5;
constexpr auto FLAGS = 3;
class Game {
private:
@@ -27,7 +28,9 @@ public:
void play();
private:
bool handleUnitSelection(const auto&, size_t&, int&, int&);
bool handleUnitMovement(auto, int&, int&);
void Random(char);
void clearScreen();
void print_field();
void print_field(int, int);
};

View File

@@ -1,11 +1,10 @@
#pragma once
class Infantry {
private:
int x;
int y;
public:
Infantry(int _x, int _y) : x(_x), y(_y) {};
void get_coordinates();
std::pair<int,int> get_coordinates();
void attack();
};

View File

@@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <vector>
#include <memory>
#include "stdafx.h"
class Player {
@@ -11,6 +12,9 @@ private:
public:
Player() : score(0.) {};
void points(double _score){
score += _score;
}
std::vector<std::unique_ptr<Infantry>>& get_army() {
return army;
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <iostream>
#include <cstdbool>
#include <array>
#ifdef WINDOWS
#include <conio.h>
@@ -12,6 +13,14 @@
#include "Game.h"
#include "Player.h"
// TODO
/*enum class State {
SELECT_UNIT,
MOVE_UNIT,
ENEMY_TURN
};
*/
enum KEY_CODES
{
ESC_KEY = 27,

View File

@@ -1,11 +1,21 @@
#include "Game.h"
static bool check_lose_win(auto& player) {
return player.empty();
}
static int Random_step() {
const std::array<KEY_CODES, 5> keys = {
ESC_KEY, UP_KEY, DOWN_KEY, LEFT_KEY, RIGHT_KEY
};
return keys[rand() % 5];
}
void Game::Random(char symbol) {
auto isNearPlayer = [this](int x, int y) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> 8 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int dy = -1; dy <= 1; ++dy) {
for (int dx = -1; dx <= 1; ++dx) {
if (dx == 0 && dy == 0) continue; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (dx == 0 && dy == 0) continue;
int nx = (x + dx + SIZE_FOR_ARRAY + 1) % (SIZE_FOR_ARRAY + 1);
int ny = (y + dy + SIZE_FOR_ARRAY + 1) % (SIZE_FOR_ARRAY + 1);
@@ -25,8 +35,8 @@ void Game::Random(char symbol) {
int x = rand() % (SIZE_FOR_ARRAY + 1);
int y = rand() % (SIZE_FOR_ARRAY + 1);
if (field[y][x] == EMPTY_CELL &&
!isNearPlayer(x, y)) {
// && !isNearPlayer(x, y)
if (field[y][x] == EMPTY_CELL) {
field[y][x] = symbol;
if (symbol == ENEMY_CELL)
gamers[1].set_army(x, y);
@@ -44,11 +54,16 @@ void Game::clearScreen() {
#endif
}
void Game::print_field() {
clearScreen();
for (const auto& row : field) {
for (char cell : row) {
std::cout << cell << ' ';
void Game::print_field(int cursorX = -1, int cursorY = -1) {
for (int i = 0; i <= SIZE_FOR_ARRAY; ++i) {
for (int j = 0; j <= SIZE_FOR_ARRAY; ++j) {
// FOR FURTHER DEVELOPMENT: field[i][j] == PLAYER_CELL
if (i == cursorY && j == cursorX) {
std::cout << "\033[32m" << field[i][j] << "\033[0m ";
}
else {
std::cout << field[i][j] << ' ';
}
}
std::cout << '\n';
}
@@ -93,16 +108,10 @@ void Game::init() {
while (true) {
clearScreen();
print_field();
int key = _getch();
if (key == ESC_KEY) {
std::cout << "Exit\n";
exit(0);
}
int newX = x, newY = y;
switch (key) {
switch (_getch()) {
case ESC_KEY: std::cout << "Exit\n"; exit(0);
case UP_KEY: newY = (y == 0) ? SIZE_FOR_ARRAY : y - 1; break;
case DOWN_KEY: newY = (y == SIZE_FOR_ARRAY) ? 0 : y + 1; break;
case LEFT_KEY: newX = (x == 0) ? SIZE_FOR_ARRAY : x - 1; break;
@@ -131,36 +140,180 @@ void Game::init() {
Random(ENEMY_CELL);
}
for (int element = 0; element < 3; ++element) {
for (int element = 0; element < FLAGS; ++element) {
Random(FLAG_CELL);
}
#ifdef DEBUG
std::cout << "Please, look at debugger" << std::endl;
#endif // DEBUG
}
void Game::play() {
#ifdef DEBUG
print_field();
auto& vec_1 = gamers[0].get_army();
auto& vec_2 = gamers[1].get_army();
bool is_active = true;
bool is_selected = false;
bool unit_selected = false;
std::cout << "Positions of player's units\n";
for (size_t i = 0; i < vec_1.size(); ++i) {
vec_1[i]->get_coordinates();
int current_unit_index = 0;
auto& player_army = gamers[0].get_army();
auto& enemy_army = gamers[1].get_army();
int cursorX = -1, cursorY = -1;
while (true) {
if (is_active) {
if (check_lose_win(player_army)) {
std::cout << "YOU LOSE\n";
exit(0);
}
auto [x, y] = player_army[0]->get_coordinates();
cursorX = x;
cursorY = y;
while (!is_selected) {
clearScreen();
print_field(cursorX, cursorY);
std::cout << "Your turn! Use 'a' or 'd' to select a unit, ENTER to confirm, ESC to exit.\n";
switch (_getch()) {
case ESC_KEY: std::cout << "Exit\n"; exit(0);
case LEFT_KEY:
if (!player_army.empty()) {
current_unit_index = (current_unit_index == 0) ? player_army.size() - 1 : current_unit_index - 1;
auto [x, y] = player_army[current_unit_index]->get_coordinates();
cursorX = x;
cursorY = y;
}
break;
case RIGHT_KEY:
if (!player_army.empty()) {
current_unit_index = (current_unit_index == player_army.size() - 1) ? 0 : current_unit_index + 1;
auto [x, y] = player_army[current_unit_index]->get_coordinates();
cursorX = x;
cursorY = y;
}
break;
case ENTER:
if (!player_army.empty() && field[cursorY][cursorX] == PLAYER_CELL) {
unit_selected = true;
#ifdef DEBUG
std::cout << "Unit selected at (" << cursorX << ", " << cursorY << ")!\n";
#endif // DEBUG
is_selected = true;
}
break;
default: continue;
}
}
bool is_moved = false;
while (!is_moved) {
clearScreen();
print_field(cursorX, cursorY);
int cp_x = cursorX;
int cp_y = cursorY;
std::cout << "Let's move!" << std::endl;
switch (_getch()) {
case ESC_KEY: std::cout << "Exit\n"; exit(0);
case UP_KEY: cursorY = (cursorY == 0) ? SIZE_FOR_ARRAY : cursorY - 1; break;
case DOWN_KEY: cursorY = (cursorY == SIZE_FOR_ARRAY) ? 0 : cursorY + 1; break;
case LEFT_KEY: cursorX = (cursorX == 0) ? SIZE_FOR_ARRAY : cursorX - 1; break;
case RIGHT_KEY: cursorX = (cursorX == SIZE_FOR_ARRAY) ? 0 : cursorX + 1; break;
case ENTER: continue;
}
is_moved = true;
switch (field[cursorY][cursorX])
{
case PLAYER_CELL:
is_moved = false;
cursorX = cp_x;
cursorY = cp_y;
break;
case ENEMY_CELL:
std::cout << "BANG! GOT IT! GET YOUR POINTS\n";
gamers[0].points(50.);
std::swap(field[cursorY][cursorX], field[cp_y][cp_x]);
break;
case FLAG_CELL:
std::cout << "YUMMY!\n";
gamers[0].points(10.);
std::swap(field[cursorY][cursorX], field[cp_y][cp_x]);
break;
default:
std::swap(field[cursorY][cursorX], field[cp_y][cp_x]);
break;
}
}
is_active = false;
}
else {
auto steps_for_enemy = [this](char c, int* _x, int* _y) {
int Y = *(_y);
int X = *(_x);
switch (c) {
case 'U':
while (field[X][Y] != PLAYER_CELL && field[X][Y] != FLAG_CELL) {
Y = (Y == 0) ? SIZE_FOR_ARRAY : Y - 1;
if (field[X][Y] == ENEMY_CELL)
return abs(*(_y) - Y);
}
return abs(*(_y)-Y);
case 'D':
while (field[X][Y] != PLAYER_CELL && field[X][Y] != FLAG_CELL) {
Y = (Y == 0) ? SIZE_FOR_ARRAY : Y + 1;
if (field[X][Y] == ENEMY_CELL)
return abs(*(_y)-Y);
}
return abs(*(_y)-Y);
case 'L':
while (field[X][Y] != PLAYER_CELL && field[X][Y] != FLAG_CELL) {
X = (X == 0) ? SIZE_FOR_ARRAY : X - 1;
if (field[X][Y] == ENEMY_CELL)
return abs(*(_x)-X);
}
return abs(*(_x)-X);
case 'R':
while (field[X][Y] != PLAYER_CELL && field[X][Y] != FLAG_CELL) {
X = (X == 0) ? SIZE_FOR_ARRAY : X + 1;
if (field[X][Y] == ENEMY_CELL)
return abs(*(_x)-X);
}
return abs(*(_x)-X);
default:
throw std::runtime_error("Error in method of enemy!");
}
};
if (check_lose_win(enemy_army)) {
std::cout << "YOU WIN\n";
exit(0);
}
int enemy_index = rand() % enemy_army.size();
auto [x, y] = enemy_army[enemy_index].get()->get_coordinates();
const int UP = steps_for_enemy('U', &x, &y);
const int DOWN = steps_for_enemy('D', &x, &y);
const int LEFT = steps_for_enemy('L', &x, &y);
const int RIGHT = steps_for_enemy('R', &x, &y);
const int max_val = std::max({ UP, DOWN, LEFT, RIGHT });
if (max_val == UP) {
cursorY = (cursorY == 0) ? SIZE_FOR_ARRAY : cursorY - 1;
}
else if (max_val == DOWN) {
cursorY = (cursorY == SIZE_FOR_ARRAY) ? 0 : cursorY + 1;
}
else if (max_val == LEFT) {
cursorX = (cursorX == 0) ? SIZE_FOR_ARRAY : cursorX - 1;
}
else if (max_val == RIGHT) {
cursorX = (cursorX == SIZE_FOR_ARRAY) ? 0 : cursorX + 1;
}
// TODO: Logic after enemy's step
}
}
std::cout << std::endl;
std::cout << "Positions of enemy's units\n";
for (size_t i = 0; i < vec_2.size(); ++i) {
vec_2[i]->get_coordinates();
}
#else
return;
#endif
}

View File

@@ -5,6 +5,6 @@ void Infantry::attack()
return;
}
void Infantry::get_coordinates() {
std::cout << x << " " << y << std::endl;
std::pair<int, int> Infantry::get_coordinates() {
return { x, y };
}