Страницы

суббота, 13 февраля 2016 г.

EV3 Саймон сказал

Что может быть лучше простых, но фановых проектов? Прошедшие пару недель мы работали над EV3-версией игры "Саймон сказал". В этой игре компьютер задумывает последовательность сущностей (действий, цветов, звуков), которые игрок должен повторить. Последовательность удлиняется при каждом правильном ходе игрока.


Если вы помните, ранее мы уже собирали "Саймона" из Arduino


Позднее мы добавляли возможность игры "Simon Says" в нашу волшебную лампу


Теперь пришла пора поиграть в игру и на платформе LEGO Mindstorms EV3. Поначалу мы планировали использовать кнопки для взаимодействия с игроком, но честно говоря результат получался скучноватым. Кнопки мы убрали и ограничились всего лишь тремя моторами, которые служат как для вывода последовательностей компьютером, так и для их ввода игроком. Плюсом этого решения можно считать возможность собрать проект как из домашней, так и из образовательной версии EV3.



Инструкцию по сборке (в форматах LDD и PDF) и программу к проекту можно скачать по ссылке

Программа написана на языке EV3 Basic, бесплатной среде программирования для EV3. О том где ее скачать и как установить можно прочитать здесь: Используя EV3 Explorer, входящий в состав EV3 Basic, создайте папку SimonSays и поместите в нее скачанные файлы проекта.

Интересной "фишкой", которую Вы можете рассмотреть в коде, является использование функции MyMotor(), которая реализует поворот мотора в нужную позицию с использованием кубического регулятора и контролем застревания. Так как EV3 Бейсик не поддерживает передачи параметров в функцию мы передаем параметры (какой мотор использовать и в какую позицию его установить) через переменные.

u = 1
M = "A"
P = 0
k = 1
For s = 1 To 20
  a = Math.GetRandomNumber(3)
  b[s] = Math.Round(a) 
EndFor   

Sub MyMotor
  t = EV3.Time
  regulator = "True"
  While regulator
    e = P - Motor.GetCount(M)
    v = e * k
    If M = "C" Then
      v = v * 0.75
    EndIf
    Motor.Start(M,v)
    If Math.Abs(Motor.GetCount(M) - P) < 5 Then
      regulator = "False"
    EndIf
    If  EV3.Time - t > 1000 Then
      regulator = "False"
    EndIf  
  EndWhile
  Motor.Stop(M,"True")
  Program.Delay(200)
  Motor.Stop(M,"False")
EndSub

While "True" 
  
  nextu:  
  
  For z = 1 To u
    If  b[z] = 1 Then
      M = "A"
      P = 50
      Speaker.Note(100, "C5", 150)
      MyMotor()
      M = "A"
      P = 0
      MyMotor()
    EndIf  
    If  b[z] = 2 Then
      M = "B"
      P = 50
      Speaker.Note(100, "D5", 150)
      MyMotor()
      M = "B"
      P = 0
      MyMotor()
    EndIf
    If  b[z] = 3 Then
      M = "C"
      P = -40
      Speaker.Note(100, "E5", 150)
      MyMotor()
      M = "C"
      P = 0
      MyMotor()
    EndIf    
  EndFor
  
  For w = 1 To u
    While Motor.GetCount("A") < 40 And Motor.GetCount("B") < 40 And Motor.GetCount("C") > -40
    EndWhile
    
    Program.Delay(200)
    
    If Motor.GetCount("A") > 40 Then
      If b[w] = 1 Then
        Speaker.Note(100, "C5", 150)
        Speaker.Wait()
      EndIf
      M = "A"
      P = 0
      MyMotor()      
      If b[w] <> 1 Then
        Speaker.Note(100, "C4", 300)
        M = "A"
        P = -50
        MyMotor()
        Speaker.Note(100, "C4", 300)
        M = "A"
        P = 0
        MyMotor()        
        Goto nextu
      EndIf        
    EndIf
    
    If Motor.GetCount("B") > 40 Then
      If b[w] = 2 Then
        Speaker.Note(100, "D5", 150)
        Speaker.Wait()
      EndIf
      M = "B"
      P = 0
      MyMotor()
      If b[w] <> 2 Then
        Speaker.Note(100, "C4", 300)
        M = "B"
        P = -50
        MyMotor()
        Speaker.Note(100, "C4", 300)
        M = "B"
        P = 0
        MyMotor()
        Goto nextu      
      EndIf
    EndIf 
    
    If Motor.GetCount("C") < -40 Then
      If b[w] = 3 Then
        Speaker.Note(100, "E5", 150)
        Speaker.Wait()
      EndIf
      M = "C"
      P = 0
      MyMotor()
      If b[w] <> 3 Then
        Speaker.Note(100, "C4", 300)
        M = "C"
        P = 50
        MyMotor()
        Speaker.Note(100, "C4", 300)
        M = "C"
        P = 0
        MyMotor()
        Goto nextu         
      EndIf        
    EndIf 
    
  EndFor
  
  u = u + 1    
  
EndWhile


Комментариев нет:

Отправить комментарий