ایجاد یک بازی تیک تاک. مبانی نظری توسعه

با سلام خدمت دوستان عزیز! در این درس نشان خواهم داد که چگونه می توانید یک بازی مرورگر - tic-tac-toe، در جاوا اسکریپت بسازید! همه شما می دانید این بازی چیست و چگونه آن را بازی کنید، اما اجازه دهید دوباره به شما یادآوری کنم:

Tic-tac-toe یک بازی منطقی بین دو بازیکن در یک زمین مربع 3 در 3 سلولی (احتمالاً بزرگتر) است. یکی با "صلیب" بازی می کند و دومی با "انگشت پا".

P.S. مانند تمام دروس مشابه جاوا اسکریپت، در انتهای مقاله می توانید فایل منبع را دانلود کنید و همچنین نتیجه کار را در یک نمونه دمو مشاهده کنید!

توضیحات بازی در حال ساخت

بیایید ویژگی های بازی را بررسی کنیم:

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

منطق ها

من الگوریتم های پیچیده (جهانی) را برای زمین بازی 3 در 3 مربع ابداع نکردم، راه دیگری را رفتم - نیروی بی رحم! (درباره این موضوع کمی بعد بیشتر توضیح دهید). من سه مرحله اصلی متوالی را شناسایی کرده ام که تمام منطق بر آنها استوار است:

مرحله 1: بررسی اینکه آیا بازیکن برنده شده است؟

در این مرحله، بررسی می کنیم که آیا 3 خانه (در همان خط) با نمادهای بازیکن یکسان (صلیب یا صفر) پر شده است یا خیر. آن ها مهم نیست که حرکت چیست (حتی اولین حرکت)، ما همیشه ابتدا بررسی می کنیم که آیا بازیکن برنده شده است یا خیر. پیروزی به این شکل است:

مرحله 2: بررسی - آیا کامپیوتر با حرکت بعدی می تواند برنده شود؟

در این مرحله، ما به دنبال خطی هستیم که در آن 2 سلول توسط رایانه پر شده و یک سلول خالی وجود داشته باشد - یعنی به دلیل بی توجهی بازیکن سعی می کنیم برنده شویم. این چیزی است که شکست به نظر می رسد (یعنی یک پیروزی کامپیوتری):

مرحله 3: ما به شما اجازه نمی دهیم برنده شوید!

در اینجا ما به دنبال همان خط مرحله دوم هستیم، فقط 2 سلول باید با علائم بازی بازیکن پر شود، یعنی در این مرحله با گذاشتن علامت در یک سلول خالی اجازه نمی دهیم رایانه ببازد. هر یک از مراحل یک تابع مستقل را نشان می دهد - می توانید این را در کد js زیر مشاهده کنید.

پیاده سازی

طرح زمین بازی بسیار ساده است - بلوک اصلی حاوی یک خط اطلاعات (کلاس - نتیجه) و 9 بلوک است که سلول ها (کلاس - بلوک) طرح HTML سلول ها هستند:

نوبت شماست!

سلول کلاس کمکی برای شناسایی دقیق سلول مورد نظر در زمین بازی ضروری است. سبک های CSS برای زمین بازی:

