Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Delphi] Создание игры морской бой 
:(
    Опции темы
hqpz
  Дата 12.12.2009, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 6.12.2009

Репутация: нет
Всего: нет



Всем привет. Буду краток. У меня есть код игры морской бой на Delphi, но там кораблики всегда стоят в одном положении. Помогите пожалуйста сделать рандомную расстановку корабликов. Ничего не получается. =(  Там в самом конце кода прописаны ячейки с корабликами. Помогите переделать на рандомную, как для меня так и для противника
Код

Unit Unit1;

Interface

Uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

Type
  TPole = Array [1..10, 1..10] Of Byte;
  TForm1 = Class(TForm)
    Pole1: TImage;
    Pole2: TImage;
    procedure Pole2MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
  Private
    { Private declarations }
  Public
    { Public declarations }
    // процедура отрисовки поля.
    Procedure PrintPole(Pole : TImage; P : TPole);
    // Бот
    Procedure Bot;
  End;


Var
  Form1: TForm1;
  // игровое поле 1 - поле игрока. 2 - пполе врага.
  // 1 - выстрел. 2 -корабль 20 - мертвый корабль. 3 - корабль врага.
  P1, P2 : TPole;
  P1Win, P2Win : Integer; // отслеживаем выигрыш.


Implementation


{$R *.dfm}


// бот
Procedure TForm1.Bot;
Var
  x, y : integer;
Begin
Randomize;
// определим координаты выстрела
Repeat
  x := Random(10) + 1;
  y := Random(10) + 1;
Until (P1[x,y] <> 1) And (P1[x,y] <> 20);
// если бот промахнулся
If (P1[x,y] <> 1) And (P1[x,y] <> 2) Then P1[x,y] := 1;
// если бот попал в корабль
If P1[x,y] = 2 Then Begin
  P1[x,y] := 20;
  P2Win := P2Win + 1;
End;
// отрисуем наше поле
PrintPole(Pole1, P1);
End;



// процедура отрисовки поля
// Pole - компонент TImage на котором надо рисовать
// P - массив, который надо отрисовать
Procedure TForm1.PrintPole(Pole : TImage; P : TPole);
Var
  i, x, y : Integer;
Begin
// заливка цветом "вода".
Pole.Canvas.Brush.Style := bsSolid;
Pole.Canvas.Brush.Color := RGB(200, 200, 200);
Pole.Canvas.Rectangle(0,0,200,200);
// рисуем сетку.
For i := 1 To 10 Do
  Begin
    Pole.Canvas.MoveTo(i * 20, 0);
    Pole.Canvas.LineTo(i * 20, 200);
    Pole.Canvas.MoveTo(0, i * 20);
    Pole.Canvas.LineTo(200, i * 20);
  End;
// пройдемся по массиву и отрисуем поля
For x := 1 To 10 Do
  Begin
    For y := 1 To 10 Do
      Begin
        If P[x, y] = 1 Then Begin // рисуем выстрел
          Pole.Canvas.Brush.Style := bsSolid;
          Pole.Canvas.Brush.Color := RGB(0, 0, 0);
          Pole.Canvas.Ellipse((x-1) * 20 + 4, (y-1) * 20 + 4, (x-1) * 20 + 16, (y-1) * 20 + 16);
        End;
        // если мы пытаемся отрисовать вражеский кораблик, то цикл начинается снова
        If IntToStr(P[x, y])[1] = '3' Then Continue;
        If IntToStr(P[x, y])[1] = '2' Then Begin // рисуем корабли
            Pole.Canvas.Brush.Style := bsSolid;
            Pole.Canvas.Brush.Color := RGB(200, 5, 5);
            Pole.Canvas.Rectangle((x-1) * 20, (y-1) * 20, (x-1) * 20 + 21, (y-1) * 20 + 21);
        End;
        If IntToStr(P[x, y])[2] = '0' Then Begin // рисуем мертвые части корабля
          Pole.Canvas.Brush.Color := RGB(0, 0, 0);
          Pole.Canvas.MoveTo((x-1) * 20 , (y-1) * 20);
          Pole.Canvas.LineTo((x-1) * 20 + 20, (y-1) * 20 + 20);
          Pole.Canvas.MoveTo((x-1) * 20 + 20 , (y-1) * 20);
          Pole.Canvas.LineTo((x-1) * 20, (y-1) * 20 + 20);
        End;
      End;
  End;
// проверим, а может ктото уже выйграл
If P1Win = 20 Then Begin ShowMessage('вы победитель!'); Application.Terminate; End;
If P2Win = 20 Then Begin ShowMessage('пока неудачник'); Application.Terminate; End;
End;



// процедура обработки целчка по вражескому полю
Procedure TForm1.Pole2MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
Var
  i : Integer;
  Mis : Boolean;
Begin
// определим чему равен x.
For i := 0 To 9 Do
  If (x >= 20 * i) And (x <= 20 + i * 20) Then
    Begin
      x := i + 1;
      Break;
    End;
// определим чему равен y.
For i := 0 To 9 Do
  If (y >= 20 * i) And (y <= 20 + i * 20) Then
    Begin
      y := i + 1;
      Break;
    End;
// присвоим значение выстрела указанному элементу массива
// если мы сюда уже стреляли
If (P2[x,y] = 1) Or (P2[x,y] = 20) Then Begin
  ShowMessage('тут уже стреляли');
  Mis := True;
End;
// если мы промахнулись
If (P2[x,y] <> 1) And (P2[x,y] <> 3) And (P2[x,y] <> 20) Then P2[x,y] := 1;
// если мы попали в корабль врага
If P2[x,y] = 3 Then Begin
  P2[x,y] := 20;
  P1Win := P1Win + 1;
End;
// Оотрисуем поле врага
PrintPole(Pole2, P2);
// заставим бота ответить нам (если мы не промахнулись).
If Mis = False Then Bot;
End;



// при создании формы
Procedure TForm1.FormCreate(Sender: TObject);
Begin
//заполним массив  (сделаем вид игры)
// наше поле
// рисуем пару кораблей
P1[8,8] := 2;
P1[7,1] := 2;
P1[7,10] := 2;
P1[6,10] := 2;
P1[5,5] := 2; P1[5,6] := 2;
P1[8,3] := 2; P1[9,3] := 2;
P1[4,8] := 2; P1[5,8] := 2;
P1[3,3] := 2; P1[4,3] := 2; P1[5,3] := 2;
P1[2,7] := 2; P1[2,8] := 2; P1[2,9] := 2;
P1[1,1] := 2; P1[1,2] := 2; P1[1,3] := 2; P1[1,4] := 2;
// поле врага
// нарисуем пару кораблей
P2[1,1] := 3;
P2[10,1] := 3;
P2[1,8] := 3;
P2[8,5] := 3;
P2[6,6] := 3; P2[6,7] := 3;
P2[9,9] := 3; P2[9,10] := 3;
P2[9,7] := 3; P2[10,7] := 3;
P2[5,2] := 3; P2[6,2] := 3; P2[7,2] := 3;
P2[3,10] := 3; P2[4,10] := 3; P2[5,10] := 3;
P2[3,3] := 3; P2[3,4] := 3; P2[3,5] := 3; P2[3,6] := 3;
// заставим отрисовать поля
PrintPole(Pole1, P1);
PrintPole(Pole2, P2);
End;

End.



Это сообщение отредактировал(а) hqpz - 12.12.2009, 23:34
PM MAIL   Вверх
Sanaff
Дата 13.12.2009, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 15.9.2009
Где: г. Северодвинск

Репутация: -1
Всего: 1



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


А вот это меня поразило:
// определим чему равен x.
For i := 0 To 9 Do
  If (x >= 20 * i) And (x <= 20 + i * 20) Then
    Begin
      x := i + 1;
      Break;
    End;

Вот так не проще
If (x >= 0) And (x <= 200) Then
x = (x\20)+1;
или как там целочисленное деление


--------------------
Программист - это локальный бог ©ICQ 373-628-456
PM MAIL WWW ICQ   Вверх
hqpz
  Дата 13.12.2009, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 6.12.2009

Репутация: нет
Всего: нет



Да там проблема собственно в том, что кораблик постоянно вылезает за пределы поля- либо на следующую строчку или просто за пределы, ну или залезает на поле противника. Как только я не пробовал прописывать условия, ничего не получается, он их просто не замечает. Щас сижу в отчаянии =(  не знаю что и делать. А срок курсовой следующая неделя ((((((
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0463 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.