Member 13053268 Ответов: 3

Игра памяти не работает должным образом


недавно я работал над небольшим проектом на языке Си#
это игра памяти с "картами", в которой игрок дважды выбирает x и y на доске, и игра" переворачивает "карты, если они одинаковы, она останется" перевернутой", иначе"покрытой".
сначала игра создает двумерный массив и заполняет его случайными символами, по умолчанию это ' ', проблема в том, что игра не всегда заполняет массив буквой (Я думаю), а некоторые карты - это просто ничто,'', класс доски:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MemoryCardYesodotProject
    {
        public class MemoryBoard
        {
    
            MemoryCard[,] board;//maarah do meimadi
            public MemoryBoard(int x, int y)
            {
    
                board = new MemoryCard[x, y];
                InitiateMemoryBoard();
    
                while (true)
                {
                    try
                    {
    
                        break;
                    }
                    catch (FormatException e)
                    {
                        Console.WriteLine("Youve entered invalid input");
                    }
                }
                board = new MemoryCard[x, y];
            }
    
            private void InitiateMemoryBoard()
            {
                for (int i = 0; i < board.GetLength(0); i++)
                {
                    for (int j = 0; j < board.GetLength(1); j++)
                    {
                        board[i, j] = new MemoryCard(i, j, ' ');
                    }
                }
            }
    
            private bool IsExistInBoard(MemoryCard[,] arr, char tav)
            {
                //check if the value of tav exists in the list of used characters
                // return true if the selected charcter is in use.
                for (int i = 0; i < board.GetLength(0); i++)
                {
                    for (int j = 0; j < board.GetLength(1); j++)
                    {
                        if (board[i, j].GetShape() == tav)
                            return false;
                    }
                }
                return true;
            }
    
    
            public void BuildMemoryBoard()
            {
                // call InitiateMemoryBoard()
                // select randomly characters from A-z.
                // Verify that each character used once (pair)
                int c = 85;
                bool flag = false;
                while (flag == false)
                {
                    Random r = new Random();
                    c = r.Next(65, 90);
                    c = (char)c;
                    //int x = board.GetLength(0);
                    flag = IsExistInBoard(board, (char)c);
                }
                // Select randomly location on board for each pair (make sure that the place in not in use
                // Repeat doing it for all pairs\
                int counter = 0;
                while (counter < 2)
                {
                    Random r = new Random();
                    int i = r.Next(0, board.GetLength(0));
                    int j = r.Next(0, board.GetLength(1));
                    if (this.board[i, j].GetShape() == ' ')
                    {
                        this.board[i, j].SetShape((char)c);
                        counter++;
                    }
                }
            }
    
            public void DrawBoard()
            {
                //Console.Clear();
                // if the memory card detected show the shape otherwise show '#'
                for (int i = 0; i < board.GetLength(0); i++)
                {
                    for (int j = 0; j < board.GetLength(1); j++)
                    {
                        if (this.board[i, j].IsDetected() == false)
                            Console.Write("# ");
                        else
                            Console.Write((this.board[i, j].GetShape()).ToString() + ' ');
                    }
                    Console.WriteLine();
                }
            }
    
            public void DrawBoardWithGuess(int x1, int y1, int x2, int y2)
            {
                //Console.Clear();
                // if the memory card detected or the location in equal to one of the two selected cards
                // show the shape otherwise show '#'
                this.board[x1, y1].Detected(true);
                this.board[x2, y2].Detected(true);
                DrawBoard();
                this.board[x1, y1].Detected(false);
                this.board[x2, y2].Detected(false);
            }
            public void PlayMemoryGame()
            {
                // while not all memory cards detected
                // call DrawBoard
                // ask from the player position of two cards
                // verify that the input is valid (handle failure)
                // if the two selected cards are equal, new pair detected (mark as detected)
                // call DrawBoardWithGuess
                // Console.WriteLine("Press any key to continue");
                //Console.ReadKey();
                // all memory cards detected print you win.
    
                InitiateMemoryBoard();
                BuildMemoryBoard();
                int counter = 0;
                while (counter != board.GetLength(0) * board.GetLength(1) / 2)
                {
                    DrawBoard();
                    Console.WriteLine("enter position of first card (without a space or a comma, first the y and then the x)");
                    int card1 = int.Parse(Console.ReadLine());
                    int y1 = card1 % 10;
                    y1--;
                    int x1 = card1 / 10;
                    x1--;
                    Console.WriteLine("enter position of second card (without a space or a comma, first the y and then the x)");
                    int card2 = int.Parse(Console.ReadLine());
                    int y2 = card2 % 10;
                    y2--;
                    int x2 = card2 / 10;
                    x2--;
                    DrawBoardWithGuess(x1, y1, x2, y2);
                    if ((this.board[x1, y1].GetShape()) == (this.board[x2, y2].GetShape()))
                    {
                        this.board[x1, y1].Detected(true);
                        this.board[x2, y2].Detected(true);
                        counter++;
                    }
                }
                Console.WriteLine("YOU WIN!");
            }
        }
    }

