2048 ක්‍රීඩාව සඳහා ප්‍රශස්ත ඇල්ගොරිතම කුමක්ද?


1921

මම මෑතකදී 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 ක් පමණි. උපරිම ලකුණු AFAIK ලකුණු 20,000 ට වඩා තරමක් වැඩි වන අතර එය මගේ වර්තමාන ලකුණු වලට වඩා විශාලය. ඉහත ඒවාට වඩා හොඳ ඇල්ගොරිතමයක් තිබේද?


84
මෙය උදව් විය හැකිය! ov3y.github.io/2048-AI
cegprakash

5
it nitish712 මාර්ගය වන විට, ඔබේ ඇල්ගොරිතමය කෑදර වන්නේ ඔබ සතුව choose the move with large number of mergesදේශීය
ප්‍රශස්ත තත්වයට

21
@ 500-අභ්‍යන්තර සේවාදායක දෝෂය: මම ඇල්ෆා-බීටා ගේම් ගස් කප්පාදු කිරීම සමඟ AI ක්‍රියාත්මක කරන්නේ නම්, නව කුට්ටි අහිතකර ලෙස ස්ථානගත කර ඇතැයි උපකල්පනය කෙරේ. එය නරකම උපකල්පනයකි, නමුත් ප්‍රයෝජනවත් විය හැකිය.
චාල්ස්

6
ඉහළ ලකුණු ලබා ගැනීම සඳහා ඔබට කාලය නොමැති විට විනෝදජනක අවධානය වෙනතකට යොමු කිරීම: හැකි අඩුම ලකුණු ලබා ගැනීමට උත්සාහ කරන්න. න්‍යාය අනුව එය 2s සහ 4s ප්‍රත්‍යාවර්ත වේ.
මාර්ක් හර්ඩ්

7
මෙම ප්‍රශ්නයේ නීත්‍යානුකූලභාවය පිළිබඳ සාකච්ඡාව මෙටා: meta.stackexchange.com/questions/227266/… හි
ජෙරොයින් වැනේවෙල්

Answers:


1268

48 ovolve හි ඇල්ගොරිතම භාවිතා කරන මිනිමැක්ස් සෙවුම වෙනුවට මම එක්ස්පෙක්ටිමැක්ස් ප්‍රශස්තිකරණය භාවිතා කරමින් 2048 AI සංවර්ධනය කළෙමි . AI හුදෙක් හැකි සෑම පියවරකටම වඩා උපරිම කිරීම සිදු කරයි, ඉන්පසු හැකි සියලුම ටයිල් ස්පෝන් වලට වඩා අපේක්‍ෂා කරයි (උළු වල සම්භාවිතාව අනුව බර, එනම් 4 සඳහා 10% සහ 2 සඳහා 90%). මා දන්නා පරිදි, අපේක්‍ෂා ප්‍රශස්තිකරණය කප්පාදු කළ නොහැක (බොහෝ දුරට ඉඩක් නැති අතු ඉවත් කිරීම හැර), එබැවින් භාවිතා කරන ඇල්ගොරිතම පරිස්සමින් ප්‍රශස්තිකරණය කළ තිරිසන් බල සෙවීමකි.

කාර්ය සාධනය

AI එහි පෙරනිමි වින්‍යාසය තුළ (උපරිම සෙවුම් ගැඹුර 8) පුවරුවේ පිහිටීමෙහි සංකීර්ණතාවය මත පදනම්ව, පියවරක් ක්‍රියාත්මක කිරීමට මීටර් 10 සිට මීටර් 200 දක්වා ඕනෑම තැනක ගත වේ. පරීක්ෂණයේදී, සමස්ත ක්‍රීඩාවක් තුළම තත්පරයට 5-10 ක සාමාන්‍ය චලනයක් AI ලබා ගනී. සෙවුම් ගැඹුර චලනයන් 6 කට සීමා කර ඇත්නම්, AI ට තත්පරයට 20+ චලනයන් පහසුවෙන් ක්‍රියාත්මක කළ හැකි අතර එමඟින් සිත්ගන්නාසුලු නැරඹීමක් ලබා ගත හැකිය.

AI හි ලකුණු ක්‍රියාකාරිත්වය තක්සේරු කිරීම සඳහා, මම AI 100 වතාවක් ධාවනය කළෙමි (දුරස්ථ පාලකය හරහා බ්‍රව්සර් ක්‍රීඩාවට සම්බන්ධ කර ඇත). සෑම ටයිල් එකක් සඳහාම, එම ටයිල් එක අවම වශයෙන් එක් වරක්වත් සාක්ෂාත් කර ගත් ක්‍රීඩා අනුපාතය:

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

සියලුම ලකුණු වලට වඩා අවම ලකුණු 124024; ලබාගත් උපරිම ලකුණු සංඛ්‍යාව 794076 කි. මධ්‍යන්‍ය අගය 387222 වේ. 2048 ටයිල් එක ලබා ගැනීමට AI කිසි විටෙකත් අසමත් විය (එබැවින් එය තරඟ 100 කට වරක්වත් පරාජය නොවීය); ඇත්ත වශයෙන්ම, එය සෑම ධාවන තරඟයකදීම අවම වශයෙන් එක් වරක්වත් 8192 ටයිල් එක ලබා ගත්තේය!

හොඳම ධාවනයේ තිර රුව මෙන්න:

32768 ටයිල්, ලකුණු 794076

මෙම ක්‍රීඩාවට මිනිත්තු 96 ක් තුළ චලනයන් 27830 ක් හෝ තත්පරයට සාමාන්‍යයෙන් 4.8 ක් ගෙන ඇත.

ක්‍රියාත්මක කිරීම

මගේ ප්‍රවේශය මුළු පුවරුවම (ඇතුළත් කිරීම් 16) තනි-බිට් 64 නිඛිලයක් ලෙස සංකේතවත් කරයි (එහිදී උළු යනු නයිබල්, එනම් 4-බිට් කුට්ටි). 64-බිට් යන්ත්‍රයක, මෙය මුළු පුවරුවම තනි යන්ත්‍ර ලේඛනයකින් යැවිය හැක.

තනි පේළි සහ තීරු උකහා ගැනීම සඳහා බිට් මාරුව මෙහෙයුම් භාවිතා කරයි. තනි පේළියක් හෝ තීරුවක් බිටු 16 ක ප්‍රමාණයකි, එබැවින් 65536 ප්‍රමාණයේ වගුවකට තනි පේළියක හෝ තීරුවක ක්‍රියාත්මක වන පරිවර්තනයන් කේතනය කළ හැකිය. නිදසුනක් ලෙස, එක් එක් පියවර තනි පේළියකට හෝ තීරුවකට බලපාන්නේ කෙසේද යන්න විස්තර කරන පෙර සැකසූ “චලන බලපෑම් වගුවකට” චලනයන් 4 ක් ලෙස ක්‍රියාත්මක වේ (නිදසුනක් ලෙස, “දකුණට ගෙනයන්න” වගුවේ “1122 -> 0023” ඇතුළත් කිරීම විස්තර කරන්නේ කෙසේද? පේළිය [2,2,4,4] දකුණට ගෙන යන විට [0,0,4,8] පේළිය බවට පත්වේ).

ලකුණු කිරීම ද වගු බැලීම මඟින් සිදු කෙරේ. වගු වල ඇති විය හැකි සියලු පේළි / තීරු මත ගණනය කළ හැකි ලකුණු අඩංගු වන අතර, එහි ප්‍රති result ලයක් ලෙස පුවරුවක් යනු එක් එක් පේළිය සහ තීරුව හරහා ඇති වගු අගයන්ගේ එකතුවයි.

මෙම පුවරු නිරූපණය, චලනය හා ලකුණු කිරීම සඳහා වගු බැලීමේ ප්‍රවේශය සමඟින්, කෙටි කාලයක් තුළ ක්‍රීඩා රාජ්‍යයන් විශාල සංඛ්‍යාවක් සෙවීමට AI ට ඉඩ දෙයි (මගේ 2011 මැද භාගයේ ලැප්ටොප් පරිගණකයේ එක් හරයක් මත තත්පරයට ක්‍රීඩා ප්‍රාන්ත 10,000,000 කට වඩා).

“අපේක්‍ෂා” පියවර (විකල්ප ටයිල් ස්පොන්ජ් ස්ථාන සහ අගයන් පරික්ෂා කිරීම, සහ එක් එක් හැකියාවෙහි සම්භාවිතාව අනුව ඒවායේ ප්‍රශස්තිකරණය කළ ලකුණු ගණනය කිරීම) සහ “උපරිම” පියවර (හැකි සෑම පියවරක්ම පරීක්ෂා කිරීම) අතර වෙනස්වන පුනරාවර්තන සෙවුමක් ලෙස අපේක්‍ෂා සෙවීම කේත කර ඇත. සහ හොඳම ලකුණු ලබා ගත් එකක් තෝරා ගැනීම). ගස් සෙවීම අවසන් වන්නේ කලින් දුටු ස්ථානයක් දුටු විට (ස්ථාන මාරු වගුවක් භාවිතා කරමින් ), එය පූර්ව නිශ්චිත ගැඹුරකට ළඟා වූ විට හෝ එය බොහෝ දුරට ඉඩක් නොමැති පුවරු තත්වයකට ළඟා වූ විට ය (උදා: උළු 6 "4" ලබා ගැනීමෙන් එය ළඟා විය ආරම්භක ස්ථානයේ සිට පේළියක). සාමාන්‍ය සෙවුම් ගැඹුර 4-8 චලනයන් වේ.

හියුරිස්ටික්

ප්‍රශස්තිකරණ ඇල්ගොරිතම වාසිදායක ස්ථාන කරා යොමු කිරීම සඳහා හියුරිස්ටික් කිහිපයක් භාවිතා කරයි. හියුරිස්ටික් නිවැරදිව තෝරා ගැනීම ඇල්ගොරිතමයේ ක්‍රියාකාරීත්වයට විශාල බලපෑමක් ඇති කරයි. විවිධ හියුරිස්ටික්ස් කිරා මැන බලා ස්ථානීය ලකුණු බවට සංයුක්ත වන අතර එමඟින් ලබා දී ඇති පුවරු පිහිටීම කෙතරම් “හොඳ ”ද යන්න තීරණය වේ. ප්‍රශස්තිකරණ සෙවුම මඟින් හැකි සෑම පුවරු තනතුරකම සාමාන්‍ය අගය උපරිම කිරීම අරමුණු කරයි. උළු ඒකාබද්ධ කිරීම සඳහා වැඩි බරක් ඇති බැවින් (ලකුණු කිරීම ප්‍රමාද වීමෙන් විශාල ප්‍රතිලාභයක් ලැබිය හැකිය) , ක්‍රීඩාවේ පෙන්වා ඇති පරිදි සත්‍ය ලකුණු පුවරුවේ ලකුණු ගණනය කිරීමට භාවිතා නොවේ .

මුලදී, මම ඉතා සරල ප්‍රතිකාර දෙකක් භාවිතා කළෙමි, විවෘත චතුරස්රයන් සඳහා "බෝනස්" ලබා දීම සහ විශාල අගයන් අද්දර තිබීම. මෙම හියුරිස්ටික්ස් ඉතා හොඳින් ක්‍රියාත්මක වූ අතර නිතරම 16384 ලබා ගත් නමුත් 32768 වෙත ළඟා නොවීය.

පීටර් මොරවෙක් (ificificurk) මගේ AI රැගෙන නව ප්‍රතිකාර දෙකක් එකතු කළේය. පළමු හියුරිස්ටික් යනු ඒකාකාරී නොවන පේළි සහ තීරු තිබීම සඳහා වන ද penalty ුවමකි, එය ශ්‍රේණිගත කිරීම් වැඩි වන විට කුඩා සංඛ්‍යා වල ඒකාකාරී නොවන පේළි ලකුණු වලට තදින්ම බලපාන්නේ නැති බව සහතික කරයි, නමුත් විශාල සංඛ්‍යාවක ඒකාකාරී නොවන පේළි ලකුණු සැලකිය යුතු ලෙස රිදවයි. දෙවන හියුරිස්ටික් විසින් විවෘත අවකාශයන්ට අමතරව විභව ඒකාබද්ධ කිරීම් (යාබද සමාන අගයන්) ගණනය කරන ලදි. ඇල්ගොරිතම ඒකාකාරී පුවරු දෙසට (ඒකාබද්ධ කිරීමට පහසු), සහ ඒකාබද්ධ කිරීම් රාශියක් ඇති පුවරු තනතුරු දෙසට තල්ලු කිරීමට මෙම හියුරිස්ටික්ස් දෙක සේවය කළේය (වැඩි බලපෑමක් සඳහා හැකි සෑම තැනකම ඒකාබද්ධ කිරීමට පෙළඹවීම).

තවද, පීටර් විසින් "මෙටා-ප්‍රශස්තිකරණ" උපාය මාර්ගයක් ( සීඑම්ඒ-ඊඑස් නමින් ඇල්ගොරිතමයක් භාවිතා කරමින්) භාවිතා කරමින් හියුරිස්ටික් පඩි ප්‍රශස්තිකරණය කරන ලද අතර එහිදී උපරිම සාමාන්‍ය ලකුණු ලබා ගැනීම සඳහා පඩි සකස් කර ගන්නා ලදී.

මෙම වෙනස්කම්වල බලපෑම අතිශයින්ම වැදගත් ය. ඇල්ගොරිතම 16384 ටයිල් එක 13% ක් පමණ ළඟා කර ගැනීමෙන් 90% කට වඩා වැඩි කාලයක් ළඟා කර ගත් අතර ඇල්ගොරිතමයෙන් කාලයෙන් 1/3 කට වඩා 32768 ක් ලබා ගැනීමට පටන් ගත්තේය (පැරණි හියුරිස්ටික්ස් කිසි විටෙකත් 32768 ටයිල් එකක් නිපදවා නැත) .

හියුරිස්ටික් වැඩිදියුණු කිරීමට තවමත් ඉඩ ඇති බව මම විශ්වාස කරමි. මෙම ඇල්ගොරිතම නිසැකවම තවමත් "ප්‍රශස්ත" නොවේ, නමුත් එය තරමක් සමීප වන බවක් මට හැඟේ.


AI සිය ක්‍රීඩා වලින් තුනෙන් එකකට වඩා 32768 ටයිල් එක ලබා ගැනීම විශාල සන්ධිස්ථානයකි; කිසියම් මිනිස් ක්‍රීඩකයෙකු නිල ක්‍රීඩාවෙන් 32768 ක් ලබාගෙන ඇත්දැයි ඇසීමෙන් මා පුදුමයට පත් වනු ඇත (එනම්, සේස්ටේට් හෝ අහෝසි කිරීම වැනි මෙවලම් භාවිතා නොකර). මම හිතන්නේ 65536 ටයිල් එක ළඟයි!

ඔබට AI අත්හදා බැලිය හැකිය. කේතය https://github.com/nneonneo/2048-ai වෙතින් ලබා ගත හැකිය .


12
@RobL: 2 ගේ කාලය 90% ක් පෙනේ; 4 ගේ කාලය 10% ක් පෙනේ. එය ප්‍රභව කේතයේ ඇත : var value = Math.random() < 0.9 ? 2 : 4;.
nneonneo

35
දැනට කුඩා වෙත වරාය කරන බැවින් GPU ඊටත් වඩා හොඳ වේගයකින් වැඩ කරයි!
nimsson

25
nenneonneo මම ඔබේ කේතය එම්ස්ක්‍රිප්ටෙන් සමඟ ජාවාස්ක්‍රිප්ට් වෙත ගෙන ගිය අතර එය දැන් බ්‍රව්සරයේ හොඳින් ක්‍රියාත්මක වේ ! සම්පාදනය කිරීමේ අවශ්‍යතාවය සහ සියල්ල නොමැතිව නැරඹීමට සිසිල් ... ෆයර්ෆොක්ස් හි කාර්ය සාධනය තරමක් හොඳයි ...
ප්‍රතිවිකුණුම් ඉංජිනේරු

7
4x4 ජාලයක න්‍යායාත්මක සීමාව ඇත්ත වශයෙන්ම IS 131072 නොව 65536 වේ. කෙසේ වෙතත් ඒ සඳහා නියම මොහොතේ 4 ක් ලබා ගැනීම අවශ්‍ය වේ (එනම් මුළු පුවරුව 4 කින් පුරවා ඇත. 65536 බැගින් - ක්ෂේත්‍ර 15 ක්) මොහොත එවිට ඔබට සැබවින්ම ඒකාබද්ධ කළ හැකිය.
බොඩෝ තිසන්

5
nenononneo 60% ක්‍රීඩා වලින් 32k දක්වා ළඟා වන අපගේ AI පරීක්ෂා කිරීමට ඔබට අවශ්‍ය විය හැකිය: github.com/aszczepanski/2048
cauchy

1253

මෙම ත්‍රෙඩ් එකේ අනෙක් අය සඳහන් කළ AI වැඩසටහනේ කතුවරයා මමයි. ඔබට AI ක්‍රියාවෙන් බැලීමට හෝ ප්‍රභවය කියවීමට හැකිය .

වර්තමානයේදී, මගේ ලැප්ටොප් පරිගණකයේ බ්‍රව්සරයේ ජාවාස්ක්‍රිප්ට් වලින් 90% ක ජයග්‍රාහී අනුපාතයක් ලබා ගැනීමට මෙම වැඩසටහන සමත් වී ඇති අතර එමඟින් එක් චලනයකට මිලි තත්පර 100 ක සිතීමේ වේලාවක් ලබා දී ඇත.

ක්‍රීඩාව විවික්ත රාජ්‍ය අවකාශයක්, පරිපූර්ණ තොරතුරු, චෙස් සහ චෙක්පත් වැනි හැරවුම් පාදක ක්‍රීඩාවක් බැවින්, මම එම ක්‍රීඩා වල වැඩ කිරීමට ඔප්පු කර ඇති ක්‍රමවේදයන්ම භාවිතා කළෙමි, එනම් ඇල්ෆා-බීටා කප්පාදු සමඟ මිනිමැක්ස් සෙවීම . එම ඇල්ගොරිතම පිළිබඳ දැනටමත් බොහෝ තොරතුරු එහි ඇති හෙයින්, මම ස්ථිතික ඇගයීමේ කාර්යයේදී භාවිතා කරන ප්‍රධාන ප්‍රතිකාර ක්‍රම දෙක ගැන කතා කරමි . අනෙක් අය මෙහි ප්‍රකාශ කර ඇති බොහෝ ප්‍රතිභාව විධිමත් කරයි.

ඒකාකාරී බව

උළු වල අගයන් සියල්ලම වම් / දකුණ සහ ඉහළ / පහළ දිශාවන් ඔස්සේ වැඩි වෙමින් හෝ අඩුවෙමින් පවතින බව සහතික කිරීමට මෙම හියුරිස්ටික් උත්සාහ කරයි. මෙම හියුරිස්ටික් පමණක් වෙනත් බොහෝ අය සඳහන් කර ඇති පරිදි, ඉහළ වටිනාකමින් යුත් උළු කෙළවරක පොකුරු කළ යුතුය. එය සාමාන්‍යයෙන් කුඩා වටිනා උළු අනාථ වීම වලක්වනු ඇති අතර පුවරුව ඉතා සංවිධානාත්මකව තබා ගනු ඇත, කුඩා උළු කැස්බෑඩ් කර විශාල උළු වලට පුරවනු ඇත.

මෙන්න පරිපූර්ණ ඒකාකාරී ජාලයක තිර රුවක්. මම මෙය ලබාගත්තේ ඇල්ගොරිතම ක්‍රියාත්මක කරමින් අනෙක් ක්‍රියාකාරීත්වය නොසලකා හැරීම සඳහා වන එවාල් ශ්‍රිතය සමඟිනි.

පරිපූර්ණ ඒකාකාරී 2048 පුවරුව

සුමට බව

ඉහත හියුරිස්ටික් පමණක් යාබද උළු වල වටිනාකම අඩු වන ව්‍යුහයන් නිර්මාණය කිරීමට නැඹුරු වන නමුත් ඇත්ත වශයෙන්ම ඒකාබද්ධ කිරීම සඳහා යාබද උළු එකම අගයක් විය යුතුය. එමනිසා, සුමටතාව හියුරිස්ටික් මගින් අසල්වැසි උළු අතර ඇති වටිනාකමෙහි වෙනස මනිනු ලබන අතර මෙම අගය අවම කිරීමට උත්සාහ කරයි.

හැකර් නිවුස් හි විචාරකයෙකු ප්‍රස්ථාර න්‍යායට අනුව මෙම අදහස සිත්ගන්නාසුලු විධිමත් කිරීමක් ලබා දුන්නේය .

මෙන්න පරිපූර්ණ සුමට ජාලයක තිර රුවක්, මෙම විශිෂ්ට උපහාසාත්මක දෙබලක අනුග්‍රහයෙනි .

පරිපූර්ණ සුමට 2048 පුවරුවක්

නොමිලේ ටයිල්ස්

අවසාන වශයෙන්, නොමිලේ ටයිල් ප්‍රමාණයක් තිබීම සඳහා ද penalty ුවමක් ඇත, මන්ද ක්‍රීඩා පුවරුව අධික ලෙස අවහිර වූ විට විකල්ප ඉක්මනින් ඉවර විය හැකිය.

ඒක තමයි! මෙම නිර්ණායක ප්‍රශස්තිකරණය කරමින් ක්‍රීඩා අවකාශය හරහා සෙවීම විශිෂ්ට කාර්ය සාධනයක් ලබා දෙයි. පැහැදිලිවම කේතනය කරන ලද උපාය මාර්ගයකට වඩා මෙවැනි සාමාන්‍යකරණය කළ ප්‍රවේශයක් භාවිතා කිරීමේ එක් වාසියක් නම් ඇල්ගොරිතමයට බොහෝ විට සිත්ගන්නාසුළු හා අනපේක්ෂිත විසඳුම් සොයා ගත හැකි වීමයි. ඔබ එය ධාවනය කරන්නේ නම්, එය බොහෝ විට පුදුම සහගත නමුත් move ලදායී පියවරයන් ගනු ඇත, එය හදිසියේම කුමන බිත්තියක් හෝ කොනක් එහාට මෙහාට මාරු කිරීම වැනි ය.

සංස්කරණය කරන්න:

මෙන්න මෙම ප්රවේශයේ බලය පිළිබඳ නිරූපණයකි. මම ටයිල් අගයන් නොසලකා හැරියෙමි (එබැවින් එය 2048 කරා ළඟා වූ පසු දිගටම පැවතුනි) සහ අත්හදා බැලීම් අටකට පසු හොඳම ප්‍රති result ලය මෙන්න.

4096 කි

ඔව්, එය 2048 ට සමගාමීව 4096 කි. =) එයින් අදහස් කරන්නේ එය එකම පුවරුවේ තුන් වතාවක් නොපැහැදිලි 2048 ටයිල් එක ලබා ගත් බවයි.


89
'2' සහ '4' ටයිල් තැබූ පරිගණකය 'ප්‍රතිවාදියා' ලෙස සැලකිය හැකිය.
යෙන්

29
EWeiYen ෂුවර්, නමුත් එය මිනිමැක්ස් ගැටළුවක් ලෙස සැලකීම ක්‍රීඩා තර්කනයට විශ්වාසවන්ත නොවේ, මන්ද පරිගණකය හිතාමතාම ලකුණු අවම කරනවාට වඩා අහඹු ලෙස ඇතැම් සම්භාවිතාවන් සමඟ උළු තබයි.
koo

57
AI අහඹු ලෙස උළු තැබුවද, ඉලක්කය නැතිවීම නොවේ. අවාසනාවන්ත වීම ප්‍රතිවාදියා ඔබ වෙනුවෙන් නරකම පියවර තෝරා ගැනීම හා සමානයි. "මිනි" කොටසෙහි අර්ථය වන්නේ ඔබ අවාසනාවන්ත ලෙස ලබා ගත හැකි භයානක පියවරයන් නොතිබීම සඳහා ඔබ ගතානුගතිකව සෙල්ලම් කිරීමට උත්සාහ කිරීමයි.
ෆ්‍රයිගුයි

196
2048 හි දෙබලක නිර්මාණය කිරීමට මට අදහසක් තිබුණි, එහිදී පරිගණකය 2 සහ 4s ස්ථානගත කිරීම වෙනුවට අහඹු ලෙස ඔබේ AI භාවිතා කර අගයන් තැබිය යුත්තේ කොතැනදැයි තීරණය කරයි. ප්‍රති result ලය: සම්පූර්ණයෙන්ම කළ නොහැකි වීම. මෙතැනින් අත්හදා බැලිය හැකිය: sztupy.github.io/2048- හාර්ඩ්
SztupY

30
ZStupY වාව්, මෙය නපුරකි. Qntm.org/hatetris Hatetris මට මතක් කර දෙයි, එමඟින් ඔබේ තත්වය අවම වශයෙන් වැඩිදියුණු කරන කෑල්ලක් තැබීමට උත්සාහ කරයි.
පතාෂු

146

දෘඩ කේත සහිත බුද්ධියක් නොමැති මෙම ක්‍රීඩාව සඳහා AI පිළිබඳ අදහස ගැන මා උනන්දු විය (එනම් හියුරිස්ටික්, ලකුණු කිරීමේ කාර්යයන් ආදිය). කෘෂිකර්ම උපදේශක යුතු "දැන" ක්රීඩාව නීති පමණක්, සහ "ඉවත් චරිතයක්" ක්රීඩාව සෙල්ලම්. මෙය බොහෝ AI වලට (මෙම ත්‍රෙඩ් එකේ මෙන්) වෙනස් වේ, එහිදී ක්‍රීඩාව අත්‍යවශ්‍යයෙන්ම තිරිසන් බලවේගයක් වන අතර එය ක්‍රීඩාව පිළිබඳ මානව අවබෝධය නියෝජනය කරන ලකුණු ශ්‍රිතයක් මගින් මෙහෙයවනු ලැබේ.

AI ඇල්ගොරිතම

මට සරල නමුත් පුදුම හිතෙන තරම් හොඳ ක්‍රීඩා ඇල්ගොරිතමයක් හමු විය: දී ඇති පුවරුවක ඊළඟ පියවර තීරණය කිරීම සඳහා, AI භාවිතා කරමින් මතකයේ ක්‍රීඩාව කරයි , ක්‍රීඩාව අවසන් වන තුරු අහඹු ලෙස චලනයන් . අවසාන ක්‍රීඩා ලකුණු පිළිබඳ සටහන් තබා ගනිමින් මෙය කිහිප වතාවක් සිදු කරයි. ආරම්භක පියවරක් සඳහා සාමාන්‍ය අවසාන අගය ගණනය කෙරේ. ඉහළම සාමාන්‍ය ලකුණු සමඟ ආරම්භක පියවර ඊළඟ පියවර ලෙස තෝරා ගනු ලැබේ.

එක් පියවරකට ලකුණු 100 ක් (එනම් මතක ක්‍රීඩා වලදී), AI විසින් ටයිල් 2048 ටයිල් 80% ක් ද 4096 ටයිල් 50% ක් ද ලබා ගනී. ලකුණු 10000 භාවිතා කිරීමෙන් 2048 ටයිල් 100%, ටයිල් 4096 සඳහා 70% සහ ටයිල් 8192 සඳහා 1% ක් ලැබේ.

එය ක්‍රියාවෙන් බලන්න

ලබාගත් හොඳම ලකුණු මෙහි දැක්වේ:

හොඳම ලකුණු

මෙම ඇල්ගොරිතම පිළිබඳ සිත්ගන්නා කරුණක් නම්, අහඹු ලෙස ක්‍රීඩා කිරීම පුදුම සහගත ලෙස තරමක් නරක වුවත්, හොඳම (හෝ අවම වශයෙන් නරක) පියවරක් තෝරා ගැනීම ඉතා හොඳ ක්‍රීඩා ක්‍රීඩාවකට මග පාදයි: සාමාන්‍ය AI ක්‍රීඩාවකට ලකුණු 70000 ක් සහ අවසාන පියවර 3000 ක් කරා ළඟා විය හැකි නමුත්, ඕනෑම ස්ථානයක සිට මතකයේ ඇති අහඹු ක්‍රීඩා ක්‍රීඩා, මිය යාමට පෙර අමතර චලනයන් 40 ක් තුළ සාමාන්‍යයෙන් අතිරේක ලකුණු 340 ක් ලබා දෙයි. (AI ධාවනය කර නිදොස් කිරීමේ කොන්සෝලය විවෘත කිරීමෙන් ඔබට මෙය දැකගත හැකිය.)

මෙම ප්‍රස්ථාරය මෙම කරුණ නිරූපණය කරයි: නිල් රේඛාව එක් එක් පියවරෙන් පසු පුවරුවේ ලකුණු පෙන්වයි. රතු ඉරෙන් පෙන්නුම් කරන්නේ ඇල්ගොරිතමයේ හොඳම අහඹු ලෙස ධාවනය වන අවසන් ක්‍රීඩා ලකුණු එම ස්ථානයේ සිට බවයි. සාරාංශයක් ලෙස, රතු අගයන් ඇල්ගොරිතමයේ හොඳම අනුමානය වන බැවින් නිල් අගයන් ඔවුන් දෙසට ඉහළට ඇද දමයි. රතු රේඛාව සෑම අවස්ථාවකම නිල් රේඛාවට වඩා ඉතා කුඩා බව දැකීම සිත්ගන්නා කරුණකි, නමුත් නිල් රේඛාව තව තවත් වැඩි වේ.

ලකුණු ප්‍රස්තාරය

ඇල්ගොරිතමයට එය නිපදවන චලනයන් තෝරා ගැනීම සඳහා හොඳ ක්‍රීඩාවක් ගැන පුරෝකථනය කිරීම අවශ්‍ය නොවීම පුදුමයට කරුණකි.

පසුව සොයා බැලීමේදී මෙම ඇල්ගොරිතම පිරිසිදු මොන්ටේ කාලෝ ගස් සෙවුම් ඇල්ගොරිතමයක් ලෙස වර්ගීකරණය කළ හැකි බව මට පෙනී ගියේය.

ක්‍රියාත්මක කිරීම සහ සබැඳි

මුලින්ම මම කළ හැකි ජාවාස්ක්රිප්ට් අනුවාදය නිර්මාණය මෙහි පියවර දක්නට . මෙම අනුවාදයට හොඳ කාලයක් තුළ ලකුණු 100 ක් ධාවනය කළ හැකිය. අමතර තොරතුරු සඳහා කොන්සෝලය විවෘත කරන්න. ( මූලාශ්‍රය )

පසුව, තවත් සමහරක් සෙල්ලම් කිරීම සඳහා මම nenneonneo ඉතා ප්‍රශස්ත යටිතල පහසුකම් භාවිතා කළ අතර C ++ හි මගේ අනුවාදය ක්‍රියාත්මක කළෙමි. මෙම අනුවාදය මඟින් එක් පියවරකට ලකුණු 100000 ක් දක්වා සහ ඔබට ඉවසීම තිබේ නම් 1000000 ක් දක්වා ඉඩ ලබා දේ. ගොඩනැගිලි උපදෙස් සපයා ඇත. එය කොන්සෝලය තුළ ක්‍රියාත්මක වන අතර වෙබ් අනුවාදය වාදනය කිරීම සඳහා දුරස්ථ පාලකයක් ද ඇත. ( මූලාශ්‍රය )

ප්රතිපල

පුදුමයට කරුණක් නම්, ලකුණු ගණන වැඩි කිරීමෙන් ක්‍රීඩාවේ ක්‍රීඩාව විශාල ලෙස වැඩි නොවේ. 4096 ටයිල් සහ කුඩා සියල්ලම 8192 ටයිල් එක ළඟා කර ගැනීමට ඉතා ආසන්නව ලකුණු 80000 ක් පමණ මෙම උපාය මාර්ගයට සීමාවක් ඇති බව පෙනේ. ලකුණු සංඛ්යාව 100 සිට 100000 දක්වා වර්ධනය වැඩි වේ ගතවෙද්දී මෙම ලකුණු සීමාව (5% සිට 40% ක් දක්වා) වෙත ලබා නමුත් එය බිඳිමින් නොව.

විවේචනාත්මක ස්ථාන අසල තාවකාලිකව 1000000 දක්වා ලකුණු 10000 ක් ධාවනය කිරීමෙන් මෙම බාධකය 1% කට වඩා අඩු කාලයකින් උපරිම ලකුණු 129892 සහ 8192 ටයිල් ලබා ගැනීමට සමත් විය.

වැඩිදියුණු කිරීම්

මෙම ඇල්ගොරිතම ක්‍රියාත්මක කිරීමෙන් පසු මම අවම හෝ උපරිම ලකුණු භාවිතා කිරීම හෝ මිනි, උපරිම සහ සාමාන්‍ය සංයෝජන ඇතුළු බොහෝ දියුණු කිරීම් අත්හදා බැලුවෙමි. මම ගැඹුර භාවිතා කිරීමට ද උත්සාහ කළෙමි: එක් පියවරකට K ලකුණු උත්සාහ කරනවා වෙනුවට, දී ඇති දිගක (උදාහරණයක් ලෙස "ඉහළ, ඉහළ, වමේ") චලනය වන ලැයිස්තුවකට K චලනයන් උත්සාහ කර හොඳම ලකුණු ලබා ගැනීමේ ලැයිස්තුවේ පළමු පියවර තෝරා ගතිමි .

පසුව මම ලකුණු ගසක් ක්‍රියාත්මක කළ අතර එය ලබා දුන් පියවර ලැයිස්තුවෙන් පසුව පියවරක් තැබීමේ කොන්දේසි සහිත සම්භාවිතාව සැලකිල්ලට ගෙන.

කෙසේ වෙතත්, මෙම අදහස් කිසිවක් සරල පළමු අදහසට වඩා සැබෑ වාසියක් පෙන්නුම් කළේ නැත. C ++ කේතයේ අදහස් දක්වා ඇති මෙම අදහස් සඳහා මම කේතය තැබුවෙමි.

මම "ගැඹුරු සෙවුම්" යාන්ත්‍රණයක් එක් කළ අතර එමඟින් ලකුණු 1000000 දක්වා තාවකාලිකව ඉහළ නංවන ලදී. මෙය කාල වැඩිදියුණු කිරීමක් ලබා දුන්නේය.

AI හි වසම්-ස්වාධීනත්වය පවත්වා ගෙන යන වෙනත් වැඩිදියුණු කිරීමේ අදහස් යමෙකුට තිබේදැයි ඇසීමට මම කැමැත්තෙමි.

2048 ප්‍රභේද සහ ක්ලෝන

විනෝදය සඳහා පමණක්, මම AI ද පොත් සලකුණක් ලෙස ක්‍රියාවට නංවා , ක්‍රීඩාවේ පාලනයට සම්බන්ධ කර ගතිමි . මෙමඟින් AI හට මුල් ක්‍රීඩාව සහ එහි බොහෝ ප්‍රභේද සමඟ වැඩ කිරීමට ඉඩ ලබා දේ .

AI හි වසම්-ස්වාධීන ස්වභාවය නිසා මෙය කළ හැකිය. ෂඩාස්රාකාර ක්ලෝනය වැනි සමහර ප්‍රභේදයන් බෙහෙවින් වෙනස් ය.


7
+1. AI ශිෂ්‍යයෙකු ලෙස මට මෙය ඉතා සිත්ගන්නා සුළු විය. නිදහස් කාලය තුළ මේ පිළිබඳව වඩා හොඳින් සොයා බලනු ඇත.
අයිසැක්

4
මෙය පුදුම සහගතයි! මම එක්ස්පෙක්ටිමැක්ස් සඳහා හොඳ සුවදායී කාර්යයක් සඳහා බර ප්‍රශස්තිකරණය කිරීමට පැය ගණනක් ගත කළ අතර මම මෙය මිනිත්තු 3 කින් ක්‍රියාත්මක කරන අතර මෙය සම්පූර්ණයෙන්ම බිඳ දමයි.
බ්‍රෙන්ඩන් Annable

8
මොන්ටේ කාලෝ සමාකරණයේ හොඳ භාවිතය.
nneonneo

5
මෙම සෙල්ලම නැරඹීම බුද්ධිමත් බවක් ඉල්ලා සිටී. මෙය සියළුම සුව කිරීම් වලට පහර දෙන නමුත් එය ක්‍රියාත්මක වේ. සුභ පැතුම්!
ස්ටෙෆාන් ගුරිචොන්

4
බොහෝ දුරට, මෙහි වඩාත්ම සිත්ගන්නා විසඳුම.
ෂෙබා

126

සංස්කරණය කරන්න: මෙය බොළඳ ඇල්ගොරිතමයක් වන අතර එය මිනිස් සවි conscious ානික චින්තන ක්‍රියාවලියක් වන අතර AI හා සසඳන විට ඉතා දුර්වල ප්‍රති results ල ලබා ගනී. ප්‍රතිචාර කාලරාමුවෙහි එය මුලින් ඉදිරිපත් කරන ලදී.

මම ඇල්ගොරිතම පිරිපහදු කර ක්‍රීඩාව පරාජය කර ඇත්තෙමි! අවසානයට ආසන්න සරල අවාසනාව හේතුවෙන් එය අසාර්ථක විය හැකිය (ඔබට කිසි විටෙකත් නොකළ යුතු පහළට යාමට බල කෙරී ඇති අතර ඔබේ ඉහළම ස්ථානය තිබිය යුතු ටයිල් එකක් දිස්වේ. ඉහළ පේළිය පුරවා තබා ගැනීමට උත්සාහ කරන්න, එවිට වමට ගමන් නොකෙරේ රටාව බිඳ දමන්න), නමුත් මූලික වශයෙන් ඔබ අවසන් වන්නේ ස්ථාවර කොටසක් සහ ජංගම කොටසක් සමඟ සෙල්ලම් කිරීමටය. මෙය ඔබේ පරමාර්ථයයි:

අවසන් කිරීමට සූදානම්

පෙරනිමියෙන් මා තෝරාගත් ආකෘතිය මෙයයි.

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

තෝරාගත් කෙළවර අත්තනෝමතික ය, ඔබ මූලික වශයෙන් කිසි විටෙකත් එක් යතුරක් එබිය යුතු නැත (තහනම් පියවර), ඔබ එසේ කරන්නේ නම්, ඔබ නැවත වරක් ප්‍රතිවිරුද්ධ දේ ඔබා එය නිවැරදි කිරීමට උත්සාහ කරයි. අනාගත ටයිල් සඳහා ආකෘතිය සැමවිටම අපේක්ෂා කරන්නේ ඊළඟ අහඹු ටයිල් එක 2 ක් වන අතර එය වර්තමාන ආකෘතියට ප්‍රතිවිරුද්ධ පැත්තේ දිස් වේ (පළමු පේළිය අසම්පූර්ණ වන අතර, පහළ දකුණු කෙළවරේ, පළමු පේළිය අවසන් වූ පසු, පහළ වම්පස කෙළවරේ).

මෙන්න ඇල්ගොරිතම. 80% ක් පමණ ජයග්රහණය කරයි (සෑම විටම "වෘත්තීය" AI තාක්ෂණයන් සමඟ ජය ගත හැකි බව පෙනේ, නමුත් මේ ගැන මට විශ්වාස නැත.)

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)
  }

නැතිවූ පියවර පිළිබඳ කරුණු කිහිපයක්. මෙහි:ආකෘති වෙනස් කිරීම

අපේක්ෂිත මාදිලියට සමීප වීමේ වාසනාව හේතුවෙන් ආකෘතිය වෙනස් වී ඇත. AI සාක්ෂාත් කර ගැනීමට උත්සාහ කරන ආකෘතියයි

 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හැකි ඊළඟ ප්‍රාන්ත වලින් හොඳම ලකුණු තක්සේරු කරන්නේ කෙසේද?
Khaled.K

evaluateResultඔබ තුළ නිර්වචනය අර්ථ දක්වා ඇත්තේ මූලික වශයෙන් හැකි උපරිම තත්වයට සමීප වීමට උත්සාහ කරන්න.
ඩැරන්

Aren ඩැරන් මම ඔබේ සවිස්තරාත්මක තොරතුරු සඳහා බලා සිටිමි
අෂු

@ashu මම ඒ සඳහා වැඩ කරමින් සිටිමි, අනපේක්ෂිත තත්වයන් නිසා එය අවසන් කිරීමට මට කාලය නොමැති විය. මේ අතර මම ඇල්ගොරිතම වැඩි දියුණු කර ඇති අතර එය දැන් එය 75% ක් විසඳයි.
ඩැරන්

13
මෙම උපාය මාර්ගයට මා සැබවින්ම කැමති දෙය නම්, ක්‍රීඩාව අතින් ක්‍රීඩා කිරීමේදී මට එය භාවිතා කළ හැකි වීමයි, එය මට ලකුණු 37k දක්වා ඉහළ නැංවීය.
සීෆලෝපොඩ්

94

මගේ බ්ලොග් අඩවියේ පළ කිරීමක අන්තර්ගතය මම මෙහි පිටපත් කරමි


මා යෝජනා කරන විසඳුම ඉතා සරල හා ක්‍රියාත්මක කිරීමට පහසුය. කෙසේ වෙතත්, එය ලකුණු 131040 දක්වා ළඟා වී ඇත. ඇල්ගොරිතම කාර්ය සාධනය පිළිබඳ මිණුම් සලකුණු කිහිපයක් ඉදිරිපත් කරයි.

ලකුණු

ඇල්ගොරිතම

හියුරිස්ටික් ලකුණු ඇල්ගොරිතම

මගේ ඇල්ගොරිතම පදනම් කරගත් උපකල්පනය තරමක් සරල ය: ඔබට ඉහළ ලකුණු ලබා ගැනීමට අවශ්‍ය නම්, මණ්ඩලය හැකි තරම් පිළිවෙලට තබා ගත යුතුය. විශේෂයෙන්, ප්‍රශස්ත සැකසුම ලබා දෙන්නේ උළු අගයන්හි රේඛීය හා ඒකාකාරී අඩු වන අනුපිළිවෙලෙනි. මෙම ප්‍රතිභානය ඔබට උළු අගයක් සඳහා ඉහළ සීමාවක් ලබා දෙනු ඇත: sමෙහි n යනු පුවරුවේ ඇති ටයිල් ගණනයි.

(අවශ්‍ය විටදී 2-ටයිල් වෙනුවට 4-ටයිල් අහඹු ලෙස ජනනය කරන්නේ නම් 131072 ටයිල් වෙත ළඟා වීමේ හැකියාවක් ඇත)

මණ්ඩලය සංවිධානය කළ හැකි ක්‍රම දෙකක් පහත රූපවල දැක්වේ:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඒකාකාරී අඩු වන අනුපිළිවෙලකට උළු අනුපිළිවෙල බලාත්මක කිරීම සඳහා, පුවරුවේ රේඛීයකරණය කළ අගයන්ගේ එකතුව ලෙස ලකුණු ගණනය කරනු ලබන්නේ පොදු අනුපාතය r <1 සමඟ ජ්‍යාමිතික අනුක්‍රමයක අගයන්ගෙන් ගුණ කිරීමෙනි.