Krestiki_noliki(عرض: 306 پیکسل؛ حاشیه: 0 خودکار؛ ) .krestiki_noliki .block(عرض: 100 پیکسل؛ ارتفاع: 100 پیکسل؛ حاشیه: 1 پیکسل جامد #cccc؛ مکان نما: نشانگر؛ شناور: چپ؛ تراز متن: مرکز؛ اندازه قلم: 100 پیکسل؛ ارتفاع خط: 94 پیکسل؛ )

حالا بیایید به کل کد JS نگاه کنیم، پس از آن در مورد نکات اصلی صحبت خواهم کرد:

$(document).ready(function())( var znak_user = "O"; var znak_comp = "X"; var rand_num = Math.round((Math.random() * (9 - 1) + 1)); if (rand_num > 3)( var znak_comp = "O"؛ var znak_user = "X"؛ $(".cell"+rand_num).text(znak_comp); ) var exit_flag = false؛ var win_user_array = ["123"، "456"،"789"،"147"،"258،"369،"159،"357"]؛ //تعیین تابع پیروزی بازیکن check_3_user(znak)( برای (var i = 0; i< 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first+",."+second+",."+third).css("background-color", "#83e2c3"); $(".result").text("Вы выиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем возможность победы компьютера function check_2_comp(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == "" && exit_flag == false){ $("."+third).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak && exit_flag == false){ $("."+second).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak && exit_flag == false){ $("."+first).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем ход компьютера function check_2_user(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == ""){ $("."+third).text(znak_comp); exit_flag = true; } } if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak){ $("."+second).text(znak_comp); exit_flag = true; } } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first).text(znak_comp); exit_flag = true; } if(exit_flag) break; } } $(".krestiki_noliki .block").click(function(){ //Если клетка пустая if($(this).text() == ""){ $(this).text(znak_user); check_3_user(znak_user); check_2_comp(znak_comp); check_2_user(znak_user); if(exit_flag == false){ for (var i = 1; i < 10; i++) { if($(".cell"+i).text() == ""){ $(".cell"+i).text(znak_comp); break; } } }else exit_flag = false; } }); });

ابتدا متغیرها را اعلام می کنیم: znak_user - در این متغیر علامتی را که کاربر با آن بازی می کند ذخیره می کنیم (به طور پیش فرض یک صفر در آنجا ذخیره می شود - این کادر انگلیسی "O" است). znak_comp - در این متغیر ما علامتی را که رایانه با آن بازی می کند ذخیره می کنیم (به طور پیش فرض ، یک ضربدر در آنجا ذخیره می شود - این کادر انگلیسی "X" است).

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

شما می توانید این منطق را به راحتی برای خود تغییر دهید، به عنوان مثال، می توانید چندین عدد تصادفی ایجاد کنید تا گزینه های بیشتری برای اینکه چه کسی اولین و چه علامتی است ایجاد کنید. exit_flag - این پرچم (متغیر) وظیفه خروج از تابع را بر عهده دارد، به عنوان مثال، زمانی که رایانه قبلاً حرکت خود را انجام داده است و شما باید از تابع خارج شده و حرکت را به پخش کننده منتقل کنید. win_user_array - این آرایه تمام گزینه های برنده را برای پر کردن سلول ها ذخیره می کند. برای روشن شدن موضوع، اجازه دهید نگاهی به این تصویر بیندازیم:

هر عنصر از آرایه یک رشته از سه عدد است که یک ترکیب برنده است، به عنوان مثال، اگر سلول های زیر اعداد 1، 2 و 3 را پر کنید، پیروزی (یا شکست) رخ می دهد. همانطور که می بینید، در مجموع 8 گزینه برنده وجود دارد؛ وظیفه ما این است که تمام این گزینه ها را مرور کنیم. بعد 3 عملکرد می آیند:

  1. check_3_user();
  2. check_2_comp();
  3. check_2_user();

هدف از این توابع (در سه مرحله) در بخش منطق (بالا) توضیح داده شده است. این توابع با کلیک بر روی هر یک از سلول های موجود در فیلد فراخوانی می شوند. یک پارامتر (znak) به هر یک از توابع ارسال می شود - این علامت بازیکن یا رایانه است (یک ضربدر یا یک صفر)، به عنوان مثال، به تابعی که پیروزی بازیکن را تعیین می کند (check_3_user)، علامت بازیکن را به ترتیب پاس می کنیم. برای پیدا کردن 3 علامت یکسان در یک خط.

پس از سه عملکرد (اگر رایانه هنوز حرکتی انجام نداده باشد)، رایانه یکی از سلول های آزاد را پر می کند. در اینجا می توانید گیم پلی بازی را پیچیده تر کنید، مثلاً آن را طوری درآورید که اگر سلول مرکزی آزاد است (سلول شماره 5)، ابتدا در آن شرط بندی کنید، اگر اشغال شده است، سپس در یکی از گوشه های آزاد شرط بندی کنید (اینها عبارتند از سلول های شماره 1، 3، 7 و 9) و غیره - به طور کلی، در اینجا به صلاحدید شما بستگی دارد.

این، در اصل، تمام چیزی است که برای ایجاد چنین بازی لازم است.

اکنون می توانید بازی را با استفاده از یک نمونه دمو تماشا کنید و فایل منبع (در مجموع 1 فایل) را دانلود کنید.

1397/06/08 - با تشکر از توجه شما به نویسنده نامه: پاتوکان باغداساریان، زمانی که کامپیوتر چندین مشکل داشت، یک باگ برطرف شد. گزینه های ممکنپیروزی ها و تمام حرکات برنده او به جای 3 خانه از 4 تا 6 سلول رنگ آمیزی شد.

این همه برای من است، امیدوارم این درس برای شما مفید بوده باشد، برای شما آرزوی موفقیت دارم، خداحافظ!

چگونه یک ربات بنویسیم که با تیک تاک قابل شکست نیست، یا مقدمه ای بر قانون minimax

کاملاً ممکن است که پس از صدها بازی تیک تاک، از خود پرسیده باشید: الگوریتم بهینه چیست؟ اما اگر اینجا هستید، پس احتمالاً سعی کرده اید یک پیاده سازی از این بازی نیز بنویسید. ما جلوتر می رویم و رباتی می نویسیم که شکست دادن آن در تیک تاک غیر ممکن خواهد بود. با پیش‌بینی سؤال شما "چرا؟"، پاسخ خواهیم داد: به لطف الگوریتم.

مانند یک شطرنج باز حرفه ای، این الگوریتم اقدامات حریف را چندین حرکت جلوتر محاسبه می کند - تا زمانی که به پایان بازی برسد، چه پیروزی، شکست یا تساوی. هنگامی که در این حالت نهایی قرار گرفت، هوش مصنوعی به خود تعداد امتیاز مثبت (در مورد ما +10) برای برد، منفی (-10) برای باخت و خنثی (0) برای تساوی به خود اختصاص می دهد.

در همان زمان، الگوریتم محاسبات مشابهی را برای حرکات بازیکن انجام می دهد. اگر هوش مصنوعی حرکت کند، حرکتی را با بالاترین امتیاز و در صورت حرکت بازیکن حرکتی با کمترین امتیاز را انتخاب می کند. با استفاده از این استراتژی، Minimax از شکست جلوگیری می کند.

سعی کنید این بازی را انجام دهید.

الگوریتم minimax به راحتی به عنوان یک تابع بازگشتی توصیف می شود که:

  1. در صورت یافتن حالت نهایی، مقداری را برمی‌گرداند (10+، 0، -10)،
  2. از تمام سلول های خالی در میدان می گذرد،
  3. تابع minimax را برای هر یک از آنها فراخوانی می کند (بازگشت)،
  4. مقادیر به دست آمده را ارزیابی می کند
  5. و بهترین را برمی گرداند.

اگر با بازگشت آشنا نیستید، پس باید این سخنرانی را از دوره CS50 هاروارد تماشا کنید:

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

اجرای Minimax

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

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

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

Var origBoard = ["O"،"1"X""X"4"X"6"O""O"];

در مرحله بعد، متغیرهای aiPlayer و huPlayer را اعلام می کنیم و به ترتیب مقادیر "X" و "O" را به آنها اختصاص می دهیم.

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

/* حالت اولیهتخته O | | X --------- X | | X --------- | O | O */ var origBoard = [“O”,1 ,”X”,”X”,4 ,”X”, 6 ,”O”,”O”]; // شخص var huPlayer = "O"; // AI var aiPlayer = "X"; // فهرستی از شاخص‌های سلول‌های خالی را در تابع تابلو برمی‌گرداند valaIndices(board)( return board.filter(s => s != "O" && s != "X"); ) // ترکیبات برنده را با در نظر گرفتن عملکرد شاخص ها برنده (تخته، بازیکن)( اگر((تابلو == بازیکن && تخته == بازیکن && تخته == بازیکن) || (تخته == بازیکن && تخته == بازیکن && تخته == بازیکن) || (تخته == بازیکن = بازیکن && تخته == بازیکن && تخته == بازیکن) || (تابلو == بازیکن && تخته == بازیکن && تخته == بازیکن) || (تخته == بازیکن && تخته == بازیکن && تخته == بازیکن) | | (تخته == بازیکن && تخته == بازیکن && تخته == بازیکن) || (تخته == بازیکن && تخته == بازیکن && تخته == بازیکن) || (تخته == بازیکن && تخته == بازیکن && تخته = = بازیکن)) (بازگشت درست؛ ) else (بازگشت نادرست؛))

بنابراین بیایید یک تابع minimax را با دو آرگومان تعریف کنیم: newBoard و player. سپس اندیس های سلول های آزاد را در فیلد پیدا کرده و به متغیر availSpots منتقل می کنیم.

// تابع اصلی minimax minimax(newBoard, player)( // سلول های موجود var availSpots = valaIndices(newBoard);

علاوه بر این، ما باید وضعیت های نهایی را پیگیری کرده و مقادیر مناسب را برگردانیم. اگر "صفر" برنده شد، باید -10 را برگردانید، اگر "صلیب" - 10 باشد. اگر اندازه آرایه availSpots صفر باشد، سلول آزاد وجود ندارد، بازی با تساوی به پایان می رسد و صفر باید برگردانده شود.

// بررسی وضعیت ترمینال (برد/باخت/تساوی) //و برگرداندن یک مقدار بر این اساس اگر (برنده (newBoard، huPlayer)) (بازگشت (امتیاز:-10)؛ ) در غیر این صورت اگر (برنده (newBoard، aiPlayer)) (بازگشت (امتیاز: 10)؛ ) else if (availSpots.length === 0) (بازگشت (امتیاز: 0)؛ )

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

سپس ایندکس سلول خالی را که به صورت عدد در origBoard ذخیره شده بود برابر با ویژگی index شی move قرار می دهیم. سپس به عنوان پخش کننده فعلی به یک سلول خالی از فیلد جدید newBoard رفته و تابع minimax را از پخش کننده دیگر و فیلد حاصل را newBoard فراخوانی می کنیم. پس از این، باید ویژگی score شیء را که توسط تابع minimax برگردانده شده است را در ویژگی score شی move قرار دهید.

اگر minimax حالت پایانی پیدا نکند، به طور بازگشتی به عمق بازی ادامه می دهد تا زمانی که به حالت پایانی برسد. پس از آن، نقاط این "سطح" بازگشت را به یک سطح بالاتر منتقل می کند.

در نهایت، تابع تغییرات را به newBoard بازنشانی می کند و شی حرکت را در آرایه moves قرار می دهد.

// آرایه برای ذخیره همه اشیا var moves = ; // از طریق سلول های موجود برای (var i = 0; i< availSpots.length; i++){ //create an object for each and store the index of that spot var move = {}; move.index = newBoard]; // совершить ход за текущего игрока newBoard] = player; //получить очки, заработанные после вызова минимакса от противника текущего игрока if (player == aiPlayer){ var result = minimax(newBoard, huPlayer); move.score = result.score; } else{ var result = minimax(newBoard, aiPlayer); move.score = result.score; } // очистить клетку newBoard] = move.index; // положить объект в массив moves.push(move); }

سپس Minimax باید بهترین حرکت را از آرایه حرکت انتخاب کند. اگر هوش مصنوعی در حال حرکت باشد به حرکتی با بالاترین امتیاز و اگر حرکت انسانی باشد با کمترین امتیاز نیاز دارد. بنابراین، اگر مقدار بازیکن aiPlayer باشد، الگوریتم متغیر bestScore را به تعداد بسیار کمی مقداردهی می‌کند و از طریق آرایه حرکت‌ها حلقه می‌زند: اگر امتیاز حرکت ارزش امتیاز بیشتری نسبت به bestScore داشته باشد، الگوریتم آن حرکت را به خاطر می‌سپارد. در مورد حرکات با نقاط مساوی، الگوریتم اولین مورد را به خاطر می آورد.

در صورتی که بازیکن برابر با huPlayer باشد، همه چیز مشابه است - فقط اکنون bestScore به تعداد زیادی مقداردهی اولیه می شود و minimax به دنبال حرکت با کمترین امتیاز می گردد.

در نتیجه، minimax شی ذخیره شده در bestMove را برمی گرداند.

// اگر این یک حرکت هوش مصنوعی است، حرکت ها را حلقه بزنید و حرکتی را که بیشترین امتیاز را دارد، var bestMove انتخاب کنید. if(player === aiPlayer)( var bestScore = -10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score >bestScore)( bestScore = moves[i].score; bestMove = i; )) )else( // در غیر این صورت حرکت ها را حلقه زده و حرکتی را با کمترین امتیاز انتخاب کنید var bestScore = 10000؛ for(var i = 0; i< moves.length; i++){ if(moves[i].score < bestScore){ bestScore = moves[i].score; bestMove = i; } } } // вернуть выбранный ход (объект) из массива ходов return moves; }

در بخش بعدی، ما برنامه خود را شبیه سازی می کنیم تا نحوه عملکرد آن را درک کنیم.

Minimax در عمل

با استفاده از نمودار زیر، مدل گام به گام الگوریتم را تحلیل خواهیم کرد.

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

  1. origBoard و aiPlayer به الگوریتم تغذیه می شوند. فهرستی از سه سلول خالی پیدا شده ایجاد می‌کند، محدود بودن حالت را بررسی می‌کند و در تمام سلول‌های خالی حلقه می‌زند. سپس الگوریتم newBoard را تغییر می‌دهد و aiPlayer را در اولین مربع خالی قرار می‌دهد. پس از آن، خود را از newBoard و huPlayer فراخوانی می کند و منتظر می ماند تا تماس دوم مقداری را برگرداند.
  2. در حالی که اولین فراخوانی تابع هنوز در حال اجرا است، دومین فراخوانی اجرا می‌شود و فهرستی از دو سلول خالی ایجاد می‌کند، وضعیت محدود را بررسی می‌کند و در تمام سلول‌های خالی حلقه می‌زند. سپس تماس دوم با قرار دادن huPlayer در اولین مربع خالی، newBoard را تغییر می‌دهد. پس از آن، از newBoard و aiPlayer خود را فراخوانی می کند و منتظر می ماند تا سومین فراخوانی مقداری را برگرداند.

  3. از آنجا که تماس دوم دو سلول خالی پیدا کرد، minimax با قرار دادن huPlayer در سلول خالی دوم، newBoard را تغییر می‌دهد. سپس خود را از newBoard و aiPlayer فراخوانی می کند.

  4. این الگوریتم لیستی از سلول های خالی را جمع آوری می کند و پس از بررسی محدود بودن وضعیت، پیروزی بازیکن را ثبت می کند. بنابراین یک شی با میدان امتیاز (-10) برمی گرداند.

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

    در این مرحله، اولین فراخوانی تابع تخمینی از حرکت aiPlayer به اولین سلول خالی دریافت کرد. سپس با قرار دادن aiPlayer در مربع خالی دوم، newBoard را اصلاح می کند. پس از آن، خود را از newBoard و huPlayer فراخوانی می کند.

  5. در فراخوانی تابع پنجم، الگوریتم لیستی از سلول‌های خالی را جمع‌آوری می‌کند و پس از بررسی محدود بودن حالت، پیروزی هوش مصنوعی را ثبت می‌کند. بنابراین یک شی با فیلد امتیاز +10 برمی گرداند.

    پس از این، اولین تماس با قرار دادن aiPlayer در سلول خالی سوم، newBoard را تغییر می دهد. سپس خود را از newBoard و huPlayer فراخوانی می کند.

  6. فراخوانی ششم لیستی از دو سلول خالی ایجاد می کند، محدود بودن حالت را بررسی می کند و در تمام سلول های خالی حلقه می زند. سپس با قرار دادن huPlayer در اولین مربع خالی، newBoard را اصلاح می کند. سپس خود را از newBoard و aiPlayer فراخوانی می‌کند و منتظر می‌ماند تا تماس هفتم مقداری را برگرداند.
  7. فراخوانی جدید فهرستی از یک سلول خالی ایجاد می کند، وضعیت محدود را بررسی می کند و newBoard را برای قرار دادن aiPlayer در سلول خالی تغییر می دهد. پس از آن، خود را از newBoard و huPlayer فراخوانی می کند و منتظر می ماند تا این فراخوانی مقداری را برگرداند.
  8. چالش هشتم است لیست خالیسلول ها را خالی کرده و پیروزی aiPlayer را پس از بررسی وضعیت اندام ثبت می کند. بنابراین، یک شی با یک فیلد شمارش برابر با (10) را به سطح بالا، هفتمین فراخوانی، برمی گرداند.

    تماس هفتم تنها یک مقدار مثبت از سطوح پایین دریافت کرد. از آنجایی که این مقدار در حین چرخش aiPlayer به دست آمده است، الگوریتم بزرگترین مقدار بدست آمده را برمی گرداند. بنابراین یک مقدار مثبت (+10) را به سطح بالا، ششمین فراخوانی برمی گرداند.

    از آنجا که تماس ششم دو سلول خالی پیدا کرد، minimax با قرار دادن huPlayer در سلول خالی دوم، newBoard را تغییر می‌دهد. سپس خود را از newBoard و aiPlayer فراخوانی می کند.

  9. پس از این، الگوریتم لیستی از سلول های خالی را جمع آوری می کند و پس از بررسی محدود بودن حالت، پیروزی aiPlayer را ثبت می کند. بنابراین، یک شی با فیلد امتیازی برابر با (+10) را به سطح بالا برمی گرداند.

    در این مرحله، چالش ششم باید بین امتیاز (+10) که چالش هفتم برگردانده شده و امتیاز (-10) که چالش نهم به دست آورده است، انتخاب کند. از آنجایی که حرکت huPlayer این دو نتیجه را ایجاد کرد، الگوریتم کوچک‌تر را انتخاب می‌کند و آن را به عنوان یک شی با فیلدهای امتیاز و شاخص به سطح بعدی برمی‌گرداند.

    در نهایت هر سه شاخه فراخوان اول ارزیابی می شوند (-10، +10، -10). از آنجایی که حرکت aiPlayer این سه نتیجه را ایجاد کرد، الگوریتم شیء حاوی بیشترین تعداد نقاط (+10) و شاخص آن (4) را انتخاب می کند.

در سناریوی فوق، minimax تصمیم می گیرد انتخاب بهینهحرکتی به سمت میدان مرکزی میدان انجام خواهد شد.

پایان!

تا به حال باید درک کرده باشید که الگوریتم مینیمکس چگونه کار می کند. سعی کنید خودتان یک پیاده سازی بنویسید یا به نمونه ای در GitHub یا CodePen نگاه کنید و آن را بهینه کنید.

اگر به موضوع هوش مصنوعی در بازی ها علاقه دارید، توصیه می کنیم مطالب ما را در این زمینه مطالعه کنید.

مرحله 1. پیکربندی پارامترهای فرم 1. برای سفارشی کردن یک فرم، اندازه آن را تنظیم کنید
510 نقطه افقی و 480 نقطه افقی
عمودی حداکثر و حداقل
اندازه را برابر با همان مقادیر نشان می دهد.
2. نام شکل را "Tic Tac Toe" بگذارید.
3. برای پس زمینه فرم، از یک فایل از پوشه استفاده کنید
تصاویر را تحت نام background.png قرار دهید و آن را قرار دهید
در مرکز فرم
4. برای یک نماد در خط عنوان
استفاده از فایل از پوشه
تصاویر تحت نام menu4.ico.
5. رنگ پس زمینه فرم باید تنظیم شود
کرم نعناعی.

مرحله 2. افزودن یک دکمه و برچسب به فرم

1. برای عناصر قرار داده شده، تغییر دهید
اندازه فونت به 12 و تنظیم پس زمینه
شفاف

1. یک نوار منو با موارد در آن ایجاد کنید
همانطور که در تصویر نشان داده شده است.

مرحله 3. اضافه کردن نوار منو به فرم

1. در آیتم منوی File یک دستور ایجاد کنید
خارج شوید.
2. برای
تیم ها
خارج شوید
تجویز کنیم
کد برنامه همان است که در
برنامه قبلی

مرحله 3. اضافه کردن نوار منو به فرم

1. در آیتم منوی Game، یک تیم ایجاد کنید
یه بازی جدید
2. برای دستور New game می نویسیم
کد برنامه در آینده از طریق
چند قدم

مرحله 3. اضافه کردن نوار منو به فرم

1. در آیتم منوی Help، یک دستور ایجاد کنید
در مورد برنامه.
2. برای دستور About the program، یک دستور جدید ایجاد کنید
کد برنامه را تشکیل داده و بنویسید
مشابه قبلی
کاربرد.

1. با کشیدن یک شی PictureBox روی فرم
اندازه آن را به 100x100 تغییر دهید.
2. یک پس زمینه شفاف تنظیم کنید.
3. PictureBox را مطابق شکل قرار دهید
تصویر بالای سلول اول زمین بازی.

مرحله 4. افزودن اشیاء جعبه تصویر به فرم

1
2
3
4
5
6
7
8
9
1. بالای سلول های باقی مانده قرار می دهیم
اشیاء PictureBox، کپی از اولین
شیء، با توجه به شماره گذاری نشان داده شده در
تصاویر.

1. قبل از نوشتن کد
در پوشه مورد نیاز است
\ ویژوال استودیو
2010\Projects\Tic Tac Toe\X's
zeros\bin\Debug\ باید دوباره رول شود
فایل های x.png، 0.png، none.png از پوشه Images.
2. روی اولی با موس سمت چپ دوبار کلیک کنید
جعبه تصویر.

مرحله 5. افزودن کد برای اشیاء جعبه تصویر

1. یک آرایه دو بعدی ایجاد کنید که برای همه عناصر موجود در آن قابل دسترسی باشد
ایجاد شده در قالب عناصر 3x3 متشکل از اعداد صحیح. فورا
هنگام اعلام آن را با صفر پر می کنیم. برای سلول های خالی ما
ما از 0، برای "صلیب" - 1، و برای "صفر" - 1 استفاده خواهیم کرد.

مرحله 5. افزودن کد برای اشیاء جعبه تصویر

در روش زمانی که شما بر روی اولین کلیک کنید
PictureBox، یک اپراتور اضافه کنید
انتخاب
که
اراده
بررسی وضعیت
سلول های آرایه ای اگر ارزش
سلول های آرایه برابر با 0 خواهد بود که
یعنی نه "صفر" وجود دارد و نه
"صلیب"، سپس در این سلول
آرایه 1 و در نوشته شده است
PictureBox1
نمایش داده
تصویر یک "صلیب"، و اگر
مقدار سلول آرایه خواهد بود
برابر 1 است سپس شامل می شود
"صلیب" و 0 در آن نوشته شده است، و
یک سلول خالی نمایش داده می شود.

مرحله 5. افزودن کد برای اشیاء جعبه تصویر

1
2
3
4
5
6
7
8
9



برای سلول های باقیمانده فیلد، کد را اضافه کنید
مانند اولی که فقط در حال تغییر است
شماره شی PictureBox و آدرس سلول
آرایه.
مثال برای سلول دوم:

در روش زمانی که روی یک دکمه کلیک می کنید
اضافه کردن
اپراتور
چرخه
که چک می کند
تمام سلول ها از اول تا
وجود سلول های خالی و اگر
سلول خالی است،
سپس به او
"صفر" نوشته شده است، یعنی در
سلول آرایه -1 نوشته می شود.
برای راحتی کار در آینده
متغیرها
من،
j
که
برای تکرار حلقه ها استفاده می شود
برای کل فرم اعلام خواهیم کرد.

مرحله 6. افزودن کد برای دکمه راه رفتن

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

مرحله 6. افزودن کد برای دکمه راه رفتن

برای نشان دادن وضعیت بازی
عنصر رابط استفاده می شود
برچسب 1. از آنجایی که بازیکن همیشه حرکت می کند
اولین
که
در
دانلودها
برنامه های کاربردی
لازم است
V
عنصر
برچسب 1
لازم است
منعکس کنند
عبارات «شما
حرکت."
برای
این
بیایید ایجاد کنیم
متغیر
پاسخ
که
بیایید این عبارت را اختصاص دهیم. آ
هنگام بارگذاری فرم یک متغیر
باید به عنصر اختصاص داده شود
Label1، برای ایجاد موارد ضروری
رویه ها
لازم است
ابتدا دوبار کلیک کنید
با توجه به فرم

مرحله 7. افزودن کد برنامه برای آیتم جدید منوی بازی

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

مرحله 8. خروجی نتیجه بازی

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

مرحله 8. خروجی نتیجه بازی

کد برنامه برای بررسی پیروزی کاربر:
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "شما برنده می شوید";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "شما برنده می شوید";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "شما برنده می شوید";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "شما برنده می شوید";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "شما برنده می شوید";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "شما برنده می شوید";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "شما برنده می شوید";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "شما برنده می شوید";
کد برنامه برای بررسی پیروزی کاربر:
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "تو باختی";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "تو باختی";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "تو باختی";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "تو باختی";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "تو باختی";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "تو باختی";
label1.Text = پاسخ;

مرحله 9 بهبود قابلیت پخش

برای بهبود قابلیت پخش
به جای خروجی سریال
به اولین های خالی
سلول های "صفر" را اجرا می کنیم
خروجی از طریق ژنراتور تصادفی
شماره.
برای این کار باید اضافه کنید
یک متغیر منطقی
uslovie و نوع حلقه را از For تغییر دهید
در حالی که، از آنجایی که ما نمی دانیم
تعداد دقیق تکرار
ژنراتور اعداد تصادفیخدا حافظ
در یک سلول خالی نمی افتد.

وزارت آموزش و پرورش و علوم روسیه

موسسه آموزشی بودجه ایالت فدرال آموزش عالی حرفه ای

"دانشگاه دولتی ولوگدا"

گروه اتوماسیون و مهندسی کامپیوتر

یادداشت توضیحی پروژه درسی در رشته

مبانی برنامه نویسی و الگوریتمی

"تیک تاک پا"

تکمیل شددانشجوی گروه EM-21

بوتوروا ال یو.

پذیرفته شده Rzheutskaya S. Yu.

معرفی

1. تجزیه و تحلیل مشکل و تعیین الزامات برای برنامه ای که باید توسعه یابد

1 هدف برنامه، کاربران آن، عملکردهای اصلی و اهدافی که در طول توسعه دنبال می شوند

2 بررسی برنامه های معروفی که عملکردهای مشابهی را انجام می دهند

3 مبانی نظری توسعه

4 انتخاب ابزار توسعه

طراحی بخشی از توسعه

1 توسعه رابط کاربری

2.2 توسعه ساختارهای داده (در اکسترنال و RAM)

2.3 توسعه و تجزیه و تحلیل الگوریتم ها

پیاده سازی برنامه به زبان C++

1 معماری برنامه

2 انتخاب اجزای استاندارد بصری و غیر بصری

نتایج آزمون

نتیجه

کتابشناسی - فهرست کتب

برنامه های کاربردی

معرفی

Tic-tac-toe یک بازی منطقی بین دو حریف در یک میدان مربعی 3 در 3 سلول یا بزرگتر است (تا یک "میدان بی پایان"). یکی از بازیکنان با "صلیب" بازی می کند، دومی - با "انگشت پا". این بازی مدت ها قبل از ظهور رایانه ها محبوب شد، فقط قبل از اینکه با یک تکه کاغذ معمولی و یک خودکار بازی شود. بازی سنتی چینی از سنگ های سیاه و سفید استفاده می کند.

در این کار دورهقوانین اساسی و اندازه استاندارد زمین بازی (سلول های 3x3) حفظ می شود. برای راحتی بازی، حق انجام اولین حرکت به کاربر واگذار می شود، یعنی «صلیب».

Tic Tac Toe برنامه ای است که برای سرگرمی کاربر طراحی شده است، بنابراین رابط کاربری آن در این دوره آموزشی به سبک بازی با ترکیبی از رنگ های مثبت ساخته شده است که بخش احساسی روند بازی را افزایش می دهد.

سه نوع در بازی وجود دارد: X در مقابل 0 - کاربر در مقابل کاربر، "سطح 1 با کامپیوتر" - برای کسانی که به تازگی در حال یادگیری اصول اولیه بازی جهانی هستند و سطح "سطح دوم با کامپیوتر" - برای کسانی که به پیروزی خود کاملاً مطمئن هستند. در سطوح 1 و 2، سه نتیجه ممکن وجود دارد: "برد"، "باخت" و "تساوی". اگر خطوط عمودی، افقی یا مورب به طور کامل با ضربدر یا صفر پر شوند، برنده ها ثابت می شوند.

اگر سلول های آزاد زمین تمام شده باشد، اما هیچ کس برنده نشود، بازی با "تساوی" به پایان می رسد.

1. تجزیه و تحلیل مشکل و تعیین الزامات برای برنامه ای که باید توسعه یابد

رابط متقابل برنامه

1.1 هدف برنامه، کاربران آن، عملکردهای اصلی و اهدافی که در طول توسعه دنبال می شود

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

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

از اینجا می توان نتیجه گرفت که وظایف اصلی عبارتند از: وظیفه سرگرمی و وظیفه توسعه پتانسیل منطقی یک فرد.

1.2 بررسی برنامه های معروفی که عملکردهای مشابهی را انجام می دهند

در اینترنت می توانید تعداد زیادی از آثاری که این بازی را پیاده سازی می کنند پیدا کنید. در حال حاضر، آنالوگ های زیادی از این بازی وجود دارد که از استانداردهای اولیه دور شده اند. نمونه ای از این برنامه ها عبارتند از "Tic-tac-toe در یک میدان بی پایان" و "Tic-tac-toe 3D". همچنین در بسیاری از بازی‌ها، «صلیب» و «انگشت پا» با نمادهای دیگری مانند «سنگ» جایگزین می‌شود.

پروژه دوره من یک برنامه کامپیوتری است. این بازی هم برای یک کاربر که حریفش هوش مصنوعی (یا یک کامپیوتر) است و هم برای دو کاربر در نظر گرفته شده است. این در یک زمینه کلاسیک 3x3 ارائه شده است.

جالب ترین و غیر معمول ترین، به نظر من، بازی "Tic Tac Toe 3D" بود. به همین دلیل آن را برای مقایسه انتخاب کردم.

تیک تاک سه بعدی بسیار جالب تر از روی کاغذ یا تخته معمولی است. فرصت های بیشتری برای برد و باخت وجود دارد و تساوی کمتر اتفاق می افتد. شما می توانید به تنهایی - در برابر کامپیوتر - یا با یک دوست بازی کنید. و غیر معمول ترین چیز در اینجا این است که برای برنده شدن، می توانید ترکیبی از سه توپ از رنگ خود (سیاه یا سفید) را نه تنها در یک سطح، بلکه در امتداد صفحه دیوارها و حتی به صورت مورب در کل زمین ایجاد کنید. شکل 1.1).

برنج. 1.1

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

1.3 مبانی نظری توسعه

تحلیل و بررسی

برای هر یک از طرفین، الگوریتم های شناخته شده ای وجود دارد که تساوی را در بازی هر حریف تضمین می کند و اگر حریف او اشتباه کند، به او اجازه می دهد تا برنده شود. بنابراین بازی در حالت است "مرگ هیچکس"<#"877528.files/image002.gif">

شکل 1.2. درخت موقعیت های بازی

درخت جزئی از موقعیت های بازی در شکل 1.2 برای بازی tic-tac-toe نشان داده شده است. درختی از موقعیت‌های بازی برای بازی تیک تاک، که در آن بازیکن برای «صلیب‌ها» ابتدا می‌رود و طبق الگوریتم بالا عمل می‌کند، و بازیکن برای «انگشت پا» می‌تواند هر کاری که می‌خواهد انجام دهد (و یک راس برای یک عمل منطقی و برای یک عمل غیرمنطقی، یعنی هر عمل دیگری داده شده است)، از 50 گره تشکیل شده است.

1.4 انتخاب ابزار توسعه

برای دستیابی به اهداف خود، به یک محیط توسعه برنامه یکپارچه نیاز داریم. بنابراین، توسعه پروژه در محیط برنامه نویسی Microsoft Visual Studio 2008 انجام شد.

Microsoft Visual Studio مجموعه ای از محصولات مایکروسافت است ، از جمله یک محیط توسعه یکپارچه نرم افزار و تعدادی ابزار دیگر. این محصولات به شما این امکان را می دهند که به صورت کنسولی توسعه پیدا کنید برنامه های کاربردی و برنامه های رابط کاربری گرافیکی ، از جمله پشتیبانی از فناوری Windows Forms ، و همچنین وب سایت ها ، خدمات وب مانند بومی ، و کنترل می شود کدهای همه پلتفرم های پشتیبانی شده توسط ویندوز ,ویندوز موبایل ,ویندوز CE , .چارچوب خالص ، ایکس باکس , ویندوز فون .NET Compact Framework و سیلورلایت .

2. طراحی بخشی از توسعه

2.1 توسعه رابط کاربری

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

) منوی اصلی برنامه

برنج. 2.1 - منوی اصلی برنامه

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

) زمین بازی

شکل 2.2 - زمین بازی

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

برنج. 2.3 - پنجره های اضافی نتیجه بازی

2.2 توسعه ساختارهای داده (در اکسترنال و RAM)

RAM برای یک آرایه تک بعدی متشکل از 9 عنصر استفاده می شود که حالت های زمین بازی را ذخیره می کند، جایی که هر سلول آرایه مربوط به یک سلول در زمین بازی است. حافظه نیز صرف متغیرهای ثابت می شود: شماره سطح، ترتیب نوبت.

برای کار کردن به 803 کیلوبایت حافظه آزاد نیاز دارد.

.3 توسعه و تجزیه و تحلیل الگوریتم ها

برای پیاده سازی الگوریتم تفکر بازی، باید یک آرایه ثابت gcnew را تنظیم کنید. (9)؛ که در آن حالت های زمین بازی ذخیره می شود، جایی که هر سلول از آرایه مربوط به یک سلول است. "0" - مربوط به یک سلول خالی است، اگر بازیکنی به سلول منتقل شود، یعنی "X"، مقدار "1" ثبت می شود و اگر کامپیوتر حرکتی انجام دهد، یعنی "O"، مقدار آن است. "2". در ابتدا، تمام عناصر آرایه برابر با "0" هستند. لازم است متغیر ثابت lvl را تنظیم کنید که داده های سطح را ذخیره می کند. در مجموع 3 سطح در این بازی وجود دارد: lvl مقدار "1" را در صورتی که کاربر نوع بازی "X vs O" را انتخاب کرده باشد، مقدار "2" در صورت "سطح اول با کامپیوتر" و مقدار "3" را می گیرد. "اگر "سطح 2 با کامپیوتر" " متغیر پخش کننده ترتیب نوبت را ذخیره می کند ("درست" نوبت بازیکن است، "نادرست" نوبت کامپیوتر است). از آنجایی که حق اولین حرکت به کاربر داده می شود، در ابتدای بازی بازیکن = درست است. متغیر static flag اطلاعاتی در مورد اینکه آیا سلول های خالی در زمین بازی وجود دارد یا خیر را ذخیره می کند: اگر flag = true - یعنی false - هیچ سلول خالی وجود ندارد. الگوریتم تأیید باید شامل تکرار پارامترهای آرایه x باشد و راه حل خود را ارائه دهد، که برای بازی بیشتر بهینه خواهد بود. این برنامه دارای 2 سطح بازی با کامپیوتر می باشد. در سطح 1، وظیفه کامپیوتر این است که حریف را شکست ندهد. از همین رو این تابعمقدار تصادفی سلولی را که کامپیوتر در آن قرار خواهد گرفت برمی گرداند. کد این الگوریتم در [پیوست 1] ارائه شده است. شکل 2.4 بلوک دیاگرام اجرای کد را نشان می دهد.

برنده ترین حرکت در ابتدای بازی حرکت به مرکز زمین است. در تابع ()dif_level، یک شرط در ابتدا بررسی می شود: اگر بازیکن به میدان مرکزی نرفت، کامپیوتر به آنجا می رود. در غیر این صورت، اگر بازیکن به مرکز رفت، تابع check(2) برای بررسی ترکیب کامپیوتر فراخوانی می شود و اگر فرصتی برای برنده شدن وجود داشت، شماره سلول را برگردانید. اگر کامپیوتر در حرکت بعدی نتواند برنده شود، تابع check(1) فراخوانی می شود: بررسی ترکیب بازیکن. شماره سلولی که بازیکن در صورت شرط بندی در آن برنده می شد، برگردانده می شود. اگر چنین ترکیبی وجود نداشته باشد، تابع low_level() فراخوانی می شود.

شکل 2.4. - نمودار بلوکی

شکل 2.5. - نمودار بلوکی

3. پیاده سازی برنامه به زبان C++

.1 معماری برنامه

این برنامه 3 فرم را اجرا می کند: منوی اصلی (شکل 2.1.)، زمین بازی (شکل 2.2) و زمینه کمک (قوانین بازی). 12 پنل که 9 تای آن اصلی است. همچنین، در پایان بازی، یک PictureBox ظاهر می شود که نتیجه آن 5 عدد است (شکل 2.3).

می توانید از کنترل کننده های کلیک پانل به عنوان پایه استفاده کنید که دقیقاً 9 مورد از آنها در زمین بازی وجود دارد. هر کنترل کننده چندین تابع را فراخوانی می کند. در ابتدا یک شرط وجود دارد، اگر کاربر نوع بازی "X در مقابل 0" را انتخاب کند، سلول ها به سادگی با مقادیر 1 یا 2 (تقاطع یا صفر) پر می شوند. سپس توابع می آیند: نشانگر پیشرفت (CrossZero())، که ضربدر را به صفر تغییر می دهد و بالعکس، سلول های اشغال شده را با checkingArray() مسدود می کند، و برنده () برنده را پیدا می کند. تابع winner() تمام گزینه های برنده ممکن را در نظر می گیرد، بنابراین اگر یکی از بازیکنان 3 مهره خود (یک ضربدر یا یک صفر) را به صورت عمودی، افقی یا مورب ردیف کند، برنده خواهد شد. در غیر این صورت، اگر زمین پر باشد، اما هیچ یک از بازیکنان در صف قرار نگرفته باشند، تابع (_friend()) tie check فراخوانی می شود که بررسی می کند سلول های آزاد در زمین باقی مانده است یا خیر. اگر fr = true باشد، هیچ سلول آزاد در میدان وجود ندارد. اگر مقدار تغییر کرده باشد، به این معنی است که یک سلول آزاد در فیلد وجود دارد.

شرط دوم در صورتی کار می کند که نوع بازی دوم یا سوم انتخاب شده باشد. سپس تابعی که حرکت کامپیوتر در آن انجام شده است، نامیده می شود: move(int n). این شماره سلولی را که بازیکن روی آن کلیک کرده است را منتقل می کند. سپس توابع می آیند: نشانگر پیشرفت (CrossZero())، مسدود کردن سلول های اشغال شده checkingArray(). سپس تابع winner() فراخوانی می شود که بررسی می کند آیا بازیکن با این حرکت برنده شده است یا خیر. اگر نه، وجود سلول های آزاد بررسی می شود. اگر سلول های آزاد وجود داشته باشد، کامپیوتر حرکت می کند. در مرحله بعد، بسته به اینکه کدام سطح بازیکن "1" یا "2" را انتخاب کرده است، توابع زیر نامیده می شوند: low_level()، dif_level(). تابع low_level() مکان قرار دادن صفر را به طور تصادفی انتخاب می کند و تابع ()dif_level الگوریتم خاصی را برای برنده شدن کامپیوتر ارائه می دهد. سپس توابع می آیند: نشانگر پیشرفت (CrossZero())، مسدود کردن سلول های اشغال شده checkingArray(). سپس تابع winner() فراخوانی می شود که بررسی می کند آیا کامپیوتر با این حرکت برنده شده است یا خیر. اگر نه، وجود سلول های آزاد بررسی می شود. اگر سلول های آزاد وجود داشته باشد، بازیکن حرکت می کند.

.2 انتخاب اجزای استاندارد بصری و غیر بصری

برای اجرای این کار، اجزای زیر انتخاب شدند:

1) فرم 1، با پارامترهای داده شده Text=Tic-Tac-Toe، ControlBox=False

