بولینگ

بولینگ

متوسط

دستورالعمل‌ها

امتیاز یک بازی بولینگ را محاسبه کنید.

بولینگ بازی‌ای است که در آن بازیکنان یک توپ سنگین را می‌غلتانند تا میله‌هایی را که به شکل مثلث چیده شده‌اند بیندازند. کدی بنویسید که امتیاز یک بازی بولینگ را پیگیری کند.

امتیازدهی در بولینگ

بازی از ۱۰ «فریم» تشکیل شده است. فریم از یک یا دو پرتاب توپ تشکیل می‌شود، در حالی که در شروع فریم ۱۰ میله سرپا هستند. برای محاسبه‌ی امتیاز یک فریم سه حالت وجود دارد.

  • «فریم باز» زمانی است که برای آن فریم امتیازی کمتر از ۱۰ ثبت شود. در این حالت امتیاز فریم برابر با تعداد میله‌های افتاده است.

  • «اسپیر» زمانی است که در پرتاب دوم همه‌ی ده میله افتاده باشند. ارزش کل یک اسپیر برابر است با ۱۰ به‌علاوه‌ی تعداد میله‌هایی که در پرتاب بعدی می‌افتند.

  • «استرایک» زمانی است که در پرتاب اول همه‌ی ده میله افتاده باشند. ارزش کل یک استرایک برابر است با ۱۰ به‌علاوه‌ی تعداد میله‌هایی که در دو پرتاب بعدی می‌افتند. اگر بلافاصله پس از یک استرایک، استرایک دوم بیاید، ارزش استرایک اول تا زمانی که توپ یک بار دیگر پرتاب نشود، مشخص نمی‌شود.

در ادامه یک مثال با سه فریم می‌بینید:

فریم ۱ فریم ۲ فریم ۳
X (استرایک) 5/ (اسپیر) 9 0 (فریم باز)

فریم ۱ برابر است با (۱۰ + ۵ + ۵) = ۲۰

فریم ۲ برابر است با (۵ + ۵ + ۹) = ۱۹

فریم ۳ برابر است با (۹ + ۰) = ۹

یعنی مجموع جاری در این لحظه ۴۸ است.

فریم دهم در بازی یک حالت خاص است. اگر کسی اسپیر یا استرایک بیندازد، به ترتیب یک یا دو «توپ تکمیلی» می‌گیرد. توپ‌های تکمیلی برای محاسبه‌ی مجموع فریم دهم وجود دارند. اگر در توپ تکمیلی استرایک یا اسپیر ثبت شود، بازیکن توپ‌های تکمیلی بیشتری نمی‌گیرد. ارزش کل فریم دهم برابر است با تعداد کل میله‌های افتاده.

برای فریم دهمی با X1/ (یک استرایک و یک اسپیر)، ارزش کل برابر با ۲۰ است.

برای فریم دهمی با XXX (سه استرایک)، ارزش کل برابر با ۳۰ است.

الزامات

کدی بنویسید که امتیاز یک بازی بولینگ را پیگیری کند. این کد باید از دو عملیات پشتیبانی کند:

  • هر بار که بازیکن توپی را می‌غلتاند، roll(pins : int) فراخوانی می‌شود. آرگومان آن تعداد میله‌های افتاده است.
  • score() : int فقط در انتهای بازی فراخوانی می‌شود. این تابع امتیاز کل آن بازی را برمی‌گرداند.

راهنمایی‌ها

برای تکمیل این تمرین باید تابع score را پیاده‌سازی کنید که دنباله‌ای از پرتاب‌های بولینگ را می‌گیرد و امتیاز نهایی یا خطای مناسب را برمی‌گرداند:

score :: [Int] -> Either BowlingError Int

data BowlingError = IncompleteGame
                  | InvalidRoll { rollIndex :: Int, rollValue :: Int }
                  deriving (Eq, Show)

این تعاریف از قبل در جای خود قرار دارند، اما تعریف تابع به عهده‌ی خودتان است.

به خاطر داشته باشید که مجموعه‌ی test انتظار دارد پرتاب‌ها از صفر شماره‌گذاری شوند.

ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Haskell Exercism

آماده‌اید بولینگ را شروع کنید؟

در Exercism ثبت‌نام کنید تا Haskell را همراه با 107 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.