Help us understand the problem. What is going on with this article?

数当てゲーム Linq練習のために

More than 5 years have passed since last update.

自分が知っている数当てゲームのルールは次の通り。
1.答えは1-9までの数字から4桁選ぶ。桁同士は重複してはいけない。
2.予想する答えを聞き、数字と位置が全て合えば終わり。桁は重複してもいい。

using System;
using System.Collections.Generic;
using System.Linq;

namespace HitAndBlow
{
    class HitAndBlowResult
    {
        /// <summary>質問</summary>
        readonly int[ ] Challenge;
        /// <summary>答え</summary>
        readonly int[ ] Answer;
        /// <summary>位置と数字が合っている数を取得します</summary>
        public int Hit
        {
            get
            {
                return Enumerable.Range( 0, 4 )
                    .Count( x => Challenge[ x ] == Answer[ x ] );
            }
        }
        /// <summary>数字だけが合っている数を取得します</summary>
        public int Blow
        {
            get
            {
                return Challenge.Count( x => Answer.Contains( x ) ) - Hit;
            }
        }

        public HitAndBlowResult( int[ ] challenge, int[ ] answer )
        {
            Challenge = challenge;
            Answer = answer;
        }
    }

    class HitAndBlow
    {
        /// <summary>答え</summary>
        readonly int[ ] Answer;

        public HitAndBlow( )
        {
            // 答えは4桁。それぞれの桁の数字は重複してはいけない。
            Answer = GetRandomValues( 0, 9 )
                .Distinct( ).Take( 4 ).ToArray( );
        }

        public HitAndBlowResult Challenge( string challenge )
        {
            return Challenge( challenge.Select( x => x - '0' ).ToArray( ) );
        }

        public HitAndBlowResult Challenge( int[ ] challenge )
        {
            if ( 4 != challenge.Count( x => 9 >= x || x >= 0 ) )
                throw new ArgumentException( "4桁の数字を指定して下さい" );
            else
                return new HitAndBlowResult( challenge, Answer );
        }

        static IEnumerable<int> GetRandomValues( int minValue, int maxValue )
        {
            for ( var random = new Random( ); ; )
                yield return random.Next( minValue, maxValue );
        }
    }

    class Program
    {
        static void Main( string[ ] args )
        {
            Run( );
            Console.WriteLine( "終了するには何かキーを押して下さい..." );
            Console.ReadKey( );
        }

        static void Run( )
        {
            Console.WriteLine( "4桁の数字を指定して下さい" );
            var hab = new HitAndBlow( );
            for ( var cnt = 1; ; ++cnt )
            {
                Console.Write( cnt + " -> " );
                try
                {
                    var challenge = Console.ReadLine( );
                    var result = hab.Challenge( challenge );
                    Console.WriteLine(
                        "{0} Hit, {1} Blow",
                        result.Hit, result.Blow );
                    if ( 4 == result.Hit )
                        break;
                }
                catch ( ArgumentException ex )
                {
                    --cnt;
                    Console.WriteLine( ex.Message );
                }
            }
        }
    }
}

このサンプルコードの実行結果

4桁の数字を指定して下さい
1 -> 1234
0 Hit, 1 Blow
2 -> 5678
0 Hit, 2 Blow
3 -> 9000
1 Hit, 2 Blow
4 -> 3760
4 Hit, 0 Blow
終了するには何かキーを押して下さい...
kuchikios
✌('ω')✌
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away