দাবা খেলা

দাবা খেলা

লার্নিং অনুশীলনী

ভূমিকা

রেঞ্জ দুটি মানের মধ্যবর্তী একটি ব্যবধান বোঝায়। রেঞ্জ সাপোর্ট করে এমন সবচেয়ে কমন টাইপগুলো হলো Int, Char এবং String. এগুলো অনেক কাজে ব্যবহার করা যায়, যেমন দ্রুত একটি কালেকশন তৈরি করা, স্ট্রিং স্লাইস করা, কোনো মান রেঞ্জের মধ্যে আছে কি না তা যাচাই করা, এবং ইটারেশন। এগুলো রেঞ্জ অপারেটর .. বা ... দিয়ে তৈরি করা হয় (যথাক্রমে অন্তর্ভুক্তিমূলক ও বর্জনমূলক)।

1..5  # A range containing 1, 2, 3, 4, 5
1...5 # A range containing 1, 2, 3, 4

দুটি রেঞ্জ অপারেটর থাকার কারণ হলো এমন রেঞ্জ তৈরি করা, যা শেষ মানটিকে অন্তর্ভুক্ত করে বা বাদ দেয়, এবং এটি কাজে লাগে যখন, উদাহরণস্বরূপ, শূন্য-ভিত্তিক ইনডেক্স নিয়ে কাজ করা হয়।

Range ইনিশিয়ালাইজার দিয়েও রেঞ্জ তৈরি করা যায়।

Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Note

Crystal-এ রেঞ্জ অপারেটর .. বা ... দিয়ে রেঞ্জ তৈরি করার সময় যদি আপনি রেঞ্জের উপর কোনো মেথড কল করতে চান, তাহলে রেঞ্জটিকে বন্ধনীর মধ্যে রাখতে হবে। কারণ অন্যথায় মেথডটি রেঞ্জ অপারেটরের দ্বিতীয় আর্গুমেন্টের উপর কল করা হবে।

(1..5).size # => 5
1..5.size # => Error: undefined method 'size' for Int32

সাবস্ট্রিং পাওয়া

একটি স্ট্রিং স্লাইস করতে চাইলে, সাবস্ট্রিং পেতে আপনি রেঞ্জ অপারেটর ব্যবহার করতে পারেন। অর্থাৎ, সাবস্ট্রিংয়ের শুরুর ও শেষ ইনডেক্স দিয়ে একটি রেঞ্জ তৈরি করে।

স্ট্রিংয়ের শেষ থেকে সাবস্ট্রিং পেতে ঋণাত্মক ইনডেক্সও ব্যবহার করতে পারেন।

"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"

আরও কিছু সাবস্ট্রিং পাওয়ার জন্য আপনি ঋণাত্মক ইনডেক্স ব্যবহার করতে পারেন।

"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"

রেঞ্জের মেথড

রেঞ্জের সাথে কাজ করার জন্য রেঞ্জের কিছু মেথড আছে। উদাহরণস্বরূপ, এই মেথডগুলো দিয়ে রেঞ্জের সব মানের যোগফল বের করা যায় বা রেঞ্জে কোনো মান আছে কি না তা যাচাই করা যায়।

মেথড বর্ণনা উদাহরণ
sum রেঞ্জের সব মানের যোগফল রিটার্ন করে (1..5).sum # => 15
size রেঞ্জের আকার রিটার্ন করে (1..5).size # => 5
includes? রেঞ্জে প্রদত্ত মানটি থাকলে true রিটার্ন করে, অন্যথায় false (1..5).includes?(3) # => true

অন্তহীন ও শুরুবিহীন রেঞ্জ

একটি রেঞ্জ অন্তহীন বা শুরুবিহীন হতে পারে। অন্তহীন বা শুরুবিহীন রেঞ্জের শুরু বা শেষ মান থাকে nil, তবে রেঞ্জ ডিফাইন করার সময় nil বাদ দেওয়া যায়।

শুরুবিহীন ও অন্তহীন রেঞ্জ কাজে লাগে যখন আপনি চান, উদাহরণস্বরূপ, স্ট্রিংয়ের শুরু থেকে বা শেষ পর্যন্ত স্লাইস করতে।

"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello"
Caution

কোনো কালেকশনের উপর ব্যবহার করা না হলে, সতর্কতার সাথে ব্যবহার না করলে অন্তহীন রেঞ্জ একটি অন্তহীন সিকোয়েন্স তৈরি করতে পারে।

Char রেঞ্জ

রেঞ্জে Char ব্যবহার করা যায় এবং দুটি Char-এর মধ্যবর্তী Char-এর একটি ব্যবধান পেতে দেয়। উদাহরণস্বরূপ, বর্ণমালা পেতে চাইলে এটি কাজে লাগতে পারে।

'a'..'z' # A range containing ['a', 'b', 'c', ..., 'z']

String রেঞ্জ

স্ট্রিংও রেঞ্জে ব্যবহার করা যায়, যা দিয়ে দুটি স্ট্রিংয়ের মধ্যবর্তী স্ট্রিংয়ের একটি ব্যবধান পাওয়া যায়। তবে স্ট্রিং রেঞ্জে একাধিক ক্যারেক্টার ব্যবহার করলে এর আচরণ Char-এর থেকে সামান্য আলাদা। আরও জটিল স্ট্রিং রেঞ্জ নিয়ে কাজ করলে এর আচরণ বিভ্রান্তিকর হয়ে উঠতে পারে, তাই সতর্ক থাকুন।

("aa".."az") # A range containing ["aa", "ab", "ac", ..., "az"]

নির্দেশনা

দাবা অনুরাগী হিসেবে আপনি খেলাটির নিজের সংস্করণ লিখতে চান। হ্যাঁ, অনলাইনে দাবার অনেক ইমপ্লিমেন্টেশন হয়তো আগেই আছে, কিন্তু আপনারটি হবে অনন্য!

আপনি শুরু করবেন গুটিগুলোর জন্য একটি বেসিক মুভমেন্ট সিস্টেম ইমপ্লিমেন্ট করে।

দাবা খেলাটি খেলা হবে আট ঘর চওড়া এবং আট ঘর লম্বা একটি বোর্ডে। প্রতিটি ঘর চিহ্নিত করা হয় একটি অক্ষর ও একটি সংখ্যা দিয়ে।

1. র‍্যাঙ্ক ও ফাইলের রেঞ্জ ডিফাইন করুন

খেলাটিকে বোর্ডের র‍্যাঙ্কগুলো সংরক্ষণ করতে হবে। র‍্যাঙ্ক হলো বোর্ডের সারি, যেগুলো ১ থেকে ৮ পর্যন্ত সংখ্যায়িত।

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

Chess::RANKS ও Chess::FILES কনস্ট্যান্ট ডিফাইন করুন, যেগুলো যথাক্রমে র‍্যাঙ্ক ও ফাইলের রেঞ্জ সংরক্ষণ করে।

Chess::RANKS
# => 1..8

Chess::FILES
# => 'A'..'H'

2. ঘরটি বৈধ কি না তা যাচাই করুন

খেলাটিকে যাচাই করতে হবে একটি ঘর বৈধ কি না। কোনো ঘরের র‍্যাঙ্ক ও ফাইল যদি র‍্যাঙ্ক ও ফাইলগুলোর রেঞ্জের মধ্যে থাকে, তাহলে ঘরটি বৈধ।

Chess.valid_square? মেথডটি ডিফাইন করুন, যা আর্গুমেন্ট হিসেবে নেয় rank, যেটিতে র‍্যাঙ্কের একটি int থাকে, এবং file, যেটিতে ফাইলের একটি char থাকে। র‍্যাঙ্ক ও ফাইল র‍্যাঙ্ক ও ফাইলগুলোর রেঞ্জের মধ্যে থাকলে মেথডটি true রিটার্ন করবে, আর অন্যথায় false রিটার্ন করবে।

Chess.valid_square?(1, 'A')
# => true

3. খেলোয়াড়ের ডাকনাম বের করুন

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

Chess.nickname মেথডটি ডিফাইন করুন, যা আর্গুমেন্ট হিসেবে নেয় first_name, যেটিতে খেলোয়াড়ের প্রথম নামের একটি স্ট্রিং থাকে, এবং last_name, যেটিতে খেলোয়াড়ের শেষ নামের একটি স্ট্রিং থাকে। মেথডটি খেলোয়াড়ের ডাকনাম বড় হাতের অক্ষরের একটি স্ট্রিং হিসেবে রিটার্ন করবে।

Chess.nickname("John", "Doe")
# => "JOOE"

4. মুভের মেসেজ তৈরি করুন

কোন খেলোয়াড় কোন ঘরে গেছে, তা জানানোর জন্য খেলাটিকে প্রতিটি মুভের একটি মেসেজ তৈরি করতে হবে। মেসেজে থাকবে খেলোয়াড়ের ডাকনাম এবং সে যে ঘরে গেছে সেটি। এছাড়া ঘরটির ফাইল ও র‍্যাঙ্ক ফাইল ও র‍্যাঙ্কগুলোর রেঞ্জের মধ্যে আছে কি না, তা যাচাই করে খেলাটিকে মুভটি বৈধ কি না তাও নির্ধারণ করতে হবে।

মুভটি বৈধ হলে মেসেজটি হবে: "{nickname} moved to {square}" আর মুভটি অবৈধ হলে মেসেজটি হবে: "{nickname} attempted to move to {square}, but that is not a valid square"

Chess.move_message মেথডটি ডিফাইন করুন, যা আর্গুমেন্ট হিসেবে নেয় first_name, যেটিতে খেলোয়াড়ের first_name-এর একটি স্ট্রিং থাকে, last_name, যেটিতে খেলোয়াড়ের last_name-এর একটি স্ট্রিং থাকে, এবং square, যেটিতে খেলোয়াড় যে ঘরে গেছে সেই ঘরের একটি স্ট্রিং থাকে। মেথডটি মুভের মেসেজটি একটি স্ট্রিং হিসেবে রিটার্ন করবে।

Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি একটি নতুন উইন্ডো বা ট্যাবে খোলে
Crystal Exercism

দাবা খেলা শুরু করতে প্রস্তুত?

Exercism-এ সাইন আপ করুন, Crystal ট্র্যাকের 26টি কনসেপ্ট142টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।