Случайные перестановки кораблей

Опубликовано Jan 10, 2013 в Алгоритмы и Структуры данных, Игры | 2 коммент.

,

Случайные перестановки кораблей

В уже накопившихся решениях игровых задач так или иначе присутствуют элементы генерации каких-то случайных данных. Нужно тасовать колоду карт, расставлять корабли и мины, сбрасывать фигуры… В  уже разобранных на нашем сайте игровых задачах, имеются варианты кода, которые это делали.

Так, например, расставлялись мины...

Игра Сапер (Minesweeper) на C#

vector tmp_minefield(x_cells*y_cells-bombs,0);
    tmp_minefield.insert(tmp_minefield.end(),bombs,1);
    srand(unsigned(time(NULL)));
    random_shuffle(tmp_minefield.begin(), tmp_minefield.end());

Опять Minesweeper (C++/MFC)

  int row, col;    // индексы клетки
        int n = 0;       // количество поставленных мин
        // инициализация генератора случайных чисел
        Random rnd = new Random();
        // расставим мины
        do
        {
          row = rnd.Next(MR);
          col = rnd.Next(MC);
          if (!GameField[row, col].HasMine)
          {
            GameField[row, col].HasMine = true;
            if (row != 0 && col != 0)
             GameField[row - 1, col - 1].NeibourMinesQty++;
            if (row != 0)
             GameField[row - 1, col].NeibourMinesQty++;
            if (row != 0 && col != MC - 1)
             GameField[row - 1, col + 1].NeibourMinesQty++;
            if (col != 0)
             GameField[row, col - 1].NeibourMinesQty++;
            if (col != MC - 1)
             GameField[row, col + 1].NeibourMinesQty++;
            if (row != MR - 1 && col != 0)
             GameField[row + 1, col - 1].NeibourMinesQty++;
            if (row != MR - 1)
             GameField[row + 1, col].NeibourMinesQty++;
            if (row != MR - 1  && col != MC - 1)
             GameField[row + 1, col + 1].NeibourMinesQty++;
            n++;
          }
        }
        while (n != NM);
      }

А так тасовалась колода...

Колода карт

 //Здесь собственно и хранится колода
      private List pack = new List();
      public List Pack {get { return (pack); }}
 public void ShufflePack()
      {
       pack = pack.OrderBy(e => Guid.NewGuid()).ToList();
      }

Развитие сюжета подобных алгоритмов может состоять во введении каких-то дополнительных требований. Например, для игры морской бой нужно на поле боя расставить (алгоритмически либо перетасовать, либо случайно сгенерировать) корабли на поле. При этом корабли имеют разные формы и размеры и не должны соприкасаться. Вот и предлагается придумать способ случайной расстановки кораблей для игры морской бой. Самый простой способ задания кораблей вместе с функцией, которая выводит простейшее изображение карты приведены ниже.

Код на C++: исходные данные и функция для вывода поля с кораблями

#include "stdafx.h"
#include <iostream>
#include <vector>
 
using namespace std;
 
const char empty_cell = ' ';
const char deck_cell = char(219);
 
int show_map(const int n, const int m, char** source_mas, char deck_cell)
{
	int decks_qty = 0;
	for(int j=0;j<m+2;j++) cout << '-'; cout << endl;
	for(int i=0;i<n;i++)
	{
		cout << '|';
		for(int j=0;j<m;j++)
		{	if(source_mas[i][j] == deck_cell) ++decks_qty;
			cout << source_mas[i][j];
		}
		cout << '|' << endl;
	}
	for(int j=0;j<m+2;j++) cout << '-'; cout << endl;
	return decks_qty;
}
 
void show_map(const int nX, const int nY, vector<vector
<pair<int,int>>> ships)
{
	bool ship_cell = false;
	for(int j = 0; j < nY + 2; j++)
		cout << '-'; cout << endl;
 
	for(int i = 0; i < nX; i++)
	{
		cout << '|';
		for(int j = 0; j < nY; j++)
		{
			ship_cell = false;
			for(int q = 0; q < ships.size(); q++)
				for(int p = 0; p < ships[q].size(); p++)
				{
					if ((ships[q][p].first == j + 1) &&
					(ships[q][p].second == i + 1))
					{
						cout << deck_cell;
						ship_cell = true;
						break;
					}
				}
			if (!ship_cell)
				cout << empty_cell;
		}
		cout << '|' << endl;
	}
	for(int j = 0; j < nY + 2; j++)
		cout << '-'; cout << endl;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
	const int nX = 10; 
	const int nY = 10;
 
 
	vector<vector<pair<int,int>>> ships(10);
 
	ships[0].push_back(pair<int, int>(1,1)); 
 
	ships[1].push_back(pair<int, int>(4,1));
	ships[1].push_back(pair<int, int>(4,2)); 
 
	ships[3].push_back(pair<int, int>(7,1));
	ships[3].push_back(pair<int, int>(8,1)); 
 
	ships[4].push_back(pair<int, int>(7,3));
	ships[4].push_back(pair<int, int>(8,3)); 
 
	ships[5].push_back(pair<int, int>(3,4));
	ships[5].push_back(pair<int, int>(3,5)); 
	ships[5].push_back(pair<int, int>(3,6));
	ships[5].push_back(pair<int, int>(3,7)); 
 
	ships[6].push_back(pair<int, int>(5,5));
 
	ships[7].push_back(pair<int, int>(8,5)); 
	ships[7].push_back(pair<int, int>(7,6)); 
	ships[7].push_back(pair<int, int>(8,6)); 
	ships[7].push_back(pair<int, int>(9,6)); 
 
	ships[8].push_back(pair<int, int>(6,8)); 
	ships[8].push_back(pair<int, int>(5,9)); 
	ships[8].push_back(pair<int, int>(6,9)); 
	ships[8].push_back(pair<int, int>(7,9)); 
	ships[8].push_back(pair<int, int>(6,10)); 
 
	ships[9].push_back(pair<int, int>(10,8)); 
	ships[9].push_back(pair<int, int>(10,9));
	ships[9].push_back(pair<int, int>(10,10)); 
	show_map(nX, nY, ships);
}
На рисунке показано поле, которое соответствует приведенным тестовым данным


Автор публикации:

2 Коммент. : “Случайные перестановки кораблей”

  1. Что такое vector>> ??

Оставить комментарий

Ваш адрес email не будет опубликован.


*