s

s

රේඛීය මාර්ග කිහිපයක් එකවර ඇගයීමට ලක් කළ හැකිය, අවසාන ලකුණු ඕනෑම මාර්ගයක උපරිම ලකුණු වේ.

තීරණ නීතිය

ක්‍රියාත්මක කරන තීරණ ගැනීමේ රීතිය එතරම් දක්ෂ නැත, පයිතන් හි කේතය මෙහි ඉදිරිපත් කෙරේ:

@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);

Minmax හෝ Expectiminimax ක්‍රියාත්මක කිරීම නිසැකවම ඇල්ගොරිතම වැඩි දියුණු කරයි. නිසැකවම වඩාත් නවීන තීරණ ගැනීමේ රීතියක් ඇල්ගොරිතම මන්දගාමී වන අතර එය ක්‍රියාත්මක කිරීමට යම් කාලයක් අවශ්‍ය වනු ඇත. නුදුරු අනාගතයේ දී අවම ක්‍රියාකාරීත්වයක් ක්‍රියාත්මක කිරීමට මම උත්සාහ කරමි. (සුසරව සිටින්න)

මිණුම් ලකුණ

  • T1 - 121 පරීක්ෂණ - විවිධ මාර්ග 8 ක් - r = 0.125
  • T2 - 122 පරීක්ෂණ - 8-වෙනස් මාර්ග - r = 0.25
  • T3 - 132 පරීක්ෂණ - 8-වෙනස් මාර්ග - r = 0.5
  • T4 - 211 පරීක්ෂණ - 2-වෙනස් මාර්ග - r = 0.125
  • T5 - 274 පරීක්ෂණ - 2-වෙනස් මාර්ග - r = 0.25
  • T6 - 211 පරීක්ෂණ - 2-වෙනස් මාර්ග - r = 0.5

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න

T2 වූ අවස්ථාවක, දස පරීක්ෂණ හතර ක සාමාන්ය ලකුණු සමග 4096 උළු ජනනය s42000

කේතය

කේතය පහත සබැඳියෙන් GiHub හි සොයාගත හැකිය: https://github.com/Nicola17/term2048-AI එය පදනම් වී ඇත්තේ 2048 පදය මත වන අතර එය ලියා ඇත්තේ පයිතන් හි ය. මම හැකි ඉක්මනින් C ++ හි වඩාත් කාර්යක්ෂම අනුවාදයක් ක්‍රියාත්මක කරමි.


නරක නැත, ඒකාබද්ධ කිරීමේ දෛශිකයන් ඇගයීමට ලක් කිරීම පිළිබඳ ඔබේ නිදර්ශනය මට අදහසක් ලබා දී ඇත
Khaled.K

හෙලෝ. ගිතබ් පිටුවේ දක්වා ඇති උපදෙස් ඔබේ ව්‍යාපෘතියට අදාළ වන බව ඔබට විශ්වාසද? මට එය උත්සාහ කර බැලීමට අවශ්‍ය නමුත් ඒවා මුල් ක්‍රීඩා කළ හැකි ක්‍රීඩාවට උපදෙස් මිස AI ඔටෝරන් නොවේ. ඔබට ඒවා යාවත්කාලීන කළ හැකිද? ස්තූතියි.
ජේ ඩී ගැම්බෝ

41

මගේ උත්සාහය ඉහත වෙනත් විසඳුම් මෙන් අපේක්‍ෂාකාරී ලෙස භාවිතා කරයි, නමුත් බිට්බෝඩ් නොමැතිව. නියොන්නියෝගේ විසඳුමට උළු 6 ක් ඉතිරිව ඇති 4 ක් පමණ ගැඹුරකින් යුත් චලනයන් මිලියන 10 ක් පරීක්ෂා කළ හැකි අතර චලනයන් 4 ක් කළ හැකිය (2 * 6 * 4) 4 . මගේ නඩුවේදී, මෙම ගැඹුර ගවේෂණය කිරීමට බොහෝ කාලයක් ගතවේ, ඉතිරිව ඇති නිදහස් උළු ගණන අනුව මම අපේක්‍ෂා සෙවීමේ ගැඹුර සකස් කරමි:

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

පුවරු වල ලකුණු ගණනය කරනු ලබන්නේ නිදහස් උළු සංඛ්‍යාවේ වර්ග ප්‍රමාණය හා 2D ජාලකයේ තිත් නිෂ්පාදනය සමඟ ය.

