-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
#4 chat gpt
- Loading branch information
Showing
17 changed files
with
426 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using UnityEngine.Networking; | ||
using Newtonsoft.Json; | ||
|
||
namespace HackathonA | ||
{ | ||
public class ChatGPTConnection | ||
{ | ||
private readonly JsonSerializerSettings settings = new(); | ||
private readonly string apiKey; | ||
private readonly string apiUrl; | ||
|
||
|
||
public ChatGPTConnection(string apiKey, string apiUrl) | ||
{ | ||
this.apiKey = apiKey; | ||
this.apiUrl = apiUrl; | ||
settings.NullValueHandling = NullValueHandling.Ignore; | ||
} | ||
|
||
public RequestHandler CreateCompletionRequest(ChatGPTDatas.RequestData requestData) | ||
{ | ||
var json = JsonConvert.SerializeObject(requestData, settings); | ||
|
||
byte[] data = System.Text.Encoding.UTF8.GetBytes(json); | ||
|
||
var request = new UnityWebRequest(apiUrl, "POST") | ||
{ | ||
uploadHandler = new UploadHandlerRaw(data), | ||
downloadHandler = new DownloadHandlerBuffer() | ||
}; | ||
request.SetRequestHeader("Authorization", $"Bearer {this.apiKey}"); | ||
request.SetRequestHeader("Content-Type", "application/json"); | ||
|
||
return new RequestHandler(request); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace HackathonA.ChatGPTDatas | ||
{ | ||
[Serializable] | ||
public class RequestData | ||
{ | ||
public string model = "gpt-3.5-turbo"; | ||
public List<Message> messages; | ||
public float? temperature = null; // [0.0 - 2.0] | ||
public float? top_p = null; | ||
public int? n = null; | ||
public bool? stream = null; | ||
public List<string> stop = null; | ||
public int? max_tokens = null; | ||
public float? presence_penalty = null; | ||
public float? frequency_penalty = null; | ||
public Dictionary<int, int> logit_bias = null; | ||
public string user = null; | ||
} | ||
|
||
[Serializable] | ||
public class Message | ||
{ | ||
public string role; | ||
public string content; | ||
} | ||
|
||
[Serializable] | ||
public class Usage | ||
{ | ||
public int prompt_tokens; | ||
public int completion_tokens; | ||
public int total_tokens; | ||
} | ||
|
||
[Serializable] | ||
public class Choice | ||
{ | ||
public Message message; | ||
public string finish_reason; | ||
public int index; | ||
} | ||
|
||
[Serializable] | ||
public class ResponseData | ||
{ | ||
public string id; | ||
public string @object; | ||
public int created; | ||
public string model; | ||
public Usage usage; | ||
public List<Choice> choices; | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using Unity.VisualScripting; | ||
using UnityEngine; | ||
|
||
namespace HackathonA | ||
{ | ||
public class DebugLoger | ||
{ | ||
[Conditional("UNITY_EDITOR"), Conditional("DEVELOPMENT_BUILD")] | ||
public static void LogError(string error) | ||
{ | ||
UnityEngine.Debug.LogError(error); | ||
} | ||
|
||
[Conditional("UNITY_EDITOR"), Conditional("DEVELOPMENT_BUILD")] | ||
public static void Log(string error) | ||
{ | ||
UnityEngine.Debug.Log(error); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
using System.Collections.Generic; | ||
using Cysharp.Threading.Tasks; | ||
using HackathonA.ChatGPTDatas; | ||
|
||
namespace HackathonA | ||
{ | ||
public class EnemyAI | ||
{ | ||
public int DefaultPhysicalAttack { get; set; } = 20; | ||
public int DefaultMagicAttack { get; set; } = 20; | ||
public int DefaultRecoveryPoint { get; set; } = 15; | ||
public int DefaultActionOnError { get; set; } = 0; | ||
|
||
private const string API_URL = "https://api.openai.com/v1/chat/completions"; | ||
private readonly string _apiKey; | ||
private readonly ChatGPTConnection _chatGPTConnection; | ||
|
||
// ChatGPTに入力するメッセージのリスト(過去の内容も一緒に渡すためリスト) | ||
private List<Message> _messages; | ||
|
||
public EnemyAI(string apiKey) | ||
{ | ||
_apiKey = apiKey; | ||
_messages = new List<Message>() | ||
{ | ||
new Message(){role = "system", content = GenerateSystemMessage()}, | ||
}; | ||
_chatGPTConnection = new ChatGPTConnection(_apiKey, API_URL); | ||
} | ||
|
||
private string GenerateSystemMessage() | ||
{ | ||
return GenerateSystemMessage(DefaultPhysicalAttack, DefaultMagicAttack, DefaultRecoveryPoint); | ||
} | ||
|
||
private string GenerateSystemMessage(int physicalAttack, int mamgicAttack, int recoveryPoint) | ||
{ | ||
return @$"Please answer with an integer from 0-4 for your action | ||
You can take the following actions | ||
0: Physical attack. {physicalAttack} damage | ||
1: Magic attack. {mamgicAttack} damage | ||
2: Recovery. {recoveryPoint} recovery | ||
3: Physical Counter. bounce back if opponen's action is Physical attack | ||
4: Magic counter. bounce back if opponent's action is Magic attack | ||
Input example: Your HP is currently 1000 and your opponent's HP is 1000 | ||
Output example: 0"; | ||
} | ||
|
||
// 敵の設定 | ||
public void Set(int physicalAttack, int mamgicAttack, int recoveryPoint) | ||
{ | ||
_messages = new List<Message>() | ||
{ | ||
new Message(){role = "system", content = GenerateSystemMessage(physicalAttack, mamgicAttack, recoveryPoint)}, | ||
}; | ||
} | ||
|
||
/// <summary> | ||
/// ChatGPTとの通信を開始 | ||
/// </summary> | ||
/// <param name="playerHP">プレイヤーのHP</param> | ||
/// <param name="enemyHP">敵のHP</param> | ||
/// <returns>アクションのタイプ(0-4)。エラー時にはDefaultActionOnErrorで設定した値が返ってくる</returns> | ||
public async UniTask<int> GetEnemyActionAsync(int playerHP, int enemyHP) | ||
{ | ||
string currentMessage = $"Currently, your HP is {enemyHP} and your opponent's HP is {playerHP}.\nChoose from the options above and respond with the corresponding number."; | ||
DebugLoger.Log(currentMessage); | ||
_messages.Add(new Message() { role = "user", content = currentMessage }); | ||
|
||
using var request = _chatGPTConnection.CreateCompletionRequest(new RequestData() { messages = _messages }); | ||
|
||
await request.SendAsync(); | ||
|
||
// エラーがあった場合は、それをコンソールに出力 | ||
if (request.IsError) | ||
{ | ||
DebugLoger.LogError(request.Error); | ||
return DefaultActionOnError; | ||
} | ||
else | ||
{ | ||
var responseMessage = request.Response.choices[0].message.content; | ||
DebugLoger.Log($"ChatGPT replied '{responseMessage}'"); | ||
|
||
// 文字列を数値に変換 | ||
if (int.TryParse(responseMessage[..1], out var action)) | ||
{ | ||
if (0 <= action && action <= 4) | ||
{ | ||
return action; | ||
} | ||
else | ||
{ | ||
return DefaultActionOnError; | ||
} | ||
} | ||
else | ||
{ | ||
|
||
DebugLoger.LogError($"Unable to parse '{responseMessage}'"); | ||
return DefaultActionOnError; | ||
} | ||
} | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using UnityEngine.Networking; | ||
using Newtonsoft.Json; | ||
using Cysharp.Threading.Tasks; | ||
using System; | ||
|
||
namespace HackathonA | ||
{ | ||
public class RequestHandler: IDisposable | ||
{ | ||
public bool IsCompleted { get; private set; } | ||
public bool IsError => Error != null; | ||
public string Error { get; private set; } | ||
public ChatGPTDatas.ResponseData Response { get; private set; } | ||
|
||
private UnityWebRequest request; | ||
|
||
public RequestHandler(UnityWebRequest request) | ||
{ | ||
this.request = request; | ||
} | ||
|
||
public async UniTask SendAsync() | ||
{ | ||
using (request) | ||
{ | ||
await request.SendWebRequest(); | ||
|
||
if (request.result != UnityWebRequest.Result.Success) | ||
{ | ||
Error = "[ChatGPTConnection] " + request.error + "\n\n" + request.downloadHandler.text; | ||
} | ||
else | ||
{ | ||
Response = JsonConvert.DeserializeObject<ChatGPTDatas.ResponseData>(request.downloadHandler.text); | ||
} | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
request?.Dispose(); | ||
} | ||
} | ||
} |
Oops, something went wrong.