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. Но лучше еще ничего не нашел. Поэтому вполне конкурентноспособно:)

volgeras 14.10.2010 16:15

Ответ: Помогите с Type
 
Вот возник еще вопрос о типе. Есть такой тип:
Код:

Type enemy_ships
        Field id
        Field alpha#
        Field rotate%
        Field long$
        Field x1%,z1%
        Field x2%,z2%
        Field x3%,z3%
        Field x4%,z4%
End Type

И такой код:
Код:

While Not Eof(stream_in)
s_l = ReadLine(stream_in)
s_x = ReadLine(stream_in)
s_z = ReadLine(stream_in)
s_r = ReadLine(stream_in)
sh.enemy_ships = New enemy_ships
sh\alpha = "1"
sh\rotate = s_r
sh\long = s_l
If s_l = 1 Then
    sh\id = LoadMesh("3d_1.3ds")
    ScaleEntity sh\id,0.35,0.3,0.2
    EntityAlpha sh\id,1
    sh\x1 = s_x
    sh\z1 = s_z
    sh\x2 = 0
    sh\z2 = 0
    sh\x3 = 0
    sh\z3 = 0
    sh\x4 = 0
    sh\z4 = 0
;Тут еще несколько похожих проверок
EndIf
Wend

Когда пытаюсь запустить программу, то на строчке, выделенной красным, она отказывается запускаться, говорит: "Variable type mismatch". Не подскажите в чем возможна проблема? Я уже много вариантов перепробовал, но все равно та же ошибка.

DStalk 14.10.2010 16:43

Ответ: Помогите с Type
 
По моему ты напутал при объявлении типа. Символ # - float(с плавющей точкой), % - boolean(true/false), $ - string(текст).

volgeras 14.10.2010 17:00

Ответ: Помогите с Type
 
Да я там менял, тоже непомогло...

baton4ik 14.10.2010 20:02

Ответ: Помогите с Type
 
Возможно ты раньше юзал другой тип как sh. Если да, то обзови этот, к примеру, she:

she.enemy_ships = New enemy_ships

Arton 14.06.2014 18:43

Ответ: Помогите с Type
 
Вопрос как листать тайп?
Мне нужно, доходя до конца списка автоматически перемещаться в начало и наоборот. Максимум получилось листать назад.

Здесь у меня уже бред, хотя писал вроде логично:
PHP код:

If xKeyHit(44) = True Then ;назад "z"

        
Sobj Before Sobj
        
If Handle(Sobj) <= 0 Then Sobj.StaticObject Last StaticObject

End 
If

If 
xKeyHit(45) = True Then ;вперёд "x"

        
Sobj After Sobj
        
If Handle(Sobj) > numbstatic Then Sobj.StaticObject First StaticObject

End 
If 

numbstatic это количество объектов в списке

Буду рад если у кого-нибудь есть собственный код реализации, для примера.

dsd 14.06.2014 19:03

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

Сообщение от Arton (Сообщение 282749)
Вопрос как листать тайп?
Мне нужно, доходя до конца списка автоматически перемещаться в начало и наоборот.

Вот так наверно.
Код:

If xKeyHit(44) = True Then ;назад "z"

        If Handle(Sobj) = First StaticObject Then Sobj.StaticObject = Last StaticObject       
        Else Sobj = Before Sobj EndIf
       
     
End If

If xKeyHit(45) = True Then ;вперёд "x"
       
        If Handle(Sobj) = Last StaticObject Then Sobj.StaticObject = First StaticObject
        Else Sobj = After Sobj EndIf

End If


Arton 14.06.2014 19:08

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

Сообщение от dsd (Сообщение 282752)
Вот так наверно.
Код:

If xKeyHit(44) = True Then ;назад "z"

        If Handle(Sobj) = First StaticObject Then Sobj.StaticObject = Last StaticObject       
        Sobj = Before Sobj
       
     
End If

If xKeyHit(45) = True Then ;вперёд "x"
       
        If Handle(Sobj) = Last StaticObject Then Sobj.StaticObject = First StaticObject
        Sobj = After Sobj

End If


Так нельзя, First и Last только перемещают.

"Error: Illegal type conversion"

dsd 14.06.2014 19:17

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

Пример:

mine.MyType=First MyType ;mine=first object in the type list
mine=After( mine ) ;mine=second object
mine=After( mine ) ;mine=third object
mine=Before( mine ) ;mine=second object
mine=Before( mine ) ;mine=first again!
'After' и 'Before' возвращают 'Null' если тип пуст или объектов дальше нет. Пример:
mine.MyType=Last MyType ;mine=last object
mine=After( mine ) ;object after last does not exist!
Так же можно вставлять опретором Insert в любое место списка. Пример:
mine1.MyType=New MyType
mine2.MyType=New MyType
Insert mine2 Before mine1
Прмер как вставить новый эллемент в начало списка:
Insert mine Before First MyType
Специальная форма For...Next позволяет вам легко проверить каждый эллемент типа в листе. Пример:
For mine.MyType=Each MyType
Next
Наконец, опертор 'Delete Each' Позволит вам удалить все эеллементы из листа типа. Пример:
Delete Each MyType
Вот от того что красным выделено надо управление делать. И хэндл объекта не является его номером.

Nex 14.06.2014 19:55

Ответ: Помогите с Type
 
Наверно будет проще задать каждому "Type" уникальный id-номер и сделать перебор с сравнением id.

Arton 14.06.2014 20:01

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

Сообщение от dsd (Сообщение 282756)
Вот от того что красным выделено надо управление делать. И хэндл объекта не является его номером.

Всё верно, After'ом и Before'ом листаю список, всё прекрасно работает. Но, когда доходит до выше начала или конца списка получается ошибка, тоже всё правильно.
Значит надо сделать проверку, когда превышает диапазон, так вот эта проверка работает через одно место. Максимум получилось стопорить если листать назад:
PHP код:

If xKeyHit(44) = True Then ;назад "z"

    
Sobj Before Sobj
    
If Handle(Sobj) < 1 Then Sobj.StaticObject First  StaticObject

End 
If 

При "вперёд" вообще ничего не сработало.

И как ты кстати предлагаешь без First и Last перемещаться в начало и конец списка?

Твой пример крутил и так и эток...

Прикрутил так, но это бред и он не работает:
PHP код:

If xKeyHit(44) = True Then ;назад "z"

        
Sobj.StaticObject Last StaticObject
        
        Sobj 
Before(Sobj)

End If 

Переходит с первого объекта (у меня сброс на начало) на второй (вместо третьего!) и останавливается.

Не понимаю :(

dsd 14.06.2014 20:12

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

If xKeyHit(44) = True Then ;назад "z"

        
Sobj Before Sobj

        
If Sobj Null Then Sobj.StaticObject Last StaticObject

End 
If

If 
xKeyHit(45) = True Then ;вперёд "x"

        
Sobj After Sobj
        
If Sobj Null Then Sobj.StaticObject First StaticObject

End 
If 

Я что то наподобие вот этого в виду имел.

Arton 14.06.2014 20:39

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

Сообщение от dsd (Сообщение 282764)
PHP код:

If xKeyHit(44) = True Then ;назад "z"

        
Sobj Before Sobj

        
If Sobj Null Then Sobj.StaticObject Last StaticObject

End 
If

If 
xKeyHit(45) = True Then ;вперёд "x"

        
Sobj After Sobj
        
If Sobj Null Then Sobj.StaticObject First StaticObject

End 
If 

Я что то наподобие вот этого в виду имел.

Вот как, я даже не думал так :4to:
Большое спасибо, всё работает.


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

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