2) f2، با پارامترهای مشخص شده BackColor، Text=Game

) comboBox1 با پارامترهای آیتم های مشخص شده:

X در مقابل 0

سطح 1 با کامپیوتر

سطح 2 با کامپیوتر

4) پانل، با پارامترهای BackColor مشخص شده، و مقادیر مختلف برای پارامترهای Visible و Enabled. برای برخی از پانل ها، رویدادهایی مانند کلیک نوشته شده است.

5) دکمه، با پارامترهای مشخص شده Font، Fore Color، BackColor، Text، برای تمامی دکمه هایی مانند کلیک نوشته شده است.

6) برچسب، با پارامترهای مشخص شده BackColor، Font، Fore Color، Text.

) pictureBox، با پارامترهای مشخص شده Image، SizeMode= StretchImage.

) textBox، با پارامترهای مشخص شده BackColor، Font، Fore Color، Text=” ” .

4. نتایج آزمون

بیایید برنامه را با مرور 3 نوع بازی آزمایش کنیم.

بیایید عملکرد دکمه های منوی اصلی را امتحان کنیم. دکمه ها به درستی کار می کنند. بیایید سعی کنیم بازی را بدون انتخاب نوع بازی شروع کنیم. برنامه یک پیغام خطا نمایش می دهد و از شما می خواهد که نوع بازی را انتخاب کنید.(شکل 4.1)

