Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.11.2017, 21:58   #1
drako08
Пользователь
 
Регистрация: 04.10.2016
Сообщений: 30
По умолчанию Отмена действия в игре(C#)

Нужно чтобы при вызове функции undo(Game3) ход отменялся он отменяется но он отменяется только один раз как сделать что нужно изменить чтобы можно было делать много откатов


Код:
//Program.cs
using System;
namespace Pyatnyasky
{
    class Program
    {
        static void Main(string[] args)
        {
            int score = 0;
            int a;
            int[] p = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 };
            Console.WriteLine("15 Puzle");
            Console.WriteLine("-1 - cancel the match \n 0 - cancel the difference \n 16 - exit");
            Game2 Random = new Game2(p);
            Random.mixer(p);
            Game3 MyGame = new Game3(p);
            MyGame.drawField();
            for (;;)
            {
                Console.WriteLine("Select number: ");
                string input = Console.ReadLine();
                if (Int32.TryParse(input, out a))
                {
                    if (a == -1)
                    {
                        MyGame.Undo();
                        MyGame.drawField();
                    }
                    else if (a == 0)
                    {
                        MyGame.Redo();
                        MyGame.drawField();
                    }
                    else if(a == 16)
                    {

                        break;

                    }
                    else
                    {
                        MyGame.Move(a, MyGame);
                        MyGame.drawField();
                        score++;
                        Console.WriteLine("Number of moves: " + score);
                    }
                }
                else
                {
                    Console.WriteLine("Input error");
                }
                if (MyGame.finish())
                {
                    MyGame.drawField();
                    Console.WriteLine("Victory!");
                    Console.WriteLine("End of the game");
                    break;
                }
            }    
            Console.ReadKey();
        }
    }
}


//Game.cs
using System;
namespace Pyatnyasky
{
    class Points
    {

        public  int x, y;
        public Points(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }
    class Game
    {

        public int[] point = new int[16];
        public int Length = 0;

        public static int[] ArrayText = new int[16];
        public const int width = 4, height = 4;
        public int[,] field = new int[width, height];
        public Points[] FieldValue = new Points[16];

        public Game(int[] point)
        {

            int r = 0;

            Length = width * height;

            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    field[j, i] = point[r];
                    FieldValue[point[r]] = new Points(j, i);
                    r++;

                }
            }
        }

        public int this[int x, int y]
        {
            get
            {
                if (x < 0 || x >= width * height || y < 0 || y >= width * height)
                {
                    throw new ArgumentOutOfRangeException("the indexes do not fit");
                }
                return field[x, y];
            }
        }

        public Points GetLocation(int value)
        {

            return FieldValue[value];
        }
        public void drawField()
        {
            Console.WriteLine("____________________________________");
            for (int i = 0; i < width; i++)
            {
               for (int j = 0; j < height; j++)
                {
                    Console.Write(field[i, j] + "\t");
                }
               Console.WriteLine();
            }
            Console.WriteLine("____________________________________");

        }
        public void Move(int value, Game3 obj)
        {
            try
            {
                if (value > 15 || value < 0)
                {
                    throw new ArgumentException();
                }
                int x = GetLocation(0).x;
                int y = GetLocation(0).y;

                int X = GetLocation(value).x;
                int Y = GetLocation(value).y;

                if ((X == x && (Y == y - 1 || Y == y + 1)) || (Y == y && (X == x - 1 || X == x + 1)))
                {
                    field[x, y] = value;
                    field[X, Y] = 0;

                    var vere = FieldValue[0];
                    FieldValue[0] = FieldValue[value];
                    FieldValue[value] = vere;

                    obj.History(value);
                }
                else
                {
                    throw new Exception();
                }
            }
            catch (ArgumentException)
            {
                Console.WriteLine("There is no such number: ");
            }
            catch (Exception)
            {
                Console.WriteLine("Along with this number is not 0: ");
            }

        }
    }
}

//Game2.cs
using System;
namespace Pyatnyasky
{
    class Game2 : Game
    {
        public Game2(int[] point) : base(point)
        {

        }
        public bool finish()
        {
            int value = 1;
            for (int i = 0; i < width; ++i)
            {
                for (int j = 0; j < height; ++j)
                {
                    if (field[i, j] == value)
                    {
                        ++value;
                        if (value == Length)
                        {
                            value = 0;
                        }
                    }
                    else
                    {
                        return false;
                    }

                }

            }
            return true;

        }

