Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ add_library(ironphoenix_core STATIC
src/tt.cpp
src/eval.cpp
src/nnue.cpp
src/tuning.cpp
src/search.cpp
src/multipv.cpp
src/fen.cpp
Expand All @@ -33,6 +34,7 @@ add_library(ironphoenix_core STATIC
include/ironphoenix/eval.hpp
include/ironphoenix/lmr.hpp
include/ironphoenix/nnue.hpp
include/ironphoenix/tuning.hpp
)

add_library(IronPhoenix::Core ALIAS ironphoenix_core)
Expand Down
156 changes: 156 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# 🔥 IronPhoenix Code of Conduct

## 🛡️ Our Commitment

IronPhoenix is an open-source project focused on building and improving a high-performance four-player chess engine.

We want the project to be a place where people can collaborate, experiment, learn, review code, test ideas, and disagree constructively. Everyone participating in the IronPhoenix community is expected to help maintain a respectful, technical, and welcoming environment.

This Code of Conduct applies to contributors, maintainers, reviewers, testers, users, and anyone participating in project spaces.

---

## 🤝 Expected Behavior

Participants are expected to:

- Communicate respectfully and professionally.
- Critique ideas, code, benchmarks, and technical decisions rather than attacking people.
- Support technical claims with testing, measurements, examples, or reasoning when practical.
- Give constructive code-review feedback that helps improve the project.
- Be patient with contributors of different experience levels.
- Ask questions when requirements, rules, benchmarks, or engine behavior are unclear.
- Respect the complexity of four-player chess and recognize that reasonable technical approaches may differ.
- Keep discussions focused on the project when using project issue trackers, pull requests, discussions, and other development channels.
- Respect private information, credentials, unpublished work, and security-sensitive information.
- Give appropriate credit for code, research, testing, ideas, and other contributions.

---

## 🚫 Unacceptable Behavior

The following behavior is not acceptable:

- Harassment, threats, intimidation, stalking, or targeted abuse.
- Discrimination or derogatory comments based on personal characteristics or identity.
- Personal insults, name-calling, humiliation, or repeated hostile behavior.
- Sexual harassment or unwanted sexual attention.
- Publishing another person's private information without permission.
- Deliberately disrupting project discussions, reviews, testing, or development.
- Spamming issues, pull requests, discussions, or other project channels.
- Knowingly submitting malicious code, credential stealers, destructive payloads, or other harmful content.
- Misrepresenting benchmark results, test results, authorship, or contribution history.
- Plagiarizing code or knowingly violating software licenses.
- Using the project community to organize harassment or abuse elsewhere.

Strong disagreement about engine design, pruning techniques, evaluation, move ordering, architecture, benchmarks, or performance is allowed. Personal attacks are not.

---

## 🧪 Technical Discussions and Engine Testing

IronPhoenix development depends heavily on experimentation and strength testing.

When discussing engine changes:

- Treat Elo estimates, SPRT results, NPS, node counts, depth, and benchmark results as evidence rather than personal status.
- Clearly distinguish measured results from predictions or speculation.
- Prefer isolated testing when evaluating search heuristics or evaluation terms.
- Negative test results are useful information and should not be mocked or hidden.
- Reproducible tests are encouraged whenever practical.
- Do not knowingly falsify, selectively alter, or misrepresent testing data.
- Respect existing project behavior and comments when modifying established engine code unless the change intentionally replaces them.

A failed experiment is not a failed contribution. Good testing that shows an idea loses strength can still help the project.

---

## 🧑‍💻 Pull Requests and Code Review

When opening or reviewing a pull request:

- Keep the change focused when possible.
- Explain what the change is intended to accomplish.
- Include relevant testing information when available.
- Avoid unrelated rewrites in a feature-specific pull request.
- Review the implementation, not the contributor.
- Be willing to revise code when review identifies correctness, performance, maintainability, or testing concerns.
- Do not pressure maintainers to merge an experimental change before it has received appropriate review or testing.

Maintainers may request that experimental engine-strength changes remain on separate branches until testing is complete.

---

## 🌐 Scope

This Code of Conduct applies in official IronPhoenix project spaces, including:

- GitHub repositories
- Issues
- Pull requests
- Discussions
- Testing and benchmarking channels
- Project documentation
- Other communication spaces officially used for IronPhoenix development

It may also apply when someone is publicly representing the IronPhoenix project.

---

## 🚨 Reporting a Problem

If you experience or witness behavior that violates this Code of Conduct, report it to the IronPhoenix repository owner or project maintainers through an appropriate private GitHub contact method when possible.

Please include relevant information such as:

- What happened
- Where it happened
- When it happened
- Links, screenshots, or other evidence when available
- Any additional context that may help the maintainers understand the situation

Reports will be reviewed as fairly and confidentially as practical.

Do not knowingly submit false or retaliatory reports.

---

## ⚖️ Enforcement

Project maintainers are responsible for interpreting and enforcing this Code of Conduct.

Depending on the severity and history of the behavior, maintainers may take actions including:

1. **Correction** — A private or public request to change inappropriate behavior.
2. **Warning** — A formal warning that continued behavior may result in further action.
3. **Temporary restriction** — Temporary limits on participation in issues, pull requests, discussions, or other project spaces.
4. **Permanent ban** — Permanent removal from participation in IronPhoenix project spaces.

Severe behavior may result in immediate restriction or removal without first using every intermediate step.

Enforcement decisions should be based on protecting the project community and maintaining a productive development environment.

---

## 🧭 Maintainer Responsibilities

Maintainers are expected to:

- Apply this Code of Conduct consistently and in good faith.
- Avoid using enforcement as retaliation for technical disagreement.
- Distinguish heated technical debate from harassment or abuse.
- Protect confidential reports where practical.
- Remove, edit, or reject comments, commits, code, issues, or contributions that violate this Code of Conduct.
- Prioritize the safety and long-term health of the project community.

---

## 🔥 Project Values

IronPhoenix values:

**Performance. Correctness. Experimentation. Reproducibility. Respect.**

We can disagree aggressively about algorithms while still treating each other well.

♟️ **Build strong code. Test it honestly. Help the engine improve.**
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ IronPhoenix includes a modern alpha-beta search stack designed specifically for

- Negamax / PVS-style search
- Quiescence search
- Aspiration Windows
- Transposition tables
- History-based move ordering
- Static Exchange Evaluation (SEE)
- Late Move Reductions (LMR)
- Late Move Pruning (LMP)
- Search pruning and reductions
- Iterative deepening
- Principal variation reporting
Expand Down
7 changes: 4 additions & 3 deletions include/ironphoenix/eval.hpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
#pragma once

#include "tuning.hpp"

namespace ironphoenix {

class Position;

namespace Eval {

struct Parameters final {

};
using Parameters = Tuning::EvalParameters;

[[nodiscard]] Parameters& parameters() noexcept;
[[nodiscard]] int evaluate(const Position& pos) noexcept;

}
Expand Down
5 changes: 4 additions & 1 deletion include/ironphoenix/lmr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ namespace ironphoenix {
std::array<std::array<std::uint8_t, LMR_MAX_MOVES + 1>,
LMR_MAX_DEPTH + 1>;

extern const LmrReductionTable lmrReduction;
// The table is rebuilt whenever an LMR tuning parameter changes.
extern LmrReductionTable lmrReduction;

void rebuildLmrReductionTable() noexcept;

inline int lmrBaseReduction(int depth, int moveCount) noexcept {
if (depth <= 0 || moveCount <= 0)
Expand Down
57 changes: 57 additions & 0 deletions include/ironphoenix/tuning.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include <iosfwd>
#include <string_view>

namespace ironphoenix {

class SearchEngine;

namespace Tuning {

struct SearchParameters final {
int aspirationStartDepth = 4;
int aspirationInitialDelta = 50;
int seePruneMaxDepth = 4;
int seePruneMarginPerDepth = 80;
int historyBonusScale = 64;
int historyBonusMax = 2048;
int counterMoveBonus = 32'000;
int checkMoveBonus = 10'000'000;
int lmrMinDepth = 3;
int lmrFullMoves = 3;
int lmrBaseX100 = 75;
int lmrDivisorX100 = 275;
};

struct EvalParameters final {
int pawnValue = 100;
int knightValue = 300;
int bishopValue = 400;
int rookValue = 500;
int queenValue = 1000;
int knightMobility = 4;
int bishopMobility = 4;
int rookMobility = 2;
int queenMobility = 1;
};

[[nodiscard]] SearchParameters& search() noexcept;
[[nodiscard]] EvalParameters& eval() noexcept;

void resetSearch() noexcept;
void resetEval() noexcept;
void resetAll() noexcept;

[[nodiscard]] bool setSearchParameter(std::string_view name, int value) noexcept;
[[nodiscard]] bool setEvalParameter(std::string_view name, int value) noexcept;

// UCI integration helpers. handleSetOption returns true when the option
// belongs to the tuning system, including recognized-but-invalid input.
[[nodiscard]] bool handleSetOption(std::string_view args, SearchEngine& searchEngine, std::ostream& out);
void printUciOptions(std::ostream& out);
void printCurrent(std::ostream& out);

} // namespace Tuning

} // namespace ironphoenix
2 changes: 2 additions & 0 deletions include/ironphoenix/uci.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ namespace ironphoenix {
Position pos_{};
Fen4State fenState_{};
std::string startFen_;
std::string nnueFile_ = "ironphoenix.nnue";
SetupType setup_ = SetupType::Modern;
int multiPV_ = 1;
bool useNNUE_ = false;
SearchEngine search_{};

bool handleLine(const std::string& line, std::ostream& out);
Expand Down
40 changes: 30 additions & 10 deletions src/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,36 @@
#include "ironphoenix/geometry.hpp"
#include "ironphoenix/nnue.hpp"
#include "ironphoenix/position.hpp"

#include <array>
#include "ironphoenix/tuning.hpp"

namespace ironphoenix::Eval {

namespace {

constexpr std::array<int, PIECE_TYPE_NB> EVAL_VALUE = {
0, 100, 300, 400, 500, 1000, 0
};
IRONPHOENIX_FORCE_INLINE int evalValue(PieceType pt) noexcept {
const auto& params = Tuning::eval();

constexpr std::array<int, PIECE_TYPE_NB> MOBILITY_WEIGHT = {
0, 0, 4, 4, 2, 1, 0
};
switch (pt) {
case PAWN: return params.pawnValue;
case KNIGHT: return params.knightValue;
case BISHOP: return params.bishopValue;
case ROOK: return params.rookValue;
case QUEEN: return params.queenValue;
default: return 0;
}
}

IRONPHOENIX_FORCE_INLINE int mobilityWeight(PieceType pt) noexcept {
const auto& params = Tuning::eval();

switch (pt) {
case KNIGHT: return params.knightMobility;
case BISHOP: return params.bishopMobility;
case ROOK: return params.rookMobility;
case QUEEN: return params.queenMobility;
default: return 0;
}
}

IRONPHOENIX_FORCE_INLINE Bitboard teamOccupancy(const Position& pos, Color c) noexcept {
const Color partner = static_cast<Color>(static_cast<unsigned>(c) ^ 2u);
Expand All @@ -28,7 +44,7 @@ namespace ironphoenix::Eval {

for (unsigned pt = PAWN; pt <= QUEEN; ++pt) {
material += pos.pieces(c, static_cast<PieceType>(pt)).popcount()
* EVAL_VALUE[pt];
* evalValue(static_cast<PieceType>(pt));
}

return material;
Expand Down Expand Up @@ -65,7 +81,7 @@ namespace ironphoenix::Eval {
}

const int mobility = (attacks & ~blockedByTeam).popcount();
score += mobility * MOBILITY_WEIGHT[static_cast<unsigned>(pt)];
score += mobility * mobilityWeight(pt);
}
};

Expand Down Expand Up @@ -102,6 +118,10 @@ namespace ironphoenix::Eval {

}

Parameters& parameters() noexcept {
return Tuning::eval();
}

int evaluate(const Position& pos) noexcept {
if (NNUE::loaded())
return NNUE::evaluate(pos);
Expand Down
Loading
Loading