Beispiel #1
0
    public void Step()
    {
        if (CurrentTime < 0)
        {
            return;
        }
        ++CurrentTime;

        // Do emulation
        foreach (int id in Photons.Keys.ToList())
        {
            if (!Photons.ContainsKey(id))
            {
                continue;
            }
            Photon p = Photons[id];

            // update position
            p.Advance();

            if (!IsInBound(p.position))
            {
                Photons.Remove(id);
            }
            else
            {
                // Find out what is there
                Cell there = this[p.position];
                switch (there.type)
                {
                case CellType.EMPTY:
                    break;

                case CellType.MIRROR:
                    switch (there.param)
                    {
                    case 0:                                     // -
                        if (p.direction.y == 0)
                        {
                            Photons.Remove(id);
                        }
                        else
                        {
                            p.Reflect();
                        }
                        break;

                    case 1:                                     // /
                        if (p.direction.y == 0)
                        {
                            p.TurnLeft();
                        }
                        else
                        {
                            p.TurnRight();
                        }
                        break;

                    case 2:                                     // |
                        if (p.direction.x == 0)
                        {
                            Photons.Remove(id);
                        }
                        else
                        {
                            p.Reflect();
                        }
                        break;

                    case 3:                                     // \ 
                        if (p.direction.x == 0)
                        {
                            p.TurnLeft();
                        }
                        else
                        {
                            p.TurnRight();
                        }
                        break;
                    }
                    break;

                case CellType.GENERATOR:
                    GeneratePhoton(there.param, p.position, p.direction);
                    p.Reflect();
                    break;

                case CellType.SLUICE:
                    p.SetDirection(DirectionIdToVector(there.param));
                    break;

                case CellType.PROCESS:
                    GeneratePhoton(p.value, p.position, DirRotateCCW90(p.direction));
                    GeneratePhoton(p.value, p.position, DirRotateCW90(p.direction));
                    Photons.Remove(id);
                    break;

                case CellType.TARPIT:
                    // I am stuck in the pit
                    if (p.direction == Vector2Int.zero)
                    {
                        break;
                    }
                    // I come to the pit
                    if (there.tarpitId == 0)
                    {
                        // No others are in the pit
                        p.SetDirection(Vector2Int.zero);                                 // I'm stuck
                        this[p.position] = there.SetTarpitId(id);
                    }
                    else
                    {
                        // Someone is in the pit
                        int thereValue = Photons[there.tarpitId].value;
                        int newValue;
                        switch (there.param)
                        {
                        case 0: newValue = thereValue + p.value; break;

                        case 1: newValue = thereValue - p.value; break;

                        case 2: newValue = thereValue * p.value; break;

                        case 3: newValue = p.value == 0 ? 0 : thereValue / p.value; break;

                        case 4: newValue = p.value == 0 ? 0 : thereValue % p.value; break;

                        default: newValue = 0; break;
                        }
                        GeneratePhoton(newValue, p.position, p.direction);
                        Photons.Remove(id);
                        Photons.Remove(there.tarpitId);
                        this[p.position] = there.SetTarpitId(0);
                        //Debug.Log($"Photon id {there.tarpitId} in tarpit removed");
                    }
                    break;

                case CellType.INPUT:
                    Photons.Remove(id);
                    break;

                case CellType.OUTPUT:
                    output.Add(p.value);
                    Photons.Remove(id);
                    break;

                case CellType.WALL:
                    Photons.Remove(id);
                    break;
                }
            }

            if (Photons.ContainsKey(id))
            {
                Photons[id] = p;
                //Debug.Log($"Photon id {id} updated to {p}");
            }
            else
            {
                //Debug.Log($"Photon id {id} removed");
            }
        }

        // Generate photon from input
        if (CurrentTime % InputSpeed == 0)
        {
            int id = InputIndex;
            if (id < input.Count)
            {
                GeneratePhoton(input[id], inputPosition, inputDirection);
            }
        }
    }