        public void mixer(int[] p)
        {
            int tmp = 0;
            Random rnd = new Random();
            for (int i = 0; i < p.Length; i++)
            {
                bool isExist = false;
                do
                {
                    isExist = false;
                    tmp = rnd.Next(0, p.Length);
                    for (int j = 0; j < i; j++)
                    {
                        if (tmp == p[j]) { isExist = true; }
                    }
                }
                while (isExist);
                p[i] = tmp;
            }
        }


    }
}

//Game3.cs
using System;
using System.Collections.Generic;

namespace Pyatnyasky_v2
{
    class Game3 : Game2
    {
        Stack<Points> undo = new Stack<Points>();
        Stack<Points> redo = new Stack<Points>();
        public Game3(int[] point) : base(point)
        {
        }

        public void History(int value)
        {
            undo.Push(GetLocation(value));
        }
        public void Undo()
        {
            if (undo.Count > 0)
            {
                var point = undo.Pop();
                this.Move(this[point.x, point.y], this);
                redo.Push(point);
            }
            else throw new Exception("Unable to cancel");
        }

        public void Redo()
        {
            if (redo.Count > 0)
            {
                var point = redo.Pop();
                this.Move(this[point.x, point.y], this);
                undo.Push(point);
            }
        }

    }
}
drako08 вне форума Ответить с цитированием
Старый 22.11.2017, 22:02   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Сохранять все состояния (просто все поле, ну или действия если надо экономить память) куда-то (стек и т.п.) и потом восстанавливать, перерисовывать.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 22.11.2017, 23:16   #3
drako08
Пользователь
 
Регистрация: 04.10.2016
Сообщений: 30
По умолчанию

Все поле нужно откатать назад
drako08 вне форума Ответить с цитированием
Старый 22.11.2017, 23:24   #4
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

И? А я о чем говорил?
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 22.11.2017, 23:40   #5
drako08
Пользователь
 
Регистрация: 04.10.2016
Сообщений: 30
По умолчанию

Ну так я зделал через stack() но откативает один ход
drako08 вне форума Ответить с цитированием
Старый 22.11.2017, 23:57   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Так вы ж и откатываете один ход за один вызов Undo.
Ну или если неправильный алгоритм, то смотрите что в стеке.
Проще всего просто весь массив сохранять.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 23.11.2017, 09:31   #7
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

при откате НЕ НАДО записывать свои действия
undo -> pop,move -> history -> push
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 23.11.2017, 11:17   #8
drako08
Пользователь
 
Регистрация: 04.10.2016
Сообщений: 30
По умолчанию

вот так но все равно ничего не изменилось

Код:
 public void Undo()
        {
            if (undo.Count > 0)
            {
                var point = undo.Pop();
                Move(this[point.x, point.y], this);
               
            }
            else throw new Exception("Unable to cancel");
        }
drako08 вне форума Ответить с цитированием
Старый 23.11.2017, 11:19   #9
drako08
Пользователь
 
Регистрация: 04.10.2016
Сообщений: 30
По умолчанию

Вот
Изображения
Тип файла: png pytn_lsit.PNG (16.4 Кб, 127 просмотров)
drako08 вне форума Ответить с цитированием
Старый 23.11.2017, 11:32   #10
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Не изменилось от чего? Вы ж Move вызываете, а в нем снова меняете историю.

ЗЫ а что тут за ООП головного мозга с наследованием Game? Подайте знак если вас пытками заставляют так делать )
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Какие знания по php и mysql нужно иметь, что бы в игре сделать такой бой в онлайн текстовой игре jonikster Общие вопросы Web 4 15.06.2016 18:10
Отмена последнего действия маГГ85 JavaScript, Ajax 6 09.02.2012 16:17
подредактировать античит к игре игре Nhl 09 (античит написан на дельфи) Viper18 Фриланс 3 03.08.2011 17:37
Отмена последнего действия пользователя ProgDel Общие вопросы Delphi 5 24.10.2010 21:23
Закрыть, Отмена. agregator Microsoft Office Excel 6 12.02.2010 09:56