using TMPro; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; using MySql.Data.MySqlClient; using ArabicSupport; using System.Text.RegularExpressions; using UnityEngine.Networking; using System.Collections; using System.Collections.Generic; using System.Linq; public class pengolahsoal : MonoBehaviour { public TextAsset soalpretest; public GameObject iconBenar; public GameObject iconSalah; private string[] soal; private string[,] soalBag; string FixArabicInMixedText(string input) { if (string.IsNullOrEmpty(input)) return ""; // Hapus karakter tak terlihat yang bisa bikin rusak (optional) input = Regex.Replace(input, @"[\u200E\u200F\u202A-\u202E]", ""); // Deteksi blok teks Arab (termasuk harakat dan ligatur) return Regex.Replace( input, @"[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF\u064B-\u0655\u06D6-\u06ED]+", match => ArabicFixer.Fix(match.Value) ); } int indexSoal; int maxSoal; bool ambilSoal; char kunciJ; //acak soal //bool[] soalSelesai; private int[] soalAcak; //acaksoal //komponen UI public TextMeshProUGUI txtSoal, txtOpsiA, txtOpsiB, txtOpsiC, txtOpsiD; bool isHasil; private float durasi; public float durasiPenilaian; int jwbBenar, jwbSalah; //float nilai; int nilai; // ubah ke int public GameObject panel; public GameObject imgPenilaian, imgHasil; public TextMeshProUGUI txtHasil; //pause [Header("Obj GUI")] public GameObject Gui_Pause; public GameObject Gui_Transisi; // Variabel untuk UiControl public bool IsTransisi, IsTidakPerlu; string SaveNamaScene; //pause public bool GameAktif; private bool skorTersimpan = false; public TextMeshProUGUI txtPesanAwal; private void Awake() { if (IsTransisi && IsTidakPerlu) { gameObject.SetActive(false); } } // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { durasi = durasiPenilaian; soal = soalpretest.ToString().Split('#'); //soalSelesai = new bool[soal.Length]; //acaksoal soalBag = new string[soal.Length, 6]; maxSoal = soal.Length; OlahSoal(); AcakSoal(); //acak soal ambilSoal = true; TampilkanSoal(); if (GlobalUser.Instance != null) { Debug.Log("User ID ditemukan: " + GlobalUser.Instance.userId); } else { Debug.LogWarning("GlobalUser.Instance NULL, pastikan diinisialisasi!"); } print(soalBag[1, 3]); //acaksoal // 👇 Panggil pesan muncul 1 detik StartCoroutine(TampilkanPesanSementara("Kerjakan pretest untuk melihat kemampuanmu", 3f)); } private void OlahSoal() { for (int i = 0; i < soal.Length; i++) { string[] tempSoal = soal[i].Split('+'); //for (int j = 0; j < tempSoal.Length; j++) //{ // soalBag[i, j] = tempSoal[j]; // // continue; //} //continue; for (int j = 0; j < 6; j++) { if (j < tempSoal.Length) soalBag[i, j] = tempSoal[j]; else soalBag[i, j] = ""; // kalau datanya kurang, isi kosong biar gak error } } } //fungsi untuk mengacak soal satu kali diawal private void AcakSoal() { soalAcak = new int[maxSoal]; for (int i = 0; i < maxSoal; i++) { soalAcak[i] = i; } for (int i = 0; i < maxSoal; i++) { int rnd = Random.Range(i, maxSoal); int temp = soalAcak[i]; soalAcak[i] = soalAcak[rnd]; soalAcak[rnd] = temp; } } private struct OpsiJawaban { public string teks; public char huruf; // A, B, C, D public bool isBenar; } private void TampilkanSoal() { if (indexSoal < maxSoal && ambilSoal) { int currentIndex = soalAcak[indexSoal]; txtSoal.text = FixArabicInMixedText(soalBag[currentIndex, 0]); // Ambil opsi dan kunci jawaban string opsiA = soalBag[currentIndex, 1]; string opsiB = soalBag[currentIndex, 2]; string opsiC = soalBag[currentIndex, 3]; string opsiD = soalBag[currentIndex, 4]; char jawabanBenar = soalBag[currentIndex, 5][0]; // Buat list opsi List opsiList = new List { new OpsiJawaban { teks = opsiA, huruf = 'A', isBenar = (jawabanBenar == 'A') }, new OpsiJawaban { teks = opsiB, huruf = 'B', isBenar = (jawabanBenar == 'B') }, new OpsiJawaban { teks = opsiC, huruf = 'C', isBenar = (jawabanBenar == 'C') }, new OpsiJawaban { teks = opsiD, huruf = 'D', isBenar = (jawabanBenar == 'D') } }; // Acak list opsiList = opsiList.OrderBy(x => Random.value).ToList(); // Tampilkan ke UI txtOpsiA.text = FixArabicInMixedText(opsiList[0].teks); txtOpsiB.text = FixArabicInMixedText(opsiList[1].teks); txtOpsiC.text = FixArabicInMixedText(opsiList[2].teks); txtOpsiD.text = FixArabicInMixedText(opsiList[3].teks); // Tentukan kunci jawaban berdasarkan posisi baru if (opsiList[0].isBenar) kunciJ = 'A'; else if (opsiList[1].isBenar) kunciJ = 'B'; else if (opsiList[2].isBenar) kunciJ = 'C'; else if (opsiList[3].isBenar) kunciJ = 'D'; ambilSoal = false; } } public void Opsi(string opsiHuruf) { CheckJawaban(opsiHuruf[0]); if (indexSoal == maxSoal - 1) { isHasil = true; } else { indexSoal++; ambilSoal = true; } panel.SetActive(true); } private int HitungNilai() { return nilai = Mathf.RoundToInt((float)jwbBenar / maxSoal * 100); // ubah ke int } public TextMeshProUGUI txtPenilaian; private void CheckJawaban(char huruf) { string penilaian; // Sembunyikan dulu ikon iconBenar.SetActive(false); iconSalah.SetActive(false); if (huruf.Equals(kunciJ)) { penilaian = "Benar!"; jwbBenar++; KumpulanSuara.instance.Panggil_Sfx(7); iconBenar.SetActive(true); // tampilkan gambar benar } else { penilaian = "Salah!"; jwbSalah++; KumpulanSuara.instance.Panggil_Sfx(8); iconSalah.SetActive(true); // tampilkan gambar salah } txtPenilaian.text = penilaian; } // Update is called once per frame void Update() { if (panel.activeSelf) { durasiPenilaian -= Time.deltaTime; if (isHasil) { imgPenilaian.SetActive(true); imgHasil.SetActive(true); if (durasiPenilaian <= 0) { txtHasil.text = "Jumlah benar: " + jwbBenar + "\nJumlah Salah: " + jwbSalah + "\n\nNilai: " + HitungNilai(); imgPenilaian.SetActive(false); imgHasil.SetActive(true); if (!skorTersimpan) { //Debug.Log("Menyimpan skor ke database..."); SimpanSkorKeDatabase(); skorTersimpan = true; } durasiPenilaian = 0; } } else { imgPenilaian.SetActive(true); imgHasil.SetActive(false); if (durasiPenilaian <= 0) { panel.SetActive(false); durasiPenilaian = durasi; TampilkanSoal(); } } } } //btn pause public void Btn_Pause(bool pause) { GameAktif = !pause; Gui_Pause.SetActive(pause); } // Fungsi dari UiControl public void btn_suara(int id) { KumpulanSuara.instance.Panggil_Sfx(0); } public void Btn_Pindah(string nama) { SceneManager.LoadScene(nama); } public void Btn_KeluarSetelahSimpan() { if (!skorTersimpan) { SimpanSkorKeDatabase(); skorTersimpan = true; } SceneManager.LoadScene("MainMenu"); } public void pindah() { SceneManager.LoadScene(SaveNamaScene); } public void Btn_Restart() { // Reset semua variabel ke kondisi awal indexSoal = 0; jwbBenar = 0; jwbSalah = 0; nilai = 0; durasiPenilaian = durasi; isHasil = false; ambilSoal = true; // Tampilkan soal pertama kembali TampilkanSoal(); // Sembunyikan semua UI yang berkaitan dengan restart atau hasil panel.SetActive(false); imgPenilaian.SetActive(false); imgHasil.SetActive(false); // Reload scene untuk memastikan semua komponen di-reset dengan benar SceneManager.LoadScene(SceneManager.GetActiveScene().name); } private void SimpanSkorKeDatabase() { StartCoroutine(SimpanSkorCoroutine()); } private IEnumerator SimpanSkorCoroutine() { int idUser = GlobalUser.Instance != null ? GlobalUser.Instance.userId : -1; int nilai = HitungNilai(); if (idUser == -1) { Debug.LogWarning("ID user tidak ditemukan, data tidak dikirim."); yield break; } WWWForm form = new WWWForm(); form.AddField("id", idUser); form.AddField("pretest", nilai); form.AddField("api", "s_pretest"); using (UnityWebRequest www = UnityWebRequest.Post("https://wifiapi.wazzgroup.com/api.php", form)) { yield return www.SendWebRequest(); if (www.result != UnityWebRequest.Result.Success) { Debug.LogError("Gagal kirim skor: " + www.error); } else { Debug.Log("Skor berhasil disimpan ke server: " + www.downloadHandler.text); } } } // 👇 Coroutine untuk pesan sementara private IEnumerator TampilkanPesanSementara(string pesan, float durasi) { txtPesanAwal.text = pesan; txtPesanAwal.gameObject.SetActive(true); yield return new WaitForSeconds(durasi); txtPesanAwal.gameObject.SetActive(false); } //// Fungsi simpan skor ke MySQL //private void Koneksi() //{ // connectionString = "Server=127.0.0.1; Database=game; User=root; Password=; Charset=utf8;"; // MS_Connection = new MySqlConnection(connectionString); // MS_Connection.Open(); //} //private void SimpanSkorKeDatabase() //{ // try // { // Koneksi(); // int idUser = GlobalUser.Instance != null ? GlobalUser.Instance.userId : -1; // float nilai = HitungNilai(); // if (idUser == -1) // { // Debug.LogWarning("ID user tidak ditemukan, data tidak disimpan."); // return; // } // string query = "UPDATE score SET pretest = @nilai WHERE id = @id"; // MS_Command = new MySqlCommand(query, MS_Connection); // MS_Command.Parameters.AddWithValue("@id", idUser); // MS_Command.Parameters.AddWithValue("@nilai", nilai); // int rows = MS_Command.ExecuteNonQuery(); // Debug.Log("Rows affected: " + rows); // if (rows == 0) // { // Debug.LogWarning("Tidak ada baris yang diperbarui. Mungkin ID user tidak ditemukan di tabel score."); // } // MS_Connection.Close(); // } // catch (MySqlException ex) // { // Debug.LogError("Gagal menyimpan skor: " + ex.Message); // } //} public void Btn_LanjutGame() { PlayerPrefs.SetInt("pretest_selesai", 1); PlayerPrefs.Save(); SceneManager.LoadScene("MainMenu"); } }