본문 바로가기
Project/[Unity] 지진 시뮬레이션

[Unity] 지진 시뮬레이션 9 - 유전학습 DNA 생성

by ruki 2024. 4. 1.

유전학습 알고리즘의 DNA를 만들 것이다.


동, 서, 남, 북, 정지를 나타내는 5가지 종류의 값을 가질 수 있는 유전자를 1000개 정도 만들고 0.1초 간격으로 유전자에 있는 행동을 행하도록 만들 것이다.

1. DNA 생성

playerMove 파일에서 DNAsize와 DNA를 추가한다.

public int DNASize;
public int[] DNA;

 

void Start()에서 DNA 배열의 크기와 값을 할당한다.

void Start()
{
    DNA = new int[DNASize];
    for(int i = 0; i < DNA.Length; i++) DNA[i] = Random.Range(0,6);
}

유전정보는 동, 서, 남, 북, 정지로 5가지의 값을 지니므로 처음에는 무작위의 0에서 5 사이의 값을 각 유전자에 할당해 준다.


2. DNA를 통한 이동

먼저 시작시간을 측정한다.

float StartTime;

void Start()
{
    StartTime = Time.time;
}

 

그리고 플레이어가 시작하고 시간이 얼마나 지났는지를 초 단위로 측정한다.

void Update()
{
    int time = (int)(Time.time - StartTime);
}

 

유전자 하나당 얼마만큼의 시간 동안 움직이는 지를 나타내는 함수를 추가한다.

public float ActionInterval;

void Update()
{
	int time = (int)((Time.time - StartTime)/ActionInterval);
}

 

유전자의 값에 따라 이동하도록 만든다.

switch (DNA[time])
{
    case 1:  r = 1;     break;
    case 2:  r = 2;     break;
    case 3:  r = 3;     break;
    case 4:  r = 4;     break;
    default: Move = 0;  break;
}
r : 방향. 동, 서, 남, 북으로 나뉘며 이 값의 방향으로 이동한다.
Move : 이동 여부이다.

 

모든 유전자를 통한 이동을 완료했다면 더 이상 명령을 수행하지 않게 하여 오류를 예방한다.

if(time < DNA.Length)

 

 

전체 코드는 아래와 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playerMove : MonoBehaviour
{
    public int DNASize;
    public float ActionInterval;
    public float playerSpeed;

    public int[] DNA;

    float StartTime;
    int r = 0;

    void Start()
    {
        DNA = new int[DNASize];
        for(int i = 0; i < DNA.Length; i++) DNA[i] = Random.Range(0,6);

        StartTime = Time.time;
    }
    
    void Update()
    {
        int time = (int)((Time.time - StartTime)/ActionInterval);
        int Move = 1;

        if(time < DNA.Length)
        {
            switch (DNA[time])
            {
                case 1:  r = 1;     break;
                case 2:  r = 2;     break;
                case 3:  r = 3;     break;
                case 4:  r = 4;     break;
                default: Move = 0;  break;
            }

            transform.Translate(Move * Vector3.right * playerSpeed * Time.deltaTime);
            
            transform.eulerAngles = Vector3.up * r * 90;
        }
    }
}

잘 작동한다.