Skip to content

Commit

Permalink
ai: Support Focus on blocking paths
Browse files Browse the repository at this point in the history
Prioritize obstructing the opponent's movement over forming mills.
Instead of focusing on removing pieces by completing mills,
the AI aims to trap the opponent, rendering them unable to move
and securing a win through attrition rather than aggressive play.
This strategy does not actively block the opponent's mills.
  • Loading branch information
calcitem committed Jul 2, 2024
1 parent d4c309a commit 81cc73f
Show file tree
Hide file tree
Showing 70 changed files with 384 additions and 67 deletions.
21 changes: 13 additions & 8 deletions src/evaluate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,29 @@ Value Evaluation::value() const

case Phase::placing:
case Phase::moving:
if (gameOptions.getConsiderMobility()) {
if (gameOptions.getConsiderMobility() ||
gameOptions.getFocusOnBlockingPaths()) {
value += pos.get_mobility_diff();
}

pieceInHandDiffCount = pos.piece_in_hand_count(WHITE) -
pos.piece_in_hand_count(BLACK);
value += VALUE_EACH_PIECE_INHAND * pieceInHandDiffCount;
if (gameOptions.getFocusOnBlockingPaths() == false) {
pieceInHandDiffCount = pos.piece_in_hand_count(WHITE) -
pos.piece_in_hand_count(BLACK);
value += VALUE_EACH_PIECE_INHAND * pieceInHandDiffCount;

pieceOnBoardDiffCount = pos.piece_on_board_count(WHITE) -
pos.piece_on_board_count(BLACK);
value += VALUE_EACH_PIECE_ONBOARD * pieceOnBoardDiffCount;
pieceOnBoardDiffCount = pos.piece_on_board_count(WHITE) -
pos.piece_on_board_count(BLACK);
value += VALUE_EACH_PIECE_ONBOARD * pieceOnBoardDiffCount;
}

switch (pos.get_action()) {
case Action::select:
case Action::place:
break;
case Action::remove:
value += VALUE_EACH_PIECE_NEEDREMOVE * pieceToRemoveDiffCount;
if (gameOptions.getFocusOnBlockingPaths() == false) {
value += VALUE_EACH_PIECE_NEEDREMOVE * pieceToRemoveDiffCount;
}
break;
case Action::none:
break;
Expand Down
4 changes: 4 additions & 0 deletions src/movepick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ void MovePicker::score()
}
#endif // !SORT_MOVE_WITHOUT_HUMAN_KNOWLEDGE
}

if (gameOptions.getFocusOnBlockingPaths() == false) {
cur->value = -cur->value;
}
}

/// MovePicker::next_move() is the most important method of the MovePicker
Expand Down
13 changes: 13 additions & 0 deletions src/option.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,18 @@ class GameOptions

bool getConsiderMobility() const noexcept { return considerMobility; }

// focusOnBlockingPaths

void setFocusOnBlockingPaths(bool enabled) noexcept
{
focusOnBlockingPaths = enabled;
}

bool getFocusOnBlockingPaths() const noexcept
{
return focusOnBlockingPaths;
}

// Developer Mode

void setDeveloperMode(bool enabled) noexcept { developerMode = enabled; }
Expand All @@ -281,6 +293,7 @@ class GameOptions
bool openingBook {false};
bool drawOnHumanExperience {true};
bool considerMobility {true};
bool focusOnBlockingPaths {false};
bool developerMode {false};

// TODO: Set this to the correct path
Expand Down
6 changes: 6 additions & 0 deletions src/ucioption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ static void on_considerMobility(const Option &o)
gameOptions.setConsiderMobility(o);
}

static void on_focusOnBlockingPaths(const Option &o)
{
gameOptions.setFocusOnBlockingPaths(o);
}

static void on_developerMode(const Option &o)
{
gameOptions.setDeveloperMode(o);
Expand Down Expand Up @@ -234,6 +239,7 @@ void init(OptionsMap &o)
o["PerfectDatabasePath"] << Option(".", on_perfectDatabasePath);
o["DrawOnHumanExperience"] << Option(true, on_drawOnHumanExperience);
o["ConsiderMobility"] << Option(true, on_considerMobility);
o["FocusOnBlockingPaths"] << Option(true, on_focusOnBlockingPaths);
o["DeveloperMode"] << Option(true, on_developerMode);

// Rules
Expand Down
2 changes: 2 additions & 0 deletions src/ui/flutter_app/lib/game_page/services/engine/engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ class Engine {
generalSettings.drawOnHumanExperience,
);
await _sendOptions("ConsiderMobility", generalSettings.considerMobility);
await _sendOptions(
"FocusOnBlockingPaths", generalSettings.focusOnBlockingPaths);
await _sendOptions("AiIsLazy", generalSettings.aiIsLazy);
await _sendOptions("Shuffling", generalSettings.shufflingEnabled);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class GeneralSettings {
this.usePerfectDatabase = false,
this.drawOnHumanExperience = true,
this.considerMobility = true,
this.focusOnBlockingPaths = false,
@Deprecated(
"We won't export the developer settings anymore. People should use the EnvironmentConfig.devMode")
this.developerMode = false,
Expand Down Expand Up @@ -195,6 +196,9 @@ class GeneralSettings {
@HiveField(27, defaultValue: false)
final bool usePerfectDatabase;

@HiveField(28, defaultValue: false)
final bool focusOnBlockingPaths;

/// Decodes a Json from a [GeneralSettings] object
Map<String, dynamic> toJson() => _$GeneralSettingsToJson(this);
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ class GeneralSettingsPage extends StatelessWidget {
logger.t("$_logTag considerMobility: $value");
}

void _setFocusOnBlockingPaths(GeneralSettings generalSettings, bool value) {
DB().generalSettings =
generalSettings.copyWith(focusOnBlockingPaths: value);

logger.t("$_logTag focusOnBlockingPaths: $value");
}

void _setIsAutoRestart(GeneralSettings generalSettings, bool value) {
DB().generalSettings = generalSettings.copyWith(isAutoRestart: value);

Expand Down Expand Up @@ -335,6 +342,17 @@ class GeneralSettingsPage extends StatelessWidget {
},
titleString: S.of(context).considerMobility,
),
SettingsListTile.switchTile(
value: generalSettings.focusOnBlockingPaths,
onChanged: (bool val) {
_setFocusOnBlockingPaths(generalSettings, val);
if (val == true) {
rootScaffoldMessengerKey.currentState!.showSnackBarClear(
S.of(context).focusOnBlockingPaths_Detail);
}
},
titleString: S.of(context).focusOnBlockingPaths,
),
SettingsListTile.switchTile(
value: generalSettings.aiIsLazy,
onChanged: (bool val) {
Expand Down
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_af.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1535,5 +1535,9 @@
"oneTimeUseMill_Detail": "Elke meul kan slegs een keer 'n teenstander se stuk verwyder. Jy kan dit weer hervorm, maar dit kan nie vir bykomende verwyderings gebruik word nie.",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "Die huidige reëls wat u ingestel het, het nie 'n ooreenstemmende perfekte databasis nie. Vir meer inligting oor die perfekte databasis, klik asseblief hier.",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "Fokus op blokkeer paaie",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "Prioritiseer om die teenstander se beweging te belemmer eerder as om rye van drie te vorm. In plaas daarvan om te fokus op die verwydering van stukke deur rye van drie te voltooi, mik die KI om die teenstander vas te keer, sodat hulle nie kan beweeg nie en 'n oorwinning deur uitputting verseker. Hierdie strategie blokkeer nie aktief die teenstander se rye van drie nie.",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_ar.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1437,5 +1437,9 @@
"oneTimeUseMill_Detail": "يمكن لكل مطحنة إزالة قطعة واحدة فقط من خصمك. يمكنك إعادة تشكيلها مرة أخرى، ولكن لا يمكن استخدامها لعمليات إزالة إضافية.",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "القواعد الحالية التي قمت بتعيينها ليس لها قاعدة بيانات مثالية مقابلة. لمزيد من المعلومات حول قاعدة البيانات المثالية، يرجى النقر هنا.",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "ركز على مسارات الحظر",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "الأولوية لإعاقة حركة الخصم بدلاً من تشكيل طواحين. بدلاً من التركيز على إزالة القطع بإكمال الطواحين، تهدف الذكاء الاصطناعي إلى محاصرة الخصم، مما يجعله غير قادر على التحرك وضمان الفوز من خلال الإنهاك بدلاً من اللعب العدواني. هذه الاستراتيجية لا تعيق طواحين الخصم بنشاط.",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_az.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1535,5 +1535,9 @@
"oneTimeUseMill_Detail": "Hər dəyirman rəqibin bir hissəsini yalnız bir dəfə çıxara bilər. Onu yenidən formalaşdıra bilərsiniz, lakin əlavə çıxarma üçün istifadə edilə bilməz.",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "Təyin etdiyiniz cari qaydalar uyğun mükəmməl verilənlər bazasına malik deyil. Mükəmməl verilənlər bazası haqqında daha çox məlumat üçün bura klikləyin.",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "Bloklama yollarına diqqət yetirin",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "Rəqibin hərəkətini maneə törətməyə üstünlük verin, üçlüyü formalaşdırmaqdan daha çox. Üçlü yaratmaqla parçaları çıxarmağa yönəlmək əvəzinə, AI rəqibi tələyə salmağa çalışır, onları hərəkətsiz vəziyyətə gətirir və aqressiv oyundan çox tükəndirməklə qalib gəlir. Bu strategiya rəqibin üçlü yaratmasına aktiv şəkildə mane olmur.",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_be.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1535,5 +1535,9 @@
"oneTimeUseMill_Detail": "Кожны млын можа выдаліць толькі адну частку суперніка. Вы можаце перафармаваць яго зноў, але яго нельга выкарыстоўваць для дадатковых выдаленняў.",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "Бягучыя правілы, якія вы ўсталявалі, не маюць адпаведнай ідэальнай базы даных. Для атрымання дадатковай інфармацыі аб ідэальнай базе даных націсніце тут.",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "Засяродзіце ўвагу на блакаванні шляхоў",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "Перавага аддаецца перашкодзе руху суперніка, а не фарміраванню тройкі. Замест таго, каб засяродзіцца на выдаленні фігур шляхам завяршэння тройкі, ШІ імкнецца паставіць суперніка ў тупік, не дазваляючы яму рухацца і забяспечваючы перамогу праз стратэгію знясілення, а не агрэсіўную гульню. Гэтая стратэгія не блакуе актыўна тройкі суперніка.",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_bg.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1437,5 +1437,9 @@
"oneTimeUseMill_Detail": "Всяка мелница може да премахне само една част от противника. Можете да го реформирате отново, но не може да се използва за допълнителни премахвания.",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "Настоящите правила, които сте задали, нямат съответна перфектна база данни. За повече информация относно перфектната база данни, моля, кликнете тук.",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "Фокус върху блокиране на пътища",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "Приоритизирайте блокирането на движението на противника вместо формирането на тройки. Вместо да се фокусирате върху премахването на фигури чрез завършване на тройки, AI цели да вкара противника в капан, като го направи неспособен да се движи и да осигури победа чрез изтощение, а не чрез агресивна игра. Тази стратегия не блокира активно тройките на противника.",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_bn.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1437,5 +1437,9 @@
"oneTimeUseMill_Detail": "প্রতিটি মিল একবারই প্রতিদ্বন্দ্বীর একটি অংশ সরিয়ে ফেলতে পারে। আপনি এটি আবার গঠন করতে পারেন, তবে এটি অতিরিক্ত অপসারণের জন্য ব্যবহার করা যাবে না।",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "আপনি যে বর্তমান নিয়মগুলি সেট করেছেন তাদের কোনও উপযুক্ত নিখুঁত ডেটাবেস নেই। নিখুঁত ডেটাবেস সম্পর্কে আরও তথ্যের জন্য, এখানে ক্লিক করুন।",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "পথ আটকে দেওয়ায় মনোনিবেশ করুন",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "মিল তৈরি করার পরিবর্তে প্রতিপক্ষের গতিকে বাধা দেওয়ার উপর অগ্রাধিকার দিন। মিল সম্পূর্ণ করার মাধ্যমে টুকরোগুলি অপসারণের উপর মনোযোগ দেওয়ার পরিবর্তে, AI প্রতিপক্ষকে আটকে রাখার চেষ্টা করে, তাদের অক্ষম করে রাখে এবং আক্রমণাত্মক খেলার পরিবর্তে দীর্ঘমেয়াদী কৌশলে বিজয় নিশ্চিত করে। এই কৌশলটি প্রতিপক্ষের মিলগুলিকে সক্রিয়ভাবে ব্লক করে না।",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_bo.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1535,5 +1535,9 @@
"oneTimeUseMill_Detail": "རེ mill ལ་ཁ་གཏད་རྩེད་འགྲན་པའི་རྡེལ་གཅིག་མ་གཏོགས་བསུབ་མི་ཆོག ཁྱོད་ཀྱིས་ཡང་བསྐྱར་བཟོ་ཐུབ། ཡིན་ནའང་དེ་ལ་បន្ថែམ་བསུབ་ཏུ་བེད་སྤྱོད་མི་ཆོག",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "ཁྱེད་ཀྱིས་གཏན་འབེབས་བྱས་པའི་ད་ལྟའི་ཁྲིམས་ལུགས་ལ་གནས་སྡུད་གཞི་གྲངས་ཡང་དག་པ་ཞིག་མེད། གཞི་གྲངས་མཛོད་ཀྱི་སྐོར་ལ་གནས་ཚུལ་མང་པོ་ཤེས་འདོད་ན། འདིར་སྣུན་རོགས།",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "འགུལ་སྐྱོད་བཀག་འགོག་ལ་དམིགས་འཛུགས་བྱེད་པ།",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "ཁྲོམ་གྲལ་བཟོ་བ་ལས་ཕ་རོལ་པོའི་འགུལ་སྐྱོད་བཀག་འགོག་བྱེད་པར་གཙོ་འདོན་བྱེད་པ། ཁྲོམ་གྲལ་བཟོས་ནས་རྡེའུ་ཕྱིར་འདོན་བྱེད་པར་དམིགས་འཛུགས་བྱེད་པའི་ཚབ་ཏུ། རིག་ནུས་ལྡན་པའི་འཕྲུལ་འཁོར་གྱིས་ཕ་རོལ་པོར་འཛིན་བཟུང་བྱེད་པ་དང་། དེ་ལ་བརྟེན་ནས་ཁོང་ཚོར་འགུལ་སྐྱོད་བྱེད་པའི་ནུས་པ་མེད་པ་བཟོས་ནས་བརྩེ་སེམས་ལྡན་པའི་རྩེད་མོའི་ཐོག་ནས་རྒྱལ་ཁ་ཐོབ་པར་བྱེད། བྱ་ཐབས་འདིས་ཕ་རོལ་པོའི་ཁྲོམ་གྲལ་བཀག་འགོག་བྱེད་པར་ཐད་ཀར་མི་དམིགས།",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_bs.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1437,5 +1437,9 @@
"oneTimeUseMill_Detail": "Svaki mlin može ukloniti samo jedan protivnički dio. Možete ga ponovno formirati, ali se ne može koristiti za dodatna uklanjanja.",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "Trenutna pravila koja ste postavili nemaju odgovarajuću savršenu bazu podataka. Za više informacija o savršenoj bazi podataka kliknite ovdje.",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "Fokusirajte se na blokiranje puteva",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "Prioritet dajte ometanju kretanja protivnika umjesto formiranja tri u nizu. Umjesto da se fokusira na uklanjanje figura dovršavanjem tri u nizu, AI nastoji da uhvati protivnika u zamku, onemogućavajući mu kretanje i osiguravajući pobjedu kroz iscrpljivanje umjesto agresivne igre. Ova strategija ne blokira aktivno protivničke tri u nizu.",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_cs.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1437,5 +1437,9 @@
"oneTimeUseMill_Detail": "Každý mlýn může odstranit pouze jeden kus soupeře. Můžete jej znovu sestavit, ale nelze jej použít pro další odstranění.",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "Aktuální pravidla, která jste nastavili, nemají odpovídající dokonalou databázi. Pro více informací o dokonalé databázi klikněte zde.",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "Zaměřte se na blokování cest",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "Prioritizujte bránění pohybu soupeře před tvořením mlýnů. Místo zaměření se na odstraňování figurek dokončováním mlýnů, AI se snaží chytit soupeře do pasti, znemožnit mu pohyb a zajistit vítězství opotřebováním místo agresivní hry. Tato strategie aktivně neblokuje soupeřovy mlýny.",
"@focusOnBlockingPaths_Detail": {}
}
6 changes: 5 additions & 1 deletion src/ui/flutter_app/lib/l10n/intl_da.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1437,5 +1437,9 @@
"oneTimeUseMill_Detail": "Hver mølle kan kun fjerne en modstanders brik én gang. Du kan gendanne den igen, men den kan ikke bruges til yderligere fjernelser.",
"@oneTimeUseMill_Detail": {},
"currentRulesNoPerfectDatabase": "De nuværende regler, du har indstillet, har ikke en tilsvarende perfekt database. For mere information om den perfekte database, klik her.",
"@currentRulesNoPerfectDatabase": {}
"@currentRulesNoPerfectDatabase": {},
"focusOnBlockingPaths": "Fokuser på at blokere veje",
"@focusOnBlockingPaths": {},
"focusOnBlockingPaths_Detail": "Prioriter at hindre modstanderens bevægelser over at danne møller. I stedet for at fokusere på at fjerne brikker ved at fuldføre møller, sigter AI på at fange modstanderen, så de ikke kan bevæge sig og sikre en sejr gennem udmattelse snarere end aggressivt spil. Denne strategi blokerer ikke aktivt modstanderens møller.",
"@focusOnBlockingPaths_Detail": {}
}
Loading

0 comments on commit 81cc73f

Please sign in to comment.