Оптимизировать алгоритм проверки победы Крестики_нолики

121
24 октября 2019, 19:40
bool isWin(const char board[], const int sizeBoard)
{
for (int i = 0; i < 9; i++)
{
    if (board[i] != ' ' && board[i] == board[i + 1] && board[i] == board[i + 2] && i > 0 && i < 3)
    {
        return true;
    }
    if (board[i] != ' ' && board[i] == board[i + 1] && board[i] == board[i + 2] && i > 2 && i < 6)
    {
        return true;
    }
    if (board[i] != ' ' && board[i] == board[i + 1] && board[i] == board[i + 2] && i > 5 && i < 9)
    {
        return true;
    }
    if (board[i] != ' ' && board[i] == board[i + 3] && board[i] == board[i + 6] && i >= 0 && i < 3)
    {
        return true;
    }
    if (board[i] != ' ' && board[0] == board[i + 4] && board[i] == board[i + 8] && i == 0)
    {
        return true;
    }
    if (board[i] != ' ' && board[2] == board[4] && board[2] == board[6] && i == 2)
    {
        return true;
    }
}
return false;

}

Подскажите как можно сделать это более корректно и без огромного количества if(), подобные решения видел, но не смог разобраться в чужом синтаксисе, многомерные массивы не использую.

Answer 1
for(var i = 0;i++;i<3)
{
    var t = i*3;
    if (board[t] != ' ' && board[t] == board[t + 1] && board[t] == board[t + 2])
    {
        return true;
    }
    if (board[i] != ' ' && board[i] == board[i + 3] && board[i] == board[i + 6])
    {
        return true;
    }
}
if (board[0] != ' ' && board[0] == board[4] && board[0] == board[8])
{
    return true;
}
if (board[2] != ' ' && board[2] == board[4] && board[2] == board[6])
{
    return true;
}

сначала делает 6 проверок на горизонтали и вертикали, потом две диагонали
но если ты хочешь сделать поле не 3х3 - придется придумать более красивый вариант

Answer 2

ну, или можно, для достки 3*3 ввести просто набор паттернов и их проверить. например

static string[] patterns = new string[] {
    "XXX______",
    "___XXX___",
    "______XXX",
    "X__X__X__",
    "_X__X__X_",
    "__X__X__X",    
    "X___X___X",
    "__X_X_X__",    
    };
bool isWin(char[] board)
{
    for (var i = 0; i < patterns.Length; i++)
    {
        if (isMatch(patterns[i], 'X', board)) return true;
        if (isMatch(patterns[i], 'O', board)) return true;
    }
    return false;
}
bool isMatch(string pattern, char winner, char[] board)
{
    int count = 0;
    for (var i = 0; i < board.Length; i++)
        if (pattern[i] == 'X' && board[i] == winner) count++;
    return count == 3;
}
Answer 3

Как вариант такой вариант например если поле тут поле любого размера и можно задавать любую комбинацию например поле 10 на 10 а будет искать комбнации выгираша если 3 в ряд

static void Main(string[] args)
        {
            new Class1().Three(new [,]
            {
                { "x", "o", "o", "x", "o", "x" },
                { "o", "o", "o", "x", "x", "o" },
                { "o", "x", "o", "x", "o", "o" },
                { "o", "o", "x", "o", "x", "x" },
                { "o", "x", "o", "x", "o", "x" },
            }, 5, 3);
            Console.ReadKey();
        }


public class Class1
    {
        public bool Three(string[,] arr, int boardSize, int winLong)
        {


            var templates = new List<Combination>();
            for (int i = 0; i < boardSize; i++)
            {
                for (int j = 0; j < boardSize; j++)
                {
                    var cv = new Combination();
                    cv.Values = new List<string>();
                    cv.Point = new List<Point>();
                    // По горизонтали +
                    cv.Point.Add(new Point { i = i, j = j });
                    cv.Values.Add(arr[i, j]);
                    for (int k = 1; k < winLong; k++)
                    {
                        if (Ex(arr, i, j + k))
                        {
                            cv.Point.Add(new Point { i = i, j = j + k });
                            cv.Values.Add(arr[i, j + k]);
                        }
                    }
                    templates.Add(cv);

                    // По вертикали + 
                    cv = new Combination();
                    cv.Values = new List<string>();
                    cv.Point = new List<Point>();
                    cv.Point.Add(new Point { i = i, j = j });
                    cv.Values.Add(arr[i, j]);
                    for (int k = 1; k < winLong; k++)
                    {
                        if (Ex(arr, i + k, j))
                        {
                            cv.Point.Add(new Point { i = i + k, j = j });
                            cv.Values.Add(arr[i + k, j]);
                        }
                    }
                    templates.Add(cv);

                    // По диагонали  по главной
                    cv = new Combination();
                    cv.Values = new List<string>();
                    cv.Point = new List<Point>();

                    cv.Point.Add(new Point { i = i, j = j});
                    cv.Values.Add(arr[i, j]);
                    for (int k = 1; k < winLong; k++)
                    {
                        var c = i;
                        var x = j;
                        if (Ex(arr, c + k, x + k))
                        {
                            cv.Point.Add(new Point { i = c + k, j = x + k });
                            cv.Values.Add(arr[c + k, x + k]);
                        }
                    }
                    templates.Add(cv);
                }
            }

            var n = templates
                .Where(v => v.Values.Count == winLong)
                .Where(v => v.Values.All(c => c == v.Values[0]));
            foreach (var z in n)
            {
                foreach (var p in z.Point)
                {
                    Console.Write($" [{p.i}:{p.j}] ");
                }
                Console.Write(" Values: =  ");
                foreach (var v in z.Values)
                {
                    Console.Write(v);
                }
                Console.WriteLine("\n");
            }
            return false;
        }

        bool Ex(string[,] arr, int i, int j)
        {
            try
            {
                var t = arr[i, j];
                return true;
            }
            catch
            {
                return false;
            }
        }

        class Combination
        {
            public List<Point> Point { get; set; }
            public List<string> Values { get; set; }
        }
        class Point
        {
            public int i { get; set; }
            public int j { get; set; }
        }
    }

надо дописать проверку по второстепенной оси

READ ALSO
сумма свойств объектов в массиве

сумма свойств объектов в массиве

Итак, имеем массив, элементами которого являются объекты

139
Експорт из mysql в excel через обработчик php

Експорт из mysql в excel через обработчик php

возникла у меня проблема при генерации excel файлаЗаключается она в том, что при попытке открыть файл в Excel вы получаете сообщение о том, что...

123
Как правильно сделать такую модель для форми yii2

Как правильно сделать такую модель для форми yii2

Не могу понять как сделать модель для форми и как оно может виглядить в viewЕсть 4 недели, в каждой недели 7 дней и в каждом дне есть по 6 страв

114