شکل 4.1.

بیایید 1 نوع بازی را انتخاب کنیم - "X در مقابل 0"، یعنی. کاربر در مقابل کاربر در این مرحله از بازی کاربر می تواند با خودش هم بازی کند. (شکل 4.2)

شکل 4.2.

در طول بازی "سطح 1 با رایانه" رایانه برای خود هدف برنده شدن شرکت کننده را تعیین نمی کند. او فقط صفر می گذارد مکان های رایگانزمینه های. در این مرحله کاربر به راحتی می تواند کامپیوتر را شکست دهد. اگرچه در این سطح گزینه های دیگری برای توسعه رویدادها نیز امکان پذیر است.

شکل 4.3.

نوع بازی: "سطح 2 با کامپیوتر". در این مرحله بازی تمامی حرکات را آنالیز می کند و سعی می کند بهینه ترین حرکت را انتخاب کند. در اینجا نیز هر سه سناریو ممکن است، زیرا کامپیوتر اولین حرکت خود را به هر سلول آزاد انجام می دهد. اغلب بازی به تساوی می رسد.

شکل 4.4.

این برنامه با موفقیت در تمام انواع آزمایشی بدون خطا اجرا می شود.

نتیجه

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

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

علیرغم سادگی ظاهری این برنامه، مملو از مشکلات متعددی است که با استفاده از تمامی تکنیک های اولیه Visual C++ اجرا می شود.

