카드 읽기

01. 무슨 카드일까요?

알버트 로봇의 바닥에는 그림 1과 같이 앞뒤로 OID 센서 2개가 있다. OID 센서는 눈에 보이지 않는 미세한 코드 패턴을 읽는 센서이며, 카드에는 코드 패턴이 인쇄되어 있어야 한다.

그림 1. 알버트 로봇의 OID 센서

알버트 로봇이 카드를 읽는 프로그램을 작성하시오.

웹 페이지 만들기를 참고하여 안드로이드 프로젝트와 웹 페이지 파일을 만들고, onInitialized(robot) 콜백 함수와 onExecute() 콜백 함수를 만들자.

 <script type="text/javascript">

 function onInitialized(robot)
 {
 }

 function onExecute()
 {
 }
 </script>

알버트 로봇에는 전방 OID 값을 읽는 디바이스로 EVENT_FRONT_OID가 있다. OID 데이터는 -1부터 65535까지의 값을 가지는데, -1은 OID 센서가 코드 패턴 위에 있지 않거나 코드를 읽지 못하였을 때 표시하는 값이다. 정상적으로 코드를 읽은 경우에는 0 이상의 값을 가진다.

 <script type="text/javascript">

 var frontOIDDevice;

 function onInitialized(robot)
 {
     frontOIDDevice = robot.findDeviceById(Albert.EVENT_FRONT_OID);
 }

 function onExecute()
 {
     var frontOID = -1;
     if(frontOIDDevice.e()) // 이벤트가 발생하였다.
     {
         frontOID = frontOIDDevice.read();
     }
 }
 </script>

OID 값을 읽는 디바이스는 이벤트 디바이스라는 것에 주의해야 한다. 이벤트 디바이스는 이벤트가 발생하였을 때만 데이터가 갱신되기 때문에 데이터를 읽기 전에 반드시 이벤트가 발생하였는지 확인해야 한다. 그렇지 않으면 이벤트가 발생한 시점을 알 수가 없기 때문에 현재 발생한 이벤트의 데이터가 아니라 과거에 발생하였던 이벤트의 데이터를 읽을 수도 있다. 이벤트가 발생하였는지는 Device 객체의 e() 함수를 사용하면 확인할 수 있다.

카드를 언제 넣으면 되는지 알려주면 좋을 것 같다. 알버트 로봇은 친절하니까 앞쪽 LED를 켜서 카드를 넣어달라고 표시해 보자. 알버트 로봇에는 앞쪽 LED에 해당하는 디바이스로 COMMAND_FRONT_LED가 있는데, 앞쪽 LED를 켜기 위해서는 1, 끄기 위해서는 0을 입력하면 된다. 카드를 넣으면 LED를 깜박이고 카드를 빼면 꺼지도록 해보자.

 <script type="text/javascript">

 var frontOIDDevice;
 var frontLEDDevice;
 var state = 0;
 var frontLED = 0;
 var count = 0;

 function onInitialized(robot)
 {
     frontOIDDevice = robot.findDeviceById(Albert.EVENT_FRONT_OID);
     frontLEDDevice = robot.findDeviceById(Albert.COMMAND_FRONT_LED);
     frontLEDDevice.write(1);
 }

 function onExecute()
 {
     var frontOID = -1;
     if(frontOIDDevice.e())
     {
         frontOID = frontOIDDevice.read();
         if(frontOID < 0)
         {
             state = 2;
             count = 0;
             frontLEDDevice.write(0);
         }
         else
             state = 1;
     }
     if(state == 1)
     {
         if(count < 10)
             count ++;
         else
         {
             count = 0;
             frontLED = 1 - frontLED;
             frontLEDDevice.write(frontLED);
         }
     }
 }
 </script>

프로그램을 실행하면 앞쪽 LED가 켜지고 그림 2와 같이 전방 OID 센서에 카드를 넣으면 깜박이다가 카드를 빼면 꺼지는 것을 볼 수 있다.

그림 2. 카드 읽기

02. 가위 바위 보

알버트 로봇의 전방 OID 센서와 후방 OID 센서를 사용하여 가위 바위 보 게임을 만들어 보자.

카드를 읽어 가위 바위 보 게임을 하는 프로그램을 작성하시오.

알버트 로봇에는 후방 OID 값을 읽는 디바이스로 EVENT_BACK_OID가 있다. 후방 OID 값을 읽는 디바이스도 이벤트 디바이스이며, -1부터 65535까지의 값을 가질 수 있다. -1은 OID 센서가 코드 패턴 위에 있지 않거나 코드를 읽지 못하였을 때 표시하는 값이며, 정상적으로 코드를 읽은 경우에는 0 이상의 값을 가진다.

지금까지는 디바이스의 데이터를 읽기 위해 Device 객체의 read(), 또는 readAt(index), readArray(data) 등의 함수를 사용하였다. 여기서는 다른 방법을 사용해 보도록 하자.

 <script type="text/javascript">

 function onDeviceDataChanged(device, values, timestamp)
 {
     var frontOID = -1;
     var backOID = -1;
     switch(device.getId())
     {
     case Albert.EVENT_FRONT_OID:
         frontOID = values[0];
         break;
     case Albert.EVENT_BACK_OID:
         backOID = values[0];
         break;
     }
 }
 </script>

onExecute 콜백 함수에서 디바이스의 데이터를 직접 읽은 것이 아니라, onDeviceDataChanged(device, values, timestamp) 콜백 함수를 통해 디바이스의 데이터를 얻었다. onDeviceDataChanged(device, values, timestamp) 콜백 함수는 각 디바이스의 데이터가 갱신될 때마다 호출되며, 이벤트 디바이스 뿐만 아니라 센서 디바이스의 경우에도 사용할 수 있다. 앞에서 이벤트 디바이스의 경우 먼저 이벤트가 발생하였는지 확인하여야 한다고 하였는데, onDeviceDataChanged(device, values, timestamp) 콜백 함수는 데이터가 갱신되었을 때, 즉 이벤트가 발생하였을 때 호출되므로 확인할 필요가 없다.

이제 알버트 로봇의 앞뒤로 카드를 넣으면서 OID 코드 값에 따라 해당 카드가 가위인지 바위인지 보인지를 확인하여 게임을 완성하면 된다.