2048 গেমটির জন্য সর্বোত্তম অ্যালগরিদম কী?


1919

আমি সম্প্রতি 2048 গেমটিতে হোঁচট খেয়েছি । আপনি "বড়" টাইলস তৈরি করতে চার দিকের যে কোনও একটিতে সরিয়ে একই ধরণের টাইলগুলিকে মার্জ করেন। প্রতিটি পদক্ষেপের পরে, একটি নতুন টাইল হয় 2বা এর মান সহ এলোমেলো খালি অবস্থানে উপস্থিত হয় 4। সমস্ত বাক্সগুলি পূর্ণ হয়ে গেলে এবং টাইলগুলি একত্রীকরণ করতে পারে এমন কোনও পদক্ষেপ নেই এমন খেলা শেষ হয় বা আপনি একটি মান সহ একটি টাইল তৈরি করেন 2048

এক, লক্ষ্যে পৌঁছানোর জন্য আমার একটি সু-সংজ্ঞায়িত কৌশল অনুসরণ করতে হবে। সুতরাং, আমি এটির জন্য একটি প্রোগ্রাম লেখার কথা ভেবেছিলাম।

আমার বর্তমান অ্যালগরিদম:

while (!game_over) {
    for each possible move:
        count_no_of_merges_for_2-tiles and 4-tiles
    choose the move with a large number of merges
}

আমি কি করছি? যেকোনো সময়, আমি মান টাইল একত্রীকরণ চেষ্টা করবে 2এবং 4যে আমার আছে করার চেষ্টা করুন, 2এবং 4টাইলস সম্ভব ন্যূনতম হিসেবে। আমি যদি এইভাবে চেষ্টা করি তবে অন্যান্য সমস্ত টাইলগুলি স্বয়ংক্রিয়ভাবে একত্রিত হয়ে গেছে এবং কৌশলটি ভাল বলে মনে হচ্ছে।

তবে, যখন আমি আসলে এই অ্যালগরিদম ব্যবহার করি, গেমটি শেষ হওয়ার আগে আমি প্রায় 4000 পয়েন্ট পাই। সর্বাধিক পয়েন্ট এএফাইক আমার ২০০০ পয়েন্টের চেয়ে কিছুটা বেশি যা আমার বর্তমান স্কোরের চেয়ে অনেক বড়। উপরের চেয়ে আরও ভাল অ্যালগরিদম আছে কি?


84
এটি সাহায্য করতে পারে! ov3y.github.io/2048-AI
cegpraकाश

5
@ নিতিশ 12১২২ যাইহোক, আপনার অ্যালগরিদম লোভী যেহেতু আপনার কাছে choose the move with large number of mergesএটি দ্রুত স্থানীয় অপটিমা
বাড়ে

21
@ 500-অভ্যন্তরীণ সার্ভারেরর: আমি যদি আলফা-বিটা গেম ট্রি গাছের ছাঁটাইয়ের সাথে একটি এআই প্রয়োগ করি , তবে এটি ধরে নেওয়া হবে যে নতুন ব্লকগুলি বিপরীতভাবে স্থাপন করা হয়েছে। এটি সবচেয়ে খারাপ ধারণা, তবে এটি কার্যকর হতে পারে।
চার্লস

6
যখন আপনার উচ্চ স্কোরের লক্ষ্য করার সময় না থাকে তখন একটি মজাদার বিভ্রান্তি: সর্বনিম্ন স্কোর পাওয়ার চেষ্টা করুন। তত্ত্বগতভাবে এটি 2s এবং 4 এর বিকল্প করছে।
মার্ক হার্ট

7
এই প্রশ্নের বৈধতা নিয়ে আলোচনা মেটাতে
জেরোইন ভেনেভেল

উত্তর:


1266

আমি @ ওভলভের অ্যালগরিদম দ্বারা ব্যবহৃত মিনিম্যাক্স অনুসন্ধানের পরিবর্তে এক্সপেক্টিপ্যাক্স অপ্টিমাইজেশন ব্যবহার করে একটি 2048 এআই তৈরি করেছি । এআই সহজেই সমস্ত সম্ভাব্য পদক্ষেপের উপরের সর্বাধিক সঞ্চালন করে, তারপরে সমস্ত সম্ভাব্য টাইল স্প্যানগুলির উপর প্রত্যাশা (টাইলগুলির সম্ভাব্যতা দ্বারা ভারিত, অর্থাৎ একটি 4 এর জন্য 10% এবং একটি 2 এর জন্য 90%)। আমি যতদূর সচেতন, এক্সপেক্টিপ্যাক্স্স অপটিমাইজেশনকে ছাঁটাই করা সম্ভব নয় (যে শাখাগুলি অত্যধিক সম্ভাব্য নয় সেগুলি অপসারণ ব্যতীত) এবং তাই ব্যবহৃত অ্যালগরিদম হ'ল সতর্কতার সাথে অপ্টিমাইজড ব্রুট ফোর্স অনুসন্ধান।

কর্মক্ষমতা

এআই এর ডিফল্ট কনফিগারেশনে (সর্বোচ্চ সন্ধানের গভীরতার গভীরতা) বোর্ডের অবস্থানের জটিলতার উপর নির্ভর করে একটি পদক্ষেপ কার্যকর করতে 10 মিমি থেকে 200 মিমি পর্যন্ত যে কোনও স্থানে লাগে। পরীক্ষায়, এআই পুরো গেমের গতিপথের সময় প্রতি সেকেন্ডে 5-10 মুভের গড় মুভ রেট অর্জন করে। যদি অনুসন্ধানের গভীরতা 6 টি পদক্ষেপের মধ্যে সীমাবদ্ধ থাকে তবে এআই সহজেই প্রতি সেকেন্ডে 20+ মুভিগুলি কার্যকর করতে পারে যা কিছু আকর্ষণীয় দেখার জন্য তৈরি করে

এআই এর স্কোর পারফরম্যান্সটি মূল্যায়ন করতে, আমি এআইএ 100 বার চালিয়েছি (রিমোট কন্ট্রোলের মাধ্যমে ব্রাউজার গেমের সাথে সংযুক্ত)। প্রতিটি টাইলের জন্য, এখানে গেমগুলির অনুপাত রয়েছে যাতে সেই টাইলটি অন্তত একবার প্রাপ্ত হয়েছিল:

2048: 100%
4096: 100%
8192: 100%
16384: 94%
32768: 36%

সমস্ত রানের সর্বনিম্ন স্কোর ছিল 124024; প্রাপ্ত সর্বোচ্চ স্কোর ছিল 40৯০767676। মিডিয়ানের স্কোর ৩77২২২। এআই কখনই ২০৪৪ টাইলটি অর্জন করতে ব্যর্থ হয় (তাই এটি 100 গেমের মধ্যে একবারেও খেলাটি হারাতে পারেনি); আসলে, এটি প্রতি রানে কমপক্ষে একবার 8192 টাইল অর্জন করেছে !

সেরা রানের স্ক্রিনশটটি এখানে:

32768 টাইল, স্কোর 794076

এই গেমটি 96 মিনিটের উপরে 27830 চাল বা প্রতি সেকেন্ডে গড়ে 4.8 চাল নিয়ে গেছে।

বাস্তবায়ন

আমার পদ্ধতির একক 64৪-বিট পূর্ণসংখ্যা হিসাবে পুরো বোর্ডকে (১ ent টি এন্ট্রি) এনকোড করা হয়েছে (যেখানে টাইলগুলি nybbles, অর্থাৎ 4-বিট খণ্ড)। -৪-বিট মেশিনে, এটি পুরো বোর্ডটিকে একক মেশিনের নিবন্ধে পাস করতে সক্ষম করে।

বিট শিফট অপারেশনগুলি পৃথক সারি এবং কলামগুলি নিষ্কাশনের জন্য ব্যবহৃত হয়। একটি একক সারি বা কলাম একটি 16-বিট পরিমাণ, সুতরাং 65536 আকারের একটি সারণী রূপান্তরগুলি এনকোড করতে পারে যা একটি একক সারি বা কলামে কাজ করে। উদাহরণস্বরূপ, প্রবর্তনগুলি একটি পূর্বনির্ধারিত "মুভ ইফেক্ট টেবিল" এ 4 লুকআপ হিসাবে প্রয়োগ করা হয় যা প্রতিটি চলন কীভাবে একটি একক সারি বা কলামকে প্রভাবিত করে তা বর্ণনা করে (উদাহরণস্বরূপ, "সরানো ডান" টেবিলটি "1122 -> 0023" এ বর্ণনা করে যে কীভাবে সারি [2,2,4,4] সারি হয়ে যায় [0,0,4,8] ডানদিকে সরানো হলে)।

টেবিল লুক ব্যবহার করে স্কোরিংও করা হয়। টেবিলগুলিতে সমস্ত সম্ভাব্য সারি / কলামগুলিতে গণনা করা হিরিস্টিক স্কোর রয়েছে এবং বোর্ডের ফলস্বরূপ স্কোর কেবল প্রতিটি সারি এবং কলাম জুড়ে সারণির মানগুলির যোগফল।

এই বোর্ডের প্রতিনিধিত্ব, আন্দোলন এবং স্কোরিংয়ের জন্য টেবিল দেখার পদ্ধতির পাশাপাশি, এআইকে অল্প সময়ের মধ্যে বিপুল সংখ্যক গেমের রাজ্য অনুসন্ধান করতে সক্ষম করে (আমার ২০১১-এর মাঝামাঝি ল্যাপটপের একটি কোরে প্রতি সেকেন্ডে 10,000,000 গেম স্টেটস)।

এক্সপেক্টিম্যাক্স অনুসন্ধান নিজেই পুনরাবৃত্ত অনুসন্ধান হিসাবে কোডেড যা "প্রত্যাশা" পদক্ষেপগুলির মধ্যে পরিবর্তিত হয় (সমস্ত সম্ভাব্য টাইল স্প্যানের অবস্থান এবং মানগুলি পরীক্ষা করে এবং প্রতিটি সম্ভাবনার সম্ভাবনা অনুসারে তাদের অনুকূলিত স্কোরগুলি ওজন করে), এবং "সর্বোচ্চকরণ" পদক্ষেপগুলি (সমস্ত সম্ভাব্য পদক্ষেপের পরীক্ষা করে এবং সেরা স্কোর সহ একটি নির্বাচন করা)। যখন পূর্বনির্ধারিত গভীরতার সীমাটি পৌঁছে যায় বা যখন এটি কোনও সম্ভাব্য নয় এমন বোর্ড বোর্ডে পৌঁছায় তখন গাছটি সন্ধান বন্ধ হয়ে যায় যখন পূর্বে দেখা অবস্থানটি ( ট্রান্সপোজিশন টেবিল ব্যবহার করে ) দেখায় বা যখন এটি অত্যন্ত অসম্ভব (যেমন 6 "4" টাইল পেয়ে পৌঁছেছিল) প্রারম্ভিক অবস্থান থেকে এক সারি)। সাধারণ অনুসন্ধানের গভীরতা 4-8 চালগুলি।

ন্যায়শাস্ত্রগত অনুসন্ধানবিদ্যা

অনুকূল অবস্থানের দিকে অনুকূলিতকরণ অ্যালগরিদমকে নির্দেশ করতে বেশ কয়েকটি হিউরিস্টিক ব্যবহার করা হয়। হিউরিস্টিকের সুনির্দিষ্ট পছন্দটি অ্যালগরিদমের পারফরম্যান্সে বিশাল প্রভাব ফেলে। বিভিন্ন হিউরিস্টিকস ওজনযুক্ত এবং একটি অবস্থানিক স্কোরের সাথে মিলিত হয়, যা প্রদত্ত বোর্ডের অবস্থানটি কতটা "ভাল" তা নির্ধারণ করে। অপ্টিমাইজেশন অনুসন্ধানের পরে সমস্ত সম্ভাব্য বোর্ড পজিশনের গড় স্কোরকে সর্বাধিক করে তোলা হবে। খেলা দ্বারা প্রদর্শিত হিসাবে প্রকৃত স্কোরটি বোর্ড স্কোর গণনা করতে ব্যবহৃত হয় না , যেহেতু এটি টাইলগুলি মার্জ করার পক্ষে খুব বেশি ভারী হয় (যখন বিলম্বিত সংশ্লেষের ফলে একটি বড় সুবিধা পাওয়া যায়)।

প্রথমদিকে, আমি দুটি খুব সাধারণ হিউরিস্টিক্স ব্যবহার করেছি, খোলা স্কোয়ারগুলির জন্য এবং প্রান্তে বড় মান থাকার জন্য "বোনাস" প্রদান করছি। এই হিউরিস্টিকগুলি বেশ ভাল পারফরম্যান্স করেছে, প্রায়শই 16384 অর্জন করে তবে কখনও 32768 এ আসে না।

পেটর মোরেভেক (@ স্পিফিকচার) আমার এআই নিয়েছিল এবং দুটি নতুন হুরিস্টিক যুক্ত করেছে। প্রথম হিউরিস্টিক অ-একঘেয়েমি সারি এবং কলামগুলি থাকার জন্য পেনাল্টি ছিল যা র‌্যাঙ্কগুলি বাড়ার সাথে সাথে বৃদ্ধি পেয়েছিল, এটি নিশ্চিত করে যে অল্প-সংখ্যক নন-একতরফা সারি স্কোরকে তীব্রভাবে প্রভাবিত করবে না, তবে বৃহত্তর সংখ্যার নন-একঘেয়ে সারিতে স্কোরটিকে যথেষ্ট আঘাত করেছে। দ্বিতীয় হিউরিস্টিক খোলা জায়গাগুলি ছাড়াও সম্ভাব্য মার্জগুলির সংলগ্ন (সংলগ্ন সমান মান) গণনা করেছে। এই দুটি তাত্ত্বিকতা একঘেয়েমি বোর্ডের দিকে আলগোরিদিমকে ধাক্কা দেয় (যা সংশ্লেষ করা সহজ) এবং প্রচুর সংশ্লেষ সহ বোর্ড পজিশনের দিকে (যেখানে আরও বেশি প্রভাবের জন্য এটি সম্ভব যেখানে মার্জগুলি সারিবদ্ধ করতে উত্সাহিত করে)।

তদ্ব্যতীত, পেটর একটি "মেটা-অপ্টিমাইজেশন" কৌশল ( সিএমএ-ইএস নামে একটি অ্যালগরিদম ব্যবহার করে ) ব্যবহার করে হিউরিস্টিক ওজনকেও অনুকূলিত করেছিলেন , যেখানে সর্বোচ্চ সম্ভাব্য গড় স্কোর অর্জনের জন্য ওজনগুলি নিজেরাই সামঞ্জস্য করা হয়েছিল।

এই পরিবর্তনগুলির প্রভাব অত্যন্ত তাৎপর্যপূর্ণ। অ্যালগরিদম সময়টি প্রায় 90% অর্জনের জন্য প্রায় 13% সময়ের মধ্যে 16384 টাইল অর্জন থেকে শুরু করে এবং অ্যালগরিদম সময়টির 1/3 অংশের মধ্যে 32768 অর্জন করতে শুরু করে (যেখানে পুরাতন হিউরিস্টিকস কখনও একবার 32768 টাইল উত্পাদন করে না) ।

আমি বিশ্বাস করি তাত্ত্বিকতার উন্নতির আরও এখনও অবকাশ আছে। এই অ্যালগরিদমটি অবশ্যই "অনুকূল" নয়, তবে আমার মনে হচ্ছে এটি বেশ কাছাকাছি চলেছে।


যে এআই তার গেমগুলির এক তৃতীয়াংশের মধ্যে 32768 টাইল অর্জন করেছে এটি একটি বিশাল মাইলফলক; কোনও মানব খেলোয়াড় অফিশিয়াল গেমটিতে 32768 অর্জন করেছে (অর্থাত স্যাভেস্টেস বা পূর্বাবস্থার মতো সরঞ্জাম ব্যবহার না করে) শুনে আমি অবাক হয়ে যাব। আমি মনে করি 65536 টাইলটি নাগালের মধ্যে রয়েছে!

আপনি নিজের জন্য এআই চেষ্টা করতে পারেন। কোডটি https://github.com/nneonneo/2048-ai এ উপলব্ধ ।


12
@ রবএল: 2 প্রদর্শিত হয় 90% সময়; 4 প্রদর্শিত হয় 10% সময়। এটা এর সোর্স কোড : var value = Math.random() < 0.9 ? 2 : 4;
nneonneo

35
বর্তমানে চুডায় পোর্টিং করা হচ্ছে যাতে জিপিইউ আরও ভাল গতির জন্য কাজ করে!
নিমসন

25
@neonneo আমি আপনার কোডটি জাভাস্ক্রিপ্টে এমস্ক্রিপ্ট দিয়ে পোর্ট করেছি, এবং এটি এখন ব্রাউজারে বেশ ভাল কাজ করে ! দেখার জন্য শীতল, সমস্ত সংকলনের প্রয়োজন ছাড়াই এবং ... ফায়ারফক্সে, পারফরম্যান্সটি বেশ ভাল ...
রিভার্স_ইনজায়ার

6
একটি 4x4 গ্রিডে তাত্ত্বিক সীমাটি আসলে 131072 হয় 65536 নয় However তবে এর জন্য সঠিক মুহুর্তে 4 পাওয়ার দরকার (অর্থাত্ পুরো বোর্ড 4 দিয়ে পূর্ণ হয় .. 65536 প্রতি একবার - 15 টি ক্ষেত্র দখল করা) এবং বোর্ডটি সেখানে স্থাপন করতে হবে that মুহূর্ত যাতে আপনি একত্রিত করতে পারেন।
বোডো থিয়েসন

5
: @nneonneo আপনি যদি আমাদের এআই, যা আরও ভাল বলে মনে হয়, গেমস 60% মধ্যে 32k চাওয়ার চেক করতে চান পারে github.com/aszczepanski/2048
কোশি

1253

আমি এআই প্রোগ্রামটির লেখক যা অন্যরা এই থ্রেডে উল্লেখ করেছেন। আপনি এআই দেখতে পারেন কর্ম বা পড়তে উৎস

বর্তমানে, প্রোগ্রামটি আমার ল্যাপটপে ব্রাউজারে জাভাস্ক্রিপ্টে চলমান প্রায় 90% জয়ের হার অর্জন করে, যা প্রতি চাল সম্পর্কে 100 মিলি সেকেন্ডের সময় চিন্তা করে, তাই নিখুঁত না হয়ে (এখনও!) এটি দুর্দান্তভাবে সম্পাদন করে।

যেহেতু গেমটি একটি পৃথক রাষ্ট্রীয় স্থান, নিখুঁত তথ্য, দাবা এবং চেকারগুলির মতো টার্ন-ভিত্তিক গেম, তাই আমি একই পদ্ধতিগুলি ব্যবহার করেছি যা সেই গেমগুলিতে কাজ করার জন্য প্রমাণিত হয়েছে, নাম মিনিম্যাক্স আলফা-বিটা ছাঁটাইয়ের সাথে অনুসন্ধান । যেহেতু ইতিমধ্যে সেখানে অ্যালগরিদম সম্পর্কে প্রচুর তথ্য রয়েছে, আমি কেবল স্থিতিশীল মূল্যায়ণ ফাংশনে যে দুটি প্রধান হিউরিস্টিক্স ব্যবহার করি এবং অন্যান্য লোকেরা এখানে প্রকাশ করেছেন এমন অনেকগুলি অন্তর্নিহিতকে আনুষ্ঠানিক রূপ দেয় তা নিয়েই আমি আলোচনা করব ।

Monotonicity

এই তাত্ত্বিকতা নিশ্চিত করে চেষ্টা করে যে টাইলগুলির মানগুলি উভয়ই বাম / ডান এবং উপরে / নীচের দিকের দিক দিয়ে বর্ধমান বা হ্রাস পাচ্ছে। এই তাত্পর্যপূর্ণ একাকী আরও অনেকে যে অন্তর্দৃষ্টি দিয়েছিল তা ক্যাপচার করে, উচ্চতর মূল্যবান টাইলগুলি এক কোণে গুছিয়ে রাখা উচিত। এটি সাধারণত ছোট মূল্যবান টাইলগুলি অনাথ হওয়া থেকে বিরত রাখে এবং বোর্ডকে খুব সুসংহত রাখবে, ছোট টাইলগুলি ক্যাসকেড করে এবং বড় টাইলগুলিতে পূরণ করে।

নিখুঁত একঘেয়ে গ্রিডের স্ক্রিনশট এখানে। অন্যান্য হিউরিস্টিকসকে উপেক্ষা করার জন্য এবং কেবল একঘেয়েতাকে বিবেচনা করার জন্য আমি এভাল ফাংশনটি সেট করে অ্যালগরিদম চালিয়ে এটি পেয়েছি।

একটি নিখুঁত একঘেয়ে 2020 বোর্ড

স্নিগ্ধতা

উপরের হিউরিস্টিক একাই এমন কাঠামো তৈরির প্রবণতা তৈরি করে যেখানে সংলগ্ন টাইলসটি মান হ্রাস পাচ্ছে, তবে অবশ্যই সংশ্লেষের জন্য, সংলগ্ন টাইলগুলি একই মান হওয়া দরকার। অতএব, মসৃণতাবাদী হিউরিস্টিক কেবল প্রতিবেশী টাইলগুলির মধ্যে মান পার্থক্য পরিমাপ করে, এই গণনাটি হ্রাস করার চেষ্টা করে।

গ্রাফিক তত্ত্বের ক্ষেত্রে হ্যাকার নিউজের একজন মন্তব্যকারী এই ধারণার একটি আকর্ষণীয় আনুষ্ঠানিককরণ দিয়েছেন ।

এই দুর্দান্ত প্যারোডি কাঁটাচামচ সৌজন্যে একটি নিখুঁত মসৃণ গ্রিডের স্ক্রিনশট এখানে ।

পুরোপুরি মসৃণ 2048 বোর্ড

ফ্রি টাইলস

এবং অবশেষে, খুব কম ফ্রি টাইল থাকার জন্য একটি শাস্তি রয়েছে, কারণ গেম বোর্ড যখন খুব বেশি সংকুচিত হয়ে যায় তখন বিকল্পগুলি দ্রুত চলে যেতে পারে।

এবং এটাই! এই মানদণ্ডের অনুকূলকরণের সময় গেমের জায়গাগুলি অনুসন্ধান করলে উল্লেখযোগ্যভাবে ভাল পারফরম্যান্স পাওয়া যায়। স্পষ্টভাবে কোডেড মুভ স্ট্র্যাটেজির পরিবর্তে এ জাতীয় সাধারণ পদ্ধতির ব্যবহারের একটি সুবিধা হ'ল অ্যালগরিদম প্রায়শই আকর্ষণীয় এবং অপ্রত্যাশিত সমাধানগুলি খুঁজে পেতে পারে। আপনি যদি এটি চালিত দেখেন তবে এটি প্রায়শই অবাক করে দেওয়ার মতো তবে কার্যকর পদক্ষেপগুলি করে তোলে, হঠাৎ এটি কোন দেয়াল বা কোণার বিরুদ্ধে বিলম্ব করছে তা হঠাৎ করে স্যুইচ করার মতো।

সম্পাদনা:

এই পদ্ধতির শক্তির একটি প্রদর্শন এখানে। আমি টাইল মানগুলি সরিয়ে ফেললাম (সুতরাং এটি 2048 এ পৌঁছানোর পরেও চলতে থাকবে) এবং আটটি পরীক্ষার পরে এখানে সেরা ফলাফল।

4096

হ্যাঁ, এটি একটি 2048 এর পাশাপাশি একটি 4096 = =) এর অর্থ এটি একই বোর্ডে তিনবার অধরা 2048 টালি অর্জন করেছে।


89
আপনি কম্পিউটারটিকে '2' এবং '4' টাইলগুলি 'প্রতিপক্ষ' হিসাবে রেখে চিকিত্সা করতে পারেন।
ওয়েই ইয়েন

29
@ ওয়েইয়েন শিওর, তবে এটি একটি মিনিম্যাক্স সমস্যা হিসাবে গেম যুক্তির প্রতি বিশ্বস্ত নয়, কারণ কম্পিউটার ইচ্ছাকৃতভাবে স্কোরকে হ্রাস করার পরিবর্তে নির্দিষ্ট সম্ভাবনার সাথে এলোমেলোভাবে টাইলস রাখছে।
কো

57
যদিও এআই এলোমেলোভাবে টাইলস রাখছে, লক্ষ্যটি হারাতে হবে না। প্রতিদ্বন্দ্বী আপনার পক্ষে সবচেয়ে খারাপ পদক্ষেপটি বেছে নেওয়ার ক্ষেত্রে দুর্ভাগ্যজনক হওয়া একই জিনিস। "মিনিট" অংশটির অর্থ হ'ল আপনি রক্ষণশীলতার সাথে খেলতে চেষ্টা করেছেন যাতে এমন কোনও ভয়াবহ পদক্ষেপ নেই যা আপনি দুর্ভাগ্যজনক হতে পারেন।
ফ্রিগুই

196
আমার ধারণা ছিল 2048 এর একটি কাঁটাচামচ তৈরি করা, যেখানে কম্পিউটার 2 এবং 4 এর পরিবর্তে এলোমেলোভাবে আপনার এআই ব্যবহার করে মানগুলি কোথায় রাখবেন তা নির্ধারণ করতে। ফলাফল: নিছক অসম্ভবতা। এখানে চেষ্টা করা যেতে পারে: sztupy.github.io/2048- হার্ড
SztupY

30
@ সজটুপওয়াই বাহ, এটি খারাপ। আমাকে qntm.org/hettris হেটেট্রিসের কথা মনে করিয়ে দেয়, এটি আপনার অংশটিকে আরও উন্নত করতে পারে এমন অংশটি রাখার চেষ্টা করে।
পাতাসু

145

হার্ড-কোডেড বুদ্ধি (যেমন কোনও হিউরিস্টিক্স, স্কোরিং ফাংশন ইত্যাদি) নেই এমন এই গেমটির জন্য আমি এআইয়ের ধারণায় আগ্রহী হয়ে উঠি । এআই উচিত "জানি" শুধুমাত্র খেলার নিয়ম এবং "জিনিসটা" খেলার। এটি বেশিরভাগ এআই (যেমন এই থ্রেডের মতো) এর বিপরীতে যেখানে গেম প্লেটি হ'ল গেমের মানবিক বোঝার প্রতিনিধিত্ব করে এমন একটি স্কোরিং ফাংশন দ্বারা চালিত জোর শক্তি।

এআই অ্যালগরিদম

আমি একটি সাধারণ তবুও আশ্চর্যজনকভাবে ভাল অ্যালগরিদম খেলেছি: প্রদত্ত বোর্ডের পরবর্তী পদক্ষেপটি নির্ধারণ করতে, এআই গেমটি শেষ না হওয়া অবধি এলোমেলো পদক্ষেপের সাহায্যে গেমটি খেলবে । শেষ খেলার স্কোরটি ট্র্যাক করে রাখার সময় এটি বেশ কয়েকবার করা হয়। তারপরে শুরুতে সরানো গড় শেষ স্কোর গণনা করা হয়। সর্বাধিক গড় শেষ স্কোর সহ প্রারম্ভিক চলনটি পরবর্তী পদক্ষেপ হিসাবে বেছে নেওয়া হয়।

প্রতি পদক্ষেপে মাত্র 100 রান (অর্থাত মেমরি গেমস) দিয়ে, এআই 2048 টাইল 80% বার এবং 4096 টাইল 50% বার অর্জন করে। 10000 রান ব্যবহার করে 2048 টাইল 100%, 4096 টাইলের জন্য 70% এবং 8192 টাইলের প্রায় 1% পায়।

এটি কর্মে দেখুন

সেরা অর্জনের স্কোর এখানে দেখানো হয়েছে:

সেরা স্কোর

এই অ্যালগরিদম সম্পর্কে একটি আকর্ষণীয় তথ্য হ'ল এলোমেলো-প্লে গেমগুলি যখন সন্দেহাতীতভাবে খারাপ হয় তবে সেরা (বা কমপক্ষে খারাপ) পদক্ষেপটি বেছে নেওয়া খুব ভাল গেম খেলার দিকে পরিচালিত করে: একটি সাধারণ এআই গেম 70000 পয়েন্ট এবং শেষ 3000 পদক্ষেপে পৌঁছতে পারে, তবুও যে কোনও অবস্থান থেকে মেমরির এলোমেলো খেলাগুলি মরার আগে প্রায় 40 অতিরিক্ত পদক্ষেপে গড়ে 340 অতিরিক্ত পয়েন্ট দেয়। (এআই চালিয়ে এবং ডিবাগ কনসোলটি খোলার মাধ্যমে আপনি এটি নিজের জন্য দেখতে পাচ্ছেন))

এই গ্রাফটি এই বিন্দুর চিত্র তুলে ধরে: নীল রেখাটি প্রতিটি পদক্ষেপের পরে বোর্ডের স্কোর দেখায়। লাল রেখাটি সেই অবস্থান থেকে অ্যালগরিদমের সেরা এলোমেলোভাবে চালানো শেষ গেমের স্কোর দেখায় । সংক্ষেপে, লাল মানগুলি নীচের দিকে তাদের দিকে নীচের দিকে "টানছে", কারণ এগুলি অ্যালগরিদমের সর্বোত্তম অনুমান। এটি দেখতে আকর্ষণীয় যে লাল রেখাটি প্রতিটি বিন্দুতে নীল রেখার চেয়ে সামান্য ছোট, তবুও নীল রেখাটি আরও এবং আরও বাড়তে থাকে to

স্কোরিং গ্রাফ

আমি এটি বেশ অবাক করে দিয়েছি যে এটি তৈরির পদক্ষেপগুলি বেছে নেওয়ার জন্য অ্যালগরিদমকে আসলে ভাল গেম খেলার আগেই ধারণা করতে হবে না।

পরে অনুসন্ধানে আমি দেখতে পেলাম যে এই অ্যালগরিদমকে খাঁটি মন্টি কার্লো ট্রি অনুসন্ধান অ্যালগরিদম হিসাবে শ্রেণিবদ্ধ করা যেতে পারে ।

বাস্তবায়ন এবং লিঙ্ক

প্রথমে আমি একটি জাভাস্ক্রিপ্ট সংস্করণ তৈরি করেছি যা এখানে কর্মে দেখা যায় । এই সংস্করণটি শালীন সময়ে 100 এর রান করতে পারে। অতিরিক্ত তথ্যের জন্য কনসোলটি খুলুন। ( উত্স )

পরে, আরও কিছুটা খেলতে আমি @neonneo অত্যন্ত অনুকূলিত অবকাঠামো ব্যবহার করেছি এবং আমার সংস্করণটি সি ++ এ প্রয়োগ করেছি। এই সংস্করণটি প্রতি পদক্ষেপে 100000 পর্যন্ত রান করার অনুমতি দেয় এবং এমনকি যদি আপনার ধৈর্য থাকে তবে 1000000। বিল্ডিং নির্দেশাবলী সরবরাহ করা হয়েছে। এটি কনসোলে চলে এবং ওয়েব সংস্করণটি খেলতে রিমোট-কন্ট্রোলও রাখে। ( উত্স )

ফলাফল

আশ্চর্যের বিষয়, রানের সংখ্যা বাড়ানো গেমের খেলায় মারাত্মকভাবে উন্নতি করে না। 4096 টাইল এবং সমস্ত ছোটগুলি 8192 টাইল অর্জনের খুব কাছাকাছি হয়ে প্রায় 80000 পয়েন্টে এই কৌশলটির সীমাবদ্ধতা রয়েছে বলে মনে হচ্ছে। 100 থেকে 100000 রানের সংখ্যা বাড়ানো এই স্কোর সীমাতে (5% থেকে 40%) পাওয়ার অসুবিধা বৃদ্ধি করে তবে তা ভেঙে না।

সমালোচনামূলক অবস্থানগুলির নিকটে অস্থায়ী বৃদ্ধি পেয়ে 1000000 এ 10000 রান চালানো 129892 এবং 8192 টাইল সর্বাধিক স্কোর অর্জনের 1% এরও কম সময়ের মধ্যে এই বাধাটি ভাঙ্গতে সক্ষম হয়েছিল।

উন্নতি

এই অ্যালগরিদম বাস্তবায়নের পরে আমি ন্যূনতম বা সর্বাধিক স্কোরগুলি ব্যবহার করে বা ন্যূনতম, সর্বাধিক এবং গড়ের সংমিশ্রণ সহ অনেকগুলি উন্নতির চেষ্টা করেছি। আমিও গভীরতা ব্যবহার করার চেষ্টা: পদক্ষেপ প্রতি কে রান চেষ্টা পরিবর্তে, আমি পদক্ষেপ প্রতি কে প্যাচসমূহ চেষ্টা তালিকা একটি প্রদত্ত দৈর্ঘ্যের ( "আপ, আপ, left" উদাহরণস্বরূপ) এবং শ্রেষ্ঠ স্কোরিং পদক্ষেপ তালিকার প্রথম পদক্ষেপ নির্বাচন।

পরে আমি একটি স্কোরিং ট্রি প্রয়োগ করেছি যা প্রদত্ত সরানো তালিকার পরে চলন খেলতে সক্ষম হওয়ার শর্তসাপেক্ষ সম্ভাবনাটিকে বিবেচনা করে।

যাইহোক, এই ধারণাগুলির কোনওটিই প্রথম প্রথম ধারণার চেয়ে সত্যিকারের সুবিধা দেখায় না। আমি এই ধারণাগুলির জন্য কোডটি সি ++ কোডে মন্তব্য করেছি left

আমি এমন একটি "ডিপ সার্চ" প্রক্রিয়া যুক্ত করেছি যা রান সংখ্যাটি অস্থায়ীভাবে 1000000 এ বৃদ্ধি পেয়েছিল যখন কোনও রান দুর্ঘটনাক্রমে পরবর্তী সর্বোচ্চ টাইলে পৌঁছাতে সক্ষম হয়। এটি সময়ের উন্নতির প্রস্তাব দেয়।

কারও কাছে এআই এর ডোমেন-স্বাধীনতা বজায় রাখার মতো আরও উন্নতি ধারণা রয়েছে কিনা তা জানতে আগ্রহী হব।

2048 রূপ এবং ক্লোনস

কেবল মজাদার জন্য, আমি এআইও বুকমার্কলেট হিসাবে প্রয়োগ করেছি , গেমের নিয়ন্ত্রণগুলিতে intoুকে পড়ে। এটি এআইকে মূল গেম এবং এর বিভিন্ন রূপগুলির সাথে কাজ করতে দেয় ।

এআই এর ডোমেন-স্বতন্ত্র প্রকৃতির কারণে এটি সম্ভব। কয়েকটি রূপগুলি বেশ স্বতন্ত্র, যেমন হেক্সাগোনাল ক্লোন।


7
+1 টি। একজন এআই ছাত্র হিসাবে আমি এটি সত্যিই আকর্ষণীয় বলে মনে করি। ফ্রি সময়ে এটিকে আরও ভালভাবে দেখবে।
আইজ্যাক

4
এটা চমৎকার! আমি কেবল এক্সপেক্টিমেক্সের জন্য উত্তম হিউরিস্টিক ফাংশনের জন্য ওজনকে অনুকূলকরণের জন্য কয়েক ঘন্টা ব্যয় করেছি এবং আমি এটি 3 মিনিটের মধ্যে প্রয়োগ করেছি এবং এটি এটি সম্পূর্ণরূপে ভেঙে ফেলে।
ব্রেন্ডন অ্যানিয়েবল

8
মন্টি কার্লো সিমুলেশনটির দুর্দান্ত ব্যবহার।
নিনেও

5
এই বাজানোটি দেখার জন্য একটি আলোকিত করার আহ্বান জানানো হয়েছে। এটি সমস্ত হিরিস্টিককে আঘাত করে এবং এটি এখনও কার্যকর হয়। অভিনন্দন!
স্টাফেন গ্যারিচন

4
এখন পর্যন্ত, এখানে সবচেয়ে আকর্ষণীয় সমাধান।
শেবাও

126

সম্পাদনা: এটি একটি নির্লজ্জ অ্যালগরিদম, মানব সচেতন চিন্তার প্রক্রিয়া মডেলিং, এবং এআইয়ের তুলনায় খুব দুর্বল ফলাফল পেয়েছে যে সমস্ত সম্ভাবনা অনুসন্ধান করে যেহেতু এটি কেবল একটি টাইল দেখায়। প্রতিক্রিয়া টাইমলাইনের প্রথম দিকে এটি জমা দেওয়া হয়েছিল।

আমি অ্যালগরিদমকে পরিমার্জন করে গেমটি মারলাম! এটি শেষের নিকটে সাধারণ দুর্ভাগ্যের কারণে ব্যর্থ হতে পারে (আপনি নীচে নামতে বাধ্য হন, যা আপনাকে কখনই করা উচিত নয়, এবং একটি টাইল উপস্থিত হয় যেখানে আপনার সর্বোচ্চটি হওয়া উচিত Just কেবল উপরের সারিটি ভরাট রাখার চেষ্টা করুন, তাই বাম দিকে সরানো না প্যাটার্নটি ভাঙা), তবে মূলত আপনি নির্দিষ্ট অংশ এবং একটি মোবাইল অংশ নিয়ে খেলেন। এটি আপনার উদ্দেশ্য:

শেষ করতে প্রস্তুত y

এটি আমিই নির্বাচিত মডেল model

1024 512 256 128
  8   16  32  64
  4   2   x   x
  x   x   x   x

নির্বাচিত কোণটি নির্বিচারে হয়, আপনি মূলত কখনই একটি কী (নিষিদ্ধ পদক্ষেপ) টিপেন না এবং যদি আপনি এটি করেন তবে আপনি আবার বিপরীতে টিপুন এবং এটি সংশোধন করার চেষ্টা করবেন। ভবিষ্যতের টাইলগুলির জন্য মডেল সর্বদা প্রত্যাশা করে যে পরবর্তী র্যান্ডম টাইলটি ২ হবে এবং এটি বর্তমান মডেলের বিপরীত দিকে উপস্থিত হবে (যখন প্রথম সারিটি অসম্পূর্ণ রয়েছে, নীচের ডান কোণে, একবার প্রথম সারিটি সম্পূর্ণ হয়ে গেলে নীচের বামে) কোণ)।

এখানে আলগোরিদিম যায়। প্রায় 80% জয় (এটি সম্ভবত "আরও বেশি" পেশাদার "এআই কৌশল দিয়ে জেতা সম্ভব বলে মনে হয়, যদিও আমি এ সম্পর্কে নিশ্চিত নই।)

initiateModel();

while(!game_over)
{    
    checkCornerChosen(); // Unimplemented, but it might be an improvement to change the reference point

    for each 3 possible move:
        evaluateResult()
    execute move with best score
    if no move is available, execute forbidden move and undo, recalculateModel()
 }

 evaluateResult() {
     calculatesBestCurrentModel()
     calculates distance to chosen model
     stores result
 }

 calculateBestCurrentModel() {
      (according to the current highest tile acheived and their distribution)
  }

অনুপস্থিত পদক্ষেপে কয়েকটি পয়েন্টার। এখানে:মডেল পরিবর্তন

প্রত্যাশিত মডেলটির কাছাকাছি যাওয়ার ভাগ্যের কারণে মডেলটি বদলেছে। এআই যে মডেলটি অর্জন করতে চাইছে তা হ'ল

 512 256 128  x
  X   X   x   x
  X   X   x   x
  x   x   x   x

এবং সেখানে যাওয়ার চেইন হয়ে গেছে:

 512 256  64  O
  8   16  32  O
  4   x   x   x
  x   x   x   x

Oনিষিদ্ধ স্পেস প্রতিনিধিত্ব ...

সুতরাং এটি ডানদিকে টিপবে, তারপরে আবার, তারপরে (4 টি যেখানে তৈরি করেছে তার উপর নির্ভর করে ডান বা উপরে) তারপরে এটি চেনটি সম্পন্ন করার আগে এগিয়ে যাবে:

চেইন শেষ

সুতরাং এখন মডেল এবং চেইন ফিরে:

 512 256 128  64
  4   8  16   32
  X   X   x   x
  x   x   x   x

দ্বিতীয় পয়েন্টার, এটির দুর্ভাগ্য হয়েছে এবং এর মূল স্থানটি নেওয়া হয়েছে। সম্ভবত এটি ব্যর্থ হবে, তবে এটি এখনও এটি অর্জন করতে পারে:

এখানে চিত্র বিবরণ লিখুন

এখানে মডেল এবং চেইনটি হ'ল:

  O 1024 512 256
  O   O   O  128
  8  16   32  64
  4   x   x   x

এটি যখন 128 এ পৌঁছানোর ব্যবস্থা করে এটি পুরো সারিটি আবারও অর্জন করে:

  O 1024 512 256
  x   x  128 128
  x   x   x   x
  x   x   x   x

execute move with best scoreসম্ভাব্য পরবর্তী রাজ্যগুলির মধ্যে আপনি কীভাবে সেরা স্কোরকে মূল্যায়ন করতে পারেন?
খালেদ.কে

evaluateResultমূলত সেরা সম্ভাব্য দৃশ্যের সবচেয়ে কাছাকাছি যাওয়ার চেষ্টা করুন আপনার মধ্যে হিউরিস্টিক সংজ্ঞায়িত হয়েছে ।
ডেরেন

@ ড্যারেন আমি আপনার বিশদ বিবরণের জন্য অপেক্ষা করছি
আশু

@ আশু আমি এটি নিয়ে কাজ করছি, অপ্রত্যাশিত পরিস্থিতি আমাকে এটি শেষ করার জন্য সময় ছাড়াই ছেড়ে দিয়েছে। ইতিমধ্যে আমি অ্যালগরিদম উন্নত করেছি এবং এটি এখন এটি 75% সময়ের মধ্যে সমাধান করে।
ডেরেন

13
এই কৌশলটি সম্পর্কে আমি যা পছন্দ করি তা হ'ল ম্যানুয়ালি গেমটি খেললে আমি এটি ব্যবহার করতে সক্ষম হয়েছি, এটি আমাকে 37k পয়েন্ট পর্যন্ত পেয়েছে।
সেফালপড

94

আমি আমার ব্লগে একটি পোস্টের বিষয়বস্তু এখানে অনুলিপি করছি


আমার প্রস্তাবিত সমাধানটি খুব সহজ এবং কার্যকর করা সহজ। যদিও, এটি 131040 এর স্কোর এ পৌঁছেছে। অ্যালগরিদম পারফরম্যান্সের বেশ কয়েকটি মানদণ্ড উপস্থাপিত হয়।

স্কোর

অ্যালগরিদম

হিউরিস্টিক স্কোরিং অ্যালগরিদম

আমার অ্যালগোরিদম যে অনুমানের উপর ভিত্তি করে রয়েছে তা অনুধাবন করার চেয়ে সহজ: আপনি যদি উচ্চতর স্কোর অর্জন করতে চান তবে বোর্ডকে যথাসম্ভব পরিপাটি করে রাখতে হবে। বিশেষত, সর্বোত্তম সেটআপটি টাইল মানগুলির লিনিয়ার এবং একঘেয়েমিক হ্রাস ক্রম দ্বারা দেওয়া হয়। এই স্বজ্ঞাততা আপনাকে একটি টাইল মানের জন্য উপরের আবদ্ধও দেয়: গুলিযেখানে বোর্ডে টাইলের সংখ্যা n

(প্রয়োজনে যখন 4-টাইলটি 2-টাইলের পরিবর্তে এলোমেলোভাবে তৈরি করা হয় তবে 131072 টাইল পৌঁছানোর সম্ভাবনা রয়েছে)

বোর্ডকে সংগঠিত করার সম্ভাব্য দুটি উপায় নিম্নলিখিত চিত্রগুলিতে দেখানো হয়েছে:

এখানে চিত্র বর্ণনা লিখুন

একঘেয়েমিক ক্রমহ্রাসমান ক্রমে টাইলগুলির সমন্বয়টি প্রয়োগ করতে, স্কোরকে সাধারণ অনুপাত আর <1 দিয়ে জ্যামিতিক অনুক্রমের মান দ্বারা গুণিত করে বোর্ডে রৈখিক মানগুলির যোগফল হিসাবে গণনা করা হয়।

গুলি

গুলি

বেশ কয়েকটি লিনিয়ার পাথ একবারে মূল্যায়ন করা যায়, চূড়ান্ত স্কোরটি যে কোনও পাথের সর্বোচ্চ স্কোর।

সিদ্ধান্তের নিয়ম

প্রয়োগ করা সিদ্ধান্তের নিয়মটি বেশ স্মার্ট নয়, পাইথনের কোডটি এখানে উপস্থাপন করা হয়েছে:

@staticmethod
def nextMove(board,recursion_depth=3):
    m,s = AI.nextMoveRecur(board,recursion_depth,recursion_depth)
    return m

@staticmethod
def nextMoveRecur(board,depth,maxDepth,base=0.9):
    bestScore = -1.
    bestMove = 0
    for m in range(1,5):
        if(board.validMove(m)):
            newBoard = copy.deepcopy(board)
            newBoard.move(m,add_tile=True)

            score = AI.evaluate(newBoard)
            if depth != 0:
                my_m,my_s = AI.nextMoveRecur(newBoard,depth-1,maxDepth)
                score += my_s*pow(base,maxDepth-depth+1)

            if(score > bestScore):
                bestMove = m
                bestScore = score
    return (bestMove,bestScore);

মিনম্যাক্স বা এক্সপাসেক্টিমিনিম্যাক্সের একটি বাস্তবায়ন অবশ্যই অ্যালগরিদমকে উন্নত করবে। স্পষ্টতই আরও একটি পরিশীলিত সিদ্ধান্তের নিয়মটি অ্যালগরিদমকে কমিয়ে দেবে এবং এটি প্রয়োগ করতে কিছুটা সময় প্রয়োজন হবে I আমি অদূর ভবিষ্যতে একটি মিনিম্যাক্স বাস্তবায়নের চেষ্টা করব। (সাথে থাকুন)

মাপকাঠি

  • টি 1 - 121 পরীক্ষা - 8 টি পৃথক পাথ - r = 0.125
  • টি 2 - 122 পরীক্ষা - 8-পৃথক পাথ - r = 0.25
  • টি 3 - 132 পরীক্ষা - 8-পৃথক পাথ - r = 0.5
  • টি 4 - 211 পরীক্ষা - 2-পৃথক পাথ - r = 0.125
  • টি 5 - 274 পরীক্ষা - 2-পৃথক পাথ - r = 0.25
  • টি 6 - 211 পরীক্ষা - 2-পৃথক পাথ - r = 0.5

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

টি 2 এর ক্ষেত্রে, দশটিতে চারটি পরীক্ষা গুলি4200 এর গড় স্কোর সহ 4096 টাইল তৈরি করে

কোড

কোডটি জিহাবের নীচের লিঙ্কে পাওয়া যাবে: https://github.com/Nicola17/term2048-AI এটি টার্ম 2048 এর উপর ভিত্তি করে এটি পাইথনে লেখা হয়েছে। আমি যত তাড়াতাড়ি সম্ভব সি ++ তে আরও দক্ষ সংস্করণটি প্রয়োগ করব।


খারাপ নয়, আপনার চিত্রটি আমাকে
মার্জিন

হ্যালো. আপনি কি গিথুব পৃষ্ঠায় প্রদত্ত নির্দেশাবলী আপনার প্রকল্পের জন্য প্রযোজ্য? আমি এটি চেষ্টা করে দেখতে চাই তবে এগুলি এআই অটোরুন নয় বরং মূল প্লেযোগ্য গেমের জন্য নির্দেশাবলী বলে মনে হচ্ছে। আপনি কি আপডেট করতে পারেন? ধন্যবাদ।
জেডি গ্যামবোয়া

41

আমার প্রচেষ্টা উপরের অন্যান্য সমাধানগুলির মতো এক্সপেক্টিমেक्स ব্যবহার করে তবে বিটবোর্ড ছাড়াই। নিউনির সমাধানটি 10 ​​মিলিয়ন মুভ যাচাই করতে পারে যা প্রায় 4 এর গভীরতায় 6 টাইল বাকী থাকে এবং 4 চালগুলি সম্ভব (2 * 6 * 4) 4 । আমার ক্ষেত্রে, এই গভীরতাটি অন্বেষণ করতে খুব বেশি সময় নেয়, আমি বাকী ফ্রি টাইলসের সংখ্যা অনুসারে এক্সপেক্টিমেक्स অনুসন্ধানের গভীরতা সামঞ্জস্য করি:

depth = free > 7 ? 1 : (free > 4 ? 2 : 3)

বোর্ডগুলির স্কোরগুলি ফ্রি টাইলসের সংখ্যার বর্গক্ষেত্রের ওজনের সমষ্টি এবং এটির সাথে 2 ডি গ্রিডের ডট পণ্যটির সাথে গণনা করা হয়:

[[10,8,7,6.5],
 [.5,.7,1,3],
 [-.5,-1.5,-1.8,-2],
 [-3.8,-3.7,-3.5,-3]]

যা উপরের বাম টাইল থেকে এক ধরণের সাপের মধ্যে টাইলসকে অবতরণ করতে বাধ্য করে।

নীচে বা গিথুবে কোড :

var n = 4,
	M = new MatrixTransform(n);

var ai = {weights: [1, 1], depth: 1}; // depth=1 by default, but we adjust it on every prediction according to the number of free tiles

var snake= [[10,8,7,6.5],
            [.5,.7,1,3],
            [-.5,-1.5,-1.8,-2],
            [-3.8,-3.7,-3.5,-3]]
snake=snake.map(function(a){return a.map(Math.exp)})

initialize(ai)

function run(ai) {
	var p;
	while ((p = predict(ai)) != null) {
		move(p, ai);
	}
	//console.log(ai.grid , maxValue(ai.grid))
	ai.maxValue = maxValue(ai.grid)
	console.log(ai)
}

function initialize(ai) {
	ai.grid = [];
	for (var i = 0; i < n; i++) {
		ai.grid[i] = []
		for (var j = 0; j < n; j++) {
			ai.grid[i][j] = 0;
		}
	}
	rand(ai.grid)
	rand(ai.grid)
	ai.steps = 0;
}

function move(p, ai) { //0:up, 1:right, 2:down, 3:left
	var newgrid = mv(p, ai.grid);
	if (!equal(newgrid, ai.grid)) {
		//console.log(stats(newgrid, ai.grid))
		ai.grid = newgrid;
		try {
			rand(ai.grid)
			ai.steps++;
		} catch (e) {
			console.log('no room', e)
		}
	}
}

function predict(ai) {
	var free = freeCells(ai.grid);
	ai.depth = free > 7 ? 1 : (free > 4 ? 2 : 3);
	var root = {path: [],prob: 1,grid: ai.grid,children: []};
	var x = expandMove(root, ai)
	//console.log("number of leaves", x)
	//console.log("number of leaves2", countLeaves(root))
	if (!root.children.length) return null
	var values = root.children.map(expectimax);
	var mx = max(values);
	return root.children[mx[1]].path[0]

}

function countLeaves(node) {
	var x = 0;
	if (!node.children.length) return 1;
	for (var n of node.children)
		x += countLeaves(n);
	return x;
}

function expectimax(node) {
	if (!node.children.length) {
		return node.score
	} else {
		var values = node.children.map(expectimax);
		if (node.prob) { //we are at a max node
			return Math.max.apply(null, values)
		} else { // we are at a random node
			var avg = 0;
			for (var i = 0; i < values.length; i++)
				avg += node.children[i].prob * values[i]
			return avg / (values.length / 2)
		}
	}
}

function expandRandom(node, ai) {
	var x = 0;
	for (var i = 0; i < node.grid.length; i++)
		for (var j = 0; j < node.grid.length; j++)
			if (!node.grid[i][j]) {
				var grid2 = M.copy(node.grid),
					grid4 = M.copy(node.grid);
				grid2[i][j] = 2;
				grid4[i][j] = 4;
				var child2 = {grid: grid2,prob: .9,path: node.path,children: []};
				var child4 = {grid: grid4,prob: .1,path: node.path,children: []}
				node.children.push(child2)
				node.children.push(child4)
				x += expandMove(child2, ai)
				x += expandMove(child4, ai)
			}
	return x;
}

function expandMove(node, ai) { // node={grid,path,score}
	var isLeaf = true,
		x = 0;
	if (node.path.length < ai.depth) {
		for (var move of[0, 1, 2, 3]) {
			var grid = mv(move, node.grid);
			if (!equal(grid, node.grid)) {
				isLeaf = false;
				var child = {grid: grid,path: node.path.concat([move]),children: []}
				node.children.push(child)
				x += expandRandom(child, ai)
			}
		}
	}
	if (isLeaf) node.score = dot(ai.weights, stats(node.grid))
	return isLeaf ? 1 : x;
}



var cells = []
var table = document.querySelector("table");
for (var i = 0; i < n; i++) {
	var tr = document.createElement("tr");
	cells[i] = [];
	for (var j = 0; j < n; j++) {
		cells[i][j] = document.createElement("td");
		tr.appendChild(cells[i][j])
	}
	table.appendChild(tr);
}

function updateUI(ai) {
	cells.forEach(function(a, i) {
		a.forEach(function(el, j) {
			el.innerHTML = ai.grid[i][j] || ''
		})
	});
}


updateUI(ai);
updateHint(predict(ai));

function runAI() {
	var p = predict(ai);
	if (p != null && ai.running) {
		move(p, ai);
		updateUI(ai);
		updateHint(p);
		requestAnimationFrame(runAI);
	}
}
runai.onclick = function() {
	if (!ai.running) {
		this.innerHTML = 'stop AI';
		ai.running = true;
		runAI();
	} else {
		this.innerHTML = 'run AI';
		ai.running = false;
		updateHint(predict(ai));
	}
}


function updateHint(dir) {
	hintvalue.innerHTML = ['↑', '→', '↓', '←'][dir] || '';
}

document.addEventListener("keydown", function(event) {
	if (!event.target.matches('.r *')) return;
	event.preventDefault(); // avoid scrolling
	if (event.which in map) {
		move(map[event.which], ai)
		console.log(stats(ai.grid))
		updateUI(ai);
		updateHint(predict(ai));
	}
})
var map = {
	38: 0, // Up
	39: 1, // Right
	40: 2, // Down
	37: 3, // Left
};
init.onclick = function() {
	initialize(ai);
	updateUI(ai);
	updateHint(predict(ai));
}


function stats(grid, previousGrid) {

	var free = freeCells(grid);

	var c = dot2(grid, snake);

	return [c, free * free];
}

function dist2(a, b) { //squared 2D distance
	return Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2)
}

function dot(a, b) {
	var r = 0;
	for (var i = 0; i < a.length; i++)
		r += a[i] * b[i];
	return r
}

function dot2(a, b) {
	var r = 0;
	for (var i = 0; i < a.length; i++)
		for (var j = 0; j < a[0].length; j++)
			r += a[i][j] * b[i][j]
	return r;
}

function product(a) {
	return a.reduce(function(v, x) {
		return v * x
	}, 1)
}

function maxValue(grid) {
	return Math.max.apply(null, grid.map(function(a) {
		return Math.max.apply(null, a)
	}));
}

function freeCells(grid) {
	return grid.reduce(function(v, a) {
		return v + a.reduce(function(t, x) {
			return t + (x == 0)
		}, 0)
	}, 0)
}

function max(arr) { // return [value, index] of the max
	var m = [-Infinity, null];
	for (var i = 0; i < arr.length; i++) {
		if (arr[i] > m[0]) m = [arr[i], i];
	}
	return m
}

function min(arr) { // return [value, index] of the min
	var m = [Infinity, null];
	for (var i = 0; i < arr.length; i++) {
		if (arr[i] < m[0]) m = [arr[i], i];
	}
	return m
}

function maxScore(nodes) {
	var min = {
		score: -Infinity,
		path: []
	};
	for (var node of nodes) {
		if (node.score > min.score) min = node;
	}
	return min;
}


function mv(k, grid) {
	var tgrid = M.itransform(k, grid);
	for (var i = 0; i < tgrid.length; i++) {
		var a = tgrid[i];
		for (var j = 0, jj = 0; j < a.length; j++)
			if (a[j]) a[jj++] = (j < a.length - 1 && a[j] == a[j + 1]) ? 2 * a[j++] : a[j]
		for (; jj < a.length; jj++)
			a[jj] = 0;
	}
	return M.transform(k, tgrid);
}

function rand(grid) {
	var r = Math.floor(Math.random() * freeCells(grid)),
		_r = 0;
	for (var i = 0; i < grid.length; i++) {
		for (var j = 0; j < grid.length; j++) {
			if (!grid[i][j]) {
				if (_r == r) {
					grid[i][j] = Math.random() < .9 ? 2 : 4
				}
				_r++;
			}
		}
	}
}

function equal(grid1, grid2) {
	for (var i = 0; i < grid1.length; i++)
		for (var j = 0; j < grid1.length; j++)
			if (grid1[i][j] != grid2[i][j]) return false;
	return true;
}

function conv44valid(a, b) {
	var r = 0;
	for (var i = 0; i < 4; i++)
		for (var j = 0; j < 4; j++)
			r += a[i][j] * b[3 - i][3 - j]
	return r
}

function MatrixTransform(n) {
	var g = [],
		ig = [];
	for (var i = 0; i < n; i++) {
		g[i] = [];
		ig[i] = [];
		for (var j = 0; j < n; j++) {
			g[i][j] = [[j, i],[i, n-1-j],[j, n-1-i],[i, j]]; // transformation matrix in the 4 directions g[i][j] = [up, right, down, left]
			ig[i][j] = [[j, i],[i, n-1-j],[n-1-j, i],[i, j]]; // the inverse tranformations
		}
	}
	this.transform = function(k, grid) {
		return this.transformer(k, grid, g)
	}
	this.itransform = function(k, grid) { // inverse transform
		return this.transformer(k, grid, ig)
	}
	this.transformer = function(k, grid, mat) {
		var newgrid = [];
		for (var i = 0; i < grid.length; i++) {
			newgrid[i] = [];
			for (var j = 0; j < grid.length; j++)
				newgrid[i][j] = grid[mat[i][j][k][0]][mat[i][j][k][1]];
		}
		return newgrid;
	}
	this.copy = function(grid) {
		return this.transform(3, grid)
	}
}
body {
	font-family: Arial;
}
table, th, td {
	border: 1px solid black;
	margin: 0 auto;
	border-collapse: collapse;
}
td {
	width: 35px;
	height: 35px;
	text-align: center;
}
button {
	margin: 2px;
	padding: 3px 15px;
	color: rgba(0,0,0,.9);
}
.r {
	display: flex;
	align-items: center;
	justify-content: center;
	margin: .2em;
	position: relative;
}
#hintvalue {
	font-size: 1.4em;
	padding: 2px 8px;
	display: inline-flex;
	justify-content: center;
	width: 30px;
}
<table title="press arrow keys"></table>
<div class="r">
    <button id=init>init</button>
    <button id=runai>run AI</button>
    <span id="hintvalue" title="Best predicted move to do, use your arrow keys" tabindex="-1"></span>
</div>


3
নিশ্চিত না কেন এর আরও বেশি অগ্রগতি নেই Not এটি সরলতার জন্য সত্যই কার্যকর।
ডেভিড গ্রেডানাস

ধন্যবাদ, দেরী উত্তর এবং এটি সত্যিই ভালভাবে সম্পাদন করে না (প্রায়শই [1024, 8192] এ), ব্যয় / পরিসংখ্যান ফাংশনটির আরও বেশি কাজ করা দরকার
22:00

আপনি খালি জায়গাগুলির ওজন কীভাবে করলেন?
ডেভিড গ্রেডানাস

1
এটি সহজ cost=1x(number of empty tiles)²+1xdotproduct(snakeWeights,grid)এবং আমরা এই
ব্যয়টি

ধন্যবাদ @ রুবস্তো, ​​আমার কোনও দিন কোডটি উন্নত করা উচিত, এটি সরল করা যায়
18:41

38

আমি একটি 2048 নিয়ামকের লেখক যা এই থ্রেডে উল্লিখিত অন্য যে কোনও প্রোগ্রামের চেয়ে ভাল স্কোর করে। কন্ট্রোলারের একটি কার্যকর বাস্তবায়ন গিথুব এ উপলব্ধ । ইন একটি পৃথক রেপো সেখানে নিয়ামক রাষ্ট্রীয় মূল্যায়ন ফাংশন প্রশিক্ষণ জন্য ব্যবহৃত কোড। প্রশিক্ষণ পদ্ধতিটি কাগজে বর্ণিত হয়েছে ।

কন্ট্রোলার আঞ্চলিক পার্থক্য শিখার (একটি শক্তিবৃদ্ধি শেখার কৌশল) বিভিন্ন দ্বারা স্ক্র্যাচ থেকে শিখানো একটি রাষ্ট্রীয় মূল্যায়ন ফাংশন (মানব 2048 দক্ষতা ছাড়াই) সাথে এক্সপেক্টিম্যাক্স অনুসন্ধান ব্যবহার করে । রাষ্ট্রীয় মান ফাংশনটি একটি এন-টুপল নেটওয়ার্ক ব্যবহার করে , যা মূলত বোর্ডে পর্যবেক্ষণের নিদর্শনগুলির একটি ভারী লিনিয়ার ফাংশন। এটি মোট 1 বিলিয়ন ওজনের জড়িত ।

কর্মক্ষমতা

1 চাল / স: 609104 এ (100 গেমস গড়)

10 চাল / সেকেন্ডে: 589355 (300 গেমস গড়)

3- প্লাইতে ( সিএ 1500 চাল / গুলি): 511759 (1000 গেমস গড়)

10 পদক্ষেপ / গুলিগুলির জন্য টাইলের পরিসংখ্যান নিম্নরূপ:

2048: 100%
4096: 100%
8192: 100%
16384: 97%
32768: 64%
32768,16384,8192,4096: 10%

(শেষ লাইনটির অর্থ বোর্ডে একই সাথে প্রদত্ত টাইলস থাকা)।

3-প্লাইয়ের জন্য:

2048: 100%
4096: 100%
8192: 100%
16384: 96%
32768: 54%
32768,16384,8192,4096: 8%

যাইহোক, আমি কখনও এটি 65536 টাইল প্রাপ্ত পর্যবেক্ষণ করি নি।


4
খুব চিত্তাকর্ষক ফলাফল। তবে আপনি সম্ভবত ব্যাখ্যাটির উত্তরটি আপডেট করতে পারেন (মোটামুটি, সহজ ভাষায় ... আমি নিশ্চিত যে সম্পূর্ণ বিবরণ এখানে পোস্ট করা খুব দীর্ঘ হবে) আপনার প্রোগ্রাম এটি কীভাবে অর্জন করবে? শেখার অ্যালগরিদম কীভাবে কাজ করে তার মোটামুটি ব্যাখ্যা হিসাবে?
সিড্রিক মামো

27

আমি মনে করি যে আমি একটি অ্যালগরিদম পেয়েছি যা বেশ ভালভাবে কাজ করে, কারণ আমি প্রায়শই 10000 এরও বেশি স্কোর পৌঁছায়, আমার ব্যক্তিগত সেরাটি 16000 এর কাছাকাছি।

নীচের কোডটি দেখুন:

while( !game_over ) {
    move_direction=up;
    if( !move_is_possible(up) ) {
        if( move_is_possible(right) && move_is_possible(left) ){
            if( number_of_empty_cells_after_moves(left,up) > number_of_empty_cells_after_moves(right,up) ) 
                move_direction = left;
            else
                move_direction = right;
        } else if ( move_is_possible(left) ){
            move_direction = left;
        } else if ( move_is_possible(right) ){
            move_direction = right;
        } else {
            move_direction = down;
        }
    }
    do_move(move_direction);
}

5
আমি "বনাম, ডান, উপরে, বাম, ..." (এবং এটি যদি প্রয়োজন হয় নিচে) তুচ্ছ চক্রীয় কৌশল বনাম এই পরীক্ষা করে 100,000 গেমস চালিয়েছি। চক্রীয় কৌশলটি একটি "গড় টাইল স্কোর" সমাপ্ত করেছে 770.6, যখন এটি একটি মাত্র পেয়েছে 396.7। আপনার কি ধারণা আছে যে তা কেন হতে পারে? আমি ভাবছি এটি অনেকগুলি আপগুলি করে, এমনকি বাম বা ডানদিকে আরও অনেক কিছু মিলিত হয়ে যায়।
থমাস আহলে

1
টাইলগুলি একাধিক দিক থেকে স্থানান্তরিত না হলে বেমানান উপায়ে স্ট্যাক রাখে tend সাধারণভাবে, একটি চক্রীয় কৌশল ব্যবহারের ফলে কেন্দ্রের বড় আকারের টাইলস দেখা দেয়, যা কসরতগুলি আরও বেশি সংকুচিত করে তোলে।
বিসিডিয়ান

25

ইতিমধ্যেই এই খেলার জন্য একটি এআই বাস্তবায়ন এখানে । README থেকে অংশ:

অ্যালগরিদম হল প্রথম আলফা-বিটা অনুসন্ধানের পুনরাবৃত্তিমূলক গভীরতা। মূল্যায়ন ফাংশন গ্রিডে টাইলগুলির সংখ্যা হ্রাস করার সময় সারি এবং কলামগুলিকে একঘেয়ে রাখার চেষ্টা করে।

এই অ্যালগরিদম সম্পর্কে হ্যাকার নিউজে একটি আলোচনাও রয়েছে যা আপনি দরকারী মনে করতে পারেন।


4
এই শীর্ষ উত্তর হওয়া উচিত, কিন্তু এটা বাস্তবায়ন সম্পর্কে আরো বিস্তারিত যোগ করার জন্য চমৎকার হবে: কিভাবে খেলা বোর্ড (ক গ্রাফ হিসাবে) স্থাপিত হয় অপ্টিমাইজেশান নিযুক্ত (কমপক্ষে-MAX টাইলস মধ্যে পার্থক্য) ইত্যাদি যেমন,
Alceu কোস্টা

1
ভবিষ্যতের পাঠকদের জন্য: এটি দ্বিতীয় প্রোগ্রামটির লেখক (ওভলভ) দ্বারা ব্যাখ্যা করা একই প্রোগ্রামটি এখানে দ্বিতীয় শীর্ষের উত্তরে । এই উত্তর এবং এই আলোচনায় ওভলভের প্রোগ্রামের অন্যান্য উল্লেখগুলি ওভলভকে উপস্থিত হতে এবং তার অ্যালগরিদম কীভাবে কাজ করেছিল তা লেখার জন্য উত্সাহিত করেছিল; সেই উত্তরের স্কোর এখন 1200
গুণকবায়ার

23

অ্যালগরিদম

while(!game_over)
{
    for each possible move:
        evaluate next state

    choose the maximum evaluation
}

মূল্যায়ন

Evaluation =
    128 (Constant)
    + (Number of Spaces x 128)
    + Sum of faces adjacent to a space { (1/face) x 4096 }
    + Sum of other faces { log(face) x 4 }
    + (Number of possible next moves x 256)
    + (Number of aligned values x 2)

মূল্যায়ন বিশদ

128 (Constant)

এটি একটি ধ্রুবক, বেস-লাইন হিসাবে এবং পরীক্ষার মতো অন্যান্য ব্যবহারের জন্য ব্যবহৃত হয়।

+ (Number of Spaces x 128)

আরও স্পেস রাজ্যটিকে আরও নমনীয় করে তোলে, আমরা 128 দ্বারা গুন করি (যা মিডিয়ান) 128 মুখগুলি পূর্ণ গ্রিড একটি অনুকূল অসম্ভব অবস্থা।

+ Sum of faces adjacent to a space { (1/face) x 4096 }

এখানে আমরা যে মুখগুলি মার্জ হওয়ার সম্ভাবনা রয়েছে তাদের পিছনে মূল্যায়ন করার মাধ্যমে টাইল 2 মান 2048 হয়ে যায়, এবং টাইল 2048 মূল্যায়ন করা হয় 2।

+ Sum of other faces { log(face) x 4 }

এখানে আমাদের এখনও স্ট্যাকড মানগুলি পরীক্ষা করা দরকার, তবে স্বল্পতার সাথে নমনীয়তা পরামিতিগুলিকে বাধাগ্রস্ত করে না, তাই আমাদের [4,44]} এর মধ্যে {x এর যোগফল রয়েছে}

+ (Number of possible next moves x 256)

কোনও রাষ্ট্রের সম্ভাব্য পরিবর্তনের আরও স্বাধীনতা থাকলে এটি আরও নমনীয়।

+ (Number of aligned values x 2)

তাত্ক্ষণিকভাবে নজর না দিয়ে এই রাজ্যের মধ্যে মিশে যাওয়ার সম্ভাবনার একটি সরল চেক।

দ্রষ্টব্য: ধ্রুবকগুলি টুইট করা যেতে পারে ..


2
আমি এটিকে পরে একটি লাইভ কোড যোগ করতে সম্পাদনা হবে, @ nitish712
Khaled.K

9
এই অ্যালগরিদমের জয়% কত?
সেগপ্রকাশ

তোমার দরকার কেন constant? আপনি যা করছেন সবগুলি যদি স্কোরের সাথে তুলনা করা হয়, তবে কীভাবে এই তুলনাগুলির ফলাফলকে প্রভাবিত করবে?
বিসিডিয়ান

@ বিসিডিআন হিউরিস্টিক (ওরফে তুলনা-স্কোর) ভবিষ্যতের রাষ্ট্রের প্রত্যাশিত মানের তুলনা করার উপর নির্ভর করে, দাবা হেরিরিস্টিক কীভাবে কাজ করে তা বাদে, এটি একটি লিনিয়ার হিউরিস্টিক ব্যতীত, যেহেতু আমরা পরবর্তী সেরা এন চলনগুলি জানতে কোনও গাছ তৈরি করি না
খালেদ.কে

12

এটি ওপি-র প্রশ্নের সরাসরি উত্তর নয়, এটি একই সমস্যাটি সমাধান করার জন্য আমি এতদূর চেষ্টা করেছি (পরীক্ষা-নিরীক্ষা) এবং এর কিছু ফলাফল পেয়েছি এবং কিছু পর্যবেক্ষণও শেয়ার করতে চাই যা আমি জানাতে চাই, আমি আগ্রহী এ থেকে আরও অন্তর্দৃষ্টি।

আমি মাত্র 3 এবং 5 এ অনুসন্ধান-গাছের গভীরতার কাট অফের সাথে আলফা-বিটা ছাঁটাইয়ের সাথে আমার মিনিম্যাক্স বাস্তবায়নের চেষ্টা করেছি Col আমি 4x4 গ্রিডের জন্য এডএক্স কোর্স কলম্বিয়াএক্সের প্রকল্প অ্যাসাইনমেন্ট হিসাবে একই সমস্যাটি সমাধান করার চেষ্টা করছিলাম : সিএসএমএম.101 এক্স আর্টিফিশিয়াল ইন্টেলিজেন্স ( এআই)

মূলত স্বজ্ঞাততা এবং উপরে আলোচিত বিষয়গুলি থেকে: আমি বেশ কয়েকটি হিউরিস্টিক মূল্যায়ন ফাংশনগুলির উত্তল সংমিশ্রণ (বিভিন্ন ভিন্নতর ওজনীয় ওজনযুক্ত চেষ্টা) প্রয়োগ করেছি:

  1. Monotonicity
  2. বিনামূল্যে স্থান উপলব্ধ

আমার ক্ষেত্রে, কম্পিউটার প্লেয়ারটি পুরোপুরি এলোমেলো, তবে তবুও আমি বিজ্ঞাপনী সেটিংস ধরে নিয়েছি এবং এআই প্লেয়ার এজেন্টকে সর্বোচ্চ প্লেয়ার হিসাবে প্রয়োগ করেছি।

গেমটি খেলার জন্য আমার 4x4 গ্রিড রয়েছে।

পর্যবেক্ষণ:

আমি যদি প্রথম হিউরিস্টিক ফাংশন বা দ্বিতীয় হিউরিস্টিক ফাংশনে খুব বেশি ওজন নির্ধারণ করি, তবে এআই প্লেয়ারের যে স্কোর পাওয়া যায় তা উভয় ক্ষেত্রেই কম। আমি হিউরিস্টিক ফাংশনগুলিতে অনেকগুলি সম্ভাব্য ওজন অ্যাসাইনমেন্টের সাথে খেলেছি এবং একটি উত্তল সংমিশ্রণ নিয়েছি, তবে খুব কমই এআই প্লেয়ার 2048 স্কোর করতে সক্ষম। বেশিরভাগ সময় এটি 1024 বা 512 এ থামে।

আমি কোণার তাত্পর্যপূর্ণ চেষ্টাও করেছি, তবে কোনও কারণে এটি ফলাফলকে আরও খারাপ করে তোলে, কোনও অন্তর্দৃষ্টি কেন?

এছাড়াও, আমি অনুসন্ধানের গভীরতা কাট-অফ 3 থেকে 5-তে বাড়ানোর চেষ্টা করেছি (ছাঁটাইয়ের পরেও স্থান অনুমতিপ্রাপ্ত সময়কে ছাড়িয়েছে যেহেতু আমি এটিকে আরও বাড়িয়ে তুলতে পারি না)) এবং আরও একটি তাত্পর্য যুক্ত করেছি যা সংলগ্ন টাইলগুলির মানগুলি দেখায় এবং দেয় যদি তারা মার্জ-সক্ষম হয় তবে আরও পয়েন্ট, তবে এখনও আমি 2048 পেতে সক্ষম নই।

আমি মনে করি মিনিম্যাক্সের পরিবর্তে এক্সপেক্টিমে্যাক্স ব্যবহার করা আরও ভাল still

নীচে অ্যানিমেশনটি কম্পিউটার প্লেয়ারের সাথে এআই এজেন্টের দ্বারা খেলানো গেমের শেষ কয়েকটি ধাপগুলি দেখায়:

এখানে চিত্র বর্ণনা লিখুন

যে কোনও অন্তর্দৃষ্টি সত্যই খুব সহায়ক হবে, আগাম ধন্যবাদ। (নিবন্ধটির জন্য এটি আমার ব্লগ পোস্টের লিঙ্ক: https://sandipanweb.wordpress.com/2017/03/06/using-minimax-with-alpha-beta-pruning- এবং-heuristic- মূল্যায়ন- to- সলভ কম্পিউটার- এবং ইউটিউব ভিডিও সহ -2048-খেলা : https://www.youtube.com/watch?v=VnVFilfZ0r4 )

নিম্নলিখিত অ্যানিমেশনটি খেলাগুলির শেষ কয়েকটি পদক্ষেপগুলি দেখায় যেখানে এআই প্লেয়ার এজেন্ট 2048 স্কোর পেতে পারে, এবারও পরম মানের হিউরিস্টিক যুক্ত করুন:

এখানে চিত্র বর্ণনা লিখুন

নিম্নলিখিত পরিসংখ্যানগুলিতে কেবলমাত্র একক পদক্ষেপের জন্য কম্পিউটারকে প্রতিপক্ষ হিসাবে ধরে নিয়েছে প্লেয়ার এআই এজেন্ট দ্বারা গেম ট্রিটিকে অন্বেষণ করা হয়েছে:

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন


9

আমি হাসকেলে একটি 2048 সমাধানকারী লিখেছি, মূলত কারণ এখনই এই ভাষাটি শিখছি।

আমার গেমটির বাস্তবায়ন প্রকৃত গেম থেকে কিছুটা আলাদা, এতে একটি নতুন টাইল সর্বদা একটি '2' থাকে (90% 2 এবং 10% 4 এর চেয়ে বেশি)। এবং যে নতুন টাইলটি এলোমেলো নয়, তবে সর্বদা উপরে বাম দিক থেকে প্রথম উপলব্ধ। এই রূপটি ডিট 2048 নামেও পরিচিত ।

ফলস্বরূপ, এই সমাধানকারী হ'ল নির্বিচারবাদী।

আমি একটি বিস্তৃত অ্যালগরিদম ব্যবহার করেছি যা খালি টাইলগুলির পক্ষে। এটি গভীরতা 1-4-এর জন্য খুব দ্রুত সম্পাদন করে, তবে গভীরতা 5 এ এটি চলন প্রতি 1 সেকেন্ডের চেয়ে বরং ধীর হয়ে যায়।

নীচে সমাধান অ্যালগরিদম বাস্তবায়ন কোড দেওয়া আছে। গ্রিডটি পূর্ণসংখ্যার 16-দৈর্ঘ্যের অ্যারে হিসাবে উপস্থাপিত হয়। এবং স্কোরিং খালি স্কোয়ারের সংখ্যা গণনা করেই করা হয়।

bestMove :: Int -> [Int] -> Int
bestMove depth grid = maxTuple [ (gridValue depth (takeTurn x grid), x) | x <- [0..3], takeTurn x grid /= [] ]

gridValue :: Int -> [Int] -> Int
gridValue _ [] = -1
gridValue 0 grid = length $ filter (==0) grid  -- <= SCORING
gridValue depth grid = maxInList [ gridValue (depth-1) (takeTurn x grid) | x <- [0..3] ]

আমি মনে করি এটির সরলতার জন্য এটি বেশ সফল। খালি গ্রিড দিয়ে শুরু করার সময় এবং গভীরতা 5 এ সমাধান করার সময় এটি পৌঁছায়:

Move 4006
[2,64,16,4]
[16,4096,128,512]
[2048,64,1024,16]
[2,4,16,2]

Game Over

উত্স কোডটি এখানে পাওয়া যাবে: https://github.com/popovitsj/2048-haskell


আসল নিয়মগুলি দিয়ে এটি প্রসারিত করার চেষ্টা করুন। হাস্কেলের এলোমেলো জেনারেটর সম্পর্কে জানার পক্ষে এটি একটি ভাল চ্যালেঞ্জ!
টমাস আহলে

আমি হাসেলকে এটি করার চেষ্টা করে খুব হতাশ হয়ে পড়েছিলাম, তবে আমি সম্ভবত এটি দ্বিতীয়বার চেষ্টা করব! আমি খুঁজে পেয়েছি যে গেমটি এলোমেলোভাবে ছাড়াই যথেষ্ট সহজ হয়ে যায়।
wvdz

এলোমেলোকরণ ছাড়াই আমি নিশ্চিত যে আপনি সর্বদা 16 কে বা 32 কে পাওয়ার কোনও উপায় খুঁজে পেতে পারেন। তবে হাস্কেলের এলোমেলোকরণটি খুব খারাপ নয়, আপনার কেবল 'বীজ' এর কাছাকাছি যাওয়ার একটি উপায় প্রয়োজন। হয় এটি স্পষ্টভাবে করুন, বা এলোমেলো মোনাদ দিয়ে।
টমাস আহলে

অ্যালগরিদমকে পরিমার্জন করা যাতে এটি সর্বদা 16k / 32k এ পৌঁছে যায় একটি নন-র্যান্ডম গেমের জন্য অন্য আকর্ষণীয় চ্যালেঞ্জ হতে পারে ...
wvdz

আপনি ঠিক বলেছেন, আমি যা ভাবি তার চেয়েও শক্ত। আমি এই ক্রমটি সন্ধান করতে পেরেছি: [ইউ.পি., লেফট, লেফট, ইউপি, লেফট, ডাউন, লেফট] যা সর্বদা গেমটি জিততে পারে তবে এটি ২০৪৮ এর উপরে যায় না ( পরেরটি ঘড়ির কাঁটার ক্রমে)
টমাস আহলে

6

এই অ্যালগরিদম গেমটি জয়ের জন্য অনুকূল নয়, তবে এটি সম্পাদন এবং প্রয়োজনীয় কোডের পরিমাণের ক্ষেত্রে মোটামুটি অনুকূল:

  if(can move neither right, up or down)
    direction = left
  else
  {
    do
    {
      direction = random from (right, down, up)
    }
    while(can not move in "direction")
  }

10
এটি আরও ভাল কাজ করে যদি আপনি বলেন তবে random from (right, right, right, down, down, up) সমস্ত পদক্ষেপ সমান সম্ভাবনার নয়। :)
ড্যারেন

3
আসলে, আপনি যদি গেমটিতে সম্পূর্ণ নতুন হন তবে এটি কেবল 3 টি কী ব্যবহার করতে সহায়তা করে যা মূলত এই অ্যালগরিদমটি করে। তাই প্রথম দর্শনে যেমন মনে হয় ততটা খারাপ নয়।
সংখ্যা 18

5
হ্যাঁ, এটি গেমটির সাথে আমার নিজের পর্যবেক্ষণের ভিত্তিতে তৈরি। আপনার চতুর্থ দিকটি ব্যবহার না করা অবধি গেমটি কোনও ধরণের পর্যবেক্ষণ ছাড়াই ব্যবহারিকভাবে নিজেকে সমাধান করবে। এই "এআই" কোনও ব্লকের সঠিক মান পরীক্ষা না করে 512-1024 এ সক্ষম হতে হবে।
এপিআই-বিস্ট

3
একটি যথাযথ এআই এমন একটি রাজ্যে প্রবেশ করা এড়াতে চেষ্টা করবে যেখানে এটি কেবল কোনও মূল্যে এক দিকে যেতে পারে।
এপিআই-বিস্ট

3
কেবলমাত্র 3 টি দিকনির্দেশ ব্যবহার করা খুব শালীন কৌশল! এটি আমাকে প্রায় 2048 টি ম্যানুয়ালি গেমটি খেলতে পেয়েছিল। যদি আপনি এই 3 টি চলনের মধ্যে সিদ্ধান্ত নেওয়ার জন্য অন্যান্য কৌশলগুলির সাথে একত্রিত করেন তবে এটি খুব শক্তিশালী হতে পারে। পছন্দটি 3 এ হ্রাস করার ফলে পারফরম্যান্সে ব্যাপক প্রভাব পড়ে mention
wvdz

4

অন্যান্য উত্তরগুলির মধ্যে অনেকগুলি এআই ব্যবহার করে সম্ভাব্য ফিউচার, হিউরিস্টিক্স, শেখা এবং এর মতো কম্পিউটারের ব্যয়বহুল অনুসন্ধানে। এগুলি চিত্তাকর্ষক এবং সম্ভবত এগিয়ে যাওয়ার সঠিক উপায়, তবে আমি অন্য একটি ধারণা অবদান রাখতে চাই।

কৌশলটির ধরণের মডেল করুন যা গেমের ভাল খেলোয়াড়েরা ব্যবহার করে।

উদাহরণ স্বরূপ:

13 14 15 16
12 11 10  9
 5  6  7  8
 4  3  2  1

পরবর্তী স্কোয়ারের মান বর্তমানের চেয়ে বেশি না হওয়া পর্যন্ত উপরের ক্রমের স্কোয়ারগুলি পড়ুন। এটি একই মানটির অন্য একটি টাইলকে এই স্কোয়ারে একীভূত করার চেষ্টা করার সমস্যাটি উপস্থাপন করে।

এই সমস্যাটি সমাধান করার জন্য, এগুলি দুটি উপায় যা চালিয়ে যাওয়া বা আরও খারাপ না হওয়া এবং দুটি সম্ভাবনা পরীক্ষা করা তত্ক্ষণাত আরও সমস্যা প্রকাশ করতে পারে, এটি নির্ভরশীলতার একটি তালিকা তৈরি করে, প্রতিটি সমস্যা প্রথমে সমাধান করার প্রয়োজন হয়। আমার মনে হয় আমার এই চেইনটি রয়েছে বা কিছু ক্ষেত্রে আমার পরবর্তী পদক্ষেপের সিদ্ধান্ত নেওয়ার সময় অভ্যন্তরীণভাবে নির্ভরশীলতার গাছ রয়েছে, বিশেষত আটকে গেলে।


টাইলটির প্রতিবেশীর সাথে মার্জ হওয়া দরকার তবে এটি খুব ছোট: এই সাথে অন্য প্রতিবেশীকে মার্জ করুন।

বড় আকারের টাইল: ছোট ছোট পার্শ্ববর্তী টাইলের মান বাড়ান।

ইত্যাদি ...


পুরো পদ্ধতির সম্ভবত এটি আরও জটিল হবে তবে বেশি জটিল হবে না। স্কোর, ওজন, নিউরোনস এবং সম্ভাবনার গভীর অনুসন্ধানগুলির অভাব অনুভব করা এই যান্ত্রিক হতে পারে। সম্ভাবনার গাছটি খুব কমই বড় হওয়া দরকার এমনকি কোনও শাখা প্রশাখার প্রয়োজন।


5
আপনি হিউরিস্টিক্স সহ স্থানীয় অনুসন্ধানের বর্ণনা দিচ্ছেন। এটি আপনাকে আটকে রাখবে, সুতরাং আপনাকে পরবর্তী পদক্ষেপের জন্য পরিকল্পনা করতে হবে। ফলস্বরূপ এটি সমাধানের সন্ধান এবং স্কোরিংয়ের দিকেও যায় (সিদ্ধান্ত নেওয়ার জন্য)। সুতরাং এটি অন্য যে কোনও উপস্থাপিত সমাধানের চেয়ে আলাদা নয়।
চালাডসরুন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.