ویژگی های این برنامه عبارتند از:

الگوریتم به وضوح ساخته شده؛

رابط بصری؛

آسان برای استفاده؛

راهنمای کاربر کاملاً واضح؛

بدون افزونه های غیر ضروری

کتابشناسی - فهرست کتب

1. http://www.pravilaigr.ru/xo.php

2. http://2igroka.com/stuff/sportivnye/krestiki_noliki_3d/15-1-0-14

3. https://www.draw.io/

Http://pol-video.ru/QPW9QHEO2GU/uroki_s_krestiki-noliki_ch1.html

ضمیمه 1

private: int low_level())(// رویه برای یک حریف سبک؛::تصادفی^ rand = gcnew System::Random();(= rand->Next(0,8);

) while (x[r] != 0);r;

ضمیمه 2

خصوصی: bool check(int n)(k = -1;// همه ترکیب ها را بررسی می کند و حرکت صحیح (x == n) را برمی گرداند (((x == n)&&(x == 0)) k =2; ((x == n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =6;((x == n)&&(x == 0)) k =3;((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =7;((x = = n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =4;((x == n)&&(x == 0)) k =6;((x = = n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =5;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =5;((x = = n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =3;((x = = n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =7;

)(x == n) (((x == n)&&(x == 0)) k =6;

)(k!=-1) return true; other return false;

