ট্র্যাক
/
Crystal
Crystal
/
অনুশীলনী
/
ব্ল্যাকজ্যাক
ব্ল্যাকজ্যাক

ব্ল্যাকজ্যাক

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

ভূমিকা

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 সাবসাম্পশন অপারেটর (===)

case সাবসাম্পশন অপারেটর (===) সমতা অপারেটর (==) থেকে কিছুটা আলাদা। এই অপারেটরটি যাচাই করে ডান দিকের মানটি বাম দিকে বর্ণিত সেটের একটি সদস্য কি না। এর মানে হলো, প্রতিটি অপারেন্ড কোন দিকে বসানো হচ্ছে সেটি গুরুত্বপূর্ণ। এটি কীভাবে কাজ করবে তা নির্ভর করে বাম দিকের টাইপের উপর। যেমন, একটি Range যাচাই করে ডান দিকের মানটি ওই রেঞ্জের মধ্যে আছে কি না, আর একটি Object যাচাই করে ডান দিকের মানটি Object-এর একটি ইনস্ট্যান্স কি না।

(1..3) == 1  # => false
(1..3) === 1 # => true

String == "foo"  # => false
String === "foo" # => true

একাধিক এক্সপ্রেশনসহ case

case-এ একটি case-এর মধ্যেই একাধিক এক্সপ্রেশন মেলানো যায়, যেখানে প্রতিটি সম্ভাব্য মান কমা দিয়ে আলাদা করা হয়। এক্সপ্রেশনগুলোর যেকোনো একটি মিললে কোডটি রান করা হয়। একাধিক সম্ভাব্য মানের একটি case-এর জন্য এটি কাজে লাগতে পারে।

case 1
when 1, 2
  puts "One or two"
else
  puts "Other"
end

রেঞ্জসহ case

case দিয়ে এটাও যাচাই করা যায় যে একটি মান কোনো রেঞ্জের মধ্যে আছে কি না। এটি করা হয় when এক্সপ্রেশন হিসেবে একটি রেঞ্জ ব্যবহার করে।

case var
when 1..3
  puts "One to three"
else
  puts "Other"
end

case এক্সপ্রেশন ছাড়া case

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

এক লাইনের when

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

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

নির্দেশনা

এই অনুশীলনীতে আমরা একটি ব্ল্যাকজ্যাক গেমের প্রথম পালা অনুকরণ করব।

1. যেকোনো কার্ডের মান হিসাব করুন

আপনি দুটি কার্ড পাবেন এবং ডিলারের খোলা কার্ডটি দেখতে পাবেন। সব কার্ডকে স্ট্রিং দিয়ে প্রকাশ করা হয়, যেমন "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
Note

সাধারণত ace কার্ডের মান 1 বা 11 হতে পারে, কিন্তু সরলতার জন্য আমরা ধরে নেব যে এর মান কেবল 11 হতে পারে।

Blackjack.parse_card মেথডটি ইমপ্লিমেন্ট করুন, যা আর্গুমেন্ট হিসেবে একটি কার্ড স্ট্রিং নেয়। মেথডটি কার্ডের মান ইন্টিজার হিসেবে রিটার্ন করবে।

Blackjack.parse_card("ace")
# => 11

2. মানের রেঞ্জগুলোর নাম দিন

প্লেয়ারের স্কোরকে মানের রেঞ্জে ভাগ করতে হবে। প্লেয়ারের স্কোর হিসাব করা হয় প্লেয়ারের দুটি কার্ডের মান যোগ করে। যে রেঞ্জগুলো ব্যবহার করা হয় সেগুলো হলো:

range value
low [4, 11]
mid [12, 16]
high [17, 20]
blackjack [21]

Blackjack.card_range মেথডটি ইমপ্লিমেন্ট করুন, যা আর্গুমেন্ট হিসেবে দুটি কার্ড স্ট্রিং নেয়। মেথডটি রিটার্ন করবে দুটি কার্ড যে মানের রেঞ্জে পড়ে তার নাম।

Blackjack.card_range("ten", "king")
# => "high"

3. প্রথম পালার সিদ্ধান্তের লজিক ইমপ্লিমেন্ট করুন

আপনার দুটি কার্ড এবং ডিলারের কার্ডের ওপর নির্ভর করে গেমের প্রথম পালার জন্য একটি স্ট্র্যাটেজি আছে, যেখানে আপনার কাছে নিচের অপশনগুলো থাকে:

  • স্ট্যান্ড (S)
  • হিট (H)
  • স্প্লিট (P)
  • স্বয়ংক্রিয়ভাবে জেতা (W)

যদিও এটি এখনো সর্বোত্তম নয়, আপনি আপনার বন্ধু Alex-এর তৈরি করা স্ট্র্যাটেজি অনুসরণ করবেন, যা নিচের মতো:

  • আপনার যদি জোড়া ace থাকে, তবে সবসময় সেগুলো স্প্লিট করতে হবে।
  • আপনার যদি ব্ল্যাকজ্যাক থাকে (দুটি কার্ড যাদের যোগফল 21), এবং ডিলারের কাছে ace, কোনো ফিগার বা ten না থাকে, তবে আপনি স্বয়ংক্রিয়ভাবে জিতে যাবেন। ডিলারের কাছে এর মধ্যে কোনো কার্ড থাকলে আপনাকে স্ট্যান্ড করতে হবে এবং অন্য কার্ডটি খোলার জন্য অপেক্ষা করতে হবে।
  • আপনার কার্ডগুলোর যোগফল [17, 20] রেঞ্জের মধ্যে হলে সবসময় স্ট্যান্ড করা উচিত।
  • আপনার কার্ডগুলোর যোগফল [12, 16] রেঞ্জের মধ্যে হলে সবসময় স্ট্যান্ড করা উচিত, যদি না ডিলারের 7 বা তার বেশি থাকে; সেক্ষেত্রে সবসময় হিট করা উচিত।
  • আপনার কার্ডগুলোর যোগফল 11 বা তার কম হলে সবসময় হিট করা উচিত।

Blackjack.first_turn মেথডটি ইমপ্লিমেন্ট করুন, যা আর্গুমেন্ট হিসেবে তিনটি কার্ড স্ট্রিং নেয়। মেথডটি আপনার নেওয়া উচিত সিদ্ধান্তটি স্ট্রিং হিসেবে রিটার্ন করবে।

Blackjack.first_turn("ace", "ace", "two")
# => "P"
GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি একটি নতুন উইন্ডো বা ট্যাবে খোলে
Crystal Exercism

ব্ল্যাকজ্যাক শুরু করতে প্রস্তুত?

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