Игра сокобан с 5по 11

В Центре Научно Технического Творчества Учащейся Молодежи города Севастополя, прошел конкурс по Информационным технологиям, победителей поздравят в воскресение, а тут я выкладываю в рамках раздела блога программы, примерные варианты решения.

Первой рассмотрю задачку Сокобан.

Писал я на надеюсь понятном для всех программистов языке – Pascal.

Пример входных данных:

Игра сокобан с 5по 11 17 10 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 2 0 0 0 0 0 2 0 2 0 4 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 3 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 3 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 3 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 игра сокобан с 5по 11 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1

Управление осуществляется клавишами w, s, a, d и ESC – выход.

Заранее предупреждаю, что хотя и верное, но не оптимальное решение задачи. Лучшее решение требует гораздо более обдуманного подхода. Следует применять динамические массивы данных и прочее.

игра сокобан с 5по 11

Задача решалась с точки зрения минимальных/требуемых знание языка Паскаль.

Tags: игра сокобан с 5по 11, сокобан

Эта статья написана в Вторник, Январь 19th, 2010 at 18:14 в разделе Задачи программирования. Вы можете подписаться на обновления комментариев к статье - RSS 2.0. Вы можете оставить комментарий, или послать игра сокобан с 5по 11 со своего сайта.

program sokoban; uses crt; type sPoint =record x:integer; y:integer; end; { тип записи точки }   const mxWidth =100; mxHeight =100; { масимальные ширина и высота поля }   maxBlocks =100; { максимальное количесво блоков}   var map:array[1.mxWidth,1.mxHeight]ofbyte; { карта } fin: Text; { дескриптор входного файла с картой } i,j:integer; { счетчики } v:byte; { вектор направления сокобана } m,n:integer; { ширина и высота предоставляемой карты } freesq,{ количесво свободных "контейнеров" для ящиков} countsq:integer; { количесво ящиков } c:char; { код клавиатуры } player: sPoint; { координаты игрока} nx, ny:integer; { временные переменные для хранения следующей позиции игрока} blockpoint:array[1.maxBlocks]of sPoint; { массив ящиков } lastpx, lastpy, lastbx, lastby, lastbi, lastc:integer; { временные переменные сохраняющие предпоследнюю позицию игрока } f:Boolean; { флаг совершения хода, чтобы нельзя было отменить ход в самом начале игры }   { возвращает идентификатор (номер) блока расположенного по координатам x,y, если блока нет, возвращает 0}function get_block(x,y:integer):integer; var i:integer; v:integer; begin v:=0; for i:=1to countsq do{ просматриваем массив блоков }if(blockpoint[i].x= x)and(blockpoint[i].y= y)thenbegin v := i; break; { если нашли, то прерываем работу цикла посика }end; get_block:=v; end;   {пытаеться переместить блок, ели его толкает сокобан, если удалось возвращает значение Истина, иначе Ложь}function TryMoveBlock(id:integer):Boolean; var nx,ny,x,y:integer; begin x:= blockpoint[id].x; игра сокобан с 5по 11 blockpoint[id].y; {запоминаем текущие координаты блока}   lastbx:=x; lastby:=y; lastbi:=id; lastc := freesq; {сохраняем параметры блока, для восстановления если пользовател отменит последний ход}   case v of{определяем направление движения сокобана, чтобы в этом же направлении сдвинуть блок}1:begin nx:=x; ny:=y-1; end; {вверх}2:begin nx:=x; ny:=y+1; end; {вниз}3:begin nx:=x-1; ny:=y; end; {влево}4:begin nx:=x+1; ny:=y; end; {вправо}end;   if(get_block(nx,ny)=0)and(map[ny,nx] <>1)then{если дальше нет стены, или второго блока, игра сокобан с 5по 11 двигаем блок}begin   blockpoint[id].x:= nx; blockpoint[id].y:= ny; if(map[ny,nx]=3)and(map[y,x]=0)then{если блок передвинут с пустой клетки, то уменьшаем счетчик свободных контейнеров}begin игра сокобан с 5по 11 dec( freesq ); endelseif(map[ny,nx]=0)and(map[y,x]=3)then{иначе если блок передвинут с фыинального места на пустое, возвращаем значения счетчика} inc( freesq );   TryMoveBlock :=True; exit; end; TryMoveBlock :=False;   end;   {пытаеться переместить сокобана на новые координаты если это возможно}procedure MoveSokoban(x,y:integer); var bi:integer; {идентификатор блока}begin lastpx:=player.x; lastpy:=player.y; { запоминаем позицию сокобана, для последующего восстановления предыдущего хода, если потребуеться}   {определяем границы возможного игра сокобан с 5по 11 x>0)and(y>0)and(x<m)and(y<m)thenif map[y,x] <> 1thenbegin{если впереди не стенка} bi := get_block(x,y); { узнаем, есть ли там блок }if bi > 0then{если есть }beginif(TryMoveBlock(bi))then{то сначало пробуем переместить блок, а если удалось - перемещаем вслед сокобана}begin player.x:= x; player.y:= y; end; игра сокобан с 5по 11 endelse{если блока и стены нет, то просто перемещаем сокобана}begin player.x:= x; игра сокобан с 5по 11 player.y:= y; end; end; end; begin freesq :=1; countsq :=0; Assign(fin,'Map.txt'); Reset(fin); {открываем файл карты}Read(fin,m,n); {считываем размеры карты}for i :=1to n dofor j :=1to m dobegin{ считываем саму карту }Read(fin, v);   case v of1: map[i,j]:=1; {стена}2: map[i,j]:=3; {"контейнер" для ящиков}3:begin blockpoint[freesq].x:= j; blockpoint[freesq].y:= i; inc(freesq); inc(countsq); end; {блок}4:begin player.x:= j; player.y:= i; end; {игрок}else map[i,j]:=0; {пустая клетка}end; end; Close(fin); {закрываем файл карты} lastc := freesq; f:=False; {запоминаем условия отмены хода}while(freesq игра сокобан с 5по 11 1)do{пока хоть один контейнер свободен}begin clrscr; {очищаем экран}   for i:=1to n dobeginfor j:=1to m dobegin{отображаем карту} gotoxy(j,i); TextColor(14); if(map[i,j]=1)thenwrite('І')elseif(map[i,j]=3)thenbegin TextColor(2); write('Ь'); end   elsewrite(' '); end;   writeln; end;   for i:=1to countsq dobegin{отображаем блоки} gotoxy( blockpoint[i].x, blockpoint[i].y); TextColor(5); write('Ы'); end;   TextColor(14); gotoxy(player.x, player.y); write(''); {отображаем игрока}   gotoxy(80,25); {убираем курсор, чтобы не мозолил глаз} c := ReadKey; case c of{проверяем ввод с клавиатуры}'w':begin nx:=player.x; ny:=player.y-1; v:=1; end; {ход вверх}'s':begin nx:=player.x; ny:=player.y+1; v:=2; игра сокобан с 5по 11 {ход вниз}'a':begin nx:=player.x-1; ny:=player.y; v:=3; end; {ход влево}'d':begin nx:=player.x+1; ny:=player.y; v:=4; end; {ход вправо}   'z':if f thenbegin freesq := lastc; player.x:= lastpx; player.y:= lastpy;   blockpoint[lastbi].x:= lastbx; blockpoint[lastbi].y:= lastby; continue; end; #27:break; {выход }end; f:=True; MoveSokoban(nx,ny); {пытаемся переместить сокобан}end; clrscr; textcolor(15);   игра сокобан с 5по 11 =1)then{сообщаем пользователю о выйгрыше если ему удалось заполнить все контейнеры}writeln('You Win!')else{или о проигрыше еслион самостоятельно прервал игру}writeln('You Игра сокобан с 5по 11 writeln('Press Enter for exit!'); readln; end.
Источник: http://old.ignatiev.su/blog/posts/sokoban