489 lines
12 KiB
C#
489 lines
12 KiB
C#
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<OpsiJawaban> opsiList = new List<OpsiJawaban>
|
|
{
|
|
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");
|
|
}
|
|
|
|
}
|