টিক-ট্যাক-টো খেলুন এবং কখনই হারাবেন না


14

(এখানে কয়েকটি চ্যালেঞ্জ রয়েছে যার জন্য সেরা কৌশলটি ব্যবহার করা প্রয়োজন তবে এখানে আমরা তা করি না you আপনি জিততে সক্ষম হলেও, আপনাকে টাই করার অনুমতি দেওয়া হয়েছে)

চ্যালেঞ্জ

এমন একটি প্রোগ্রাম লিখুন যা গেমটি টিক-ট্যাক-টু খেলবে। এটি হারাতে হবে না (সুতরাং, এটি টাই বা জয়ের মাধ্যমে খেলাটি শেষ করা উচিত)।

অনুমোদিত I / O পদ্ধতিগুলি

  1. ইনপুট বর্তমান বোর্ড হতে পারে। আপনি ধরে নিতে পারেন যে ২ য় প্লেয়ারের পূর্ববর্তী সমস্ত চালগুলি আপনার ইঞ্জিন দ্বারা চালিত হয়েছিল।
  2. ইনপুট প্রথম প্লেয়ারের চাল হতে পারে এবং আপনার ফাংশন স্টোরগুলি যা চলমানগুলি অতীতে ঘটেছিল। এই ক্ষেত্রে ফাংশনটি একাধিকবার বলা হয়, প্রতিটি পদক্ষেপের জন্য একবার; অথবা একাধিকবারের জন্য ফাংশন / প্রোগ্রাম প্রম্পট ইনপুট।
  3. আপনি যদি প্রথম খেলোয়াড় হন তবে আপনাকে অতিরিক্ত ইনপুট নেওয়ার অনুমতি দেওয়া হয়, বা প্রথম-প্লেয়ার সমস্যা এবং দ্বিতীয় খেলোয়াড় সমস্যা সমাধানের জন্য দুটি (সম্ভবত সম্পর্কিত) ফাংশন লিখুন। যদি আপনার প্রোগ্রামটির ইনপুট পদ্ধতি 2 (একাধিক কল) ব্যবহারের প্রয়োজন হয় তবে প্রথম কলটিতে কী পাস হবে তা আপনি সিদ্ধান্ত নিতে পারেন।
  4. আপনার পালা পরে আউটপুট বোর্ড হতে পারে।
  5. আউটপুট আপনার চল হতে পারে।
  6. একটি পদক্ষেপ সংখ্যার জোড় (0-ইনডেক্সিং বা 1-ইনডেক্সিং হতে পারে), 0 ~ 8 রেঞ্জের একটি সংখ্যা বা 1 ~ 9 রেঞ্জের একটি সংখ্যা হিসাবে প্রতিনিধিত্ব করা যেতে পারে।
  7. বোর্ডটি 3 × 3 অ্যারে বা দৈর্ঘ্যের একটি অ্যারে হিসাবে উপস্থাপিত হতে পারে the এমনকি যদি ভাষাতে 0-সূচীকরণ অ্যারে থাকে তবে আপনি 1-ইনডেক্সিং ব্যবহার করতে পারেন।
  8. গ্রিড উপর কোষ ইঙ্গিত কোন 3 মান আলাদা ব্যবহার করতে পারেন X, Oএবং খালি।

জয়ের মানদণ্ড

প্রতিটি ভাষার জিতে সংক্ষিপ্ত কোড।


যদি কোনও হারানো আপনাকে দেওয়া হয় তবে আপনার সমাধানটি অবৈধ। আপনি অন্যের সাথে খেলছেন, সুতরাং we can assume that all previous moves of the 2nd player were also played by our engine
দাবাবোর্ডটি


1
@ l4m2 কেবল দোভাষী পুনরায় চালু করুন। সম্পন্ন. কেন এ নিয়ে বিরক্ত করবেন? এটি অকারণে কিছুই করার জন্য বাইট গণনা বৃদ্ধি করে।
ব্যবহারকারী 202729


4
বোনাস করবেন না। হয় এটির প্রয়োজন হয় বা এটি সরান, এটি alচ্ছিক করবেন না। বোনাস চ্যালেঞ্জ ধ্বংসাবশেষ ..
Rɪᴋᴇʀ

উত্তর:


4

বেফুঞ্জ, 181 168 বাইট

>>4&5pp20555>>03>16p\::5g8%6p5v
 ^p5.:g605$_ #!<^_|#:-1g61+%8g<
543217539511|:_^#->#g0<>8+00p3+5%09638527419876
v<304p$_v#:->#$$:2`#3_:^
>#\3#13#<111v124236478689189378

বোর্ডে পজিশনগুলি 1 থেকে 9. নম্বরযুক্ত হয় ডিফল্টরূপে আপনি প্রথম পদক্ষেপটি পান তবে আপনি যদি কম্পিউটারটিকে প্রথমে যেতে দিতে চান তবে আপনার প্রথম পদক্ষেপের জন্য আপনি কেবল 0 লিখতে পারেন। আপনি যখন কোনও পদক্ষেপ নেবেন, তখন কম্পিউটার তাদের সংখ্যাটি নির্দেশ করে এমন একটি সংখ্যার সাথে প্রতিক্রিয়া জানাবে।

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

ইন্টারেক্টিভ ইনপুট সহ কোনও অনলাইন দোভাষী নেই বলে এই অনলাইনটি পরীক্ষা করা কিছুটা কঠিন difficult তবে, আপনি যদি জানেন যে আপনি কী পদক্ষেপগুলি আগাম তৈরি করতে যাচ্ছেন (যা ধরে নিচ্ছে কম্পিউটারটি কীভাবে প্রতিক্রিয়া জানাতে চলেছে), আপনি টিআওও-তে পরীক্ষা চালাতে পারেন এই পদক্ষেপগুলি প্রিগ্রোগ্রামড দিয়ে।

ব্যবহারকারী প্রথমে খেলে: এটি অনলাইনে চেষ্টা করুন!
কম্পিউটার প্রথম চালায়: এটি অনলাইনে চেষ্টা করুন!

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

ব্যবহারকারী প্রথমে খেলে: এটি অনলাইনে চেষ্টা করুন!
কম্পিউটার প্রথম চালায়: এটি অনলাইনে চেষ্টা করুন!

মনে রাখবেন যে ফলাফলগুলি দেখার আগে আপনাকে টিআইওর সময়সীমা শেষ হওয়ার অপেক্ষা করতে হবে।

ব্যাখ্যা

বোর্ডটি বেফঞ্জ মেমরি অঞ্চলে 9 টি মানের সমতল অ্যারে হিসাবে 1 থেকে 9 পর্যন্ত সূচিত হয় from এটি আমাদের শূন্য অফসেটটিকে একটি বিশেষ কেস "নো মুভ" হিসাবে ব্যবহার করতে দেয় যখন আমরা কম্পিউটারকে প্রথমে খেলতে চাই। প্লেয়ার মুভগুলি 4 হিসাবে সংরক্ষণ করা হয়, এবং কম্পিউটার 5 হিসাবে সরানো হয় সমস্ত অবস্থানের সাথে শুরু করতে 32 (বেফুঞ্জ মেমরি ডিফল্ট) থেকে শুরু করা হয়, তাই যখনই আমরা বোর্ডটি 8 দিয়ে মোডে প্রবেশ করি তখন আমরা 0, 4 এর সাথে ফিরে আসব either বা 5।

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

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

আমরা যে ট্রিপলগুলির পরীক্ষা করি তার প্রধান তালিকা হ'ল বিজয়ী সংমিশ্রণগুলি (1/2/3, 1/5/9, 1/4/7, ইত্যাদি)। আমরা প্রথমে মোট 10 টি অনুসন্ধান করি (কম্পিউটারটি জিততে চলেছে), এবং তারপরে মোট 8 জন (প্লেয়ার জিততে চলেছে এবং আমাদের সেই পদক্ষেপটি আটকাতে হবে)। স্পষ্টতই, আমরা মোট 9 টিও পরীক্ষা করে দেখি (যদি প্লেয়ার এবং কম্পিউটারের প্রতিটি পজিশনের একটি থাকে তবে কম্পিউটারের পক্ষে তৃতীয়টি নেওয়া ভাল কৌশল)।

শেষ দৃশ্যের আগে, আমরা যে অন্যান্য কৌশলগত পদক্ষেপ করি তা হ'ল সমস্ত কোণার সেটগুলি (1/2/4, 2/3/6, ইত্যাদি) পাশাপাশি দুটি বিরোধী কোণার সংমিশ্রণ (1/8/9 এবং 3) পরীক্ষা করা / 7/8)। এই সংমিশ্রণের মধ্যে যদি 8 টির সমষ্টি হয়, অর্থাৎ প্লেয়ার দুটি পদ গ্রহণ করে থাকে তবে কম্পিউটারের জন্য বাকি নিখরচায় অবস্থান নেওয়া ভাল কৌশল।

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

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


আমি বেফুঞ্জকে বেশ জানি না, তবে সম্ভবত আপনি সমস্ত সম্ভাব্য ইনপুট পরীক্ষা করতে পারেন ( নমুনা )
l4m2

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

2

পাইথন 2: 399 401 349 333 317 370 বাইট

2x বাগ ফিক্স: ক্রেডিট l4m2

-52 চরিত্রগুলি: ভূগর্ভস্থমোনরেলে জমা il

-16 অক্ষর: জনাথন ফ্রেচের কাছে কৃতিত্ব

-26 অক্ষর: ব্যবহারকারীকে ক্রেডিট 202729

def f(b):
 t=4,9,2,3,5,7,8,1,6;n=lambda k:[t[i]for i,j in enumerate(b)if j==k];p,o,a,I=n(2),n(1),n(0),t.index
 for i in p:
    for j in p:
     for k in a:
        if i+j+k==15and-j+i:return I(k)
 for i in o:
    for j in o:
     for k in a:
        if i+j+k==15and-j+i:return I(k)
 for i in 9,3,7,1:
    if i in a and 5 in p:return I(i)
 for i in 5,4,2,8,6:
    if i in a:return I(i)
 return I(a[0])

অনলাইনে চেষ্টা করে দেখুন!

লিনিয়ার বীজগণিত কোর্সের প্রথম দিন আমি শেষ সেমিস্টার নিয়েছিলাম, আমার অতিপ্রাকৃত স্নাতক ছাত্র প্রশিক্ষক প্রস্তাব করেছিলেন যে আপনি যদি টিক-ট্যাক-টো বোর্ডকে ম্যাট্রিক্স হিসাবে উপস্থাপন করেন:

4 | 9 | 2
--+---+--
3 | 5 | 7
--+---+--
8 | 1 | 6

তারপরে পরপর তিনটি পাওয়া পারা [1,9] এর মধ্যে 15 টি সংখ্যা যুক্ত করে তিনটি সংখ্যা বাছাইয়ের সমান This এই উত্তরটি এই ধারণাটি কাজে লাগায়। ফাংশনটি বোর্ডের প্রতিনিধিত্বকারী নয় নম্বর সমন্বিত একটি তালিকা গ্রহণ করে। 0 একটি খালি স্থান নির্দেশ করে, 1 প্রতিপক্ষের দ্বারা দখল করা হয়েছে, এবং 2 প্রোগ্রাম দ্বারা নির্মিত পূর্ববর্তী নাটকটির প্রতিনিধিত্ব করে। প্রথম 3 লাইনগুলি বুঝতে পারে যে প্রোগ্রামটি কী সংখ্যাটি বেছে নিয়েছে (পি), বিরোধীরা বাছাই করেছে (ও) এবং এখনও উপলব্ধ (ক)। এটি তখন উপলভ্য সংখ্যাগুলির মধ্যে নজর রাখে এবং দেখায় যে তাদের মধ্যে দুটি সংখ্যার সাথে মিলিত হয়ে এটি ইতিমধ্যে পনেরোটি যোগ করেছে। এটি যদি করে তবে এটি স্কোয়ারটি বাছাই করবে এবং জিতবে। যদি তাত্ক্ষণিকভাবে বিজয়ী পদক্ষেপ না থাকে, তবে প্রতিপক্ষ একই পদ্ধতি ব্যবহার করে জিততে পারে কিনা তা পরীক্ষা করে দেখবে। যদি তারা পারেন তবে এটি তাদের বিজয়ী স্কয়ার লাগবে take যদি বিজয়ী বা অবরুদ্ধ পদক্ষেপ নাও পাওয়া যায় তবে এটি একটি কোণে সরানো হবে। এটি একটি বোকা সঙ্গীকে বাধা দেয়:

- - - 
- X -
- - -

- O -             # Bad Move
- X -
- - -

- O X
- X -
- - -

- O X
- X -
O - -

- O X
- X -
O - X

যদি এগুলির কোনওটি না ঘটে তবে এটি নির্বিচারে একটি বর্গ নির্বাচন করবে। ফাংশনটি অ্যালগরিদম দ্বারা নির্বাচিত 0 সূচকযুক্ত বর্গের প্রতিনিধিত্ব করে [0,8] এর একটি সংখ্যা আউটপুট করে।

সম্পাদনা করুন: অ্যালগরিদমটি এখন তির্যক কেন্দ্রের উপরে কেন্দ্রকে অগ্রাধিকার দেয়, যা l4m2 এবং সম্পর্কিত কৌশল দ্বারা নির্দেশিত অন্য বোকা সঙ্গীর সম্ভাবনা রোধ করবে।

সম্পাদনা: স্পষ্ট করার জন্য, ফাংশনটি অ্যারে আকারে একটি বোর্ডে নিয়ে যায় এবং [0,8] তে পূর্ণসংখ্যার হিসাবে একটি পদক্ষেপ আউটপুট করে। কারণ এই আই / ও কৌশলটি এতটাই জটিল, এখানে একটি মোড়ক স্ক্রিপ্ট এটি আরও ইন্টারেক্টিভ করে তোলে। এটিতে একটি একক কমান্ড লাইন আর্গুমেন্ট লাগে, যা প্লেয়ারের আগে চলে গেলে 1 হওয়া উচিত এবং প্রোগ্রামটি আগে চলে গেলে 0 হবে।

import sys

def f(b):
 t=4,9,2,3,5,7,8,1,6;n=lambda k:[t[i]for i,j in enumerate(b)if j==k];p,o,a,I=n(2),n(1),n(0),t.index
 for i in p:
    for j in p:
     for k in a:
        if i+j+k==15and-j+i:return I(k)
 for i in o:
    for j in o:
     for k in a:
        if i+j+k==15and-j+i:return I(k)
 for i in 9,3,7,1:
    if i in a and 5 in p:return I(i)
     for i in 5,4,2,8,6:
        if i in a:return I(i)
 return I(a[0])

board = [0,0,0,0,0,0,0,0,0]
rep = {0:"-",1:"X",2:"O"}

turn = int(sys.argv[1])
while True:
    for i in range(3):
        print rep[board[i*3]]+" "+rep[board[i*3+1]]+" "+rep[board[i*3+2]]
        print
    if turn:
        move = int(raw_input("Enter Move [0-8]: "))
    else:
        move = f(board)
    board[move] = turn+1
    turn = (turn+1)%2 


1
returnশেষ এক ব্যতীত আপনার সমস্ত লাইন তাদের সামনে লাইনে রাখা যাবে, সাদা স্থান সংরক্ষণ করে
আন্ডারগ্রাউন্ডোমোরাইল

1
এছাড়াও আমি খুবই আশ্চর্য যদি এটা বাইট, পরিবর্তে করছেন বাঁচাতে হবে না করতে পারেন e=enumerate, কি f=lambda n:[t[i]for i,j in enumerate(b)if j==n]এবং বরাদ্দ p, oএবং aফাংশন ব্যবহার করে। যদিও এটি গণনা করা হয়নি
আন্ডারগ্রাউন্ডোমোরিয়েল

3
তবুও হ্যাকxkcd.com/832 সত্যিই সহায়তা করে
l4m2

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.