[[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
මෙයට වැඩි දියුණුවක් නැත්තේ ඇයිදැයි විශ්වාස නැත. එහි සරල බව සඳහා එය සැබවින්ම effective ලදායී වේ.
ඩේවිඩ් ග්‍රේඩනස්

ස්තූතියි, ප්‍රමාද වූ පිළිතුර සහ එය එතරම් හොඳින් ක්‍රියාත්මක නොවේ (සෑම විටම පාහේ [1024, 8192]), පිරිවැය / සංඛ්‍යාලේඛන ක්‍රියාකාරිත්වයට වැඩි වැඩක් අවශ්‍ය වේ
caub

හිස් අවකාශය ඔබ බර කළේ කෙසේද?
ඩේවිඩ් ග්‍රේඩනස්

1
එය සරලවම වන cost=1x(number of empty tiles)²+1xdotproduct(snakeWeights,grid)අතර අපි මෙම පිරිවැය උපරිම කිරීමට උත්සාහ කරමු
caub

ස්තුති @Robusto, මම යම් දිනක කේතය වැඩි දියුණු කළ යුතු, එය සරල කළ හැක
caub

38

මෙම ත්‍රෙඩ් එකේ සඳහන් වෙනත් ඕනෑම වැඩසටහනකට වඩා හොඳ ලකුණු ලබා දෙන 2048 පාලකයක කතුවරයා මම වෙමි. පාලකය කාර්යක්ෂමව ක්‍රියාත්මක කිරීම ගිතුබ්හි ඇත. දී වෙනම ණයකට පාලකය ගේ රාජ්ය ඇගයීම කාර්යය පුහුණු කිරීම සඳහා භාවිතා වන කේතය ද ඇත. පුහුණු ක්‍රමය පුවත්පතේ විස්තර කර ඇත .

තාවකාලික වෙනස ඉගෙනීමේ ප්‍රභේදයක් (ශක්තිමත් කිරීමේ ඉගෙනුම් ක්‍රමයක්) මුල සිටම (මානව 2048 විශේෂ ise තාවයකින් තොරව) ඉගෙන ගත් රාජ්‍ය ඇගයීම් ශ්‍රිතයක් සමඟ පාලකය අපේක්‍ෂා සෙවීම භාවිතා කරයි . රාජ්ය-අගය ශ්‍රිතය n-tuple ජාලයක් භාවිතා කරයි , එය මූලික වශයෙන් පුවරුවේ නිරීක්ෂණය කරන ලද රටා වල බරින් යුත් රේඛීය ශ්‍රිතයකි. එහි බර කිලෝග්‍රෑම් 1 කට වඩා වැඩිය .

කාර්ය සාධනය

1 චලනයන් / තත්පර: 609104 (ක්‍රීඩා 100 සාමාන්‍ය)

චලනයන් 10 ක් / තත්පර: 589355 (ක්‍රීඩා 300 ක සාමාන්‍යය)

3- ප්ලයි ( ca. 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
ඉතා ආකර්ෂණීය ප්රති result ලය. කෙසේ වෙතත් ඔබට පැහැදිලි කිරීම සඳහා පිළිතුර යාවත්කාලීන කළ හැකිද (දළ වශයෙන්, සරල වචන වලින් ... සම්පූර්ණ තොරතුරු මෙහි පළ කිරීමට බොහෝ කාලයක් ගතවනු ඇතැයි මට විශ්වාසයි) ඔබේ වැඩසටහන මෙය සාක්ෂාත් කරගන්නේ කෙසේද? ඉගෙනුම් ඇල්ගොරිතම ක්‍රියාත්මක වන ආකාරය පිළිබඳ දළ පැහැදිලි කිරීමක දී මෙන්?
සෙඩ්රික් මාමෝ

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
උළු බහුවිධ දිශාවලට මාරු නොවන්නේ නම් නොගැලපෙන ආකාරවලින් ගොඩගැසී ඇත. පොදුවේ ගත් කල, චක්‍රීය උපාය මාර්ගයක් භාවිතා කිරීමෙන් මධ්‍යයේ විශාල උළු ඇති වන අතර එමඟින් උපාමාරු වඩාත් අවුල් සහගත වේ.
bcdan

25

මෙම ක්‍රීඩාව සඳහා දැනටමත් AI ක්‍රියාත්මක කිරීමක් තිබේ . README වෙතින් උපුටා ගැනීම:

ඇල්ගොරිතම යනු පුනරාවර්තන ගැඹුරු කිරීමේ ගැඹුර පළමු ඇල්ෆා-බීටා සෙවීමයි. ඇගයීමේ කාර්යය මඟින් පේළි සහ තීරු ඒකාකාරී ලෙස තබා ගැනීමට උත්සාහ කරයි (සියල්ල අඩු හෝ වැඩි වේ) විදුලිබල පද්ධතියේ උළු ගණන අවම කරයි.

ඔබට ප්‍රයෝජනවත් විය හැකි මෙම ඇල්ගොරිතම ගැන හැකර් ප්‍රවෘත්ති පිළිබඳ සාකච්ඡාවක් ද ඇත .


4
මෙය ඉහළම පිළිතුර විය යුතුය, නමුත් ක්‍රියාත්මක කිරීම පිළිබඳ වැඩි විස්තර එකතු කිරීම සතුටක් වනු ඇත: උදා: ක්‍රීඩා මණ්ඩලය ආදර්ශනය කර ඇති ආකාරය (ප්‍රස්ථාරයක් ලෙස), භාවිතා කරන ප්‍රශස්තිකරණය (උළු අතර වෙනස අවම වශයෙන්) යනාදිය
ඇල්සියු කොස්ටා

1
අනාගත පා readers කයින් සඳහා: මෙහි දෙවන ඉහළම පිළිතුරෙන් එහි කර්තෘ (ovolve) විසින් පැහැදිලි කරන ලද එකම වැඩසටහන මෙයයි . මෙම පිළිතුර සහ මෙම සාකච්ඡාවේදී ඩිම්බකෝෂයේ වැඩ සටහනේ වෙනත් සඳහනක් නිසා ඩිම්බකෝෂය පෙනී සිටිමින් ඔහුගේ ඇල්ගොරිතම ක්‍රියා කළ ආකාරය ලිවීමට පෙළඹුණි; එම පිළිතුරට දැන් ලකුණු 1200 ක් ඇත.
MultiplyByZer0

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 ඇගයීමට ලක් කෙරේ.

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

මෙහිදී අපි තවමත් සිරස්ව ඇති අගයන් පරික්ෂා කර බැලිය යුතුය, නමුත් නම්‍යශීලී පරාමිතීන්ට බාධා නොකරන අඩු ආකාරයකින්, එබැවින් අපට [4,44] in හි {x එකතුවක් ඇත.

+ (Number of possible next moves x 256)

සිදුවිය හැකි සංක්‍රාන්ති වලට වැඩි නිදහසක් තිබේ නම් රාජ්‍යයකට වඩාත් නම්‍යශීලී වේ.

+ (Number of aligned values x 2)

මෙය බැලූ බැල්මට තොරව එම ප්‍රාන්තය තුළ ඒකාබද්ධ වීමේ හැකියාව පිළිබඳ සරල කරන ලද පරීක්‍ෂණයකි.

සටහන: නියතයන් අතුගා දැමිය හැකිය ..


2
සජීවී කේතයක් එක් කිරීම සඳහා මම මෙය පසුව සංස්කරණය කරමි @ nitish712
Khaled.K

9
මෙම ඇල්ගොරිතමයේ ජයග්‍රාහී% කුමක්ද?
cegprakash

ඔබට අවශ්‍ය constantඇයි? ඔබ කරමින් සිටින්නේ ලකුණු සංසන්දනය කිරීම නම්, එම සංසන්දනයන්හි ප්‍රති come ලයට එය බලපාන්නේ කෙසේද?
bcdan

සඳහා කලපුවේ කිලෝමීටරයක් (සංසන්දනය ලකුණු හෙවත්) @bcdan ඊළඟ එන් පියවර හොඳම දැන ගසක් ඉදි නොවන බැවින් මෙම, රේඛීය සඳහා කලපුවේ කිලෝමීටරයක් වේ හැර, කොහොමද චෙස් ස්වතෝන්වේෂණ වැඩ කිරීමට සමාන අනාගත රාජ්ය අපේක්ෂිත අගය සන්සන්දනය මත රඳා පවතී
Khaled.K

12

මෙය OP ගේ ප්‍රශ්නයට answer ජු පිළිතුරක් නොවේ, මෙය එකම ගැටළුව විසඳීම සඳහා මා මෙතෙක් උත්සාහ කර ඇති ප්‍රති results ල සහ ප්‍රති results ල ලබාගෙන බෙදාහදා ගැනීමට අවශ්‍ය නිරීක්ෂණ කිහිපයක් ඇත, අපට කුතුහලයක් තිබේ මෙයින් වැඩිදුර අවබෝධයක්.

මම 3 සහ 5 යන ස්ථානවල සෙවුම්-ගස් ගැඹුරේ කප්පාදුව සමඟ ඇල්ෆා-බීටා කප්පාදු කිරීම සමඟ මගේ මිනිමැක්ස් ක්‍රියාවට නැංවීමට උත්සාහ කළෙමි. කොලොම්බියාඑක්ස්: CSMM.101x කෘතිම බුද්ධිය ( AI) .

ප්‍රධාන වශයෙන් ප්‍රතිභානයෙන් සහ ඉහත සාකච්ඡා කළ ඒවායින් මම උත්තල ඇගයීම් කාර්යයන් කිහිපයක උත්තල සංයෝජනය (විවිධ හියුමස් බර කිරා බැලීමට උත්සාහ කළෙමි).

  1. ඒකාකාරී බව
  2. නිදහස් ඉඩ තිබේ

මගේ නඩුවේදී, පරිගණක වාදකය සම්පූර්ණයෙන්ම අහඹුයි, නමුත් තවමත් මම විරුද්ධවාදී සැකසුම් උපකල්පනය කර AI ක්‍රීඩක නියෝජිතයා උපරිම ක්‍රීඩකයා ලෙස ක්‍රියාත්මක කළෙමි.

ක්රීඩාව සඳහා මට 4x4 ජාලයක් ඇත.

නිරීක්ෂණය:

පළමු හියුරිස්ටික් ශ්‍රිතයට හෝ දෙවන හියුරිස්ටික් ශ්‍රිතයට මා වැඩි බරක් පවරන්නේ නම්, AI ක්‍රීඩකයාට ලැබෙන ලකුණු දෙකම අඩුය. මම හියුරිස්ටික් කාර්යයන් සඳහා හැකි බොහෝ බර පැවරුම් සමඟ ක්‍රීඩා කර උත්තල සංයෝජනයක් ලබා ගත්තෙමි, නමුත් ඉතා කලාතුරකින් AI ක්‍රීඩකයාට 2048 ලකුණු ලබා ගත හැකිය. බොහෝ විට එය 1024 හෝ 512 හි නතර වේ.

මම ද කෝනර් හියුරිස්ටික් අත්හදා බැලුවෙමි, නමුත් කිසියම් හේතුවක් නිසා එය ප්‍රති results ල නරක අතට හැරේ, කිසියම් බුද්ධියක් ඇයි?

එසේම, සෙවුම් ගැඹුර කපා හැරීම 3 සිට 5 දක්වා වැඩි කිරීමට මම උත්සාහ කළෙමි (කප්පාදු කිරීමේදී පවා ඉඩ දී ඇති කාලය ඉක්මවා යන බව සෙවීම නිසා මට එය වැඩි කළ නොහැක) සහ යාබද උළු වල අගයන් දෙස බලා ලබා දෙන තවත් ur ෂධයක් එකතු කළෙමි. තවත් ලකුණු ඒකාබද්ධ කළ හැකි නම්, නමුත් තවමත් මට 2048 ලබා ගත නොහැක.

මිනිමැක්ස් වෙනුවට එක්ස්පෙක්ටිමැක්ස් භාවිතා කිරීම වඩා හොඳ වනු ඇතැයි මම සිතමි, නමුත් තවමත් මට අවශ්‍ය වන්නේ මිනිමැක්ස් සමඟ පමණක් මෙම ගැටළුව විසඳා 2048 හෝ 4096 වැනි ඉහළ ලකුණු ලබා ගැනීමයි. මට කිසිවක් මග හැරී ඇත්දැයි මට විශ්වාස නැත.

පහත දැක්වෙන සජීවිකරණය මඟින් පරිගණක ක්‍රීඩකයා සමඟ AI නියෝජිතයා විසින් ක්‍රීඩා කරන ලද ක්‍රීඩාවේ අවසාන පියවර කිහිපයක් පෙන්වයි:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඕනෑම අවබෝධයක් ඇත්තෙන්ම ඉතා ප්‍රයෝජනවත් වනු ඇත, කල්තියා ස්තූතියි. (ලිපිය සඳහා මගේ බ්ලොග් සටහනේ සබැඳිය මෙයයි: https://sandipanweb.wordpress.com/2017/03/06/using-minimax-with-alpha-beta-pruning-and-heuristic-evaluation-to-solve -2048-ක්‍රීඩාව සමඟ පරිගණකය / සහ යූ ටියුබ් වීඩියෝ: https://www.youtube.com/watch?v=VnVFilfZ0r4 )

පහත දැක්වෙන සජීවිකරණය මඟින් AI ක්‍රීඩක නියෝජිතයාට ලකුණු 2048 ක් ලබා ගත හැකි ක්‍රීඩාවේ අවසාන පියවර කිහිපය පෙන්වයි.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

පහත දැක්වෙන සංඛ්‍යා වලින් දැක්වෙන්නේ ක්‍රීඩකයාගේ ඒජන්ත ඒජන්තවරයා විසින් ගවේෂණය කරන ලද ක්‍රීඩා ගස එක පියවරක් සඳහා පරිගණකය සතුරා ලෙස උපකල්පනය කරයි:

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න


9

මම 2048 දී හස්කල්හි විසඳුමක් ලිව්වෙමි, ප්‍රධාන වශයෙන් මම මේ භාෂාව ඉගෙන ගන්නා නිසාය.

මගේ ක්‍රීඩාව ක්‍රියාත්මක කිරීම සැබෑ ක්‍රීඩාවට වඩා තරමක් වෙනස් ය, නව ටයිල් එකක් සැමවිටම '2' වේ (90% 2 සහ 10% 4 වෙනුවට). නව ටයිල් එක අහඹු නොවන බවත්, නමුත් සෑම විටම ඉහළ වමේ සිට ලබා ගත හැකි පළමු එක බවත්. මෙම ප්‍රභේදය ඩෙට් 2048 ලෙසද හැඳින්වේ .

ප්‍රති consequ ලයක් ලෙස මෙම විසඳුම නිර්ණායක වේ.

හිස් ටයිල් වලට කැමති පරිපූර්ණ ඇල්ගොරිතමයක් මම භාවිතා කළෙමි. ගැඹුර 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 වන ගැඹුරේදී විසඳන විට ලැබෙන ප්‍රති result ලය:

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

සසම්භාවීකරණයකින් තොරව මට විශ්වාසයි ඔබට සෑම විටම 16k හෝ 32k ලබා ගැනීමට ක්‍රමයක් සොයාගත හැකිය. කෙසේ වෙතත්, හස්කල් හි සසම්භාවීකරණය එතරම් නරක නැත, ඔබට අවශ්‍ය වන්නේ 'බීජය' වටා යාමට ක්‍රමයක් පමණි. එක්කෝ එය පැහැදිලිව කරන්න, නැතහොත් සසම්භාවී මොනාඩ් සමඟ කරන්න.
තෝමස් අහ්

අහඹු නොවන ක්‍රීඩාවක් සඳහා ඇල්ගොරිතම සෑම විටම 16k / 32k කරා ළඟා වීම තවත් සිත්ගන්නා සුළු අභියෝගයක් විය හැකිය ...
wvdz

ඔයා හරි, මම හිතුවට වඩා අමාරුයි. මෙම අනුක්‍රමය සොයා ගැනීමට මට හැකි විය: [UP, LEFT, LEFT, UP, LEFT, DOWN, LEFT] සෑම විටම ක්‍රීඩාව ජයග්‍රහණය කරයි, නමුත් එය 2048 ට වඩා ඉහළින් නොයයි. (නීතිමය පියවරක් නොමැති විට, චක්‍රීය ඇල්ගොරිතම තෝරා ගනී ඊළඟ එක දක්ෂිණාවර්තව)
තෝමස් අහ්

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 ක් පමණක් භාවිතා කිරීමට උපකාරී වේ, මූලික වශයෙන් මෙම ඇල්ගොරිතම කරන්නේ කුමක්ද. ඒ නිසා බැලූ බැල්මට පෙනෙන තරම් නරක නැත.
ඉලක්කම්

5
ඔව්, එය පදනම් වී ඇත්තේ ක්‍රීඩාව සමඟ මගේ නිරීක්ෂණය මත ය. ඔබ 4 වන දිශාව භාවිතා කරන තුරු ක්‍රීඩාව කිසිදු ආකාරයක නිරීක්ෂණයකින් තොරව ප්‍රායෝගිකව විසඳනු ඇත. මෙම "AI" කිසිදු කොටසක නිශ්චිත වටිනාකම පරීක්ෂා නොකර 512/1024 වෙත ළඟා විය යුතුය.
API-Beast

3
නිසි AI ආයතනයකට ඕනෑම දිශාවකට පමණක් එක් දිශාවකට ගමන් කළ හැකි තත්වයකට පත්වීම වළක්වා ගැනීමට උත්සාහ කරනු ඇත.
API-Beast

3
දිශාවන් 3 ක් පමණක් භාවිතා කිරීම ඇත්ත වශයෙන්ම ඉතා යහපත් උපාය මාර්ගයකි! එය මට අතින් ක්‍රීඩාව කරන 2048 ට ආසන්න විය. ඉතිරි පියවර 3 අතර තීරණය කිරීම සඳහා ඔබ මෙය වෙනත් උපාය මාර්ග සමඟ ඒකාබද්ධ කළහොත් එය ඉතා බලවත් විය හැකිය. තේරීම 3 දක්වා අඩු කිරීම කාර්ය සාධනය කෙරෙහි විශාල බලපෑමක් ඇති කරන බව සඳහන් නොකල යුතුය.
wvdz

4

වෙනත් බොහෝ පිළිතුරු AI භාවිතා කරන්නේ අනාගතය, හියුරිස්ටික්ස්, ඉගෙනීම වැනි දේ ගණනය කිරීම සඳහා මිල අධික ලෙස සෙවීමෙනි. මේවා ආකර්ෂණීය හා බොහෝ දුරට නිවැරදි මාර්ගයයි, නමුත් මම තවත් අදහසක් ඉදිරිපත් කිරීමට කැමැත්තෙමි.

ක්‍රීඩාවේ හොඳ ක්‍රීඩකයින් භාවිතා කරන උපායමාර්ගය ආදර්ශනය කරන්න.

උදාහරණයක් වශයෙන්:

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

ඊළඟ චතුරස්රයේ අගය වත්මන් අගයට වඩා වැඩි වන තුරු ඉහත පෙන්වා ඇති අනුපිළිවෙලෙහි ඇති චතුරස්රයන් කියවන්න. එකම අගයක තවත් ටයිල් එකක් මෙම චතුරස්රයට ඒකාබද්ධ කිරීමට උත්සාහ කිරීමේ ගැටළුව මෙය ඉදිරිපත් කරයි.

මෙම ගැටළුව විසඳීම සඳහා, ඒවා වමට හෝ නරක අතට හැරීමට නොහැකි ක්‍රම 2 ක් වන අතර, හැකියාවන් දෙකම පරීක්ෂා කිරීමෙන් වහාම තවත් ගැටලු අනාවරණය විය හැකිය, මෙය පරායත්තතා ලැයිස්තුවක් සාදයි, සෑම ගැටළුවක්ම පළමුව විසඳිය යුතු වේ. මගේ ඊළඟ පියවර තීරණය කිරීමේදී, විශේෂයෙන් සිරවී සිටින විට, මට මෙම දාමය හෝ සමහර විට අභ්‍යන්තරව යැපීම් ගසක් ඇතැයි මම සිතමි.


ටයිල්ට අසල්වැසියා සමඟ ඒකාබද්ධ කිරීම අවශ්‍ය නමුත් එය ඉතා කුඩා ය: තවත් අසල්වැසියෙකු මේ සමඟ ඒකාබද්ධ කරන්න.

මාර්ගයෙහි විශාල ටයිල්: අවට කුඩා ටයිල් එකක වටිනාකම වැඩි කරන්න.

etc ...


සමස්ත ප්‍රවේශය මීට වඩා සංකීර්ණ වනු ඇති නමුත් වඩා සංකීර්ණ නොවේ. ලකුණු, බර, නියුරෝන සහ හැකියාවන් පිළිබඳ ගැඹුරු සෙවීම් නොමැති වීම මෙම යාන්ත්‍රික හැඟීම විය හැකිය. ඕනෑම ශාඛාවක් අවශ්‍ය වන තරමට විශාල විය හැකි ගස විශාල විය යුතුය.


5
ඔබ හියුරිස්ටික් සමඟ දේශීය සෙවුමක් විස්තර කරයි. එය ඔබව හිර කර දමනු ඇත, එබැවින් ඔබ ඊළඟ පියවරයන් සඳහා කල්තියා සැලසුම් කළ යුතුය. එමඟින් ඔබ විසඳුම් සෙවීමට සහ ලකුණු කිරීමට (තීරණය කිරීම සඳහා) යොමු කරයි. එබැවින් මෙය වෙනත් ඉදිරිපත් කළ විසඳුමකට වඩා වෙනස් නොවේ.
runDOSrun
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.