-
شما باید کد هوش مصنوعی خود را در تابع turn که در فایل AI.java (در تمامی کلاینتها فایلی با همین اسم قرار دارد)، پیادهسازی کنید.
-
شما میتوانید کد کلاینت داده شده را تغییر دهید، به آن فایل اضافه کنید یا از آن فایل حذف کنید، به شرط آنکه تغییرات داده شده در کامپایل و اجرای کلاینت و ارتباط آن با سرور اختلالی ایجاد نکند. در مورد هر کلاینت نکاتی ذکر شده که به آنها نیز باید توجه شود. همچنین باید تغییرات احتمالی فایلهای دیگر کلاینت، یعنی فایلهایی غیر از فایلی که در آن کد میزنید) را در نظر بگیرید.
-
شما میتوانید برای به روز بودن کلاینتها یا سرور خود به آخرین نسخه منتشر شده در repository مسابقه مراجعه کنید.
-
نکتهی قابل توجه در مورد کلاینت، این است که برای هر کدام از نیروها، چه مورچهها و چه عقربها، یک بار به طور جداگانه کد کلاینت اجرا میشود. در نتیجه نیروها حافظهی مشترکی با یکدیگر ندارند و تنها راه ارتباطی آنها از طریق چت باکس میباشد (توضیحات چتباکس را در مستند بازی بخوانید).
کلاینتهای جاوا، برای اجرا توسط سرور، باید به فایل jar تبدیل شوند. برای ساخت فایل jar کلاینت جاوا، باید از Intellij استفاده کنید. در Intellij، از مسیر زیر میتوانید فایل jar رابسازید.
File --> Project Structure --> Project Settings --> Artifacts --> green plus sign --> Jar --> From modules with dependencies
هر بار که تغییری در کد کلاینت داده شد، برای اجرا باید یک فایل jar تازه ساختهشود. مراحل ساخت فایل jar و اطلاعات بیشتر را در داکیومنتیشن Intellij و همچنین این پست در Stack Overflow نیز میتوانید مشاهده کنید.
برای ارسال کد کلاینت جاوا، ابتدا آن را مطابق آموزش بالا تبدیل به jar کنید، سپس فایل jar را zip کرده و از قسمت ارسال کد بفرستید.
برای اجرای کلاینتهای پایتون، باید کدها و تمامی dependency ها در یک پکیج تجمیع شود (Binary). این کار با ابزار Pyinstaller به راحتی امکانپذیر است. برای نصب این پکیج، میتوانید از دستور pip install pyinstaller استفاده کنید. اگر pip را نصب ندارید، طریقهی نصب آن روی سیستمعاملهای مختلف، از لینکهای زیر مشاهده کنید:
پس از نصب pip و سپس pyinstaller، باید کد زیر را با آدرس درست Controller.py اجرا کنید.
pyinstaller --onefile /path/to/Controller.py
پس از آن، دو فولدر dist و build و یک فایل Controller.spec در محل کامند، ساخته خواهد شد. شما باید آدرس dist/Controller را که یک فایل باینری قابل اجراست، به سرور بدهید.
دقت کنید که پس از هر بار تغییر در کد، پوشه های build و dist را پاک کنید و مجددا با PyInstaller بیلد بگیرید.
در کلاینت پایتون، شما میتوانید از کتابخانههای زیر استفاده کنید:
numpy==1.20.2
pandas==1.2.3
scikit-learn==0.24.1
scipy==1.6.2
torch==1.8.1+cpu
توجه کنید که اگر کتابخانهی دیگیری را استفاده کرده باشید، بازی شما دچار مشکل میشود.
برای ارسال کد پایتون خود، دایرکتوری پروژه را zip کنید و در قسمت ارسال کد آپلود کنید. به صورتی که زمانی که وارد پوشهی آنزیپ شده میشویم، فایل Controller.py در آنجا باشد.
برای دریافت و اجرای کلاینت، دستورات زیر را اجرا کنید.
cd path/to/working/directory
git clone --depth=1 https://github.com/SharifAIChallenge/AIC21-Client-Cpp
cd AIC21-Client-Cpp
mkdir build
cd build
cmake ..
make
بعد از هر تغییر در فایلها، فقط باید دستور make را بزنید. اگر یک فایل جدید به پروژه اضافه یا فایلی را از پروژه حذف کردید، ابتدا دستور cmake ..
و سپس دستور make
را اجرا کنید.
برای ارسال کد، کل پوشهی پروژهی خود را zip و از قسمت ارسال کد، آپلود کنید.
برای اجرای بیلد کردن کلاینت روی سیستمعامل ویندوز، باید از ابزار cygwin استفاده کنید. برای نصب cygwin و راهاندازی کلاینت، میتوانید مطابق راهنمای ذکر شده در فایل README.md در ریپو کلاینت سیپلاسپلاس پیش روید. مراحل به طور کامل و با تصویر توضیح داده شدهاند.
برای اجرای سرور، بهتر از java 11 به بالا استفاده کنید.
ابتدا آخرین نسخه ریلیز سرور را از اینجا دانلود کنید (فایل server.jar).
فایل map.config را از ریپوی گیم دریافت کنید د در کنار سرور قرار دهید.
سپس سرور را به این شکل اجرا کنید:
java -jar server.jar --first-team=/path/to/first/client --second-team=/path/to/second/client --read-map=/path/to/map/json/file
برای تولید این دستور، میتوانید از gui.py ای که در کنار سرور در ریپوی بازی قرار دادهشدهاست نیز استفاده کنید. نحوهی استفاده از آن را در این بخش میتوانید مشاهده کنید.
در بالا دو آرگومان اول محل قرار گیری فایل کلاینت برای تیم اول و تیم دوم را مشخص می کنند. این فایل برای کلاینت جاوا همان فایل jar تولید شده است ، برای کلاینت پایتون خروجی باینری و برای کلاینت cpp همان خروجی حاصل از بیلد گرفتن کلاینت است.
برای اجرای سرور به دو فایل کانفیگ نیاز است. فایل map.config باید با همین نام با سرور در یک پوشه باشد. فایل map.json برای خواندن اطلاعات جزئی نقشه است. درصورتی که مقدار متغیر READ_MAP_FROM_FILE در فایل map.config برابر false باشد، سرور اقدام به تولید نقشه تصادفی می کند. اگر این متغیر true باشد، سرور ابتدا در پوشه فعلی دنبال فایل دوم یعنی map.json می گردد. اگر این فایل وجود نداشت باید با آرگومان —read-map این فایل به سرور داده شود. همانند مثال
برای توضیحات بیشتر به ریپازیتوری سرور مراجعه کنید.
دقت کنید که اگر فایل کلاینت یا مپ شما در پوشه سرور قرار دارد (مثلا نام آن client است) از ./ در ابتدای آن استفاده کنید:
--first-team=./client
به طور پیشفرض، اسم تیمها، first_team و second_team در نظر گرفته میشود. برای تنظیم اسم تیمها، میتوانید از آپشنهای زیر استفاده کنید. توجه کنید که این نامها در گرافیک نمایش داده میشوند.
--first-team-name=holoo
--second-team-name=bepar_too_galoo
برای نمایش لاگ بیشتر از سرور جهت دیباگ کردن (و همچنین نمایش خروجی کلاینت ها در لاگ سرور) از آرگومان --show-log
نیز میتوانید استفاده کنید.
مثال:
java -jar server.jar --first-team=/path/to/first/client --second-team=/path/to/second/client --show-log
با استفاده از آرگومان --max-agent
می توانید یک کران بالا برای تعداد نیرو های ساخته شد (instance های اجرایی از کلاینت) تعیین کنید تا سیستم شما دچار مشکل در اجرا نشود (پیشنهاد ما حداکثر ۵۰ است)
مثال:
java -jar server.jar --first-team=/path/to/first/client --second-team=/path/to/second/client --max-agent=20
این مقدار به طور پیش فرض 200 در نظر گرفته می شود.
در صورت تمایل به اجرای کلاینت ها بصورت دستی، می توانید از آرگومان --run-manually
استفاده کنید. در این صورت هر موقع سرور منتظر وصل شدن کلاینت جدید ماند، باید یک instance از کلاینت خود را دستی اجرا کنید. در این صورت می توانید به طور کامل لاگ کلاینت را در کنسول مشاهده کنید. (در این صورت توصیه می شود از اعداد کوچک برای inital_ant_num
در map.config
استفاده کنید.)
-
برای تست کردن کد، با تعداد کم نیرو این روش بسیار مفید خواهد بود. ضمن این که برای اجرا در این روش نیازی به خروجی گرفتن از کلاینت نیست.
-
دقت کنید که هرموقع نیاز به کلاینت جدید بود، سرور در خروجی ای رشته را چاپ می کند:
Run a new instance of your client, waiting...
با استفاده از این برنامه، میتوانید به صورت گرافیکی فایل سرور و کلاینتها و مپ را بدهید، و دستور لازم برای اجرای سرور با آن کلاینتها و مپ را دریافت کنید.
برای اجرا، نیاز به پکیج PySimpleGUI دارید. این پکیج را میتوانید با دستورهای زیر برای پایتون ۲ و پایتون ۳ نصب کنید.
pip install PySimpleGUI
pip3 install PySimpleGUI
بعد از نصب این پکیج، میتوانید با دستور python gui.py
برنامه را اجرا کنید.
در هر مرحله با ایمپورت کردن مورد خواسته شده، در نهایت کامند مورد نیاز نمایش داده میشود.
در کلاینتها، زمین بازی و خانههای آن (Cell) طبق مختصات زیر مقداردهی می شوند:
- خانهی بالا چپ زمین مختصات (0,0) دارد.
- مقدار x برای هر خانه، شماره ستون آن (از چپ) است.
- مقدار y برای هر خانه، شماره سطر آن (از بالا) است.
در مورد کلاینتها نکات زیر قابل توجه هستند:
- در بین دستوراتی که از کلاینتها به سرور فرستاده میشود، در صورت نامعتبر بودن یک دستور، این دستور نادیده گرفته میشود.
- رفرنس شی World و شیهای درونی آن در هر نوبت از ابتدا ساخته میشود رفرنسهای نوبت قبل در نوبت فعلی معتبر نیستند.
- نام توابع و کلاسها در تمامی کلاینتها (سیپیپی، پایتون و جاوا) یکسان است.
-
اطلاعات نقشه بازی در یک فایل به نام
map.config
در کنار سرور بازی باید قرار بگیرد که نمونه ی آن را در ریپو سرور می توانید پیدا کنید. -
خروجی گرافیکی سرور پس از پایان یک بازی در یک فایل به نام
log.json
در کنار سرور قابل دسترسی است. -
در هنگام اجرای سرور حتما به درست وارد کردن آدرس کلاینت های بازی دقت کنید!
-
برای مطمین شدن از این که سرور کار خود را با موفقیت به پایان رسانده است، در خروجی باید winner مشخص شده باشد. (نه لزوما خط آخر)
این کلاس فقط تابع زیر را دارا میباشد:
Answer turn(World)
این تابع در هر نوبت بازی صدا زده می شود. هر نیرو در آن نوبت یک شی Answer تولید میکند که از جهت حرکت نیرو و پیام (در صورت ارسال پیام) و ارزش آن تشکیل شده است.
اطلاعات عمومی بازی را از طریق توابع گفته شده در زیر در اختیار ایجنت قرار میدهد. اطلاعات انحصاری هر ایجنت از طریق آبجکت Ant در دسترس خواهد بود. Ant getAnt()
اطلاعات انحصاری آن نیرو را برمیگرداند. برای اطلاعات بیشتر راجع به اطلاعت انحصاری ایجنت، توابع کلاس Ant را مطالعه کنید.
AntType getAntType()
نوع نیرو فعلی را برمی گرداند که یکی از دو حالت SARBAAZ
و یا KARGAR
است.
ChatBox getChatBox()
اطلاعات چت باکس تیم نیرو فعلی را بر میگرداند. چت باکس لیستی از چت ها را در بر دارد که هر چت نیز خود شامل محتوای متنی چت و شماره نوبتی است که چت در آن ارسال شده است.
int getMapWidth()
عرض زمین بازی را برمی گرداند.
int getMapHeight()
ارتفاع زمین بازی را برمی گرداند.
int getBaseX()
مختصات X پایگاه تیم نیرو فعلی را بر می گرداند.
int getBaseY()
مختصات Y پایگاه تیم نیرو فعلی را بر می گرداند.
int getHealthKargar()
مقدار جان اولیه کارگر را بر می گرداند.
int getHealthSarbaaz()
مقدار جان اولیه نیرو های سرباز را بر می گرداند.
int getAttackDistance()
فاصله منهتنی برای حمله نیرو سرباز را برمی گرداند.
int getGenerateKargar()
مقدار منبع مورد نیاز برای تولید کارگر را برمی گرداند.
int getGenerateSarbaaz()
مقدار منبع مورد نیاز برای تولید سرباز را برمی گرداند.
int getRateDeathResource()
مقدار پارامتر rate_death_resource را برمی گرداند.
این آبجکت اطلاعات انحصاری هر ایجنت را در بر دارد. برای دسترسی به این اطلاعات از توابع زیر میتوانید استفاده کنید:
Map getVisibleMap()
این تابع نقشه قابل مشاهده ایجنت را برمیگرداند که با استفاده از تابع getRelativeCell آن میتوان به خانه مورد نظر دسترسی پیدا کرد. همانطور که از اسم تابع مشخص است، ورودی های آن مختصات نسبی (نسبت به ایجنت) خانهای میباشد که میخواهیم به آن دسترسی داشته باشیم.
int getXCoordinate()
مختصات X خانه فعلی نیرو را بر می گرداند.
int getYCoordinate()
مختصات Y خانه فعلی نیرو را بر می گرداند.
AntType getType()
نوع نیرو فعلی را بر می گرداند
AntTeam getTeam()
تیم نیرو را بر می گرداند. (شی Ant برای نیرو های خانه های همسایه نیز قابل استفاده است).
ALLIED → هم تیمی نیرو فعلی
ENEMY → تیم مقابل نیرو فعلی
Resource getCurrentResource()
مقدار و نوع منبعی که نیرو فعلی حمل می کند را بر می گرداند.
int getHealth()
میزان جان مورجه فعلی را بر می گرداند.
getAttackDistance()
مقدار پارامتر attack_distance را برای نیرو فعلی برمیگرداند.
getViewDistance()
مقدار پارامتر
view_distance
را برای نیرو فعلی بر می گرداند.
getAttacks()
لیستی از حمله ها را خروجی میدهد که هر حمله شامل اطلاعاتی چون محل حملهکننده (شماره سطر و ستون) و همینطور مکان مورچهی مورد حمله قرار گرفته (شماره سطر و ستون) و اینکه آیا حمله از طرف نیروهای خودی بوده است یا خیر میباشد.
در صورتی که در اجرای سرور به مشکلی بر خوردید، از طریق سایت، یک تیکت در قالب زیر برای ما ارسال کنید:
-
.شرح مشکل پیش آمده
-
کدی که در بخش AI برای کلاینت خود زدید بعلاوه نوع کلاینتی که استفاده می کنید.
-
لاگ خروجی سرور پس از اجرا که در آدرس
Log/server/server.log
در کنار سرور قرار میگیرد ( برای خروجی مفصل تر، سرور را با--show-log
اجرا کنید سپس این فایل را بفرستید). -
فایل
map.config
استفاده شده. -
کامندی که با آن سرور را اجرا میکنید (با آرگومانها).
در صورتی که در اجرا و کارکردن با هر یک کلاینت ها به مشکل برخوردید، از طریق سایت، یک تیکت در قالب زیر ارسال کنید:
-
شرح مشکل پیش آمده.
-
نوع کلاینتی که استفاده میکنید (پایتون، جاوا یا سیپیپی).
-
کد کامل کلاینت به صورت فشرده (zip)
تماشای بازیها به صورت گرافیکی نیز امکانپذیر است. بعد از اجرای سرور که پیشتر مراحل آن توضیح داده شد، میتوانید با اجرای رابط گرافیکی بازی و ایمپورت کردن فایل log.json که سرور بعد از اجرای بازی آنرا تولید میکند، اتفاقات بازی را به صورت گرافیکی مشاهده کنید.
پس از unzip کردن فایل گرافیک با توجه به سیستمعاملتان، با کلیک کردن بر روی فایلپس Linux.x86_64 یا AIC21-Graphic.exe ی برنامه گرافیک بازی را باز کنید و با کلیک روی دکمهی Browse GameLog، آدرس فایل log.json تولید شده توسط سرور را به آن بدهید.
پس از آن میتوانید بازی را به صورت گرافیکی مشاهده کنید.
توجه کنید که روی سیستمعاملهای unix based، ابتدا باید با اجرای دستورchmod +x /path/to/graphic/file
آن را قابل اجرا کنید.
در صورتی که در اجرای نسخهی یونیتی دچار مشکل میشدید، میتوانید از نسخهی LocalWebGL که روی ریپوی گیم قرار دارد استفاده کنید. نحوهی استفاده از آن به این صورت است.
بعد از دانلود فایل LocalWebGL.zip، آن را اکسترکت کنید تا از حالت فشرده خارج شود. سپس cmd یا terminal را در مسیر پوشهی LocalWebGL باز کنید و با دستور زیر یک پایتون سرور بسازید.
python -m http.server
حالا browser خود را باز کنید و آدرس زیر را جستوجو کنید
localhost:8000
اگر بازی گرافیک باز نشد، و لیست فایلهای پوشه نمایش داده شد، فایل index.html را انتخاب کنید.
در بالای رابط گرافیکی، نواریست که امکانات و همچنین اطلاعاتی از بازی در اختیار شما قرار میدهد. این اطلاعات و امکانات به شرح زیراند:
۱- این دکمه چت باکس هر تیم را نشان میدهد.
۲- در این قسمت اسم هر تیم نشان داده میشود.
۳- این بخش مربوط به turnهای بازیست. با کلید سمت راست، به نوبت بعد و با کلید سمت چپ، به نوبت قبل میتوان رفت. عدد بین دو دکمه، تعداد کل حرکتهای بازی و حرکت در حال نمایش را نشان میدهد. به طور مثال، در این عکس، بازی در کل ۱۰۰ حرکت دارد که اکنون در حرکت ۲۰ام هستیم.
۴- این دو نوار، میزان سلامتی هر کدام از
۵- این بخش تعداد مورچه های در اختیار تیم را نشان میدهد.
۶- این بخش تعداد عقرب های در اختیار تیم را نشان میدهد.
۷- این بخش میزان گندم در اختیار تیم را نشان میدهد.
۸- این بخش میزان علف در اختیار تیم را نشان میدهد.
۹- در این قسمت، سرعت پخش بازی مشخص میشود. با زدن دکمهی سمت راست، سرعت پخش ۲ برابر و با زدن دکمهی سمت چپ، نصف میشود. با کلیک روی دکمهی میانی نیز بازی متوقف (pause) میشود. عدد زیر دکمهی توقف، سرعت فعلی پخش بازی را نشان میدهد.
۱۰- برای رفتن به یک حرکت خاص، میتوانید شماره ی حرکت مورد نظر را در باکس بنویسید و سپس با زدن دکمه ی Apply Turn به آن حرکت بروید.
۱۱- با زدن این دکمه میتوانید صدای بازی را قطع یا وصل کنید.
از نسخهی 1.5.1 به بعد، یک خطکش به نوار امکانات اضافه شدهاست. با استفاده از این ابزار، میتوانید نحوهی نمایش نقشه را بین حالت شیفتخورده و نرمال سوییچ کنید.
- .با کشیدن نقشه با استفاده از موس، یا با استفادهاز کلیدهای جهت میتوان نقشه را جابهجا کرد
- با اسکرول کردن روی صفحه، میتوان zoom in و zoom out کرد.
- چتباکس داخل گرافیک، برای کمک به دیباگ کردن شما، تمامی پیامهایی که کلاینتها برای نمایش روی چتباکس ارسال میکنند را نمایش میدهد، اما پیامهایی که در اصل درون چتباکس هستند و برای کلاینتها قابل مشاهدهاند را به صورت متمایز نشان میدهد.
مشکلات و ایرادات پیش آمده در گرافیک بازی را از طریق سایت با ارسال تیکت در قالب زیر، با ما در میان بگذارید:
- شرح مشکل پیشآمده
- .تصویر یا تصاویری از مشکل پیشآمده
- فایل log.json که در گرافیک در حال اجرای آن بوده.