MENACE প্রয়োগ করুন


11

পটভূমি

মেনেস ( এম আচিন দুর্বল) এন oughts একটি য় সি Rosses ngine) খেলা একপ্রকার খেলা 1960-এর দশকে ব্রিটিশ কম্পিউটার বিজ্ঞানী ডোনাল্ড Michie দ্বারা নির্মিত একটি প্রাথমিক অগভীর মেশিন লার্নিং আলগোরিদিম হয়। এটি মূলত 304 ম্যাচবাক্সগুলির সাথে বাস্তবায়িত হয়েছিল, প্রতিটি বোর্ডের অবস্থান সহ লেবেলযুক্ত এবং রঙিন পুঁতিযুক্ত (নয়টি রঙের মধ্যে একটি, সম্ভাব্য পদক্ষেপের প্রতিনিধিত্ব করে)। মিচি গণনা করেছেন যে এই 304 টি ম্যাচবক্সগুলি বোর্ডে প্রতিটি পদক্ষেপের জন্য যথেষ্ট ছিল were

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

-------
|X|0|X|
| |0| |
|X|X| |
-------

(দুটি বাদুড় এবং চারটি ক্রস)

এরপরে, তিনি আবর্তনের জন্য ক্ষতিপূরণ দিয়েছিলেন। উদাহরণস্বরূপ, যদি ম্যাচবক্সে আমরা দেখতে পাই:

-------
| |0|0|
|X| |X|
| |0| |
-------

আমরা একই বাক্সটি ব্যবহার করতে পারি

-------
| |X| |
|0| |0|
| |X|0|
-------

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

-------
| |0|0|
|X| |X|
| |0| |
-------

সুতরাং আমরা জানতে চাই যে এটি বোর্ডের ক্ষেত্রে, তারপরে লাল জপমালাটির অর্থ হবে:

-------
|R|0|0|
|X| |X|
| |0| |
-------

তবে এটি যদি বোর্ড হয়:

-------
| |X| |
|0| |0|
| |X|0|
-------

লাল জপমালা মানে

-------
| |X|R|
|0| |0|
| |X|0|
-------

এই রূপান্তরগুলি ঘূর্ণন এবং বিপরীতকরণের জন্য প্রয়োগ করা হয়েছে (তির্যক সহ সমস্ত দিকের)) আবার একবারে আপনার কেবল প্রতিটি ম্যাচবক্স সংরক্ষণ করতে হবে: প্রতিটি রূপান্তরের জন্য আলাদা ভার্চুয়াল বাক্স তৈরি করবেন না!

মিচি তৈরি করা অন্য সরলকরণটি ছিল কম্পিউটারটি প্রথমে চলে যায় তা নিশ্চিত করা। এইভাবে, তিনি বাক্স বাক্সের প্রায় পঞ্চমাংশ সরিয়ে, প্রথম স্তরের সমস্ত পদক্ষেপ সরিয়ে ফেলতে পারেন। অবশেষে, তিনি সমস্ত গেম-এন্ডিং বাক্সগুলি সরিয়ে ফেললেন (এই পদক্ষেপগুলিতে কোনও 'সামগ্রী' বা চালচলনের প্রয়োজন নেই)।

ডান, এখন নিজেই অ্যালগোরিদমে (এটি খুব সাধারণ)

  1. প্রথমে পুঁতির রঙগুলি কী উপস্থাপন করে তা সিদ্ধান্ত নিন। বোর্ডে প্রতিটি ফাঁকা স্থানকে উপস্থাপন করতে আপনার 9 রঙের প্রয়োজন।
  2. গেমের শুরুতে 304 টি ম্যাচবক্সের প্রত্যেকটিতে পুঁতি রয়েছে। পুঁতিগুলি এলোমেলো রঙের (তাই ডুপ্লিকেটগুলি ভাল), তাদের সম্ভাব্য চলন হওয়া উচিত (সুতরাং যদি বোর্ডের রাজ্যের চিত্রটি মাঝের ডানদিকে একটি 'ও' চিত্রিত করে, তবে আপনি মাঝের- প্রতিনিধিত্বকারী জপমালা ব্যবহার করতে পারবেন না- ডান)।
  3. প্রতিবার এটি MENACE (X) এর পালা হওয়ার সাথে সাথে বর্তমান বোর্ড পজিশনের সাথে ম্যাচবক্সটি সন্ধান করুন (বা এটির কিছু রূপান্তর) এটিতে মুদ্রিত।
  4. ম্যাচবক্সটি খুলুন এবং এলোমেলোভাবে সেখানে কোনও পুঁতি বেছে নিন।
  5. ম্যাচবক্সে চিত্রটিতে উঠতে কীভাবে বোর্ডের স্থিতিটি রূপান্তরিত হয়েছে তা সন্ধান করুন (উদাহরণস্বরূপ 90deg এন্টিকলোকের দিকে ঘোরানো)। তারপরে, সেই রূপান্তরটি পুঁতিতে প্রয়োগ করুন (যেমন উপরে-বামটি বাম-বামে পরিণত হয়)।
  6. সেই স্কোয়ারে একটি এক্স রাখুন। ম্যাচবক্স থেকে নির্বাচিত জপমালা সরান। ফলস্বরূপ বাক্সটি যদি খালি ছেড়ে যায়, তবে বাক্সে তিনটি এলোমেলো (সম্ভাব্য) জপমালা রাখুন এবং সরানোর জন্য তার মধ্যে একটি বেছে নিন।
  7. খেলা শেষ না হওয়া পর্যন্ত 3-6 পুনরাবৃত্তি করুন।
  8. MENACE গেমটি জিতে থাকলে, MENACE নিয়ে যাওয়া প্রতিটি ম্যাচবক্সে ফিরে যান। তারপরে, সেই পদক্ষেপে এটি কী রঙের পুঁতি ব্যবহার করেছে তা পিছনে ট্রেস করুন। সেই রঙের পুঁতির দুটি রঙ বাক্সে রাখুন (যাতে মূল পুঁতিটি + আরও একটি থাকে, এর ফলে MENACE এর সম্ভাবনা বাড়িয়ে দেয় যা পরের বার যখন to অবস্থানে পৌঁছে যায়)
  9. MENACE গেমটি হেরে গেলে কিছুই করবেন না ( করবেন না) নিয়েছিল প্রতিস্থাপন )।
  10. যদি MENACE গেমটি আকর্ষণ করে, তবে এর প্রতিটি চালগুলিতে ব্যবহৃত পুঁতিটি প্রতিস্থাপন করুন, তবে অতিরিক্ত কোনও যোগ করবেন না, যাতে আপনি যা শুরু করেছিলেন তা রেখেই চলে যান।

এটি আমাদের কাছে একটি অ্যালগোরিদম ফেলেছে যা খুব সহজ, তবে কার্যকর করা কঠিন। এটি আপনার চ্যালেঞ্জের ভিত্তি তৈরি করে।

আপনি যদি এখনও বিভ্রান্ত থাকেন তবে দেখুন http://chalkdustmagazine.com/features/menace-machine-educable-noughts-crosses-engine/ - আমি যখন এই অ্যালগরিদম সম্পর্কে জানলাম তখনই এটি পড়েছিলাম

চ্যালেঞ্জ

কম্পিউটারের সাথে টিক-ট্যাক-টোয়ের একটি খেলা খেলুন। প্রতিটি পদক্ষেপে, ম্যাচবাক্সগুলির সমস্ত বিষয়বস্তু আউটপুট করুন।

ইনপুট

  • প্রোগ্রামটির শুরুতে একটি নম্বর বলে আপনি MENACE এর বিরুদ্ধে কয়টি গেম খেলতে চান
  • তারপরে, MENACE এর প্রথম ঘুরার পরে, আপনি আপনার দুটি পদক্ষেপের স্ট্রিং হিসাবে নিজের পদক্ষেপটি ইনপুট করুন, প্রথম অক্ষরটি "এল", "আর", বা "এম" (বাম, ডান বা মাঝখানে) Y অক্ষকে উল্লেখ করে। তারপরে আপনি এক্স অক্ষটি উল্লেখ করে অন্য একটি অক্ষর (আবার "এল", "আর" বা "এম") ইনপুট করুন। সমস্ত চাল এবং গেমগুলির জন্য পুনরাবৃত্তি করুন।

আউটপুট

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

বিধি

  1. এটি , তাই বাইট জেতে সংক্ষিপ্ত উত্তর।
  2. MENACE এর প্রতিক্রিয়া দেখে আমার অবশ্যই চালিত ইনপুট করতে সক্ষম হব। না 'আপনার সমস্ত পদক্ষেপগুলি এই ফাংশনে প্রবেশ করুন এবং গেমটি কীভাবে কার্যকর হয় তা দেখুন'।
  3. বোর্ড অবশ্যই গেমসের মধ্যে সাফ করতে হবে।
  4. ম্যাচবক্সগুলি অবশ্যই গেমগুলির মধ্যে পরিষ্কার করা উচিত নয় (এটি মেশিন লার্নিংটিকে পুনরায় সেট করবে)
  5. আপনার অবশ্যই 304 ম্যাচবক্স থাকতে হবে। যে কোনও ব্যক্তি সমস্ত 19,683 ম্যাচবক্সের সাহায্যে এই অ্যালগরিদমটি প্রয়োগ করতে পারে, তবে শিখতে ধীর গতির (কারণ এটির জন্য প্রচুর প্রয়োজন দরকারী সামগ্রী সহ পেতে গেম )।
  6. আউটপুটটি যেকোন যুক্তিসঙ্গত ফর্ম্যাটে থাকতে পারে এবং পিপিসিজি মান অনুযায়ী ইনপুট নেওয়া যেতে পারে (যতক্ষণ না এটি নিয়ম 2 মেনে চলে)। আপনার যদি ইনপুট ফর্ম্যাটটি সামঞ্জস্য করতে হয় (' ইনপুট ' বিভাগে বর্ণিত ) তবে এটি যতক্ষণ তা বোঝায় ততক্ষণ ঠিক।
  7. যখন কোনও খেলোয়াড় জিতে যায় (একটি সারিতে তিনটি ত্রিভুজের, অনুভূমিকভাবে বা উল্লম্বভাবে পেয়ে) বা যদি কোন ড্র হয় (বোর্ড পূর্ণ থাকে এবং বিজয়ী না হয়)
  8. যদিও মেন্যাসে সম্ভাব্য পদক্ষেপগুলি করা দরকার (এবং প্রতিটি ম্যাচবক্সের ভিতরে কেবল সম্ভাব্য পুঁতি থাকতে পারে), চ্যালেঞ্জের জন্য আপনাকে ব্যবহারকারীর ইনপুটটিকে বৈধতা দেওয়ার দরকার নেই। যদি তারা কোনও ভুল টাইপ করে থাকে তবে আপনার প্রোগ্রামটি যা কিছু করতে পারে (সম্পূর্ণ পাগল হয়ে যায়, ত্রুটি ছুঁড়ে ফেলা ইত্যাদি) - আপনি ধরে নিতে পারেন ইনপুটটি সঠিক।

আমার মনে আছে মার্টিন গার্ডনার সহজ গেম হেক্সাপাউন ব্যবহার করে এই ধারণাটি প্রদর্শন করেছিলেন, যদিও তিনি ভুলে গেছেন যে তিনি "কম্পিউটার" তৈরি করেছিলেন যা তিনি তৈরি করেছিলেন।
নিল

নিল পার্সোনাল পেজস.ম্যানচেস্টার.এক.উক / স্টাফ / অ্যান্ড্রু।হাজেল/… হয়তো?
গেজা কেরেসসেনি


1
দুর্দান্ত চ্যালেঞ্জ। দ্রুত প্রশ্নের যুগল: ১. একটি বাক্সে প্রদত্ত স্থানে একবারে একাধিক পুঁতি হলে, কীভাবে আউটপুটটিতে এটি উপস্থাপন করা উচিত? ২. আপনি কি প্রতিটি পদক্ষেপের পরে সমস্ত 304 বাক্স (২36 cells36 কোষ) আউটপুট পেতে চান?
নিক কেনেডি

@ নিক কেনেডি মতামতের জন্য ধন্যবাদ। যদি আপনি জপমালা প্রতিনিধিত্ব করতে সংখ্যার বেছে নেওয়া হয়েছে আমি যেমন আশা করতে চাই যখন এটি লগ এর জপমালা প্রতিনিধিত্ব করা একটি অ্যারের হিসাবে (যদিও আপনি এটা ভিন্নভাবে কি করতে পারেন বিভিন্ন ভাষায় না সীমিত করতে): [[0, 2, 6], [4, 8, 4, 3, 3], [7, 7, 7, 7, 7, 7, 7, 8], [1], ... [3, 3, 5, 4]]
গেজা কেরেসসেনি

উত্তর:


3

আর , 839 বাইট

options(max.print=1e5)
s=colSums
r=rowSums
m=matrix
a=array
y=apply
S=sum
p=sample
b=m(rep(i<-1:(K=3^9),e=9)%/%(E=3^(8:0))%%3,c(9,K))
V=a(1:9,c(3,3,8))
V[,,2:4]=c(V[x<-3:1,,1],V[,x,1],V[x,x,1])
V[,,5:8]=y(V[,,1:4],3,t)
d=aperm(a(b[c(V),],c(9,8,K)),c(1,3,2))
v=m(V,9)
g=y(m(match(e<-y(d*E,2:3,S),i),,8),1,min)
g[K]=K
G=9-y(t(e==g)*8:1,2,max)
h=s(a(c(b,d[,,5],b[c(1,5,9,3,5,7,1:3),]),c(3,3,K,3))*3^(0:2))
k=r(s(h==13))>0
l=r(s(h==26))>0
o=s(b>0)
M=b
M[M==0]=-1
repeat{A=b[,t<-K]
z=j=c();B=1
repeat{if(S(pmax(-M[,t],0))<1)M[p(9,pmin(3,S(x)),,x<-M[,t]<1),t]=-1
z=c(z,u<-p(9,1,,pmax(-M[,t],0)))
j=c(j,t)
A[v[,G[B]][u]]=1
print(m(A,3))
if(k[B<-S(A*E)]||o[B]==9)break
A[ceiling((utf8ToInt(readline())-76)/5)%*%c(1,3)+1]=2
if(l[B<-S(A*E)])break
t=g[B]}
M[x]=M[x<-cbind(z,j)]-k[B]+l[B]
print(a(M[,g==seq(g)&!k&!l&s(b==1)==s(b==2)&o<8],c(3,3,304)))}

এটি অনলাইন চেষ্টা করুন!

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

এটি মন্তব্য সহ কম গল্ফযুক্ত সংস্করণ (তবে এখনও সংক্ষিপ্ত পরিবর্তনশীল নাম)। মনে রাখবেন যে এটি ম্যাচবক্সগুলি মুদ্রণ করে না কারণ তারা খুব দীর্ঘ। এটি একটি ইন্টারেক্টিভ প্লেয়ার 2, এলোমেলো প্লেয়ার 2 বা প্লেয়ার 2 এর জন্য একই ম্যাচবক্স কৌশল বাস্তবায়িত করতে পারে।

auto = 1 # 1 = Random player 2, 2 = Player 2 uses learning strategy
         # 0 for interactive
print_board <- function(board) {
  cat(apply(matrix(c(".", "X", "O")[board + 1], 3), 1, paste, collapse = ""), "", sep = "\n")
}
E = 3 ^ (8:0) # Number of possible arrangements of board
              # ignoring rotations etc.
# Make all possible boards
b = matrix(rep(1:3 ^ 9, e = 9) %/% E %% 3, c(9, 3 ^ 9))
# Define the eight possible rotation/inversion matrices
V = array(1:9, c(3, 3, 8))
V[, , 2:4] = c(V[x <- 3:1, , 1], V[, x, 1], V[x, x, 1])
V[, , 5:8] = apply(V[, , 1:4], 3, t)
# Create eight copies of the 19683 boards with each transformation
d = aperm(array(b[c(V), ], c(9, 8, 3 ^ 9)), c(1, 3, 2))
v = matrix(V, 9)
# Create reverse transformations (which are the same except for rotation)
w = v[, c(1:5, 7, 6, 8)]
# Find the sums of each transformation using base 3
e = apply(d * E, 2:3, sum)
# Find the lowest possible sum for each board's transformed versions
# This will be the one used for the matchboxes
f = matrix(match(e, 1:3 ^ 9), , 8)
g = apply(f, 1, min)
# Store which transformation was necessary to convert the lowest board
# into this one
G = 9 - apply(t(e == g) * 8:1, 2, max)
# Work out which boards have 3-in-a-row
h = colSums(array(c(b, d[, , 5], b[c(1, 5, 9, 3, 5, 7, 1:3), ]), c(3, 3, 3 ^ 9, 3)) * 3 ^ (0:2))
k = rowSums(colSums(h == 13)) > 0 # player 1 wins
l = rowSums(colSums(h == 26)) > 0 # player 2 wins
# Store how many cells are filled
o = colSums(b > 0)
# Create matchboxes. These contain the actual board configuration, but
# instead of zeroes for blanks have a minus number. This is initially -1,
# but will ultimately represent the number of beads for that spot on the
# board.
M = b
M[M == 0] = -1
repeat {
  # Initialise board and storage of moves and intermediate board positions
  A = b[, t <- 3 ^ 9]
  z = j = c()
  C = 1
  # If we're automating player 2 also, initialise its storage
  if (auto) {
    Z = J = c()
  }
  repeat {
    # If the current board's matchbox is empty, put up to three more beads
    # back in
    if (sum(pmax(-M[, t], 0)) == 0) {
      M[sample(9, pmin(3, sum(x)), , x <- M[, t] == 0), t] = -1
    }
    # Take out a bead from the matchbox
    u = sample(9, 1, , pmax(-M[, t], 0))
    # Mark the bead as taken out
    M[u, t] = M[u, t] + 1
    # Store the bead and board position in the chain for this game
    z = c(z, u)
    j = c(j, t)
    # Mark the spot on the board
    A[v[, C][u]] = 1
    # Print the board
    if (!auto) print_board(matrix(A, 3))
    # Check if  player 1 has won or board is full
    if (k[B <- sum(A * E)] || o[B] == 9) break
    if (auto) {
      # Repeat for player 2 if we're automating its moves
      # Note if auto == 1 then we pick at random
      # If auto == 2 we use the same algorithm as player 1
      D = g[B]
      if (sum(pmax(-M[, D], 0)) == 0) {
        M[sample(9, pmin(3, sum(x)), , x <- M[, D] == 0), D] = -1
      }
      U = sample(9, 1, , if (auto == 1) M[, D] <= 0 else pmax(-M[, D], 0))
      Z = c(Z, U)
      J = c(J, D)
      A[v[, G[B]][U]] = 2
    } else {
      cat(
        "Please enter move (LMR for top/middle/bottom row and\nLMR for left/middle/right column, e.g. MR:"
      )
      repeat {
        # Convert LMR into numbers
        q = ceiling((utf8ToInt(readline()) - 76) / 5)
        if (length(q) != 2)
          stop("Finished")
        if (all(q %in% 0:2) && A[q %*% c(1, 3) + 1] == 0) {
          break
        } else {
          message("Invalid input, please try again")
        }
      }
      A[q %*% c(1, 3) + 1] = 2
    }
    if (l[B <- sum(A * E)])
      break
    # Player 2 has won
    t = g[B]
    C = G[B]
  }
  if (auto) {
    cat(c("D", 1:2)[1 + k[B] + 2 * l[B]])
  } else {
    cat("Outcome:", c("Draw", sprintf("Player %d wins", 1:2))[1 + k[B] + 2 * l[B]], "\n")
  }
  # Add beads back to matchbox
  M[x] = M[x <- cbind(z, j)] - k[B] - 1 + l[B]
  if (auto)
    M[x] = M[x <- cbind(Z, J)] - l[B] - 1 + k[B]
}

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