forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   2D-программирование (http://forum.boolean.name/forumdisplay.php?f=13)
-   -   Помогите с Type (http://forum.boolean.name/showthread.php?t=13396)

volgeras 23.09.2010 17:08

Помогите с Type
 
Итак, есть примерно такой тип:
Код:

Type cube
  field x;координата х
  field y;координата у
  field number_x;порядковый номер строки, в которой расположен куб
  field number_y;порядковый номер столбца, в котором расположен куб
  field use;занят ли куб
End Type

Вот, я создаю поле из кубиков. И мне надо найти такие 3 кубика, чтобы cub\number_x у троих был один, а cub\number_y подряд шли(3,4,5 или 1,2,3 например) и эти 3 были свободны(field use). Не подскажите как это сделать. Вроде надо
Код:

for cub.cube = each cube
  if...
next

использовать, но я не придумаю никак какое условие в if писать.

Venom2 23.09.2010 19:57

Ответ: Помогите с Type
 
Если влоб решать, то цикл там не один, как и кол-во условий:
Код:

For cube1 = Each cube
        If cube1\use = False Then
                For cube2 = Each cube
                        If cube2\use = False Then
                                If cube2 <> cube1 And cube2\number_x = cube1\number_x And cube2\number_y - cube1\number_y = 1 Then
                                        For cube3 = Each cube
                                                If cube3\use = False Then
                                                        If cube3 <> cube1 And cube3 <> cube1 And cube3\number_x = cube1\number_x And cube3\number_y - cube2\number_y = 1 Then
                                                                Goto Found
                                                        End If
                                                End If
                                        Next
                                End If
                        End If
                Next
        End If
Next
Goto NotFound
.Found
; кубы найдены.
.NotFound

Т.е. берем первый куб, и начинаем сравнивать его с другими, так чтобы number_x были равны, и соответственно разница между number_y была +1 (вдобавок нужно исключить проверку кубика с самим с собой). Как только нашли второй куб, ищем так-же (перебирая список) третий куб, получается перебор тройной вложенности. Решение в худшем случае O(N^3) сложности, поэтому лучше поискать что-то побыстрее или переформулировать саму задачу :) Можно оптимизировать немного, например сделать два списка (два Type) один с занятыми, другой со свободными кубиками и соответственно перемещать кубы между ними. Меньше перебирать прийдется да и условие занятости сократится. Еще можно кешировать (запоминать в отдельные переменные) поля number чтобы во внутренних циклах сократить доступ к ним.

ЗЫ
Сорри за goto, но в блице нет переменного Exit, поэтому чтобы не городить еще кучу условий проще его заюзать :)

Жека 24.09.2010 14:17

Ответ: Помогите с Type
 
Может лучше хранить объекты не в списке, а в своём двумерном массиве?

volgeras 24.09.2010 17:49

Ответ: Помогите с Type
 
Не,в массиве не поместится информации столько же сколько так. Я в массив только ссылку на сам сделаю, а надо еще координаты, номера и еще что-то.

volgeras 24.09.2010 19:38

Ответ: Помогите с Type
 
Вот, сделал так:
Код:

For cub1.cubes = Each cubes
        If cub1\is_use = 0 Then
                DebugLog "ok1"
                For cub2.cubes = Each cubes
                        DebugLog "ok2"
                        If cub2\is_use = 0 And cub2\cube_x = cub1\cube_x And cub2\cube_z = cub1\cube_z+1 Then
                                DebugLog "ok3"
                                For cub3.cubes = Each cubes
                                        DebugLog "ok4"
                                        If cub3\is_use = 0 And cub2\cube_x = cub1\cube_x And cub2\cube_z = cub1\cube_z+2 Then
                                                DebugLog "ok5"
                                                Goto label1
                                        EndIf
                                Next
                        EndIf
                Next
        EndIf
Next

Однако, почему-то код зацикливается тут. В дебуге выводится каждую секунду то ОК2, то ОК4. Сам всю голову сломал, но не вижу никак, где ошибка. Не подскажите?

Venom2 24.09.2010 19:55

Ответ: Помогите с Type
 
Цитата:

Сообщение от volgeras (Сообщение 163119)
Вот, сделал так:
Код:

For cub1.cubes = Each cubes
        If cub1\is_use = 0 Then
                DebugLog "ok1"
                For cub2.cubes = Each cubes
                        DebugLog "ok2"
                        If cub2\is_use = 0 And cub2\cube_x = cub1\cube_x And cub2\cube_z = cub1\cube_z+1 Then
                                DebugLog "ok3"
                                For cub3.cubes = Each cubes
                                        DebugLog "ok4"
                                        If cub3\is_use = 0 And cub2\cube_x = cub1\cube_x And cub2\cube_z = cub1\cube_z+2 Then
                                                DebugLog "ok5"
                                                Goto label1
                                        EndIf
                                Next
                        EndIf
                Next
        EndIf
Next

Однако, почему-то код зацикливается тут. В дебуге выводится каждую секунду то ОК2, то ОК4. Сам всю голову сломал, но не вижу никак, где ошибка. Не подскажите?

1) во внутренних циклах нет исключения проверки куба с самим собой
2) cub2\cube_z = cub1\cube_z+1
не равно, а минус должно быть.
3) Выходить надо из цикла сразу как нашел нужные кубы
Внимательнее же код смотри :)

volgeras 25.09.2010 13:36

Ответ: Помогите с Type
 
Цитата:

Сообщение от Venom2 (Сообщение 163120)
1) во внутренних циклах нет исключения проверки куба с самим собой
2) cub2\cube_z = cub1\cube_z+1
не равно, а минус должно быть.
3) Выходить надо из цикла сразу как нашел нужные кубы

3)Я так и делаю(goto)
2)Не понял, какой минус.
Код:

If cub2\cube_z - cub1\cube_z+1
Че за ерунда?
1)ша посмотрю, че там у меня

volgeras 25.09.2010 13:48

Ответ: Помогите с Type
 
Вот я дурак невнимательный. В двух местах опечатался, он у меня 3 проверку не делал поэтому.

Жека 25.09.2010 16:48

Ответ: Помогите с Type
 
Цитата:

Сообщение от volgeras (Сообщение 163112)
Не,в массиве не поместится информации столько же сколько так. Я в массив только ссылку на сам сделаю, а надо еще координаты, номера и еще что-то.

Чё за фигня?:)

С экземпляром объекта мы работаем через указатель (ссылку) на него, поэтому - имея указатель в массиве, мы имеем доступ ко всем полям.

Вот массив объектов:
Код:

Type TElem
        Field x%,y%
        Field width%,height%
        Field r%, g%,b%
End Type

Global colCount% = 8, rowCount% = 8

Dim mas.TElem(colCount, rowCount)

И доступ
Я написал примерчик, чтоб удостовериться, что оно работает в блице. Итог: оно работает:)



Type TElem
Field x%,y%
Field width%,height%
Field r%, g%,b%
End Type

Global colCount% = 8, rowCount% = 8

Dim mas.TElem(colCount, rowCount)

Global screenWidth% = 800
Global screenHeight% = 600

Graphics(screenWidth, screenHeight, 16, 2)
SetBuffer (BackBuffer ())

fnCreateElems(screenWidth, screenHeight)

While(Not(KeyHit(1)))
fnDrawElems()
Flip()
Cls()
Wend

End



Function fnCreateElems(width%, height%)
Local cube.TElem
Local w%,h%
For c%=0 To colCount-1
For r%=0 To rowCount-1
cube = New TElem
w = Rand(10,30)
h = Rand(10,30)
cube\x = Rand(0, width-w)
cube\y = Rand(0, height-h)
cube\width = w
cube\height = h
cube\r = Rand(0,255)
cube\g = Rand(0,255)
cube\b = Rand(0,255)
mas(c, r) = cube
Next
Next
End Function

Function fnDrawElems()
For c%=0 To colCount-1
For r%=0 To rowCount-1
Color(mas(c, r)\r, mas(c, r)\g, mas(c, r)\b)
Rect (mas(c, r)\x, mas(c, r)\y, mas(c, r)\width, mas(c, r)\height)
Next
Next
End Function


volgeras 25.09.2010 19:03

Ответ: Помогите с Type
 
А, вон как. Я подумал немного иначе. Так тоже неплохо, но я уже сделал другим путем, переделывать придется много, так что оставлю другой вариант, но все-равно большое спасибо.

volgeras 30.09.2010 18:16

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

Crayzi 01.10.2010 04:08

Ответ: Помогите с Type
 
Цитата:

Сообщение от volgeras (Сообщение 163554)
Созрел такой вопрос еще(не по теме, но не хочется новую создавать тему). Вот в оконном режиме если нажать крест красный(закрытие окна), можно ли как-то сделать функцию, которая будет обрабатываться тогда, либо просто неактивным крест сделать. А то мне необходимо, чтобы при выходе из игры обработалась информация кое-какая.

Както через Win API, точно незнаю как... :(

Жека 01.10.2010 07:51

Ответ: Помогите с Type
 
Во чо я нашол:)
Обработка WM_CLOSE

Randomize 11.10.2010 14:37

Ответ: Помогите с Type
 
источник
PHP код:

AppTitle "test123"

First parameter is the scancode to fakethe second is the window name
InstallCloseHandler
(72"test123")

While (
Not KeyHit(1))
    ; 
This if will be TRUE when the user tries to close the windowusually don't use a common key
    If KeyHit(72)  
        DebugLog("yeah")
    EndIf
Wend

UnInstallCloseHandler() 

Оххохо вот это решение! :-D

volgeras 12.10.2010 16:22

Ответ: Помогите с Type
 
Цитата:

Сообщение от Randomize (Сообщение 164278)
источник
PHP код:

AppTitle "test123"

First parameter is the scancode to fakethe second is the window name
InstallCloseHandler
(72"test123")

While (
Not KeyHit(1))
    ; 
This if will be TRUE when the user tries to close the windowusually don't use a common key
    If KeyHit(72)  
        DebugLog("yeah")
    EndIf
Wend

UnInstallCloseHandler() 

Оххохо вот это решение! :-D

Решение, конечно, дурацкое, т.к. там окно можно закрыть и любой кнопкой на клавиатуре, например тут 72. Но лучше еще ничего не нашел. Поэтому вполне конкурентноспособно:)


Часовой пояс GMT +4, время: 22:47.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot