using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; public class Operation { public int idx, val, op; // 0: ChangeValue // 1: OpenDoor // 2: CloseDoor // 3: Delay // 4: AddValue } public class Initalize : MonoBehaviour { public GameObject[] Boxes; public DoorAnimation[] Door; public NewTextModify[] Label; public GameObject AllBoxes; public int IndexChange = -1, ActionChange = -1, TimeStop = 0, Accumulator = 0; public bool ActionExisted = false, ActionMoving = false; Queue AllOperation = new Queue(); public GameObject TextAreaInstruction, TextAreaInput, CompileButton; public TextMeshProUGUI Instruction, Input, AnotherDisplayAccumulator; Queue AllInput = new Queue(); public int Output; private bool GonnaCompile = true; private int FakeAccumulator = 0; private int[] FakeBoxes = new int[100]; // Start is called before the first frame update void Start() { // public string s = DisplayAccumulator.GetComponent(); for(int i = 0; i < 100; ++i) { Boxes[i] = AllBoxes.gameObject.transform.GetChild(i).gameObject; Label[i] = Boxes[i].GetComponent(); Door[i] = Boxes[i].gameObject.transform.GetChild(0).GetChild(0).GetComponent(); Label[i].Init(i); } } public Operation Cope(int idx, int val, int op) { var Op = new Operation(); Op.idx = idx; Op.val = val; Op.op = op; return Op; } // Put value from Box into Accumulator void Op5(int idx) { AllOperation.Enqueue(Cope(idx, 0, 1)); AllOperation.Enqueue(Cope(100, FakeBoxes[idx], 0)); AllOperation.Enqueue(Cope(0, 100, 3)); AllOperation.Enqueue(Cope(idx, 0, 2)); FakeAccumulator = FakeBoxes[idx]; } // Put value from Accumulator into Box void Op3(int idx) { // Code to animate number to fly up from Accumulator AllOperation.Enqueue(Cope(idx, 0, 1)); AllOperation.Enqueue(Cope(idx, FakeAccumulator, 0)); AllOperation.Enqueue(Cope(0, 100, 3)); AllOperation.Enqueue(Cope(idx, 0, 2)); FakeBoxes[idx] = FakeAccumulator; } // Get value from Box and add into Accumulator void Op1(int idx) { AllOperation.Enqueue(Cope(idx, 0, 1)); AllOperation.Enqueue(Cope(100, FakeBoxes[idx], 4)); AllOperation.Enqueue(Cope(0, 100, 3)); AllOperation.Enqueue(Cope(idx, 0, 2)); FakeAccumulator += FakeBoxes[idx]; } // Get value from Box and subtract from Accumulator void Op2(int idx) { AllOperation.Enqueue(Cope(idx, 0, 1)); AllOperation.Enqueue(Cope(100, -FakeBoxes[idx], 4)); AllOperation.Enqueue(Cope(0, 100, 3)); AllOperation.Enqueue(Cope(idx, 0, 2)); FakeAccumulator -= FakeBoxes[idx]; } void Op901() { // Code to summon number from Input Bracket AllOperation.Enqueue(Cope(100, AllInput.Peek(), 0)); FakeAccumulator = AllInput.Peek(); AllInput.Dequeue(); } void Op902() { // Code to summon number from Accumulator AllOperation.Enqueue(Cope(101, FakeAccumulator, 0)); // Output = FakeAccumulator; } // Just update value of a box from nowhere void UpdateValue(int idx, int value) { AllOperation.Enqueue(Cope(idx, 0, 1)); AllOperation.Enqueue(Cope(idx, value, 0)); AllOperation.Enqueue(Cope(0, 100, 3)); AllOperation.Enqueue(Cope(idx, 0, 2)); FakeBoxes[idx] = value; } void CompileError() { } bool CheckDigit(char c) { return (c >= '0' && c <= '9'); } public void Compile() { if(!GonnaCompile) return; GonnaCompile = false; string InstructionText = Instruction.text; string InputText = Input.text; TextAreaInstruction.gameObject.SetActive(false); CompileButton.gameObject.SetActive(false); TextAreaInput.gameObject.SetActive(false); int InputLength = InputText.Length; for(int i = 0; i < InputLength; ++i) { int idx = i, value = 0; while(idx < InputLength && CheckDigit(InputText[idx])) { value = value * 10 + (InputText[idx] - '0'); ++idx; } if(i != idx) { i = idx - 1; AllInput.Enqueue(value); } } int[] EncodeOperation = new int[100]; int InstructionLength = InstructionText.Length, Counter = 0; for(int i = 0; i < InstructionLength - 2; i += 4) { while(i < InstructionLength && !CheckDigit(InstructionText[i])) ++i; EncodeOperation[Counter] = Convert.ToInt32(InstructionText.Substring(i, 3)); Counter += 1; } int ptr = 0; while(true) { int OpType = EncodeOperation[ptr] / 100; int OpValue = EncodeOperation[ptr] % 100; if(OpType == 0) { break; } else if(OpType == 9) { if(OpValue == 1) Op901(); if(OpValue == 2) Op902(); } else if(OpType == 1) { Op1(OpValue); } else if(OpType == 2) { Op2(OpValue); } else if(OpType == 3) { Op3(OpValue); } else if(OpType == 5) { Op5(OpValue); } else if(OpType == 6) { ptr = OpValue; continue; } else if(OpType == 7 && FakeAccumulator == 0) { ptr = OpValue; continue; } else if(OpType == 8 && FakeAccumulator >= 0) { ptr = OpValue; continue; } ptr += 1; } } // Update is called once per frame void Update() { // Compile(); if(TimeStop > 0) { TimeStop -= 1; return; } if(ActionExisted) { if(!Door[IndexChange].DoorIsMoving) { if(ActionChange == 1) Door[IndexChange].OpenDoor(); else Door[IndexChange].CloseDoor(); } if(Door[IndexChange].TimePassed >= 1.0f) { ActionExisted = false; IndexChange = -1; ActionChange = -1; } } else { if(AllOperation.Count == 0) return; var Current = AllOperation.Peek(); AllOperation.Dequeue(); if(Current.op == 0) { if(Current.idx == 100) { Accumulator = Current.val; AnotherDisplayAccumulator.text = Accumulator.ToString(); return; } else if(Current.idx == 101) { Output = Current.val; return; } Label[Current.idx].ChangeValue(Current.val); } else if(Current.op == 4) { if(Current.idx == 100) { Accumulator += Current.val; AnotherDisplayAccumulator.text = Accumulator.ToString(); return; } } else if(Current.op == 3) { TimeStop = Current.val; } else { ActionExisted = true; IndexChange = Current.idx; ActionChange = Current.op; } } } void LateUpdate() { } }