برنامه نویسی

چگونه من یک مشاور شطرنج برای خودم در CSHARP/WPF نوشتم

این حتی در مورد چیست؟

هدر

این یک داستان دو ماهه در مورد ایجاد یک مشاور شطرنج برای کمک به بازی در Chess.com و Lichess.org است. این یک برنامه کوچک ویندوز است که بر روی CSHARP و WPF نوشته شده است که برای عملکرد آن به ماهی ماهی نیاز دارد. شما باید آن را بارگیری کنید و آن را در هر پوشه قرار دهید. این برنامه برای لذت شخصی در اوقات فراغت من تهیه شده است. استفاده از آن رایگان است و کد منبع در GitHub موجود است. احساس راحتی کنید که از آن استفاده کنید ، آن را تغییر دهید یا ایده ها را در پروژه های خود بگنجانید. اگر می توانستید در این روند به من اعتبار دهید ، قدردانی می کنم. شما می توانید این برنامه را تقلب در نظر بگیرید ، و این تا حدی درست است. اما من می خواهم به جزئیات فنی آن توجه کنم.

چگونه همه چیز آغاز شد

من واقعاً عاشق بازی شطرنج هستم. من دائماً ده دقیقه بازی را در Chess.com انجام می دهم. اما من یک مشکل دارم – یک چشم انداز تونل. من یک حرکت را می بینم و روی آن ثابت می شود. به همین دلیل ، فرصت های زیادی را از دست می دهم و قطعات را نادیده می گیرم. رتبه من هرگز از 1500 بالا نمی رود. اگر فقط من یک مشاور در این نزدیکی داشتم که وقتی من یک اشتباه می کنم ، مرا متوقف می کند …

من مدتهاست که فکر می کردم به دنبال ماهیگیری باشم ، اما تصور می کردم ادغام آن دشوار است. در ماه دسامبر ، مقاله ای در مورد آن خواندم ، که ذکر کرد که از ورودی-خروجی کنسول کاملاً پشتیبانی می کند ، و از ایده ساختن آن دستیار خود هیجان زده شدم.

در شب کریسمس ، ما کار نمی کردیم ، و من شروع به بررسی نحوه ادغام آن با Chess.com کردم. Stockfish را می توان به عنوان یک فرآیند کودک راه اندازی کرد ، می توانید یک موقعیت رمزگذاری شده و تنظیمات (از جمله چقدر زمان فکر کردن) را به کنسول منتقل کنید ، و … پاسخ را بخوانید. اما چگونه موقعیت را بدست آوریم؟

مدتی با دید دستگاه گزینه هایی را در نظر گرفتم. اما در Chess.com ، ده ها گزینه تخته و قطعه در تنظیمات وجود دارد. به علاوه ، اندازه و موقعیت تخته می تواند متفاوت باشد. سپس شروع به فکر کردن در مورد اتصال به مرورگر کردم. اما مرورگرهای زیادی وجود دارد ، به علاوه دردسر خواندن یک فرآیند دیگر … یک افزودنی مرورگر؟ من هیچ تجربه ای برای نوشتن آنها ندارم. راه حل برای من پیش آمد – من مرورگر را در برنامه خود جاسازی می کردم. سپس مشکلی برای خواندن صفحه وب فعلی وجود نخواهد داشت.

نسخه نهایی به این شکل به نظر می رسد-یک برنامه WPF ساده با یک پنجره واحد و یک کنترل وب ، راه اندازی سهام ماهی به عنوان یک فرآیند کودک و تعامل با آن از طریق جریان های ورودی-خروجی کنسول. در پنج دقیقه ، من یک پروژه WPF جدید را در ویژوال استودیو ایجاد می کنم ، به عنوان کنترل اصلی یک وب سایت اضافه می کنم ، صفحه اصلی آن را روی Chess.com قرار می دهم ، آن را راه اندازی می کنم … و خطاهای JavaScript ، هیچ کاری نمی کند.

مرورگر داخلی

کنترل WPF باستانی Webrowser هنوز به کتابخانه های اینترنت اکسپلورر متکی است ، که با صفحات وب مدرن ناسازگار هستند. چیز جدیدتر مورد نیاز است – کروم یا لبه (که همچنین کروم است ، اما با پوسته دیگری). کتابخانه ها برای هر دو گزینه در دسترس است. مرورگر اصلی من Microsoft Edge است ، بنابراین من این مؤلفه را از خود مایکروسافت نصب می کنم – Microsoft.Web.WebView2 ، از طریق NUGET.

تصویر چسبیده 20250302175652

اکنون همه چیز کار می کند. من حتی وارد حساب خود شدم ، برنامه را بستم ، دوباره آن را راه اندازی کردم – و من هنوز وارد حساب خود هستم. بنابراین کوکی ها و جلسات پشتیبانی می شوند. فوق العاده با این حال ، کار با DOM مانند قبل امکان پذیر نخواهد بود. در WebView2 ، شما فقط نمی توانید مانند روزهای خوب قدیمی به htmldocument و dom دسترسی پیدا کنید. جهان تغییر کرده است ، صفحات پویا هستند ، بنابراین ما محتوا را متفاوت مشاهده می کنیم.

const string script = "document.documentElement.outerHTML";
var result = await WebBrowser.CoreWebView2.ExecuteScriptAsync(script);
var decodedHtml = Regex.Unescape(result.Trim('"'));
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این باقی مانده است که بفهمید چگونه تخته و قطعات را از صفحه HTML استخراج کنید.

تابلو شطرنج تجزیه

در اجرای فعلی ، صفحه Chess.com با مجموعه ای از بخش ها رمزگذاری می شود.

class="piece bb square-55" style="">

class="piece square-78 bk" style="">

class="piece square-68 br" style="">

...

class="piece square-61 wk" style="">

class="element-pool" style="">

class="piece wq square-41" style="">

class="element-pool" style="">

حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

کلاس یک قطعه همیشه با “قطعه” شروع می شود ، اولین شخصیت کلاس دو حرف همیشه “W” یا “B” (قطعه سفید یا سیاه) است ، دوم خود قطعه (“r” برای Rook ، “P” برای پیاده ، “q” برای ملکه و غیره) و “Square-Xy” مربع را نشان می دهد. 11 IS A1 ، 88 H8 است. با این حال ، اگر ما به عنوان سیاه بازی کنیم ، می توان تخته را چرخاند. این توسط یک عنصر دیگر ، کمی زودتر تعیین می شود.

 class="board flipped">
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

حضور یک flipped کلاس نشان می دهد که هیئت مدیره روشن شده است. می توانید موقعیت های تمام قطعات را با یک بیان منظم ساده استخراج کنید. معلوم شد که انتقال آنها به ماهی ماهی دشوارتر است.

تعامل ماهی ماهی

من نسخه باینری را بارگیری کردم Stockfish-Windows-X86-64-AVX2.exe از اینجا نیازی به نصب ندارد و می تواند در هر پوشه قرار گیرد. هنگام راه اندازی ، یک پنجره کنسول خالی را مشاهده می کنید.

همیشه گفتگو را با دستور شروع کنید “uci“موتور اطلاعاتی در مورد خود ارائه می دهد و خروجی را با کلمه نشانگر پایان می دهد”ucio“در مرحله بعد ، توصیه می شود تعداد موضوعات را برای بهبود عملکرد (به طور پیش فرض ، از یک موضوع استفاده می شود) با دستور مشخص کنید”Name Name Threads مقدار xxxx“. پس از اتمام تنظیمات ، دستور را ارسال کنید”نام“، که به معنای یک بازی جدید است. سپس ، شما باید موقعیت تجزیه و تحلیل را مشخص کنید ،”موقعیت fen xxxx“، جایی که xxxx موقعیت رمزگذاری شده است. من قالب زیر را توضیح می دهم. و درخواست می کنم آن را با دستور بپذیرید”آماده“. اگر همه چیز نظم داشته باشد ، موتور با” پاسخ می دهد “آماده“سرانجام ، ما باید تجزیه و تحلیل را با دستور شروع کنیم رفتن با پارامترها من استفاده کردم “Go Movetime xxxx“، جایی که xxxx تعداد میلی ثانیه است که برای تفکر داده شده است.

تصویر چسبیده 20250302185139

پس از این ، موتور شروع به ارزیابی گزینه ها (ریختن اطلاعات جالب زیادی در کنسول ، مانند ارزیابی موقعیت فعلی) می کند و با پیام به پایان می رسد “BestMove xxxx“(بهترین حرکتی که یافت شد). این همان چیزی است که من در نوار وضعیت نمایش خواهم داد. سپس جریان و روند کودک می تواند بسته شود. رشته رمزگذاری شده Fen Heck چیست؟

"rnbqkbnr/.../RNBQKBNR w KQkq - 0 1"؟؟؟

یک موقعیت FEN شامل شرح هشت رده است که با برش ها از هم جدا شده اند. به عنوان مثال ، رتبه سوم به این شکل است: “2p2n2”. “2” به معنای اول دو مربع خالی ، سپس یک پیاده سفید (“P” در قسمت بزرگ) ، سپس دوباره دو مربع خالی ، یک شوالیه سفید (“N” در قسمت فوقانی) و سپس دوباره دو مربع خالی. قطعات سیاه به صورت کوچک نوشته شده است.

سپس یک بلوک اطلاعاتی از شش قسمت ارائه می شود. چرا در صورت روشن بودن موقعیت ، به آنها احتیاج دارند؟ در واقع ، اینطور نیست. در موقعیتی که از وسط یک بازی گرفته شده است ، اطلاعات اضافی از دست رفته است. اولین زمینه “حرف“نشان می دهد که نوبت سفید است ، یا”شرح“برای نوبت بلک. سپس ما باید لیست های احتمالی را لیست کنیم (چهار نفر وجود دارد -“kqkq“، دو برای هر طرف) یا”جدید“اگر ریخته گری در دسترس نباشد. به عنوان مثال ، یک پادشاه ممکن است قبل از بازیگری حرکت کند و بعداً به میدان خود بازگردد. این موقعیت” بی گناه “به نظر می رسد ، اما احتمال از بین رفتن پادشاه از بین رفته است. در مرحله بعد ، ما باید نشان دهیم که آیا وجود دارد عبور ضبط ، که همیشه از موقعیت مشخص نیست. میدان پیش فرض ساعت نیمه حرکت است. در صورت عدم وجود حرکات پیاده یا ضبط برای مدت طولانی ، این امر برای تعیین قرعه کشی لازم است. قسمت آخر تعداد حرکات کامل را نشان می دهد (یعنی حرکتی برای سیاه و سفید). صادقانه بگویم ، مشخص نیست که آنها را از کجا تهیه کنید. یک تخته ساده با قطعات چنین اطلاعاتی را ارائه نمی دهد. در نسخه اول ، من همیشه بیان می کنم “– – 0 1“. این به طور کلی نادرست است ، ریخته گری هرگز ارائه نمی شود ، اما برای نسخه اول قابل اعتماد و مناسب است. بعداً ، من این را اصلاح کردم (باز کردن دروازه های جهنم). برای جزئیات بیشتر در مورد فن ، من به توضیحات فن اشاره می کنم.

بنابراین ، ما قطعات را از صفحه خواندیم ، که موقعیت را در Fen رمزگذاری کردیم (در حال حاضر ، فقط خود قطعات ، بدون اطلاعات اضافی) ، آن را به Stockfish منتقل کردند “.BestMove xxxx“، و آن را در نوار وضعیت نمایش داد.

هدر

آیا کار حل شده است؟ شماره

سهام ماهی خیلی خوب بازی می کند

با انجام تنها بهترین حرکات ، من در برابر همه ، از جمله قهرمان جهان پیروز خواهم شد و به طور عادلانه ممنوعیت حساب را دریافت خواهم کرد. این چیزی نیست که من به هیچ وجه نیاز دارم. من به یک مشاور احتیاج دارم که مرا از حرکات احمقانه محافظت کند و پیشنهاد نمی کند که خیلی قوی تر یا ضعیف تر از حریف بازی کند.

مجبور شدم به دستورات UCI بپردازم. در واقع Stockfish تنظیماتی برای تنظیم قدرت بازی (یا در سطح 1-20 یا با رتبه ELO (1320-3190)) دارد ، اما در نسخه فعلی ، یک الگوریتم نسبتاً ساده (در کد منبع به راحتی قابل خواندن است) ، که بعضی اوقات حرکات تصادفی ، پوچ و بی فایده را انتخاب می کند. برای علاقه مندان ، در اینجا آغاز این عملکرد است.

Skill(int skill_level, int uci_elo) {
    if (uci_elo) {
        double e = double(uci_elo - LowestElo) / (HighestElo - LowestElo);
        level = std::clamp((((37.2473 * e - 40.8525) * e + 22.2943) * e - 0.311438), 0.0, 19.0);
    }
    else {
        level = double(skill_level);
    }
    ...
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

برای شروع ، تنظیمات را کشف کردم “NAME NAME NAME MULDV Value n را تنظیم کنید“. این به Stockfish دستور می دهد تا نه تنها بهترین حرکت بلکه در حرکات برتر N ، مرتب شده به ترتیب نزولی را برگرداند. علاوه بر این ، برای هر حرکت ، می توانید آمار WDL (” Win-Draw-Loss “) را برگردانید”نام setoption uci_showwdl مقدار درست است“. این سه عدد است که به عنوان مثال ،” 30-60-10 “به یک صد اضافه می شود ، که به شما امکان می دهد تقریباً احتمال پیروزی یا از دست دادن را محاسبه کنید. آیا باید سه حرکت برتر را برای شروع امتحان کنیم؟

header-github-2

اما ، فقط سه حرکت ممکن باعث خوشحالی من نمی شود.

من می خواهم همه حرکات را ببینم

سه گزینه از استحکام مختلف بهتر از یک است. اما اگر ارزیابی هر حرکت را از قبل می دانیم ، بیایید سطح مورد نظر را در تنظیمات مشخص کنیم ، به عنوان مثال ، “+3.00” (مزیت یک اسقف اضافی) یا “-1.00” (بگذارید حریف یک پیاده اضافی داشته باشد). در عین حال ، بیایید حرکت را در سایه های مختلف – از قرمز تا سبز – رنگ کنیم. و به جای نشان دادن سه حرکت برتر ، بیایید همه آنها را نشان دهیم!

0126-2

برای جلوگیری از آزار و اذیت از حرکات مضحک ، من کتابی از دهانه های مختلف را به یک پرونده .csv واحد (مقدار نسبتاً کمی ، حدود 3000 موقعیت) تهیه کردم. اگر حرکتی در تئوری وجود داشته باشد ، نام آن می تواند نمایش داده شود.

تصویر چسبیده 20250303081904

چرا فقط chess.com؟

در این مرحله ، من روی یکی از سیستم عامل ها لاف زدم. یکی از مفسران ذکر کرد که Chess.com در هنگام بازی با یک ربات گزینه اشاره ای دارد. و جوانب مثبت در lichess.org قرار دارند. چنین گزینه ای در آنجا وجود ندارد. مجبور شدم بفهمم چگونه هیئت مدیره در آنجا کدگذاری شده است.


 class="black rook" style="transform: translate(0px, 0px);">
 class="black bishop" style="transform: translate(174px, 0px);">
 class="black queen" style="transform: translate(174px, 87px);">
 class="black king" style="transform: translate(522px, 0px);">
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

منطق از جهات دیگر یکسان است. می توانید در هر زمان بین سایت ها انتخاب کنید.

0124-8

من به یک مشاور احتیاج دارم ، نه یک ربات شطرنج

به نظر می رسد همه چیز خوب است ، اما به روشی که من قصد داشتم معلوم نشد. من تصمیم گرفتم که خودم حرکات را انجام دهم ، اما به پاسخ سریع در مورد اینکه آیا این حرکت یک اشتباه است و به سادگی از دست دادن نیاز دارم. جستجوی حرکت من در نوارهای چند رنگ خسته کننده است. بنابراین ، من تصمیم گرفتم که حرکات را بر اساس قطعات گروه بندی کنم.

var groups = _moves
    .Values
    .OrderByDescending(move => move.Score)
    .GroupBy(move => move.FirstMove[..2])
    .Select(group => group.ToArray())
    .OrderByDescending(list => list.First().Score)
    .ToArray();
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

تصویر چسبیده 20250303113537

به دنبال یک حرکت از این طریق سریعتر است ، اما طراحی بیش از حد بارگذاری شده است. نمادهای تکرار شونده بسیار زیادی وجود دارد. بنابراین تصمیم گرفتم آنها را دور بیندازم. از این گذشته ، نیمه اول حرکت این قطعه یکسان است.

بنابراین ، ما به رابط فعلی نزدیک شده ایم.

0 1 2-1

حرکاتی که به نمره مورد نیاز نزدیکتر هستند (مانند 5/5 در تصویر) به طور کامل نشان داده می شوند. بقیه توسط میله ها نشان داده می شوند. شما می توانید با انتخاب نمره با استفاده از دکمه ها در سمت راست شاخص ، شدت بازی را تنظیم کنید (حرکات انتخاب شده به صورت پویا تغییر می کند). از طرف دیگر ، می توانید به سادگی روی یک حرکت جالب کلیک کنید و شدت آن بر اساس آن تنظیم می شود.

0 1 2-3

در اینجا تصمیم گرفتیم با تنظیم سطح “-1.50” به آرامی از دست بدهیم. جای تعجب نیست که همه حرکات قرمز است … به جز یک سبز. این به عنوان یک نوار خوش بینانه سبز نشان داده شده است ، اما با معلق کردن مکان نما موش بر روی آن ، می توانید بخوانید که در موقعیت باخت ، ما این فرصت را داریم که در چهار حرکت همسایه را بررسی کنیم.

فقط این است که خواندن روی نوارها حرکت می کند و ترجمه “H5F7” روی صفحه هنوز خسته کننده است. اگر فقط می توان حرکت را مستقیماً روی صفحه انجام داد …

ترسیم یک حرکت

در ابتدا ، من فکر می کردم که قرار دادن یک بوم در مقابل عنصر WebBrowser ، آسان است ، با استفاده از یک عملکرد JS ، جبران صفحه را نسبت به گوشه سمت چپ بالا بگیرید و سپس هر چیزی را روی صفحه بکشید ، خط یا متن آن باشد. اما این کار نکرد. WebView2 از شتاب سخت افزاری و کارگردانی برای ارائه محتوای خود استفاده می کند ، که در هنگام ادغام با سیستم سنتی رندر WPF ، پیچیدگی هایی را ایجاد می کند. من فقط موفق شدم کنترل را با یک پنجره دیگر ، بدون مرز و عنوان ، پوشانده و تمام حرکات پنجره اصلی را ردیابی کنم … کاملاً یک کابوس ، و همه این کار بی ثبات بود.

سپس تصمیم گرفتم عناصر خود را درست مانند Chess.com در صفحه اجرا کنم. یعنی ما یک فلش را به عنوان چند ضلعی ترسیم می کنیم و با استفاده از JS مستقیماً آن را در کد صفحه قرار می دهیم.

var x1 = (src[0] - 'a') * 12.5 + 6.25;
var x2 = (dst[0] - 'a') * 12.5 + 6.25;
var y1 = ('8' - src[1]) * 12.5 + 6.25;
var y2 = ('8' - dst[1]) * 12.5 + 6.25;
if (!isWhite) {
    x1 = 100.0 - x1;
    x2 = 100.0 - x2;
    y1 = 100.0 - y1;
    y2 = 100.0 - y2;
}
var dx = x2 - x1;
var dy = y1 - y2;
var angle = Math.Round(Math.Atan2(dx, dy) * (180.0 / Math.PI), 2);
var length = Math.Round(Math.Sqrt(dx * dx + dy * dy), 2);
const double headRadius = 1.5;
var point1X = x1 + headRadius;
var point2Y = y1 - length + headRadius * 2;
var point3X = x1 + headRadius * 2;
var point4Y = y1 - length;
var point5X = x1 - headRadius * 2;
var point6X = x1 - headRadius;
var points = $"{point1X},{y1} {point1X},{point2Y} {point3X},{point2Y} {x1},{point4Y} {point5X},{point2Y} {point6X},{point2Y} {point6X},{y1}";
var svgElement = $"{points}" style="fill: rgb(255, 255, 0); opacity: 0.7;" />";
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

کاملاً خوب شد.

0 1 2-6

یک اشکال وجود دارد – اگر حریف حرکت کند ، فلش به تنهایی ناپدید نمی شود. مکانیسم لازم است که در صورت بروز تغییراتی در صفحه ، به طور خودکار فلش را از بین می برد. به عنوان مثال ، یک MutationObserver. فلش را اضافه می کنیم ، MutationObserver را فعال می کنیم. این باعث می شود (به عنوان مثال ، اگر ما یا حریف حرکت می کنیم) – فلش برداشته می شود. در حقیقت ، فلش در طول حرکت ناپدید می شود ، زیرا انتخاب یک قطعه با ماوس ، تغییر در DOM است.

window._chessBoardObserver = new MutationObserver(function(mutations){{
  if(window._disableArrowObserver){{
    return;
  }}
  mutations.forEach(function(mutation){{
    if(mutation.type === 'childList' || mutation.type === 'attributes'){{
      removeArrow();
    }}
  }});
}});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

گودال غیر منتظره

با این حال ، آنچه بد است این است که موقعیت فن در قسمت آخر نادرست است ، که من همیشه آن را دارم “KQKQ – 0 1“. هنوز مشخص نیست که آیا وجود دارد عبور پیاده ، خواه حق قلعه از بین رفته باشد ، چه تعداد حرکتی بدون حرکات پیاده انجام شده است … بدون این همه اطلاعات ، سهام ماهی در درصد مشخصی از موقعیت ها تجزیه و تحلیل نادرست را ارائه می دهد. من حتی پیش بینی نکردم که این کار جزئی چقدر پیچیده باشد.

در ابتدا ، من سعی کردم فن موقعیت فعلی را در کد صفحه chess.com پیدا کنم. در واقع می توان با ایجاد یک درخواست وب ، آن را بدست آورد … اما فقط هنگام بازی در برابر ربات. هنگام بازی در برابر یک انسان ، این گزینه در دسترس نیست. به احتمال زیاد ، این عمد است که تجزیه و تحلیل موقعیت را برای برنامه های شخص ثالث دشوار کند.

اما در صفحه ما ، ما سابقه ای از تمام حرکات قبلی داریم. در هر دو سایت ، chess.com و lichess.org است ، اما با فرمت دیگری.

تصویر چسبیده 20250303200854

یعنی از لحاظ نظری ، می توان از موقعیت اولیه شروع کرد و با تکرار همه این حرکات به موقعیت فعلی رسید. اما در این حالت ، ما می دانیم که همه چیزهایی را که برای ساخت فنر واقعی نیاز داریم ، می دانیم: چه پادشاهان یا روک ها حرکت کرده اند ، چه تعداد نیمه حرکات بدون حرکت پیاده ساخته شده است ، چه وجود داشته باشد. عبور پیاده ها …

8 class="">Nf3 class="">Nc6
9 class="">Be2 class="">a6
10 class="">Nbxd4 class="">Bc5
11 class="">c3 class="">O-O
12 class="">Bd3 class="">Ne7
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

به نظر می رسد ساده است – یک آرایه 8×8 را با Chars به ​​عنوان قطعات تنظیم کنید ، نمادها را به اطراف منتقل کنید … اما برای این کار ، باید بدانیم که از کدام مربع قطعه حرکت می کند و به کجا. در San Notation ، مفهوم “از کجا” وجود ندارد. بنابراین ترجمه حرکتی از “BD3” (SAN) به “C1D3” (UCI) با توجه به ابهامات ، یک کار غیر مهم است. این زمانی است که قطعات مختلف می توانند به همان مربع حرکت کنند و شما باید نمادهای اضافی SAN را تجزیه و تحلیل کنید. و سپس ریخته گری ، چک و سایر پیچیدگی ها وجود دارد. متأسفانه ، خود Stockfish نمی تواند SAN را به UCI ترجمه کند. شما یا باید خودتان یک موتور شطرنج بنویسید یا از یک کتابخانه خارجی استفاده کنید.

من یک کتابخانه شطرنج بسیار خوب پیدا کردم – Geras1mleo (60 ستاره در Github به علاوه یکی از من) و شروع به مطالعه کد منبع کردم. در ابتدا ، من می خواستم از آن استفاده کنم ، اما من مشتاق بودم که برخی از موارد را متناسب با نیازهای خود اصلاح کنم. علاوه بر این ، 80 ٪ از کد برای من غیر ضروری بود (چاپ ، تجزیه کردن FEN و PGN ، تبدیل UCI به SAN ، بررسی اعتبار را حرکت می دهد). از طرف دیگر ، هیچ گزینه ای برای تنظیم دستی قطعات وجود نداشت. و من به هر دو گزینه احتیاج دارم – تنظیم موقعیت (اگر تاریخچه حرکت در دسترس نیست ، به عنوان مثال هنگام حل مطالعات) و بازگرداندن FEN از تاریخ حرکت.

بگذارید تکرار کنم ، کتابخانه بسیار عالی است ، و برخی از تفاوت های ظریف FEN پس از مطالعه کد منبع روشن شد. من از کد تا حدی استفاده کردم ، حتی نام برخی از کارکردها را حفظ کردم. با این وجود ، تقریباً به 1000 خط کد و تست های واحد نوشتن منجر شد. با افزودن محاسبه موقعیت دقیق فن در مرورگر ، هفت شب کدگذاری و اشکال زدایی را به خود اختصاص داد.

0 1 2-4

به هر حال ، Fen در نوار وضعیت را می توان با موش برجسته کرد و کپی کرد. به عنوان مثال ، برای تجزیه و تحلیل توسط برخی از برنامه ها.

KQ – 2 12“در اینجا به این معنی است که فقط بازیکن سیاه می تواند هر دو کاستلینگ خود را انجام دهد (” KQ “) ، هیچ وجود ندارد عبور ضبط (“-“) ، دو حرکت نیمه بدون حرکات پیاده ساخته شده است و 12 حرکت کامل از شروع بازی گذشته است. اکنون تجزیه و تحلیل موقعیت سهام ماهی 100 ٪ دقیق است.

رابط واقعی

0 1 1-8-p

پایان

من این کار را کردم (و من آن را به صورت رایگان به اشتراک می گذارم) برای تفریح. من به شما یادآوری می کنم که تقلب ناعادلانه و ناعادلانه نسبت به حریف شما است. از طرف دیگر ، این مشاور به شما امکان می دهد اگر مخالفان در دسته های مختلف وزن باشند ، قدرت بازی را “سطح” کنید. بازی ها جالب می شوند. اگر حریف به عنوان مثال 1800 امتیاز داشته باشد ، تنظیم قدرت در “+0.50” به شما امکان می دهد با امتیاز 1900-2000 بازی کنید. البته این فقط باید با اجازه و تأیید حریف انجام شود. به عنوان مثال برای اهداف آموزشی.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا