একটি Smart Game Format স্ট্রিং পার্স করা।
SGF হলো বোর্ড গেমের ফাইল সংরক্ষণের একটি স্ট্যান্ডার্ড ফরম্যাট, বিশেষ করে গো খেলার।
SGF বেশ সরল একটি ফরম্যাট। একটি SGF ফাইলে সাধারণত নোডের একটিমাত্র ট্রি থাকে, যেখানে প্রতিটি নোড একটি প্রপার্টি লিস্ট। প্রপার্টি লিস্টে কী (key)-মান জোড়া থাকে; প্রতিটি কী (key) একবারই আসতে পারে, তবে একাধিক মান থাকতে পারে।
এই অনুশীলনীতে আপনাকে একটি SGF স্ট্রিং পার্স করতে হবে এবং প্রপার্টির একটি ট্রি স্ট্রাকচার রিটার্ন করতে হবে।
একটি SGF ফাইল দেখতে এমন হতে পারে:
(;FF[4]C[root]SZ[19];B[aa];W[ab])
এটি তিনটি নোডের একটি ট্রি:
আপনি নিশ্চয়ই বুঝতে পারছেন, একটি SGF ফাইলে একটি মাত্র চাইল্ডযুক্ত অনেক নোড থাকে, তাই এর জন্য একটি শর্টহ্যান্ড আছে।
SGF খেলার বিভিন্ন ভ্যারিয়েশন এনকোড করতে পারে। গো খেলোয়াড়েরা তাদের রিভিউতে অনেক ব্যাকট্র্যাকিং করেন (চলুন এটা চেষ্টা করি, কাজ করল না, চলুন ওটা চেষ্টা করি), আর SGF খেলার সিকোয়েন্সের ভ্যারিয়েশন সাপোর্ট করে। যেমন:
(;FF[4](;B[aa];W[ab])(;B[dd];W[ee]))
এখানে রুট নোডের দুটি ভ্যারিয়েশন আছে। প্রথমটি (যা প্রচলিত নিয়মে বোঝায় আসলে কী খেলা হয়েছে) হলো সেটি, যেখানে কালো 1-1 পয়েন্টে খেলে। কালোকে এই ফাইলটি পাঠিয়েছিলেন তার শিক্ষক, যিনি রুট নোডের দ্বিতীয় চাইল্ডে আরও যুক্তিসঙ্গত একটি খেলা দেখিয়েছিলেন: B[dd] (4-4 পয়েন্ট, কোণা নেওয়ার একটি খুবই স্ট্যান্ডার্ড ওপেনিং)।
একটি কী (key)-এর সাথে একাধিক মান যুক্ত থাকতে পারে। যেমন:
(;FF[4];AB[aa][ab][ba])
এখানে AB (add black) বোর্ডে তিনটি কালো পাথর যোগ করতে ব্যবহৃত হয়।
সব প্রপার্টির মানই হবে SGF Text টাইপ। আপনাকে আর কোনো মান টাইপ ইমপ্লিমেন্ট করতে হবে না। যদিও আপনি Text টাইপের সম্পূর্ণ ডকুমেন্টেশন পড়তে পারেন, গুরুত্বপূর্ণ বিষয়গুলোর একটি সারসংক্ষেপ নিচে দেওয়া হলো:
\-এর পরে আসে, তাহলে সেটি মুছে ফেলা হয়; অন্যথায় সেটি নিউলাইন হিসেবেই থাকে।\ হলো এস্কেপ ক্যারেক্টার।
\-এর পরে আসা যেকোনো নন-হোয়াইটস্পেস ক্যারেক্টার যেমন আছে তেমনই বসানো হয়।
\-এর পরে আসা যেকোনো হোয়াইটস্পেস ক্যারেক্টার উপরের নিয়ম মেনে চলে।
মনে রাখবেন, SGF-এ \t বা \n-এর মতো হোয়াইটস্পেস ক্যারেক্টারের জন্য কোনো এস্কেপ সিকোয়েন্স নেই।এই দুইয়ের মধ্যে গুলিয়ে ফেলবেন না:
SGF পার্সারে পাস করার আগেই প্রোগ্রামিং ভাষার পার্সার স্ট্রিং লিটারালের এস্কেপ সিকোয়েন্স প্রসেস করে ফেলতে পারে।
SGF-এ (এবং সাধারণভাবে পার্সিংয়ে) আরও কিছু জটিলতা আছে, যেগুলো আপনি বেশিরভাগ ক্ষেত্রেই এড়িয়ে যেতে পারেন। ধরে নেবেন যে ইনপুট UTF-8-এ এনকোড করা, টেস্টে কোনো ক্যারসেট প্রপার্টি থাকবে না, তাই এটা নিয়ে চিন্তা করবেন না। এছাড়াও আপনি ধরে নিতে পারেন যে সব নিউলাইন ইউনিক্স স্টাইলের (\n, টেস্টে কোনো \r বা \r\n থাকবে না), আর টেস্টে প্রপার্টি, নোড ইত্যাদির মাঝে কোনো অপশনাল হোয়াইটস্পেস থাকবে না।
Sgf মডিউলটির নিচের সিগনেচার-সহ একটি parseSgf মডিউল এক্সপোর্ট করা উচিত:
parseSgf :: Text -> Maybe (Tree (Map Text [Text]))
SgfTree আর SgfNode-এর নিচের ডেফিনিশনগুলো কপি করে রাখলে আপনার কাজে লাগতে পারে:
-- | A tree of nodes.
type SgfTree = Tree SgfNode
-- | A node is a property list, each key can only occur once.
-- Keys may have multiple values associated with them.
type SgfNode = Map Text [Text]
parsec লাইব্রেরিটি Haskell Platform-এর অংশ। আপনার সুবিধার জন্য এটি ব্যবহার করুন।
Exercism-এ সাইন আপ করুন, Haskell ট্র্যাকের 107টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।