the card class: 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MemoryCardYesodotProject
    {
        public class MemoryCard
        {
            private int x;
            private int y;
            private char shape;
            private bool detected;
    
            public MemoryCard(int x, int y, char c)
            {
                this.x = x;
                this.y = y;
                this.shape = c;
                this.detected = false;
            }
    
            public int GetX() { return this.x; }
            public int GetY() { return this.y; }    
            public char GetShape() { return this.shape; }
    
            public void SetX(int x) { this.x = x; }
            public void SetY(int y) { this.y = y; }
            public void SetShape(char s) { this.shape = s; }
    
            public bool IsDetected() { return this.detected; }
            public void Detected(bool d) { this.detected = d; }
    
            public void DisplayMemoryCard() { Console.Write(this.shape + " "); }
            public void DisplayHiddenCard() { Console.Write("# "); }
    
            public override string ToString()
            {
                string str;
                if (this.detected)
                    str = "detected";
                else
                    str = "not detected";
                return "(x=" + this.x + " y=" + this.y + "): shapr: " + this.shape + " " + str;
            }
        }
    }


Что я уже пробовал:

я пробовал заполнять массив сам, это сработало, но это не имеет значения, программа должна заполняться сама по себе

Michael_Davies

Похоже, что цикл в BuildMemoryBoard завершится в тот момент, когда он обнаружит, что код еще не был использован, тогда как вы хотите выйти из цикла, когда все слоты на плате будут заполнены. Используйте отладчик и наблюдайте, что происходит.

Вы передаете массив в качестве параметра IsExistInBoard, не используете его, а непосредственно используете глобальную переменную, которую передаете в качестве аргумента...

3 Ответов

Рейтинг:
2

OriginalGriff

Это ваш код, и просто выбросить его нам и сказать, что он не работает, никому не поможет.
Так что все будет зависеть от тебя.
Поместите точку останова в первую строку функции и запустите код через отладчик. Затем посмотрите на свой код и на свои данные и определите, что должно произойти вручную. По одному шагу в каждой строке, проверяя, что то, что вы ожидали, произойдет именно так, как и произошло. Когда это не так, тогда у вас есть проблема, и вы можете вернуться назад (или запустить ее снова и посмотреть более внимательно), чтобы выяснить, почему.

Извините, но мы не можем сделать это за вас-вам пора освоить новый (и очень, очень полезный) навык: отладку!


Рейтинг:
2

Patrice T

Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволяет вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения, это невероятный инструмент обучения.

Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010-YouTube[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.


Рейтинг:
2

Ralf Meier

Я не совсем уверен, что я там видел ...
Сколько элементов должно быть в вашей доске ?
Я думаю, что у вас есть (например) доска с 10 строками и 8 столбцами.
Так что ваша доска-Арри тоже должна иметь такие размеры.
Для этого вы должны итерировать таким образом свой массив - я возьму ваш метод "" например :

private bool IsExistInBoard(MemoryCard[,] arr, char tav)
            {
                //check if the value of tav exists in the list of used characters
                // return true if the selected charcter is in use.
                for (int i = 0; i < rows_Count; i++)
                {
                    for (int j = 0; j < columns_count; j++)
                    {
                        if (board[i, j].GetShape() == tav)
                            return false;
                    }
                }
                return true;
            }


Так... то, что вы должны сделать, это :
- запомните, насколько велик размер вашего массива, и работайте с этими переменными, и возьмите это, чтобы перебрать десятицентовики вашего массива - в каждом методе, где вы хотите его использовать ...