public void AI_DeepLearning_NoFeedback() { //검색한 행동의 타이머가 끝날 때마다 수행한다. if (isbehaveCoolTimeOn) { //거리 계산 curDist = Vector3.Distance(transform.position, enemyController.playerTransform.position); //현재 상황(캐릭터와 Target까지의 벡터)에서 Q값이 가장 높다고 예측된 행동 검색 sitCUR = enemyCollector.SearchGoodSitCUR(curDist, enemyController.GET_enemyAIEngine.angleComp, true, false); //검색한 행동의 시간동안 타이머 작동 StartCoroutine(enemyController.enemyCoolTimer.Timer(sitCUR._time, (input) => { isbehaveCoolTimeOn = input; }, true)); } //검색한 행동을 수행한다. //공격 쿨타임이 완료되었고 공격을 하려는 경우 if (sitCUR._doing.vecZ != 0 && _enemyAIEngine._PUB_enemy_Is_ON_CoolTime[1]) { //검색한 공격 행동 수행 behaveList_Attack[sitCUR._doing.vecZ](); } //검색한 이동 및 회전 수행 behaveList_Move[sitCUR._doing.vecX](); behaveList_Rotate[sitCUR._doing.vecY](); }
//비교를 위해 추가된 예전 버전의 Bigdata함수 public void __OLD__AI_DeepLearning__BigData_Ver() { ////임시로 추가한 것, P을 누르면 모든 데이터 수집 개체 삭제 및 데이터 저장 //if (Input.GetKeyDown(KeyCode.P)) //{ // Destroy(gameObject); //} //20190606 임시 //if (behaveCount_FOR_PPT == 100) //{ // enemyCollector.listScore_FOR_PPT.Add(scoreCount_FOR_PPT); // Destroy(gameObject); //} float dummy = 0f; float curDist = Vector3.Distance(transform.position, enemyController.playerTransform.position); if (beforeBehaveID == "N_U_L_L") { beforeBehaveID = "NULL"; beforeDist = curDist; beforeAngleComp = enemyController.GET_enemyAIEngine.angleComp; beforeVec2 = new Vector2(transform.position.x, transform.position.z); } if (isbehaveCoolTimeOn) { //20190606 임시 behaveCount_FOR_PPT++; float time = sitCUR._time; behaveID = System.DateTime.Now.ToString() + ": " + gameObject.GetInstanceID().ToString(); //if (beforeDist > curDist) isCloser = true; //20190606 임시 SituationCUR cur_FOR_PPT = new SituationCUR(behaveID, beforeVec2.x, beforeVec2.y, beforeDist, beforeAngleComp, __OLD__forSave, time); SituationAFT aft_FOR_PPT = new SituationAFT(behaveID, transform.position.x, transform.position.z, curDist, enemyController.GET_enemyAIEngine.angleComp, beforeBehaveID, getDamagedCounter, hitCounter, false); enemyCollector.listSitCUR.Add(cur_FOR_PPT); enemyCollector.listSitAFT.Add(aft_FOR_PPT); sitCUR = enemyCollector.SearchGoodSitCUR(curDist, enemyController.GET_enemyAIEngine.angleComp, false, false); //DataBase에서 긁어온 정보의 time동안 행동한다. StartCoroutine(enemyController.enemyCoolTimer.Timer(sitCUR._time, (input) => { isbehaveCoolTimeOn = input; }, true, (input) => { dummy = input; })); //20190606 임시 //AI_Score_Cal(false, cur_FOR_PPT, aft_FOR_PPT); //AI_Score_Cal(hitCounter); beforeBehaveID = behaveID; beforeDist = curDist; beforeAngleComp = enemyController.GET_enemyAIEngine.angleComp; beforeVec2 = new Vector2(transform.position.x, transform.position.z); hitCounter = 0; getDamagedCounter = 0; } //1차적으로 일반 공격만 생각하도록 한다. //공격 쿨타임도 끝났고 공격을 하려는 경우 if (_enemyAIEngine._PUB_enemy_Is_ON_CoolTime[1] && sitCUR._doing.vecZ != 0 && sitCUR._doing.vecZ < behaveList_Attack.Count) { //주어진 공격 수행 behaveList_Attack[sitCUR._doing.vecZ](); } //주어진 이동 수행 behaveList_Move[sitCUR._doing.vecX](); //주어진 회전 수행 behaveList_Rotate[sitCUR._doing.vecY](); }
//강화학습을 위한 형태로 개조됨 //강화학습 데이터대로 행동했지만 결과가 좋지 못한 경우(행동 점수 <= 0) 임의 행동을 한 뒤 별도의 DB에 저장할 수 있도록 한다. //별도의 DB에 저장된 데이터를 일단 수동으로 학습하도록 한다.(프로그래머가 수동으로 변수나 코드를 바꿔줘야 하는 방식) public void AI_DeepLearning__BigData_Ver() { if (isbehaveCoolTimeOn) { curDist = Vector3.Distance(transform.position, enemyController.playerTransform.position); isHPLOW = true; sitCUR = enemyCollector.SearchGoodSitCUR(curDist, enemyController.GET_enemyAIEngine.angleComp, isHPLOW, false); ////디버깅 //if (sitCUR._doing.vecZ != 0) //{ // behaveCount_FOR_PPT++; //} bool isCloser = false; behaveID = System.DateTime.Now.ToString() + ": " + gameObject.GetInstanceID().ToString(); if (beforeDist > curDist) { isCloser = true; } if (simpleSpining == 1) { sitCUR._doing.vecX = 1; sitCUR._doing.vecY = 1; sitCUR._doing.vecZ = 0; } else { //이전 상황과 행동에 대한 결과 저장 IntVector3 forSave = new IntVector3(sitCUR._doing.vecX, sitCUR._doing.vecY, sitCUR._doing.vecZ); SituationCUR cur_FOR_PPT = new SituationCUR(behaveID, beforeVec2.x, beforeVec2.y, beforeDist, beforeAngleComp, forSave, sitCUR._time); SituationAFT aft_FOR_PPT = new SituationAFT(behaveID, transform.position.x, transform.position.z, curDist, enemyController.GET_enemyAIEngine.angleComp, beforeBehaveID, 0, hitCounter, isCloser); AI_Score_Cal(hitCounter); AI_Score_Cal(isHPLOW, cur_FOR_PPT, aft_FOR_PPT); aft_FOR_PPT._beforeDB = scoreCount_FOR_PPT; if (rewardCount <= 1) { sitCUR = enemyCollector.SearchGoodSitCUR(curDist, enemyController.GET_enemyAIEngine.angleComp, isHPLOW, true); } if (forSave.vecZ != 0) { enemyCollector.listSitCUR.Add(cur_FOR_PPT); enemyCollector.listSitAFT.Add(aft_FOR_PPT); } if (Random.Range(0.0f, 1.0f) < sigma) { sitCUR._doing.InitIntVector3((int)(Random.Range(0, 2)), (int)(Random.Range(0, 6)), (int)(Random.Range(0, 3))); sitCUR._time = Random.Range(0.5f, 1.5f); } rewardCount = 0; } //DataBase에서 긁어온 정보의 time동안 행동한다. StartCoroutine(enemyController.enemyCoolTimer.Timer(sitCUR._time, (input) => { isbehaveCoolTimeOn = input; }, true)); beforeBehaveID = behaveID; beforeDist = curDist; beforeAngleComp = enemyController.GET_enemyAIEngine.angleComp; beforeVec2 = new Vector2(transform.position.x, transform.position.z); hitCounter = 0; getDamagedCounter = 0; } //공격 쿨타임도 끝났고 공격을 하려는 경우 if (sitCUR._doing.vecZ != 0) { if (_enemyAIEngine._PUB_enemy_Is_ON_CoolTime[1])// && sitCUR._doing.vecZ < behaveList_Attack.Count && curDist < 30f) { //주어진 공격 수행 behaveList_Attack[sitCUR._doing.vecZ](); } } //주어진 이동 및 회전 수행 behaveList_Move[sitCUR._doing.vecX](); behaveList_Rotate[sitCUR._doing.vecY](); ////디버깅 용도 //if (deleteIt) //{ // enemyCollector.listScore_FOR_PPT.Add(scoreCount_FOR_PPT); // Destroy(gameObject); //} //if ((Input.GetKeyDown(KeyCode.P) || behaveCount_FOR_PPT < -1 || behaveCount_FOR_PPT >= 49) && simpleSpining != 1) // deleteIt = true; }
//행동 점수의 총합을 구하기 위한 함수 //후에 행동점수를 결정하는 단일함수로 사용할 예정 private void AI_Score_Cal(bool isHPLOW, SituationCUR cur, SituationAFT aft) { int resultScore = aft._hitCounter; //체력 절반 이하, 절반 초과에 따라 다른 행동점수 가산점 OR 불이익 정책 사용 if (!isHPLOW) { if (cur._doing.vecX != 0 && cur._doing.vecY != 0) { resultScore += (aft._hitCounter * 7); } if (cur._dist >= 30f && cur._doing.vecX != 0 && cur._doing.vecY != 0 && aft._closer == true && aft._dist + 10f < cur._dist) { resultScore += 10; } if (cur._dist >= 30f && cur._doing.vecX == 0 && cur._doing.vecY == 0 && aft._closer == false && aft._dist >= cur._dist) { resultScore -= (int)(20 + aft._dist); } if (cur._dist < 30f && aft._hitCounter > 0) { resultScore += 40; } if (aft._hitCounter == 0 && cur._doing.vecZ != 0) { aft._beforeDB -= 10; } } else { if (cur._doing.vecX != 0 && cur._doing.vecY != 0) { resultScore--; } if (aft._dist > cur._dist) { resultScore++; } if (cur._dist >= 30f && cur._doing.vecX == 0 && cur._doing.vecY == 0 && aft._closer == true && aft._dist <= cur._dist) { resultScore -= 3; } if (cur._dist >= 30f && cur._doing.vecX != 0 && cur._doing.vecY != 0 && aft._closer == false && aft._dist > cur._dist) { resultScore += 3; } if (cur._dist <= 30f && cur._doing.vecX == 0 && cur._doing.vecY == 0 && aft._closer == true && aft._dist <= cur._dist) { resultScore -= 3; } if (cur._dist <= 30f && cur._doing.vecX != 0 && cur._doing.vecY != 0 && aft._closer == true && aft._dist > cur._dist) { resultScore += 3; } } rewardCount += resultScore; }