Как в игре "Пятнадцать" реализовать рандом так, чтобы пустая клетка оставалось на месте?

class Game
{
    int size;
    int[,] map;
    int space_x,space_y;
    static Random rand = new Random();          
    
    public Game (int size)
    {
        if(size<2)size=2;
        if(size>5)size=5;
        this.size = size;
        map = new int[size,size];
    }
    
    public void start()
    {
        for (int x = 0; x<size;x++)
            for(int y=0;y<size;y++)
                map[x,y] = coords_to_position(x,y) + 1;
        space_x=size - 1;
        space_y = size - 1;
        map[space_x,space_y]=0;
    }
    
    public void shift(int position)
    {
        int x,y;
        position_to_coords(position, out x, out y);
        if(Math.Abs(space_x - x) + Math.Abs(space_y - y) != 1)
            return;
        map[space_x,space_y]=map[x,y];
        map[x,y]=0;
        space_x = x;
        space_y = y;
    }

    public bool check_numbers()
    {
        if(!(space_x == size-1 && space_y == size - 1))
            return false;
        for(int x = 0; x<size;x++)
            for(int y=0;y<size;y++)
                if(!(x == size-1 && y == size - 1))
                  if (map[x,y] != coords_to_position(x,y) + 1)
                    return false;
        return true;
    }
    
    public int get_number(int position)
    {
        int x,y;
        position_to_coords(position, out x, out y);
        if(x<0 || x>=size) return 0;
        if(y<0 || y>=size) return 0;
        return map[x,y];
    }           
    
    private int coords_to_position(int x,int y)
    {
        if(x<0)x=0;
        if(x>size-1)x=size-1;
        if(y<0)y=0;
        if(y>size-1)y=size-1;
        return y * size + x;
    }           
    
    private void position_to_coords(int position, out int x, out int y)
    {
        if(position<0)position=0;
        if(position>size*size-1)position=size*size-1;
        x = position % size;
        y = position / size;
    }
}

public partial class MainForm : Form
{
    Game game;
    public MainForm()
    {
        //
        // The InitializeComponent() call is required for Windows Forms designer support.
        //
        InitializeComponent();
        game = new Game(4);
        //
        // TODO: Add constructor code after the InitializeComponent() call.
        //
    }
    
    void Button0Click(object sender, EventArgs e)
    {
        int position = Convert.ToInt16(((Button)sender).Tag);
        game.shift(position);
        refresh();
        if(game.check_numbers())
        {
            MessageBox.Show("Поздравляю!Вы победили!");
            start_game();
        }
    }
    
    private Button button (int position)
    {
        switch(position)
        {
            case 0:return button0;
            case 1:return button1;
            case 2:return button2;
            case 3:return button3;
            case 4:return button4;
            case 5:return button5;
            case 6:return button6;
            case 7:return button7;
            case 8:return button8;
            case 9:return button9;
            case 10:return button10;
            case 11:return button11;
            case 12:return button12;
            case 13:return button13;
            case 14:return button14;
            case 15:return button15;
            default: return null;
        }
    }
    
    private void MainFormLoad(object sender, EventArgs e)
    {
        start_game();
    }
    
    void Menu_startClick(object sender, EventArgs e)
    {
            start_game();
    }

    private void start_game()
    {    
        game.start();
        refresh();
    }

    private void refresh()
    {
        for(int position=0;position<16;position++)
        {
            int n = game.get_number(position);
            button(position).Text = n.ToString();
            button(position).Visible = (n>0);
        }                   
    }
                
    void HelpClick(object sender, EventArgs e)
    {
        MessageBox.Show("Как играть в игру? Для этого нужно двигать коробки с числовыми значениями на пустое поле." +
                        "Чтобы победить расставьте коробки в порядке от 1 до 15! " +
                        "После того как вы расставите все коробки в порядке возрастания, будет выведен результат, что вы победили.");
    }
}

Использую SharpDevelop.


Ответы (1 шт):

Автор решения: Andrew

а, до меня дошло что такое пустая клетка.

Все просто, тебе нужно

  1. сгенерировать 15 чисел.
  2. разместить их вслучайной последовательности.
  3. Всунуть их в поле при этом оставив клетку [0][0] или [3][3] пустой.

Это просто.

// инициализируем поле 4х4
int[][] map = [4][4]

//перемешанный случайным образом набор цифр 1-15
var nums = Enumerable
                  .Range(1, 15)
                  .Select(x => new { value = x, order = rnd.Next() })
                  .OrderBy(x => x.order)
                  .Select(x => x.value)
                  .ToList()

//заполняем поле
for (var i = 0; i< 4; i++)
{
   for (var j = 0; i< 4; i++)
   {
        if (i == 3 && j== 3)
        {
            // заполняем пустую клетку
            map[i][j] = -1;
        }
        else 
        {
            // заполняем остальные клетки
            map[i][j] = nums.last;
            nums.Remove(nums.last);
        }
   }
} 

код писался из головы и может содержать некоторые логические или синтаксические ошибки.

Последняя ячейка в map всегда будет иметь значение "-1"

И научись нормально формулировать вопросы, пожалуста.

→ Ссылка