Compare commits

...

64 Commits

Author SHA1 Message Date
Hatvani Tamás
566d72c2d6 Merge pull request #7 from htamas1210/Workflow
Workflow
2025-11-12 18:45:08 +01:00
ad26d22281 indentation error in python script 2025-11-12 18:44:00 +01:00
352b4e57d7 rewrote the python script
the script now checks for project name on every line read from the log
file and appends it to a list named by the project, if the branch is
master then it appends all lines into one list, then it checks if there
is any data in the list and uploads them to the correct tab that matches
the project name or master
2025-11-12 18:42:17 +01:00
Hatvani Tamás
cdd8b45da8 Merge pull request #6 from htamas1210/Engine/movegen-utils
Engine/movegen utils
2025-11-12 11:08:36 +01:00
Varga Dávid Lajos
6006442f90 added '#[inline(always)]' annotation to hot functions: utils::pop_lsb, utils::pop_msb 2025-11-11 14:23:30 +01:00
Varga Dávid Lajos
eebdfdbee2 implemented utility function: bitboard::utils::notation_from_square_number 2025-11-11 14:21:11 +01:00
Varga Dávid Lajos
a6aba8801e implemented utility function: bitboard::utils::pop_msb 2025-11-11 14:16:33 +01:00
Varga Dávid Lajos
8d1300d7e2 implemented utility function: bitboard::utils::pop_lsb 2025-11-11 14:14:39 +01:00
Varga Dávid Lajos
d0e6ce81ce fixed bad test values in test utils::tests::pop_lsb_test 2025-11-11 14:06:43 +01:00
Varga Dávid Lajos
f3dea86ded fixed typo in test utils::tests::pop_msb_test 2025-11-11 14:05:31 +01:00
Varga Dávid Lajos
092ed19104 added frame and tests for function: bitboard::util::notation_from_square_number 2025-11-11 13:59:53 +01:00
Varga Dávid Lajos
f8894bbdff added frame and tests for function: bitboard::util::pop_msb 2025-11-11 13:51:14 +01:00
Varga Dávid Lajos
258a8a0da9 added frame and tests for function: bitboard::util::pop_lsb 2025-11-11 13:39:26 +01:00
Varga Dávid Lajos
dca6eac3ba added file bitboard/utils.rs 2025-11-11 12:50:53 +01:00
Hatvani Tamás
5ee797e1f8 Add conditional logging for master branch 2025-11-11 12:32:03 +01:00
Hatvani Tamás
eaf3bfa192 Merge pull request #5 from htamas1210/Engine/movegen-lut
Engine/movegen lut
2025-11-11 12:17:48 +01:00
Hatvani Tamás
9c73ca6838 Fix formatting of conditional checks in dispatcher.yml 2025-11-11 11:34:05 +01:00
Hatvani Tamás
0f50f31b13 Update branch checks to be case-sensitive
Refactor branch checks to be case-sensitive for Engine, Server, and UI.
2025-11-11 11:27:42 +01:00
Hatvani Tamás
b6f0b6ee5e Fix conditional syntax in dispatcher.yml 2025-11-11 11:22:21 +01:00
4ae9eea7e2 removed pull_request dispatcher from release workflow 2025-11-11 11:13:45 +01:00
1f368551c1 removed pull_request dispatch from the test files 2025-11-11 11:12:39 +01:00
Hatvani Tamás
4e9f222ddc Allow case-insensitive branch checks in dispatcher.yml 2025-11-11 11:01:38 +01:00
Varga Dávid Lajos
061795a039 implemented the generation of LUT: RAY_TABLE 2025-11-11 10:39:51 +01:00
Varga Dávid Lajos
1af497f063 implemented the generation of LUT: KNIGHT_ATTACK_MAP 2025-11-11 10:33:51 +01:00
Varga Dávid Lajos
b6cdf5b778 implemented the generation of LUT: PAWN_ATTACK_MAP 2025-11-11 10:32:41 +01:00
Varga Dávid Lajos
4eb4bc1348 implemented the generation of LUT: KING_ATTACK_MAPS 2025-11-11 10:25:23 +01:00
Varga Dávid Lajos
c2fe2e968a added masks for use against wrap-around 2025-11-11 10:22:05 +01:00
Varga Dávid Lajos
21f2890b92 added frame and tests for table: RAY_TABLE 2025-11-10 17:17:30 +01:00
Varga Dávid Lajos
5d748b07d2 added frame and tests for table: KNIGHT_ATTACK_MAP 2025-11-10 16:54:14 +01:00
Varga Dávid Lajos
b252f16b2d added frame and tests for table: PAWN_ATTACK_MAP 2025-11-10 15:50:58 +01:00
Varga Dávid Lajos
18f4060df0 added frame and tests for table: KING_ATTACK_MAP 2025-11-10 15:28:15 +01:00
Varga Dávid Lajos
033440fbac added dependency to Cargo.toml: once_cell 2025-11-10 13:18:48 +01:00
Varga Dávid Lajos
bfb2a6db23 added file and module structure for attackmaps.rs 2025-11-10 13:13:03 +01:00
Bence
70d10719e6 Dokumentumok feltöltése a master branch-re 2025-11-10 12:21:27 +01:00
Hatvani Tamás
85f7c6e690 Remove checkout step from upload_data workflow
Removed checkout step from upload job in workflow.
2025-11-09 15:05:10 +01:00
Hatvani Tamás
2ac2f17d1a Fix subprocess by adding decode to file path in upload_data.yml 2025-11-09 15:01:42 +01:00
Hatvani Tamás
7cd4bb6b09 Refactor subprocess call and print statement
Updated subprocess command to use list format and modified print statement for clarity.
2025-11-09 14:55:23 +01:00
1bf4d875af Workflow: added subprocess run to have the correct path for the test log file 2025-11-09 14:48:04 +01:00
Hatvani Tamás
8a01bba644 Update pip install command to break system packages 2025-11-09 14:34:18 +01:00
Hatvani Tamás
cf2edab297 Remove Python setup from upload_data workflow
Removed Python setup step for Google Sheets API.
2025-11-09 14:31:18 +01:00
Hatvani Tamás
5443002c5f Workflow: removed runs-on: self-hosted from test upload job 2025-11-09 14:26:28 +01:00
e19a5aac9a Workflow: Re added test-upload job, added workflow_call trigger 2025-11-09 14:24:24 +01:00
Hatvani Tamás
3515703a90 Modify zip commands in release workflow to include files in the folder with the wildcard
Update zip commands to include all files in the directories.
2025-11-09 13:12:27 +01:00
Hatvani Tamás
a6966e055d Compress build folders for upload
Added compression step for build folders before release.
2025-11-09 13:05:23 +01:00
Hatvani Tamás
e41be61321 Modify release files to target linux and windows
Update release workflow to include specific OS directories.
2025-11-09 12:55:14 +01:00
1b4194ee7d Cleanup job depend on release, added missing .cargo folder to fix cc error on workflow build 2025-11-09 12:44:33 +01:00
Hatvani Tamás
4763cbed95 Update dispatcher.yml to include permissions
Add permissions for write access to contents
2025-11-09 12:36:33 +01:00
Hatvani Tamás
9253283953 Workflow: re enabled test-data-upload with temp commands 2025-11-09 12:34:45 +01:00
596828e827 Added release workflow, started work on the upload to spreadsheet 2025-11-09 12:29:46 +01:00
Hatvani Tamás
c6c2e27d34 Add cleanup job to dispatcher workflow
Add a cleanup job to the workflow for final cleanup.
2025-11-07 13:19:40 +01:00
bc2eca7eac added new test.sh script
The test.sh script will run the cargo test and save a formatted output
from each project and then append them to a final log file which will be
the data to be uploaded to the spreadsheet
2025-11-07 12:54:11 +01:00
86ceab10ad Workflow: removed rust setup from the tests, as it is installed on device 2025-11-05 15:27:47 +01:00
785e40f538 Workflow: removed branch from tests call 2025-11-05 15:24:35 +01:00
39da1be9de Workflow: added new triggers for running test workflows 2025-11-05 15:08:33 +01:00
Hatvani Tamás
7ef9855016 Update workflow paths and conditions in dispatcher.yml 2025-11-05 15:00:42 +01:00
Hatvani Tamás
b5902c0bb7 Merge pull request #2 from htamas1210/Workflow
Workflow: dispatching workflow with 'uses'
2025-11-05 14:58:42 +01:00
76a1c18b56 Workflow: dispatching workflow with 'uses' 2025-11-05 14:58:08 +01:00
Hatvani Tamás
27394df920 Merge pull request #1 from htamas1210/Workflow
Workflow: Trying workflow on master branch
2025-11-05 14:49:08 +01:00
3df33093ed Workflow: Added the workflow files, changed ls to pwd in tests 2025-11-05 14:47:50 +01:00
300b3cde34 Workflow: Triggering the workflow a different way with gh script 2025-11-05 13:46:29 +01:00
a19e0bf922 Workflow: added missing repository checkout
Repository checkout was missing from the dispatch workflow
2025-11-05 13:30:58 +01:00
7625eecbd9 Workflow: Dispatch and Test runner workflow test #1
Testing the dispatcher and engine_test workflow for any bugs, the
changes on these files always need to be uploaded to github to test if
it is working correctly
2025-11-05 13:26:23 +01:00
d819368962 Expand GitHub workflow documentation
Detailed the GitHub workflow process for automated testing and releases,
including branch naming conventions and test result logging.
2025-11-05 12:36:30 +01:00
8818b12fa5 követelmény lista hozzáadása 2025-11-03 18:52:06 +01:00
18 changed files with 797 additions and 0 deletions

95
.github/workflows/dispatcher.yml vendored Normal file
View File

@@ -0,0 +1,95 @@
name: Dispatcher
on:
push:
branches:
- '**'
permissions:
contents: write
jobs:
dispatch:
runs-on: self-hosted
outputs:
engine: ${{ steps.check.outputs.engine }}
server: ${{ steps.check.outputs.server }}
ui: ${{ steps.check.outputs.ui }}
steps:
- name: Determine which tests to run
id: check
run: |
BRANCH="${{ github.ref_name }}"
echo "Branch: $BRANCH"
ENGINE=false
SERVER=false
UI=false
if [[ "$BRANCH" == *"Engine"* ]] ; then
ENGINE=true
fi
if [[ "$BRANCH" == *"Server"* ]] ; then
SERVER=true
fi
if [[ "$BRANCH" == *"UI"* ]] ; then
UI=true
fi
# Run all on master
if [[ "$BRANCH" == "master" ]]; then
ENGINE=true
SERVER=true
UI=true
fi
echo "engine=$ENGINE" >> $GITHUB_OUTPUT
echo "server=$SERVER" >> $GITHUB_OUTPUT
echo "ui=$UI" >> $GITHUB_OUTPUT
engine:
needs: dispatch
if: needs.dispatch.outputs.engine == 'true'
uses: ./.github/workflows/engine_test.yml
secrets: inherit
server:
needs: dispatch
if: needs.dispatch.outputs.server == 'true'
uses: ./.github/workflows/server_test.yml
secrets: inherit
ui:
needs: dispatch
if: needs.dispatch.outputs.ui == 'true'
uses: ./.github/workflows/ui_test.yml
secrets: inherit
test-data-upload:
needs: [engine, server, ui]
if: always()
uses: ./.github/workflows/upload_data.yml
secrets: inherit
release:
needs: test-data-upload
if: github.ref == 'refs/heads/master'
uses: ./.github/workflows/release.yml
secrets: inherit
cleanup:
runs-on: self-hosted
needs: [engine, server, ui, test-data-upload, release]
if: always()
steps:
- name: Final cleanup
run: |
echo "Final cleanup on self-hosted runner..."
cd "$GITHUB_WORKSPACE"
git clean -fdx
git reset --hard

16
.github/workflows/engine_test.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Engine Tests
on:
workflow_dispatch:
workflow_call:
jobs:
engine-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Run Engine tests
run: |
bash .github/workflows/test.sh engine/

105
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,105 @@
name: Release build
on:
workflow_dispatch:
workflow_call:
permissions:
contents: write
jobs:
release:
name: Build and release (master only)
runs-on: self-hosted
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Build Engine for Linux
run: |
cd $(git rev-parse --show-toplevel)
pwd
mkdir release/linux -p
cd engine/
rustup target add x86_64-unknown-linux-gnu
cargo build --release --target x86_64-unknown-linux-gnu
pwd
cp target/x86_64-unknown-linux-gnu/release/engine $(git rev-parse --show-toplevel)/release/linux/engine
- name: Build Server for Linux
run: |
cd $(git rev-parse --show-toplevel)
pwd
mkdir release/linux -p
cd server/
rustup target add x86_64-unknown-linux-gnu
cargo build --release --target x86_64-unknown-linux-gnu
pwd
cp target/x86_64-unknown-linux-gnu/release/server $(git rev-parse --show-toplevel)/release/linux/server
- name: Build UI for Linux
run: |
cd $(git rev-parse --show-toplevel)
pwd
mkdir release/linux -p
cd ui/
rustup target add x86_64-unknown-linux-gnu
cargo build --release --target x86_64-unknown-linux-gnu
pwd
cp target/x86_64-unknown-linux-gnu/release/ui $(git rev-parse --show-toplevel)/release/linux/ui
- name: Build Engine for Windows
run: |
cd $(git rev-parse --show-toplevel)
pwd
mkdir release/windows -p
cd engine/
rustup target add x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnu
pwd
cp target/x86_64-pc-windows-gnu/release/engine.exe $(git rev-parse --show-toplevel)/release/windows/engine.exe
- name: Build Server for Windows
run: |
cd $(git rev-parse --show-toplevel)
pwd
mkdir release/windows -p
cd server/
rustup target add x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnu
pwd
cp target/x86_64-pc-windows-gnu/release/server.exe $(git rev-parse --show-toplevel)/release/windows/server.exe
- name: Build UI for Windows
run: |
cd $(git rev-parse --show-toplevel)
pwd
mkdir release/windows -p
cd ui/
rustup target add x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnu
pwd
cp target/x86_64-pc-windows-gnu/release/ui.exe $(git rev-parse --show-toplevel)/release/windows/ui.exe
- name: Compress build folders for upload
run: |
cd $(git rev-parse --show-toplevel)
pwd
cd release/
zip linux.zip linux/*
zip windows.zip windows/*
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: "v${{ github.run_number }}"
name: "Release v${{ github.run_number }}"
generate_release_notes: true
files: |
release/linux.zip
release/windows.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

16
.github/workflows/server_test.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Server Tests
on:
workflow_dispatch:
workflow_call:
jobs:
server-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Run Server tests
run: |
bash .github/workflows/test.sh server/

40
.github/workflows/test.sh vendored Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -e
# --- ARGUMENT CHECK ---
if [ -z "$1" ]; then
echo "Usage: $0 <project_path>"
exit 1
fi
# --- SETUP VARIABLES ---
PROJECT_PATH="$1"
PROJECT_NAME=$(basename "$PROJECT_PATH")
ROOT_DIR=$(git rev-parse --show-toplevel)
LOG_FILE="${PROJECT_NAME}_test.log"
FINAL_LOG="${ROOT_DIR}/test_data.log"
# --- MOVE TO PROJECT DIRECTORY ---
echo ">>> Running tests for project: $PROJECT_NAME"
cd "$PROJECT_PATH" || { echo "Error: Could not cd into $PROJECT_PATH"; exit 1; }
# --- RUN TESTS ---
cargo test --verbose | tee full_test_output.log
# --- EXTRACT TEST SECTION ---
# Create the log file with the project name as the first line
echo "$PROJECT_NAME" > "$LOG_FILE"
# Then append only the lines between "running X test(s)" and the first empty line
awk '/^running [0-9]+ test[s]?$/,/^$/' full_test_output.log >> "$LOG_FILE"
# --- APPEND TO GLOBAL LOG (in repo root) ---
if [[ $(git rev-parse --abbrev-ref HEAD) == "master" ]]; then
echo "master" >> $FINAL_LOG
fi
cat "$LOG_FILE" >> "$FINAL_LOG"
# --- SUMMARY ---
echo ">>> Test output extracted to $PROJECT_PATH/$LOG_FILE"
echo ">>> Appended to $FINAL_LOG"

16
.github/workflows/ui_test.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: UI Tests
on:
workflow_dispatch:
workflow_call:
jobs:
ui-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Run UI tests
run: |
bash .github/workflows/test.sh ui/

90
.github/workflows/upload_data.yml vendored Normal file
View File

@@ -0,0 +1,90 @@
name: Upload Test Results to Google Sheets
on:
workflow_dispatch:
workflow_call:
jobs:
upload:
runs-on: self-hosted
steps:
- name: Install dependencies
run: |
pip install gspread google-auth --break-system-packages
- name: Upload test_data.log to Google Sheets
env:
GOOGLE_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_JSON }}
SPREADSHEET_ID: ${{ secrets.SPREADSHEET_ID }}
run: |
echo "$GOOGLE_SERVICE_ACCOUNT_JSON" > service_account.json
python <<'PYCODE'
import gspread, json, subprocess
creds = json.load(open("service_account.json"))
gc = gspread.service_account_from_dict(creds)
sh = gc.open_by_key("${{ secrets.SPREADSHEET_ID }}")
v = subprocess.run(['git','rev-parse','--show-toplevel'], capture_output=True).stdout.decode().strip()
print(f"{v}/test_data.log")
def writeRowsToSpreadsheet(data_list, worksheet):
existing_rows = len(worksheet.get_all_values())
start_row = existing_rows + 3
rows_to_append = [row.split() for row in data_list]
print(f"{rows_to_append}")
for i, row in enumerate(rows_to_append):
worksheet.insert_row(row, start_row + i)
with open(f"{v}/test_data.log", "r") as f:
lines = [line.strip() for line in f if line.strip()]
isMaster = False
project = lines[0].lower()
if project == "master":
isMaster = True
engine_data = []
server_data = []
ui_data = []
master_data = []
for entry in lines:
if not isMaster and entry == "engine":
project = "engine"
elif not isMaster and entry == "server":
project = "server"
elif not isMaster and entry == "ui":
project = "ui"
if project == "engine" and entry != "engine":
engine_data.append(entry)
elif project == "server" and entry != "server":
server_data.append(entry)
elif project == "ui" and entry != "ui":
ui_data.append(entry)
elif project == "master" and entry != "master":
master_data.append(entry)
print("PRINTING FILTERED DATA\n\n")
print(f"engine\n{engine_data}")
print(f"server\n{server_data}")
print(f"ui\n{ui_data}")
print("\n\n\n")
if isMaster and len(master_data) != 0:
worksheet = sh.worksheet("master")
writeRowsToSpreadsheet(master_data, worksheet)
exit(0)
if len(engine_data) != 0:
writeRowsToSpreadsheet(engine_data, sh.worksheet("engine"))
if len(server_data) != 0:
writeRowsToSpreadsheet(server_data, sh.worksheet("server"))
if len(ui_data) != 0:
writeRowsToSpreadsheet(ui_data, sh.worksheet("ui"))
PYCODE

51
Docs/funk_spec.md Normal file
View File

@@ -0,0 +1,51 @@
## 5. Követelménylista
### Szerver
| Név | Verzió | Leírás |
| --- | ------ | ------ |
| **WebSocket** | 1.0 | A szerver és a kliens között folyamatos kétirányú kommunikációt biztosít. A kapcsolat létrejötte után a szerver valós időben képes fogadni és továbbítani az eseményeket (pl. lépés végrehajtása, állapotfrissítés). Hiba esetén a kapcsolat automatikusan újraépül. |
| **Kapcsolatok csoportosítása** | 1.0 | A szerver figyeli az elérhető, szabad klienseket, majd két szabad kapcsolatot automatikusan összerendel egy meccsbe. A csoportosítás után a játékosok azonos „room”-ba kerülnek, és a szerver biztosítja az egymás közötti adatkommunikációt. |
| **Kommunikáció az engine-nel** | 1.0 | A szerver a játékosoktól érkező lépéseket és játékinformációkat továbbítja az engine-nek feldolgozásra. Az engine válasza után a szerver visszaküldi az eredményt a klienseknek (pl. érvényes lépés, matt, patt). A kommunikáció aszinkron módon zajlik, válaszidő-ellenőrzéssel. |
| **Kommunikáció a UI-al** | 1.0 | A szerver WebSocket-en keresztül adatokat továbbít a felhasználói felület és az engine között. A UI által kért műveletek (pl. új meccs létrehozása, állapotlekérés) feldolgozását a szerver közvetíti.|
### Engine
| Név | Verzió | Leírás |
| --- | ------ | ------ |
| **Bitboard** | 1.0 | A játék táblaállapotát bitműveletekkel reprezentálja a hatékonyság érdekében. Minden bábu típus és szín külön bitmask-on kerül tárolásra, lehetővé téve a gyors lekérdezéseket és lépésellenőrzéseket. |
| **Lépésgenerálás LUT** | 1.0 | Előre kiszámított lookup táblák segítségével gyorsítja a lépésgenerálást és szabályellenőrzést. Ez csökkenti a számítási időt, és optimalizálja az engine teljesítményét. |
| **Lépésgenerálás** | 1.0 | A különböző bábutípusok (gyalog, bástya, futó, stb.) lépési logikáját valósítja meg. A függvények ellenőrzik a lépés érvényességét, figyelembe véve az aktuális állást, sakkhelyzetet és speciális szabályokat (pl. sáncolás, en passant). |
| **Util függvények** | 1.0 | Segédfüggvények az engine belső működéséhez, például raycast műveletek, bitműveleti maszkok kezelése, valamint logikai ellenőrzések a lépések és ütések számításához. |
### UI
| Név | Verzió | Leírás |
| --- | ------ | ------ |
| **Belépés** | 1.0 | A felhasználó a kezdőképernyőn keresztül adhatja meg a nevét lokális játékhoz, vagy hitelesítheti magát online játékmód esetén. Hibás adatok esetén a rendszer figyelmeztetést küld. |
| **Főmenü** | 1.0 | Az alkalmazás központi navigációs felülete, ahol a felhasználó meccset kereshet, új játékot indíthat lokálisan, vagy beállításokat módosíthat. A menü megjeleníti az aktuális státuszt (online/offline). |
| **Játék** | 1.0 | A játékfelület megjeleníti a táblát, bábukat, lépéseket, és az aktuális játékállást. Támogatja mind az online, mind a lokális módot. A felület kezeli az interakciókat (lépéskattintás, visszavonás, végeredmény kijelzés). |
| **Kommunikáció a szerverrel** | 1.0 | A kliens a szerveren keresztül kommunikál az engine-nel. A UI felel az üzenetek küldéséért (lépés, új játék, visszajelzés), valamint a szervertől kapott események vizuális megjelenítéséért. |
### GitHub Actions (CI/CD)
| Név | Leírás |
| --- | ------ |
| Folyamatos tesztelés | A projekt minden commit után automatikusan tesztelődik. A pipeline lefuttatja a teszteket, és értesítést küld hibás build esetén. |
| Folyamatos integráció | Az új funkciók beolvadásakor a rendszer automatikusan integrálja a változtatásokat, új buildet hoz létre, és frissíti a fejlesztői környezetet. |
| Tesztadatok | A tesztadatok legyenek elérhetőek egy táblázatban, dátummal ellátva. (Google Sheets) |
## A github workflow folyamata:
A githubon tárolt kód minden feltöltésnél a kód mindig automatikus tesztelve van, egy workflow által. Ennek a működése:
1. A brancheket a következő képpen kell elnevezni: Projekt/task_neve (a task neve a kanban tablabol jon).
2. 3 projekt van a github repository-ban: Engine, Server és a UI. Ennek megfelelően a következőképpen kell kinézniük a brancheknek:
- Engine/task_1
- Server/task_1
- UI/task_1
Erre azért van szükség mert a github workflow ezek alapján az elnevezések alapján fogja eldönteni melyik teszteket futtassa. Ha az Engine projekthez lett feltöltve kód, akkor csak az ahhoz tartozó teszteket futtassa.
3. A workflow folyamat a következő:
Amikor feltöltődik a három projekt közül valamelyikére egy új commit. A github workflow megnézni mi a branch neve. Ezután letölti a projektet githubról, és lefuttatja azon projekt teszteit. A tesztek eredményét feltölti egy google táblazat fájlba, ahonnan bármikor visszenézhető. Minden teszt eredmény az annak megfelően elnevezett munkalapra kerül be (Engine, Server, UI), egymás alá táblázatos elrendezésben. Az oszlopok a következőek: Dátum, függvény neve, teszt bemenet, teszt kimenet, sikeres-e.
Amikor a main/master branchre kerül fel kód. A teszt az előbbiek alapján ugyanúgy lefut, csak itt mind a 3 projekt tesztje le fog futni és az eredmény egy main/master nevű munkalapra fog feltöltődni a táblázatban. Amint sikeresen lefut a tesztelés, elindul egy automatikus build, ami le fogja build-elni a projekteket. Ezután létrehoz egy új Release-t githubon, ahol beállítja a verzió számot a rust projektben beállított verzió számra, majd feltölti oda a fájlokat amiket a build hozott létre, és kiteszi ezt a buildet.
A workflow 3 külön fáljba van bontva:
1. A dispatcher (dispatch.yml). Ez indítja el a workflow-t ami teszteli a kódot a megfelelő branchen, elindítja a release workflow-t ami feltölti a master branchről buildelt projekt fájlokat.
2. A teszter (tests.yml). Ez a workflow bele fog lépni a megfelelő projekt mappába és lefutattja a megírt teszteket, és feltölti az eredményt egy google spreadsheet-be.
3. A release (release.yml). Amint sikeresek a tesztek elindul ez a workflow és lefordítja a kódot majd feltölti github-ra egy új release-ként

View File

View File

@@ -0,0 +1,4 @@
[target.x86_64-unknown-linux-gnu]
linker = "x86_64-linux-gnu-gcc"
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"

View File

@@ -4,3 +4,4 @@ version = "0.1.0"
edition = "2024"
[dependencies]
once_cell = "1.19"

2
engine/src/bitboard.rs Normal file
View File

@@ -0,0 +1,2 @@
mod attackmaps;
mod utils;

View File

@@ -0,0 +1,252 @@
use once_cell::sync::Lazy;
const A_FILE: u64 = 0x0101_0101_0101_0101;
const H_FILE: u64 = 0x8080_8080_8080_8080;
const AB_FILE: u64 = 0x0303_0303_0303_0303;
const GH_FILE: u64 = 0xC0C0_C0C0_C0C0_C0C0;
/*
EXPLANATIONS:
> square_index: 8 * rank number + file number (a-h = 0-7)
> side: white = 0, black = 1
> direction_index: 0..8 = [E, NE, N, NW, W, SW, S, SE]
*/
// KING_ATTACK_MAP[<square_index>]
pub static KING_ATTACK_MAP: Lazy<[u64; 64]> = Lazy::new(|| {
let mut table: [u64; 64] = [0u64; 64];
for sq in 0..64 {
let king: u64 = 1 << sq;
let left_attacks: u64 = king << 7 | king >> 1 | king >> 9;
let right_attacks: u64 = king << 1 | king << 9 | king >> 7;
table[sq] = (left_attacks & !H_FILE) | (right_attacks & !A_FILE) | king << 8 | king >> 8;
}
return table;
});
// PAWN_ATTACK_MAP[<square_index>][<side>]
pub static PAWN_ATTACK_MAP: Lazy<[[u64; 2]; 64]> = Lazy::new(|| {
let mut table: [[u64; 2]; 64] = [[0u64; 2]; 64];
for sq in 0..64 {
let pawn: u64 = 1 << sq;
table[sq][0] |= (pawn << 9) & !A_FILE;
table[sq][0] |= (pawn << 7) & !H_FILE;
}
for sq in 0..64 {
let pawn: u64 = 1 << sq;
table[sq][1] |= (pawn >> 9) & !H_FILE;
table[sq][1] |= (pawn >> 7) & !A_FILE;
}
return table;
});
// KNIGHT_ATTACK_MAP[<square_index>]
pub static KNIGHT_ATTACK_MAP: Lazy<[u64; 64]> = Lazy::new(|| {
let mut table: [u64; 64] = [0u64; 64];
for sq in 0..64 {
let knight: u64 = 1 << sq;
let far_left_attacks: u64 = knight << 6 | knight >> 10;
let near_left_attacks: u64 = knight << 15 | knight >> 17;
let far_right_attacks: u64 = knight << 10 | knight >> 6;
let near_right_attacks: u64 = knight << 17 | knight >> 15;
table[sq] = (far_left_attacks & !GH_FILE) | (far_right_attacks & !AB_FILE) | (near_left_attacks & !H_FILE) | (near_right_attacks & !A_FILE);
}
return table;
});
// RAY_TABLE[<square_index>][<direction_index>]
pub static RAY_TABLE: Lazy<[[u64; 8]; 64]> = Lazy::new(|| {
let mut table: [[u64; 8]; 64] = [[0u64; 8]; 64];
let dirs: [i8; 8] = [1, 9, 8, 7, -1, -9, -8, -7];
for sq in 0..64 {
for d in 0..8 {
let mut ray: u64 = 0u64;
let origin: u64 = 1 << sq;
let mut new_target: u64 = if dirs[d] > 0 {origin << dirs[d]} else {origin >> -dirs[d]};
if [0, 1, 7].contains(&d) {
new_target &= !A_FILE;
}
else if [3, 4, 5].contains(&d) {
new_target &= !H_FILE;
}
while new_target != 0 {
ray |= new_target;
new_target = if dirs[d] > 0 {new_target << dirs[d]} else {new_target >> -dirs[d]};
if [0, 1, 7].contains(&d) {
new_target &= !A_FILE;
}
else if [3, 4, 5].contains(&d) {
new_target &= !H_FILE;
}
}
table[sq][d] = ray;
}
}
return table;
});
// <----- TESTS ----->
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_king_attack_map() {
// test setup for corners [SW, SE, NW, NE]
let corner_indexes: [usize; 4] = [0, 7, 56, 63];
let corner_attack_maps: [u64; 4] = [
(1u64 << 1) | (1u64 << 8) | (1u64 << 9),
(1u64 << 6) | (1u64 << 14) | (1u64 << 15),
(1u64 << 48) | (1u64 << 49) | (1u64 << 57),
(1u64 << 54) | (1u64 << 55) | (1u64 << 62)
];
// tests for corners
for index in 0..4 {
assert_eq!(KING_ATTACK_MAP[corner_indexes[index]], corner_attack_maps[index]);
}
// test setup for sides [S, E, W, N]
let side_indexes: [usize; 4] = [3, 31, 32, 60];
let side_attack_maps: [u64; 4] = [
(1 << 2) | (1 << 4) | (1 << 10) | (1 << 11) | (1 << 12),
(1 << 22) | (1 << 23) | (1 << 30) | (1 << 38) | (1 << 39),
(1 << 24) | (1 << 25) | (1 << 33) | (1 << 40) | (1 << 41),
(1 << 51) | (1 << 52) | (1 << 53) | (1 << 59) | (1 << 61)
];
// tests for sides
for index in 0..4 {
assert_eq!(KING_ATTACK_MAP[side_indexes[index]], side_attack_maps[index]);
}
// test setup for center
let center_index: usize = 27;
let center_attack_map: u64 = (1 << 18) | (1 << 19) | (1 << 20) | (1 << 26) | (1 << 28) | (1 << 34) | (1 << 35) | (1 << 36);
// test for center
assert_eq!(KING_ATTACK_MAP[center_index], center_attack_map);
}
#[test]
fn test_pawn_attack_map() {
// test setup for white sides
let white_side_indexes: [usize; 2] = [24, 31];
let white_side_attack_maps: [u64; 2] = [
(1 << 33),
(1 << 38)
];
// tests for white sides
for index in 0..2 {
assert_eq!(PAWN_ATTACK_MAP[white_side_indexes[index]][0], white_side_attack_maps[index])
}
// test setup for black sides
let black_side_indexes: [usize; 2] = [32, 39];
let black_side_attack_maps: [u64; 2] = [
(1 << 25),
(1 << 30)
];
// tests for black sides
for index in 0..2 {
assert_eq!(PAWN_ATTACK_MAP[black_side_indexes[index]][1], black_side_attack_maps[index])
}
// test setup for white center
let white_center_indexes: [usize; 2] = [11, 12];
let white_center_attack_maps: [u64; 2] = [
(1 << 18) | (1 << 20),
(1 << 19) | (1 << 21)
];
// tests for white center
for index in 0..2 {
assert_eq!(PAWN_ATTACK_MAP[white_center_indexes[index]][0], white_center_attack_maps[index])
}
// test setup for black center
let black_center_indexes: [usize; 2] = [51, 52];
let black_center_attack_maps: [u64; 2] = [
(1 << 42) | (1 << 44),
(1 << 43) | (1 << 45)
];
// tests for black center
for index in 0..2 {
assert_eq!(PAWN_ATTACK_MAP[black_center_indexes[index]][1], black_center_attack_maps[index])
}
}
#[test]
fn test_knight_attack_map() {
// test setup for corners [SW, SE, NW, NE]
let corner_indexes: [usize; 4] = [0, 7, 56, 63];
let corner_attack_maps: [u64; 4] = [
(1 << 17) | (1 << 10),
(1 << 13) | (1 << 22),
(1 << 41) | (1 << 50),
(1 << 46) | (1 << 53)
];
// tests for corners
for index in 0..4 {
assert_eq!(KNIGHT_ATTACK_MAP[corner_indexes[index]], corner_attack_maps[index]);
}
// test setup for sides [S, E, W, N]
let side_indexes: [usize; 4] = [3, 31, 32, 60];
let side_attack_maps: [u64; 4] = [
(1 << 9) | (1 << 13) | (1 << 18) | (1 << 20),
(1 << 14) | (1 << 21) | (1 << 37) | (1 << 46),
(1 << 17) | (1 << 26) | (1 << 42) | (1 << 49),
(1 << 43) | (1 << 45) | (1 << 50) | (1 << 54)
];
// tests for sides
for index in 0..4 {
assert_eq!(KNIGHT_ATTACK_MAP[side_indexes[index]], side_attack_maps[index]);
}
// test setup for center
let center_index: usize = 27;
let center_attack_map: u64 = (1 << 10) | (1 << 12) | (1 << 17) | (1 << 21) | (1 << 33) | (1 << 37) | (1 << 42) | (1 << 44);
// test for center
assert_eq!(KNIGHT_ATTACK_MAP[center_index], center_attack_map);
}
#[test]
fn test_ray_table() {
// test setup for all directions from center
let starting_square_index: usize = 27;
let ray_masks: [u64; 8] = [
(1 << 28) | (1 << 29) | (1 << 30) | (1 << 31),
(1 << 36) | (1 << 45) | (1 << 54) | (1 << 63),
(1 << 35) | (1 << 43) | (1 << 51) | (1 << 59),
(1 << 34) | (1 << 41) | (1 << 48),
(1 << 26) | (1 << 25) | (1 << 24),
(1 << 18) | (1 << 9) | (1 << 0),
(1 << 19) | (1 << 11) | (1 << 3),
(1 << 20) | (1 << 13) | (1 << 6)
];
// tests for all directions from starting_square
for direction in 0..8 {
assert_eq!(RAY_TABLE[starting_square_index][direction], ray_masks[direction]);
}
}
}

View File

@@ -0,0 +1,99 @@
#[inline(always)]
pub fn pop_lsb(value: &mut u64) -> usize {
let idx = value.trailing_zeros() as usize;
*value &= !(1 << idx);
return idx;
}
#[inline(always)]
pub fn pop_msb(value: &mut u64) -> usize {
let idx = 63 - value.leading_zeros() as usize;
*value &= !(1 << idx);
return idx;
}
const RANK_NUMBERS: [char; 8] = ['1', '2', '3', '4', '5', '6', '7', '8'];
const FILE_LETTERS: [char; 8] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
pub fn notation_from_square_number(sq: u8) -> String {
let row = sq / 8;
let col = sq % 8;
let mut notation = String::new();
let row_not = RANK_NUMBERS[row as usize];
let col_not = FILE_LETTERS[col as usize];
notation.push(col_not);
notation.push(row_not);
return notation;
}
// <----- TESTS ----->
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pop_lsb_test() {
// test setup
let test_values: [u64; 6] = [
0x8000_0000_0000_0000,
0x4E91_CF05_713E_451B,
0xD588_2D58_6962_34B0,
0x9581_3335_DCAB_1DD4,
0xBEAC_DBE0_903A_AC00,
0x01E8_C895_A6F0_0000
];
let expected_values: [usize; 6] = [63, 0, 4, 2, 10, 20];
// tests
for index in 0..6 {
let mut test_value = test_values[index];
assert_eq!(pop_lsb(&mut test_value), expected_values[index])
}
}
#[test]
fn pop_msb_test() {
// test setup
let test_values: [u64; 6] = [
0x86D6_8EB0_96A8_8D1C,
0x0000_0000_0000_0001,
0x3809_24AF_A7AE_8129,
0x0277_DA36_3B31_86D9,
0x0000_C1C3_201C_0DB1,
0x0000_0203_0DE4_E944
];
let expected_values: [usize; 6] = [63, 0, 61, 57, 47, 41];
// tests
for index in 0..6 {
let mut test_value = test_values[index];
assert_eq!(pop_msb(&mut test_value), expected_values[index])
}
}
#[test]
fn notation_from_square_number_test() {
// test setup
let square_indices: [u8; 8] = [1, 12, 22, 27, 32, 47, 53, 58];
let notations: [String; 8] = [
String::from("b1"),
String::from("e2"),
String::from("g3"),
String::from("d4"),
String::from("a5"),
String::from("h6"),
String::from("f7"),
String::from("c8")
];
// tests
for index in 0..8 {
let notation = notation_from_square_number(square_indices[index].clone());
assert_eq!(notation, notations[index]);
}
}
}

View File

@@ -1,3 +1,5 @@
mod bitboard;
fn main() {
println!("Hello, world!");
}

View File

@@ -0,0 +1,4 @@
[target.x86_64-unknown-linux-gnu]
linker = "x86_64-linux-gnu-gcc"
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"

4
ui/.cargo/config.toml Normal file
View File

@@ -0,0 +1,4 @@
[target.x86_64-unknown-linux-gnu]
linker = "x86_64-linux-gnu-gcc"
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"