ちょっとビンゴゲーム判定ロジック作ってみた

まだ途中だけど、とりあえず公開。ソースコードもリファクタしたいところ。
めちゃ中途半端な状態だから動作の保証はできんです。(一応、下のテストパターンは通ってるはず。)

想定される入力

bingoWidth:ビンゴの行列数(N=3なら、3×3のビンゴ)
holes:すでにあいている穴の数
holeInfo:あいている穴の位置(X Yで記述する)

入力例:

4
4
4 1
3 2
2 3
1 4

説明
ナナメでリーチ(右下がりバージョン)

expect
リーチ




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

namespace bingo
{
    class Program
    {
        static void Main(string[] args)
        {
            //入力チェックめんどいから、正しいものが入力される想定でやる。

            //ビンゴの縦横数を取得
            int bingoWidth = ReadBingoWidth();
            //既に空いている穴の数を取得
            int holes = ReadHoles();
            //穴の入力についての説明
            WriteDescription();

            
            Dictionary<int, int> holeRowInfo, holeColInfo;
            //穴情報を初期化
            InitHoleInfomation(bingoWidth, out holeRowInfo, out holeColInfo);


            //入力値がソートされている前提であれば、以下のforの中でナナメのビンゴを判定できる。
            //ソートされていないことを前提として、以下のようにタプルのリストを生成
            List<(int, int)> tupleList = new List<(int, int)>();
            for (int i = 0; i < holes; i++)
            {
                var temp = Console.ReadLine().Split(' ');
                var X = int.Parse(temp[0]);
                var Y = int.Parse(temp[1]);
                holeRowInfo[X]++;
                holeColInfo[Y]++;
                tupleList.Add((X, Y));
            }
            tupleList = tupleList.OrderBy(item => item.Item2).ToList();



            var retRow = holeRowInfo.Values.Max();
            var retCol = holeColInfo.Values.Max();
            bool rowColReachFlg = false;
            if (retRow == bingoWidth || retCol == bingoWidth)
            {
                Console.WriteLine("ビンゴ");
                return;
            }
            else if (retRow == bingoWidth - 1 || retCol == bingoWidth - 1)
            {
                rowColReachFlg = true;
            }


            int tupleLen = tupleList.Count();
            int successCount = 0;
            int failureCount = 0;
            for (int i = 0; i < tupleLen; i++)
            {
                var reverseNum = bingoWidth - tupleList[i].Item1 + 1;
                if (tupleList[i].Item1 == tupleList[i].Item2 ||
                    reverseNum == tupleList[i].Item2)
                {
                    successCount++;
                }
                else
                {
                    failureCount++;
                }
            }
            if (failureCount == 0 && successCount == bingoWidth)
            {
                Console.WriteLine("ビンゴ");
                return;
            }
            if (failureCount == 1 || rowColReachFlg || bingoWidth - successCount > 0)
            {
                Console.WriteLine("リーチ");
                return;
            }

        }

        private static void InitHoleInfomation(int bingoWidth, out Dictionary<int, int> holeRowInfo, out Dictionary<int, int> holeColInfo)
        {
            //行ビンゴ判定用
            holeRowInfo = new Dictionary<int, int>();
            //列ビンゴ判定用
            holeColInfo = new Dictionary<int, int>();
            for (int i = 1; i <= bingoWidth; i++)
            {
                holeRowInfo.Add(i, 0);
                holeColInfo.Add(i, 0);
            }
        }

        private static void WriteDescription()
        {
            Console.WriteLine("穴の位置を横:x,縦:yとした時、それぞれの位置を以下のように入力してください。");
            Console.WriteLine("N=3の時、真ん中に穴がある場合は、2 2 を入力する。");
            Console.WriteLine("一行に一つの穴の情報を入力し、複数存在する場合は、穴の位置を開業して入力してください。");
        }

        private static int ReadHoles()
        {
            Console.WriteLine("ビンゴの穴の数を入力してください");
            int holes = int.Parse(Console.ReadLine());
            return holes;
        }

        private static int ReadBingoWidth()
        {
            Console.WriteLine("ビンゴの幅を指定してください");
            int bingoWidth = int.Parse(Console.ReadLine());
            return bingoWidth;
        }
    }
}

以下テストパターン

C#

Posted by takumioda