case (অন্য ভাষায় সাধারণত যাকে switch বলা হয়) হলো if-else-এর মতো এক ধরনের কন্ট্রোল এক্সপ্রেশন।
case দিয়ে একাধিক if-else-if স্টেটমেন্ট একসাথে জোড়া যায়, এটি পড়তে আরও সহজ হতে পারে, এবং শক্তিশালী কনস্ট্রাক্ট লেখা সম্ভব করে।
একটি case ডিফাইন করা হয় case কিওয়ার্ড দিয়ে, যার পরে থাকে একটি ঐচ্ছিক এক্সপ্রেশন।
এরপর প্রতিটি ক্ষেত্রের জন্য when কিওয়ার্ড ব্যবহার করা হয়, যার পরে থাকে এমন একটি এক্সপ্রেশন যা case এক্সপ্রেশনের সাথে তুলনা করা হয়।
when কিওয়ার্ডটি case কিওয়ার্ডের চেয়ে ভেতরে ইনডেন্ট করা উচিত নয়।
when কিওয়ার্ডের পরে থাকে সেই কোড, যা case এক্সপ্রেশনটি when এক্সপ্রেশনের সাথে মিলে গেলে রান করা উচিত।
case-এ একটি ঐচ্ছিক else স্টেটমেন্ট থাকতে পারে, যা অন্য কোনো case-এর সাথে না মিললে রান করা হয়।
case এক্সপ্রেশনটি মূল্যায়ন করা হয়, তারপর প্রতিটি when এক্সপ্রেশনের সাথে তুলনা করা হয়।
এই তুলনাটি করা হয় case সাবসাম্পশন অপারেটর (===) দিয়ে।
case 1
when 1
puts "One"
when 2
puts "Two"
else
puts "Other"
end
# => One
# This is the same as:
tmp = 1
if 1 === tmp
puts "One"
elsif 2 === tmp
puts "Two"
else
puts "Other"
end
===)case সাবসাম্পশন অপারেটর (===) সমতা অপারেটর (==) থেকে কিছুটা আলাদা।
এই অপারেটরটি যাচাই করে ডান দিকের মানটি বাম দিকে বর্ণিত সেটের একটি সদস্য কি না।
এর মানে হলো, প্রতিটি অপারেন্ড কোন দিকে বসানো হচ্ছে সেটি গুরুত্বপূর্ণ।
এটি কীভাবে কাজ করবে তা নির্ভর করে বাম দিকের টাইপের উপর। যেমন, একটি Range যাচাই করে ডান দিকের মানটি ওই রেঞ্জের মধ্যে আছে কি না, আর একটি Object যাচাই করে ডান দিকের মানটি Object-এর একটি ইনস্ট্যান্স কি না।
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
case-এ একটি case-এর মধ্যেই একাধিক এক্সপ্রেশন মেলানো যায়, যেখানে প্রতিটি সম্ভাব্য মান কমা দিয়ে আলাদা করা হয়। এক্সপ্রেশনগুলোর যেকোনো একটি মিললে কোডটি রান করা হয়। একাধিক সম্ভাব্য মানের একটি case-এর জন্য এটি কাজে লাগতে পারে।
case 1
when 1, 2
puts "One or two"
else
puts "Other"
end
case দিয়ে এটাও যাচাই করা যায় যে একটি মান কোনো রেঞ্জের মধ্যে আছে কি না। এটি করা হয় when এক্সপ্রেশন হিসেবে একটি রেঞ্জ ব্যবহার করে।
case var
when 1..3
puts "One to three"
else
puts "Other"
end
case এক্সপ্রেশনের প্রয়োজন না থাকলে সেটি বাদ দেওয়া যায়। এভাবে করলে প্রতিটি এক্সপ্রেশন সত্য কি মিথ্যা, তা বিবেচনা করা হয়। আর এতে তারা if-else-if স্টেটমেন্টের মতো আচরণ করে।
case
when 1 == 1
puts "One is equal to one"
when 1 > 2
puts "One is greater than two"
else
puts "Other"
end
Crystal এক লাইনের case স্টেটমেন্ট লেখার সুবিধা দেয়।
সরল এক লাইনের স্টেটমেন্ট থাকলে এটি ব্যবহার করা যায়।
এক লাইনের when লেখা হয় when <expression> then <statement>. আকারে।
আর else স্টেটমেন্টে ব্যবহার করলে লেখা হয় else <statement> আকারে।
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
case দিয়ে টাইপের সাথে মেলানো যায়।
তুলনার সময় is_a? অপারেটর দিয়ে ভ্যারিয়েবলের টাইপ যাচাই করা হয়।
যেমন, এতে একটি ইউনিয়ন টাইপের প্রতিটি টাইপের জন্য আলাদা শাখা রাখা যায়।
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
case-এ ইমপ্লিসিট অবজেক্ট ব্যবহার করা যায়। এতে উদাহরণস্বরূপ, একটি when এক্সপ্রেশন হয়ে ওঠে case এক্সপ্রেশনের উপর করা একটি মেথড কল। মেথডটি ট্রুথি বা ফলসি মান রিটার্ন করে কি না, তার উপর নির্ভর করে case-টি মেলে কি না।
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
এই অনুশীলনীতে আমরা একটি ব্ল্যাকজ্যাক গেমের প্রথম পালা অনুকরণ করব।
আপনি দুটি কার্ড পাবেন এবং ডিলারের খোলা কার্ডটি দেখতে পাবেন। সব কার্ডকে স্ট্রিং দিয়ে প্রকাশ করা হয়, যেমন "ace", "king", "three", "two" ইত্যাদি। প্রতিটি কার্ডের মান হলো:
| card | value | card | value |
|---|---|---|---|
| ace | 11 | eight | 8 |
| two | 2 | nine | 9 |
| three | 3 | ten | 10 |
| four | 4 | jack | 10 |
| five | 5 | queen | 10 |
| six | 6 | king | 10 |
| seven | 7 | অন্য | 0 |
সাধারণত ace কার্ডের মান 1 বা 11 হতে পারে, কিন্তু সরলতার জন্য আমরা ধরে নেব যে এর মান কেবল 11 হতে পারে।
Blackjack.parse_card মেথডটি ইমপ্লিমেন্ট করুন, যা আর্গুমেন্ট হিসেবে একটি কার্ড স্ট্রিং নেয়।
মেথডটি কার্ডের মান ইন্টিজার হিসেবে রিটার্ন করবে।
Blackjack.parse_card("ace")
# => 11
প্লেয়ারের স্কোরকে মানের রেঞ্জে ভাগ করতে হবে। প্লেয়ারের স্কোর হিসাব করা হয় প্লেয়ারের দুটি কার্ডের মান যোগ করে। যে রেঞ্জগুলো ব্যবহার করা হয় সেগুলো হলো:
| range | value |
|---|---|
| low | [4, 11] |
| mid | [12, 16] |
| high | [17, 20] |
| blackjack | [21] |
Blackjack.card_range মেথডটি ইমপ্লিমেন্ট করুন, যা আর্গুমেন্ট হিসেবে দুটি কার্ড স্ট্রিং নেয়।
মেথডটি রিটার্ন করবে দুটি কার্ড যে মানের রেঞ্জে পড়ে তার নাম।
Blackjack.card_range("ten", "king")
# => "high"
আপনার দুটি কার্ড এবং ডিলারের কার্ডের ওপর নির্ভর করে গেমের প্রথম পালার জন্য একটি স্ট্র্যাটেজি আছে, যেখানে আপনার কাছে নিচের অপশনগুলো থাকে:
যদিও এটি এখনো সর্বোত্তম নয়, আপনি আপনার বন্ধু Alex-এর তৈরি করা স্ট্র্যাটেজি অনুসরণ করবেন, যা নিচের মতো:
Blackjack.first_turn মেথডটি ইমপ্লিমেন্ট করুন, যা আর্গুমেন্ট হিসেবে তিনটি কার্ড স্ট্রিং নেয়।
মেথডটি আপনার নেওয়া উচিত সিদ্ধান্তটি স্ট্রিং হিসেবে রিটার্ন করবে।
Blackjack.first_turn("ace", "ace", "two")
# => "P"
Exercism-এ সাইন আপ করুন, Crystal ট্র্যাকের 26টি কনসেপ্ট142টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।