{ -------------------------------------------------------- В принципе основной модуль, управляющий описанным в модуле SeaField объектом GameField. -------------------------------------------------------- Copyright(c) 1997 by Jassinskaja Jana, Jelena Kuznetsova -------------------------------------------------------- } Unit SeaPlay; interface procedure SeaWarKuj; procedure SeaWarInit; procedure SeaWarDone; procedure SeaWarPlay; implementation uses Crt, SeaField; const PauseTime = 5000; { время задержки для сообщений } Key_Esc = #27; { код клавиши ESC } var Computer : ComputerFieldPtr; { поле компьютера } Human : HumanFieldPtr; { а это поле человека } HitsNumC, HitsNumH : byte; { число попаданий по всем кораблям; =20 для победы } procedure SeaWarKuj; var i: integer; begin textbackground(green); gotoxy(1, 1); for i:=1 to 80 do write(' '); for i:=1 to 24 do begin gotoxy( 1, i); write(' '); gotoxy(80, i); write(' '); end; gotoxy(1, 24); for i:=1 to 80 do write(' '); textbackground(black); end; { создаем игровые поля и устанавливаем на них корабли } procedure SeaWarInit; begin SeaWarKuj; Randomize; { загрузка базы случайных чисел } New(Computer, Init(10, 8)); New(Human, Init(50, 8)); { устанавливаем кораблики } Computer^.SetUpField; Human^.SetUpField; { число попаданий ставим на 0 } HitsNumC := 0; HitsNumH := 0; end; { освободим занятую память } procedure SeaWarDone; begin Dispose(Computer, Done); Dispose(Human, Done); end; { человек делает свой ход возвращает FALSE при прерывании программы или при победе человека } function HumanMotion : boolean; var X, Y, Status : byte; { X, Y - вводимые координаты; Status - инфо из клетки с поля компьютера } Ch : char; { сюда читаем символ с клавиатуры } Code : integer; { временная переменная используемая при преобразовании знака в число (Val) } begin { повторяем наш ход до тех пор пока не промажем } repeat { чистим строки и выводим сообщение в верху экрана } GotoXY(32, 20); ClrEol; GotoXY(3, 3); ClrEol; Write('Ваш ход - X : '); { почистим буфер клавиатуры - вдруг мы жали не те клавиши } while KeyPressed do Ch := Readkey; { а теперь ждем нажатия клавиш 0-9 или ESC } repeat Ch := Readkey; { читаем символ с клавиатуры } until Ch in ['0'..'9', Key_Esc]; { если нажали ESC, то выходим из программы } if Ch = Key_Esc then begin HumanMotion := FALSE; exit; end else Val(Ch, X, Code); { преобразуем символ '0'-'9' в цифру } Write(X); Write(' Y : '); { теперь вводим координату Y } repeat Ch := Readkey; until Ch in ['0'..'9', Key_Esc]; if Ch = Key_Esc then begin HumanMotion := FALSE; exit; end else Val(Ch, Y, Code); Writeln(Y); { проверяем заданную координатами ячейку на попадание } Status := Computer^.GetCell(X, Y); GotoXY(32, 20); ClrEol; case Status of { если там есть кораблик, то ОООООООО!!!!! - попали } Ship1, Ship2, Ship3, Ship4 : begin Inc(HitsNumH); { увеличим число потопленных частей } Writeln('П О П А Л ! ! !'); Computer^.PutOnePart(X, Y, Hit+Status); { потопим подбитую часть } end; BusyCell, FreeCell : begin { а если ячейка пуста, то ..... МИМО } Write('М И М О ! ! !'); { отметим ячецку как стрелянную чтобы 2 раза не стрелять в 1 место } Computer^.SetCell(X, Y, PastMove); end; { ну а если мы стреляем в уже потопленный корабль или туда куда уже стреляли, то ..... Мдааааа.... Глупо } PastMove, Hit..255 : Write('ОЧЕНЬ ГЛУПЫЙ ХОД !'); end; { перерисуем поле компьютера } Computer^.DrawField; Delay(PauseTime); { и паузу } { а не потопили ли мы все корабли компьютера ? } if HitsNumH = 20 then begin { а раз потопили, то надо праздновать } GotoXY(32, 20); ClrEol; Writeln('Вы победили !'); HumanMotion := FALSE; Delay(PauseTime); exit; { заканчиваем программу } end; { если были попадания, то снова наш ход } until not (Status in [Ship1, Ship2, Ship3, Ship4]); end; { ход компьютера: возвращает FALSE при выходе из программы или при победе компа } function ComputerMotion : boolean; var X, Y : byte; { координаты клетки } Status : byte; { инфо из клетки (X, Y) с поля человека } begin { компьютер стреляем до тех пор пока не промажет } repeat GotoXY(32,20); ClrEol; { находим новые координаты для выстрела } repeat X := Random(FieldSize+1); Y := Random(FieldSize+1); Status := Human^.GetCell(X, Y); { проверяем, не стрелял ли комп сюда до этого } until not (Status in [BusyCell, PastMove, Hit..255, NotAvail]); GotoXY(3, 3); ClrEol; Write('Мой ход - X : ', X, ' Y : ',Y); GotoXY(32, 20); ClrEol; case Status of Ship1, Ship2, Ship3, Ship4 : begin { смотри ка! компьютер попад в наш кораблик! } Inc(HitsNumC); { увеличим счетцик числа подбитых кораблей } Writeln('Я ПОПАЛ ! ! !'); Human^.PutOnePart(X, Y, Hit+Status); { зафиксируем попадание } end; FreeCell : begin { ааааа.... И компы умеют мазать! } Write('Я ПРОМАЗАЛ ! ! !'); Human^.SetCell(X, Y, PastMove); { отметим промах на поле } end; end; Human^.DrawField; { переррисуем поле человека } Delay(PauseTime); if HitsNumC = 20 then begin { проверим не победил ли комп? } GotoXY(32, 20); ClrEol; Writeln('Я победил !'); ComputerMotion := FALSE; Delay(PauseTime); exit; { если победил то выйдем из процедуры } end; { если были попадания в корабли, то еще один ход } until not (Status in [Ship1, Ship2, Ship3, Ship4]); end; procedure SeaWarPlay; begin { выводим на экран игровые поля } Computer^.DrawField; Human^.DrawField; { выводим заголовки для полей } TextColor(Yellow); GotoXY(18, 6); Write('Компьютер'); GotoXY(59, 6); Write('Человек'); TextColor(LightGray); { играем до тех пока не нажмем ESC или кто-то не победит } while TRUE do begin if not HumanMotion then exit; if not ComputerMotion then exit; end; end; end.