ضمیمه 3

private: int dif_level())(//دشمن سخت

//بازگشت چک(2);(x == 0) return (4)؛(چک(2)) return k; else (بررسی (1)) بازگشت k; else low_level();

کاربرد 4

خصوصی: void CrossZero())(// صلیب را به صفر تغییر می دهد (نشانگر پیشرفت) (بازیکن) (->Visible = true;->Visible = false;

) else (-> قابل مشاهده = درست;-> قابل مشاهده = نادرست;

): void checkingArray())(// تابع بررسی اینکه آیا چیزی در یک سلول وجود دارد یا خیر، اگر وجود داشته باشد، دیگر نمی توانید روی این سلول کلیک کنید. (x == 1) (panel1->BackgroundImage = panel11->BackgroundImage ;panel1- >Enabled = false;)(x == 2) (panel1->BackgroundImage = panel10->BackgroundImage;panel1->Enabled = false;)(x == 1) (panel2->BackgroundImage = panel11->BackgroundImage ;panel2- >Enabled = false;)(x == 2) (panel2->BackgroundImage = panel10->BackgroundImage;panel2->Enabled = false;)(x == 1) (panel3->BackgroundImage = panel11->BackgroundImage ;panel3- >Enabled = false;)(x == 2) (panel3->BackgroundImage = panel10->BackgroundImage;panel3->Enabled = false;)(x == 1) (panel4->BackgroundImage = panel11->BackgroundImage ;panel4- >Enabled = false;)(x == 2) (panel4->BackgroundImage = panel10->BackgroundImage;panel4->Enabled = false;)(x == 1) (panel5->BackgroundImage = panel11->BackgroundImage ;panel5- >Enabled = false;)(x == 2) (panel5->BackgroundImage = panel10->BackgroundImage;panel5->Enabled = false;)(x == 1) (panel6->BackgroundImage = panel11->BackgroundImage ;panel6- >Enabled = false;)(x == 2) (panel6->BackgroundImage = panel10->BackgroundImage;panel6->Enabled = false;)(x == 1) (panel7->BackgroundImage = panel11->BackgroundImage ;panel7- >Enabled = false;)(x == 2) (panel7->BackgroundImage = panel10->BackgroundImage;panel7->Enabled = false;)(x == 1) (panel8->BackgroundImage = panel11->BackgroundImage ;panel8- >Enabled = false;)(x == 2) (panel8->BackgroundImage = panel10->BackgroundImage;panel8->Enabled = false;)(x == 1) (panel9->BackgroundImage = panel11->BackgroundImage ;panel9- >Enabled = false;)(x == 2) (panel9->BackgroundImage = panel10->BackgroundImage;panel9->Enabled = false;)

): bool winner())(// بررسی برنده و مسدود کردن تمام سلول های باقی مانده.

//پرچم bool = غلط;(((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x = = 2)) |||((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2 )) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)))( (lvl==1) (picturePo->Visible = true;)(picturePr->Visible = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Enabled = false;-> Enabled = false;-> Enabled = false;-> Enabled = false;-> Enabled = false;true;

)(((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || (( x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x = = x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)))((lvl==1) ( picturePx->Visible = true;)(picturePobeda->Visible = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Enabled = false;-> Enabled = false;-> Enabled = false;-> Enabled = false;true;

): void _friend())(fr = true;(int i = 0; i< 9; i++) if (x[i] == 0) {fr = false; break;}(fr) { pictureN->قابل مشاهده = واقعی؛)

): void move(int n)(// تابع حرکت کامپیوتر= false;[n] = 1;= !player;();();(winner()) () ((int i = 0; i< 9; i++) if (x[i] == 0) flag = true;(flag){(lvl == 2) = 2; = 2;= !player;();();();

): System:: Void button1_Click(System::Object^ فرستنده، System::EventArgs^ e) (// بازی جدید>Visible = false;>Visible = false;>Visible = false; >Visible = false; >Visible = false; = comboBox1->Text;(typeGame == "")(::Show("ابتدا نوع بازی خود را انتخاب کنید!");

) else ((typeGame == "X در مقابل 0") lvl = 1;(typeGame == "سطح اول با کامپیوتر") lvl = 2;(typeGame == "سطح دوم با کامپیوتر") lvl = 3;( = true;(int i = 0; i< 9; i++) x[i] = 0;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage =panelBackgroundImage->BackgroundImage = panelImage->BackgroundImage BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->Enabled = true;->Enabled = true;->Enabled =Enabled- true; = true;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;

): System::Void panel1_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 0;(lvl == 1)((player)( = 1;

)= !player;();();();

): System::Void panel2_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 1;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel3_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 2;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel4_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 3;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel5_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 4;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel6_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 5;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel7_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 6;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel8_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 7;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel9_MouseClick(System::Object^ فرستنده، System::Windows::Forms::MouseEventArgs^ e) (n = 8;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System:: Void button2_Click(System::Object^ sender, System::EventArgs^ e) (();

): System::Void picturePx_Click(System::Object^ فرستنده، System::EventArgs^ e) (>Visible = false;

): System::Void picturePo_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void picturePobeda_Click(System::Object^ فرستنده، System::EventArgs^ e) (>Visible = false;

): System::Void picturePr_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void pictureN_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

توجه! این یک نسخه مقدماتی از درس است که ممکن است مطالب آن ناقص باشد.

به عنوان دانشجو وارد سایت شوید

برای دسترسی به مطالب مدرسه به عنوان دانش آموز وارد شوید

ایجاد تنظیمات 1C: نوشتن "Tic Tac Toe" قسمت 1/3

ما از طریق بازی یاد خواهیم گرفت و بنابراین اولین پروژه ما خلق کردن برای همه خواهد بود
یک بازی آشنا از دوران کودکی - "Tic Tac Toe".

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

قبل از شروع برنامه نویسی بازی Tic-Tac-Toe، بیایید در مورد آن فکر کنیم.

قبلاً می دانیم که فرم دارای عناصر است که یکی از آنها دکمه است. دکمه ها قادر به اجرای دستورات هستند و در عین حال دارای ویژگی هایی هستند که به شما امکان می دهد نمایش آنها را روی فرم (مثلا عنوان) کنترل کنید.

به عنوان مثال، می توانید از یک دکمه برای ایجاد یک فیلد با 9 ناحیه فعال استفاده کنید (آن سلول هایی که روی آنها کلیک می کنیم و عمل را ضبط می کنیم، در حالی که به طور همزمان کتیبه هایی به شکل "O" و "X" نمایش می دهیم). دکمه برای این کار بیش از حد مناسب است.

چه چیزی نیاز داریم؟ بدیهی است که ما باید حرکت خود را به خاطر بسپاریم و حرکت کامپیوتر را به خاطر بسپاریم. ما همچنین باید عنوان دکمه ها را تغییر دهیم: وقتی کلیک می کنیم، عنوان دکمه همیشه "O" است، زمانی که کامپیوتر حرکت می کند، "X" است.

ابتدا باید یک پایگاه داده جدید ایجاد کنیم که در آن بازی خود را بسازیم. بیا انجامش بدیم.

مرحله 1: ایجاد یک پایگاه داده خالی

بیایید یک پایگاه داده Tic-Tac-Toe خالی ایجاد کنیم.

دستورالعمل های دقیق

راه اندازی کنیممیانبر 1C برای باز کردن لیستی از پایگاه های اطلاعاتی موجود در رایانه. شما در حال خواندن نسخه آزمایشی درس هستید، دروس کامل در دسترس است. ما به خلقت نیاز داریم پایه جدید، بنابراین دکمه " را فشار دهید اضافه کردن":

پنجره افزودن باز خواهد شد پایگاه اطلاع رسانی، که در آن باید اولین مورد را انتخاب کنید " ایجاد پایگاه اطلاع رسانیو روی دکمه «بعدی» کلیک کنید:

در پنجره بعدی، مورد دوم را انتخاب کنید. ایجاد یک پایگاه اطلاعاتی بدون پیکربندی برای ایجاد یک پیکربندی جدید...و دوباره روی دکمه "Next" کلیک کنید:

در پنجره بعدی از ما خواسته می شود که نام پایگاه داده جدید را وارد کنیم که در زیر آن در لیست دیتابیس ها نمایش داده می شود. وارد شویم" تیک تاک پاو روی دکمه «بعدی» کلیک کنید:

در پنجره بعدی باید مسیر پوشه خالی که پایگاه داده ما در آن ذخیره می شود را مشخص کنید. در این مورد، من پوشه " تیک تاک پا" در پوشه "1C Databases" در درایو D:

در پنجره بعدی، تمام تنظیمات را به عنوان پیش فرض رها کنید و روی " کلیک کنید آماده":

پس از یک مکث کوتاه، پایگاه داده ایجاد و به لیست اضافه شد. دو حالت اصلی کار با پایگاه داده وجود دارد: 1C: سازمانیو پیکربندی:

در حالت Configurator ما پایگاه داده را پیکربندی و برنامه ریزی می کنیم، در حالت 1C: Enterprise می بینیم که چه چیزی از آن حاصل می شود.

مرحله 2: پیکربندی را باز کنید

بیایید دکمه " را فشار دهیم پیکربندیبرای وارد شدن به حالت پیکربندی:

مرحله 3: درخت پیکربندی را باز کنید

دستور منو را اجرا کنید " پیکربندی"->"پیکربندی را باز کنید":

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

مرحله چهارم: پردازش را اضافه کنید

برای قرار دادن منطق بازی خود، از بخش "پردازش" استفاده می کنیم. بیایید کلیک کنیم کلیک راستدر بخش " درمان هاو دستور «افزودن» را انتخاب کنید:

پنجره ای برای ایجاد یک پردازش جدید در مقابل ما باز شده است. بیایید نام را وارد کنیم " تیک تاک پا". مترادف به خودی خود درج می شود. این برای ذخیره پردازش ما (هنوز خالی) در پایگاه داده کافی است. روی دکمه "بستن" کلیک کنید:

مرحله شماره 5: اولین اشکال زدایی برنامه

می توانید از حالت کاربر بررسی کنید که چه اتفاقی افتاده است ( 1C: سازمانی). برای ورود مستقیم به آن از پیکربندی، دستور منو را اجرا کنید " اشکال زدایی"->"اشکال زدایی را شروع کنید":

از آنجایی که ما تغییری در پایگاه داده ایجاد کرده ایم، از ما پرسیده می شود که آیا با این تغییر موافقت می کنیم؟ این سوال به طور مداوم در طول فرآیند توسعه از ما پرسیده خواهد شد. ما موافقیم (دکمه" آره"):

پایگاه داده در حالت "1C: Enterprise" شروع شد. شما در حال خواندن نسخه آزمایشی درس هستید، دروس کامل در دسترس است. اما همانطور که می بینیم، کار با آن هنوز دشوار است - به سادگی چیزی برای انتخاب وجود ندارد. عجیب است، زیرا ما قبلاً پردازش را ایجاد کرده‌ایم و در تئوری، باید در پانل زرد ظاهر شود.




بالا