Страницы: 1
RSS
Программка дилетанта. Игра Змейка, посмотрите, потыкайте палками
 
Написал програмку чисто для развлечения и упражнения в VBA
Код
Sub lenta2()
Dim i As Integer
Dim rr As Integer
Dim im As Integer
Dim jm As Integer
Dim col As Integer
Dim i2 As Integer
Randomize
im = Int((20 - 1 + 1) * Rnd + 1)
jm = Int((20 - 1 + 1) * Rnd + 1)
col = Int((30 - 1 + 1) * Rnd + 1)
Cells(im, jm).Interior.ColorIndex = col
For i = 1 To 59
Application.Wait (Now + TimeValue("0:00:01"))
rr = Int((4 - 1 + 1) * Rnd + 1)
Select Case rr
Case 1
im = im
jm = jm + 1
Case 2
im = im
jm = jm - 1
Case 3
im = im + 1
jm = jm
Case 4
im = im - 1
jm = jm
End Select
i2 = i2 + 1
If jm = 1 Or im = 1 Or jm > 19 Or im > 19 Then
GoTo Ende
Else
col = Int((30 - 1 + 1) * Rnd + 1)
Cells(im, jm).Interior.ColorIndex = col
End If
Next i
Ende:
Cells(2, 24).Interior.ColorIndex = col
Cells(1, 24).Value = i2
End Sub
Програмка случайным образом находит ячейку от 1,1 до 20,20, потом ставит случайный цвет от 1 до 30 и рисует змейку случайными же цветами, пока змейка не доростет до края 1,1 - 20,20. Потом записывает количество прошедших циклов (их может быть максимум 59) и последний цвет.

Подскажите  пожалуйста - где можно оптимизировать и сократить программу?
Goedenavond!
 
Посмотрел свежим оком и увидел просто шедевр.
Код
im = im
:D  :D  :D
Да, очень немногие программисты смогут дойти своим умом до такого решения.

Переписал программу, выкинул "шедевры", выкинул goto и два рендома. Минус 9 строк.
Код
Sub lenta2()
Dim i As Integer
Dim im As Integer
Dim jm As Integer
Dim col As Integer
Randomize
im = Int((20 - 1 + 1) * Rnd + 1)
jm = Int((20 - 1 + 1) * Rnd + 1)
col = Int((30 - 1 + 1) * Rnd + 1)
Cells(im, jm).Interior.ColorIndex = col
For i = 1 To 59
Application.Wait (Now + TimeValue("0:00:01"))
Select Case col
Case 1 To 7
jm = jm + 1
Case 8 To 15
jm = jm - 1
Case 16 To 22
im = im + 1
Case 23 To 30
im = im - 1
End Select
If jm = 1 Or im = 1 Or jm > 19 Or im > 19 Then
Cells(1, 24).Value = i
i = 60
Else
col = Int((30 - 1 + 1) * Rnd + 1)
Cells(im, jm).Interior.ColorIndex = col
End If
Next i
Cells(2, 24).Interior.ColorIndex = col
End Sub
Goedenavond!
 
1. Добавить очистку диапазона перед заливкой
2. Проверять. залита ли выбранная ячейка, иначе не змейка получаается, а комплект клубков )
3. Останавливать при попытке выйти за границы или если деваться некуда и себя есть приходится
 
seggi, а почему иногда задний ход включается? на сколько я помню, то есть 3 действия поворот на лево, право и вперед.
Изменено: БМВ - 23.04.2021 23:09:56
По вопросам из тем форума, личку не читаю.
 
Выбор цвета - вручную или случайным образом
Переключение скорости движения
Отображение направления движения
Указатель "хвоста" и "головы"
Змейка не выходит за пределы поля и не "переползает" через себя
Финиш - когда некуда двигаться

Добавил мангустов. Если змея встречается с мангустом - увы, он ее..
Но и змейке помог - на поле добавлены жизни. Нашла - подкрепилась. После встречи с мангустом - минус жизнь. Но если тупик, то и 10 жизней не спасут.

Не реализована проверка наличия символа в ячейке при расстановке мангустов/жизней (т.е. после расстановки их может оказаться меньше указанного количества)
Код
Sub RandomTape()
    Dim sDirect As String, sOldDirect As String
    Dim bFlagColor As Boolean, bFlagDirect As Boolean
    Dim lColor As Long, lSymbol As Long, dSpeed As Double
    Dim lThreat As Long, lLife As Long
    Dim n As Long, i As Long, j As Long
    
    Randomize

    Range("B2:U21").Interior.Pattern = xlNone
    Range("B2:U21").ClearContents
    Cells(16, 23).Value = 1
    Cells(18, 23).ClearContents
    Cells(19, 23).Interior.Pattern = xlNone
    
    lColor = Cells(4, 23).Interior.Color
    bFlagColor = Cells(5, 23).Value
    If Cells(6, 23).Value Then dSpeed = 2 Else dSpeed = 1
    bFlagDirect = Cells(7, 23).Value
    lThreat = Cells(9, 23).Value
    lLife = Cells(11, 23).Value
    
    For n = 1 To lThreat
         i = Int(20 * Rnd + 2): j = Int(20 * Rnd + 2)
         Cells(i, j).Value = Chr$(136)
    Next n
    
    For n = 1 To lLife
         i = Int(20 * Rnd + 2): j = Int(20 * Rnd + 2)
         Cells(i, j).Value = Chr$(114)
    Next n
    
    i = Int(20 * Rnd + 2): j = Int(20 * Rnd + 2)
    n = 0: lLife = 0
           
    Do: Application.Wait (Now + TimeValue("0:00:01")) / dSpeed
        sDirect = ""
        If Cells(i - 1, j).Interior.Pattern = xlNone Then sDirect = sDirect & "U"
        If Cells(i, j + 1).Interior.Pattern = xlNone Then sDirect = sDirect & "R"
        If Cells(i + 1, j).Interior.Pattern = xlNone Then sDirect = sDirect & "D"
        If Cells(i, j - 1).Interior.Pattern = xlNone Then sDirect = sDirect & "L"
        
        If sDirect <> "" Then
            sDirect = Mid$(sDirect, Int(Len(sDirect) * Rnd + 1), 1)
            lSymbol = fSymbol(sOldDirect, sDirect)
            If bFlagDirect = True Then Cells(i, j).Value = Chr$(lSymbol)
            If n = 1 Then Cells(i, j).Value = Chr$(250)
            
            Select Case sDirect
            Case "U": i = i - 1
            Case "R": j = j + 1
            Case "D": i = i + 1
            Case "L": j = j - 1
            End Select
            
            If bFlagColor = True Then lColor = Int(16581375 * Rnd + 1)
            Cells(i, j).Interior.Color = lColor
            
            sOldDirect = sDirect
            n = n + 1
            
            If Cells(i, j).Value = Chr$(114) Then
                lLife = lLife + 1: Cells(16, 23).Value = lLife + 1
            End If
            
            If Cells(i, j).Value = Chr$(136) Then
                lLife = lLife - 1: Cells(16, 23).Value = lLife + 1
                If lLife < 0 Then Exit Do
            End If
        End If
    Loop Until sDirect = ""
    
    If sDirect = "" Then Cells(i, j).Value = Chr$(113)
    Cells(16, 23).Value = 0
    Cells(18, 23).Value = n
    Cells(19, 23).Interior.Color = lColor
    Beep
End Sub

Function fSymbol(sOldDirect As String, sDirect As String) As Long
    Select Case sOldDirect
    Case "U"
        Select Case sDirect
        Case "U": fSymbol = 53
        Case "R": fSymbol = 59
        Case "L": fSymbol = 58
        End Select
    Case "R"
        Select Case sDirect
        Case "U": fSymbol = 61
        Case "R": fSymbol = 52
        Case "D": fSymbol = 63
        End Select
    Case "D"
        Select Case sDirect
        Case "R": fSymbol = 57
        Case "D": fSymbol = 54
        Case "L": fSymbol = 56
        End Select
    Case "L"
        Select Case sDirect
        Case "U": fSymbol = 60
        Case "D": fSymbol = 62
        Case "L": fSymbol = 51
        End Select
    End Select
End Function
 
не, ну просто назад на ..... помню на фортране писал с псевдографикой. кажется был 9-10 класс. Увы на ЕС и перфокартах играть было невозможно  :D .
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ написал: помню на фортране писал
У меня это была вторая платформа. Первая - БЭСМ-4, Алгол-60. :)  
Владимир
 
Я на Радио-86 РК пробовал язык освоить. Потом Синклеры собирал-настраивал, хотел в программировании чему-то научиться...
Не пошло )
 
Цитата
vikttur написал: Не пошло )
заметно
Цитата
Range("B2:U21").Interior.Pattern = xlNone
Range("B2:U21").ClearContents
With так и не освоил  :D
По вопросам из тем форума, личку не читаю.
 
Не издевайся ) Строки добавлял-переставлял и чего-то не заметил (если порыться, то еще можно чего наскрести)

Зацепился за идею выбора направления с помощью строки "URDL" и интересно было прописать это. А потом стрелочки простые придумались,  потом интересно стало стрелки сделать зависимыми от предыдущего направления, потом еще... В общем, seggi виноват, что несколько часов убито. Но я доволен  :)
 
vikttur, красиво, конечно. И код выглядит понятно, буду изучать.
Только что программка дожила почти до 100 линий, съела 4 жизни и пережила трех мангустов. Просто треш.  :D

Хотел спросить насчет Function -  в каких случаях ее имеет смысл использовать?
Goedenavond!
 
Кто больше? :)
Скрытый текст

Функции (как и процедуры) удобно выносить отдельно, когда они могут быть задействованы в других процедурах, когда имеют "законченную мысль",  для разгрузки основной процедуры (так читать код удобнее)

Примеры.
1. Заполнение поля жизнями и препятствиями (два отдельных цикла) можно заменить одной процедурой, передав нужные параметры:
Скрытый текст
Количество выполняемых циклов от этого не изменится, но в основном макросе осталась пара строк, на которых внимание особо не задерживается.

2. Изменение количества жизней - или +, или -. Тоже в отдельную процедуру и вызываем ее из двух мест:
Скрытый текст

3. Определение разрешенных направлений - функцией
Скрытый текст

А результат получаем одной строкой в основной процедуре

4. Предстартовые подготовки и финишные результаты - отдельно
...и т.д.
 
Запустите макрос на большой скорости змейки :)
Код
Sub test_()
    DoEvents
    Call RandomTape
    If Cells(18, 23).Value > 200 Then Beep: Exit Sub
'    Application.Wait Time:=Now + TimeValue("0:00:01")
    Call test_
End Sub

Можно еще прикрутить переменную для записи количества циклов
 
vikttur, Вить, ну хрень ведь. Хвост нужно подбирать и длину растить спустя N циклов, а не на каждом. То есть змейка ползти должна и не просто тянутся.
По вопросам из тем форума, личку не читаю.
 
Да ну, это же не змейка, которая змейка, а змейка, которая "длинный путь в никуда" :)
 
Цитата
vikttur написал:
Кто больше?
240 Изи. Свою животинку пока не писал. В Вашем варианте автозапуска с beep не хватает счётчика количества итераций. У меня вышло 57 577 + ещё где-то 7 запусков раз по  приблизительно 2400 итераций, благодаря которым я теперь знаю про существование ошибки "out of stack space". Что удивительно цифра 222 выпадала минимум 2 раза. Логи результатов не вёл.
Я не волшебник, я только учусь.
 
Цитата
Wiss написал: знаю про существование ошибки "out of stack space".
Рекурсия не всегда применима. Здесь правильнее циклом заменить, шагов так на 30-50 тысяч - и пусть мотает )
Изменено: vikttur - 07.05.2021 11:09:31
 
Новая поделка - генерация набора цифр для лотто, 6 из 49. 6 случайных цифр от 1 до 49, без повторов и по порядку, которые выводятся в первом листе и в третьем столбце.

Главное условие для меня было - не использовать никаких чужих решений, только свои знания. Табуретка, конечно, кривая, но своя, собственная  :D

Отсутствие надежного алгоритма заменяем огромным количество циклов.   8)

Скрытый текст
Изменено: seggi - 07.05.2021 11:21:13
Goedenavond!
 
Цитата
seggi: Новая подделка
— для новой темы + поДелка, а не китайская поДДелка  ;)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх