Конференция "Сети" » Алгоритм сложения камней в игре
 
  • Редька (08.11.12 00:56) [0]
    Добрый вечер.
    Подскажите алгоритм для игры.
    Думаю все знают такие игры. Поле к примеру 8 на 8 с разными камнями. Необходимо передвинуть один из камней чтобы получилось 3 и более камней по горизонтали или вертикали. К сожалению не могу придумать алгоритм как это просчитать?

    Пример поля  http://s017.radikal.ru/i408/1211/da/4b05de740080.jpg

    Написал вот такой код. Проходит по всем камням по центру. Берет по 1 пикселю и его цвет RGB и по нему определяет цвет.


    procedure TForm1.get_fieldClick(Sender: TObject);
    var
     bmp : TBitmap;
     y, x : Integer;
     R, G, B : LongInt;
     RGB : TColor;
     DC : HDC;
     text : string;
    begin

     DC := GetDC(0);  //Дескpиптоp экpана

     field_img.Picture.Bitmap.Width := StrToInt(field_width_edit.Text);
     field_img.Picture.Bitmap.Height := StrToInt(field_height_edit.Text);

     bitblt(field_img.Picture.Bitmap.Canvas.Handle, 0, 0, StrToInt(field_width_edit.Text), StrToInt(field_height_edit.Text), DC, StrToInt(field_x_edit.Text), StrToInt(field_y_edit.Text), SRCCOPY);

     bmp := TBitmap.Create;
     bmp.Width := field_img.Picture.Bitmap.Width;
     bmp.Height := field_img.Picture.Bitmap.Height;
     bmp.Assign(field_img.Picture.Bitmap);

      for y := 0 to StrToInt(stone_height_edt.Text) - 1 do
       begin

         text := '';

         for x := 0 to StrToInt(stone_width_edt.Text) - 1 do
          begin

            RGB := ColorToRGB(bmp.Canvas.Pixels[(x * StrToInt(get_color_x_edt.Text)) + Floor(StrToInt(get_color_x_edt.Text)/2),(y * StrToInt(get_color_y_edt.Text)) + Floor(StrToInt(get_color_y_edt.Text) / 2)]);

            R := GetRValue(RGB);
            G := GetGValue(RGB);
            B := GetBValue(RGB);

            field_img.Picture.Bitmap.Canvas.Pixels[(x * StrToInt(get_color_x_edt.Text)) + Floor(StrToInt(get_color_x_edt.Text)/2),(y * StrToInt(get_color_y_edt.Text)) + Floor(StrToInt(get_color_y_edt.Text) / 2)]:= $ffffff;

            if (R <= 195) and (R >= 175) and (G <= 18) and (G >= 0) and (B <= 38) and (B >= 18) then text := text + '|| К '
            else if (R <= 41) and (R >= 21) and (G <= 207) and (G >= 187) and (B <= 255) and (B >= 241) then text := text + '|| Г '
            else if (R <= 250) and (R >= 230) and (G <= 250) and (G >= 230) and (B <= 253) and (B >= 233) then text := text + '|| Б '
            else if (R <= 176) and (R >= 156) and (G <= 176) and (G >= 156) and (B <= 253) and (B >= 233) then text := text + '|| С '
            else if (R <= 244) and (R >= 220) and (G <= 12) and (G >= 0) and (B <= 247) and (B >= 227) then text := text + '|| Ф '
            else if (R <= 90) and (R >= 70) and (G <= 220) and (G >= 200) and (B <= 10) and (B >= 0) then text := text + '|| З '
            else if (R <= 225) and (R >= 205) and (G <= 198) and (G >= 178) and (B <= 10) and (B >= 0) then text := text + '|| О '
            else text := text + '||' + IntToStr(R) + ' ' + IntToStr(G) + ' ' + IntToStr(B)
          end;

          all_color.Lines.Add(text);
         
       end;

     bmp.Free;
    end;



    В Memo вот такой текст после работы.

    || К || Г || Б || С || Ф || К || Ф || К
    || Б || З || С || З || О || К || Ф || З
    || Ф || О || З || Б || С || С || К || Б
    || Ф || О || Ф || Ф || Г || З || О || К
    || З || К || О || Б || Ф || С || Б || С
    || З || О || С || Г || К || С || О || Г
    || С || О || Ф || К || Ф || З || Г || З
    || Ф || С || Ф || С || С || Г || З || Г

    Подскажите как организовать алгоритм сравнения камней чтобы собирать их?
  • Smile (08.11.12 09:13) [1]
    Возьми здесь:
    http://www.sources.ru/delphi/games/lines.rar

  • Плохиш © (08.11.12 12:57) [2]

    > Пример поля  http://s017.radikal.ru/i408/1211/da/4b05de740080.
    > jpg

    Для такого у меня даже мысли не возникает о сравнении цветов. Каждый вид камня имеет номер, внутренняя матрица с типами для обработки действий, экран только для рисования состояний.
  • RWolf © (08.11.12 13:01) [3]
    > Плохиш ©   (08.11.12 12:57) [2]

    может, человек бота для Lines пишет )
  • brother © (08.11.12 13:08) [4]
    тогда, лучше анализировать области...
  • Редька (08.11.12 13:31) [5]
    Пишу как раз бота) По этому и думаю какой алгоритм применить. Причем алгоритм не как сходить. А выбрать как лучше сходить с учетом собираемых камней. Где каждого цвета камень имеет свой вес.
  • brother © (08.11.12 13:39) [6]
    где оригинал игры? (я так понимаю, онлайн...)
  • Редька (08.11.12 14:24) [7]

    > где оригинал игры? (я так понимаю, онлайн...)

    Игра драгоценные камни в VK.
    Да и зачем оригинал? Если все такие игры построены на одном алгоритме передвинуть два камня чтобы сложить 3 и более вместе. За место сложенных сверху падают новые.
    Не могу придумать как анализировать лучший ход.
  • Редька (08.11.12 16:58) [8]
    Нашел код один на AutoIt для подобной игры. Но не все могу перевести в Delphi.



           Func _DfsAreaSize(ByRef $aiField, $iStartX, $iStartY) ; нерекурсивный алгоритм поиска размера одноцветной области
           ; методом поиска в глубину
           Local $aiResult[$iNumCols * $iNumRows][2] ; список клеток входящих в область
           Local $iResultSize = 0
           Local $afMap[$iNumRows][$iNumCols] ; флаги пройденности
           For $iRow = 0 to $iNumRows - 1
           For $iCol = 0 to $iNumCols - 1
           $afMap[$iRow][$iCol] = False
           Next
           Next
           $afMap[$iStartX][$iStartY] = True
           Local $aiStack[$iNumRows * $iNumCols][2] ; активный стек
           Local $iStackSize = 1
           $aiStack[0][0] = $iStartX
           $aiStack[0][1] = $iStartY
           While $iStackSize > 0
           $iStackSize -= 1
           $iX = $aiStack[$iStackSize][0]
           $iY = $aiStack[$iStackSize][1]
           $aiResult[$iResultSize][0] = $iX
           $aiResult[$iResultSize][1] = $iY
           $iResultSize += 1
           For $iDirection = 0 to 3 ; перебор 4 рядомстоящих клеток
           Local $iNewX = $iX
           Local $iNewY = $iY
           Switch $iDirection
           Case 0
           $iNewY += 1
           Case 1
           $iNewY -= 1
           Case 2
           $iNewX += 1
           Case 3
           $iNewX -= 1
           EndSwitch
           If ($iNewX >= 0 And $iNewX < $iNumRows And _
           $iNewY >= 0 And $iNewY < $iNumCols And _
           Not($afMap[$iNewX][$iNewY]) And $aiField[$iNewX][$iNewY] = $aiField[$iStartX][$iStartY]) Then
           $afMap[$iNewX][$iNewY] = True
           $aiStack[$iStackSize][0] = $iNewX
           $aiStack[$iStackSize][1] = $iNewY
           $iStackSize += 1
           EndIf
           Next
           WEnd
           Return $iResultSize
           EndFunc


 
Конференция "Сети" » Алгоритм сложения камней в игре
Есть новые Нет новых   [119110   +107][b:0][p:0.005]