Exemplo n.º 1
0
    static FastIndex()
    {
        var directions = EnumArray <HexNeighborDirection> .Values;

        NeighborMap = new FastIndex[85 * directions.Length];
        MirrorMap   = new FastIndex[85];
        for (byte i = 0; i < 85; i++)
        {
            var slowIndex   = Index.CalculateFromByte(i);
            int offsetStart = i * directions.Length;

            for (int j = 0; j < directions.Length; j++)
            {
                HexNeighborDirection direction = directions[j];
                FastIndex            neighbor  = FastIndex.Invalid;
                if (slowIndex.TryGetNeighbor(direction, out Index slowNeighbor))
                {
                    neighbor = new FastIndex(slowNeighbor);
                }
                NeighborMap[offsetStart + j] = neighbor;
            }

            MirrorMap[i] = CalculateMirror(FromByte(i));
        }
    }
Exemplo n.º 2
0
 public FastIndex?GetNeighborAt(HexNeighborDirection direction)
 {
     if (TryGetNeighbor(direction, out FastIndex index))
     {
         return(index);
     }
     return(null);
 }
Exemplo n.º 3
0
 public                       Index this[HexNeighborDirection dir]
 {
     get
     {
         if (TryGetNeighbor(dir, out Index neighbor))
         {
             return(neighbor);
         }
         return(Index.invalid);
     }
 }
Exemplo n.º 4
0
 public bool TryGetNeighbor(HexNeighborDirection direction, out FastIndex index)
 {
     if (IsInBounds)
     {
         index = NeighborMap[HexId * 6 + (int)direction];
         return(index.IsInBounds);
     }
     else
     {
         index = Invalid;
         return(false);
     }
 }
Exemplo n.º 5
0
    static IEnumerable <FastIndex> GenerateRay(FastIndex start, HexNeighborDirection direction)
    {
        FastIndex target = start;

        for (int j = 0; j < 20; j++)
        {
            target = target[direction];
            if (!target.IsInBounds)
            {
                break;
            }

            yield return(target);
        }
    }
Exemplo n.º 6
0
    public void UpdateEdge(HexNeighborDirection toUpdate)
    {
#if UNITY_EDITOR
        Material mat = new Material(meshRenderer.sharedMaterial);
        mat.SetFloat(
            name: $"_Edge{(int)toUpdate}",
            value: Mathf.Abs(meshRenderer.sharedMaterial.GetFloat($"_Edge{(int)toUpdate}") - 1).Floor()
            );
        meshRenderer.material = mat;
#elif !UNITY_EDITOR
        meshRenderer.material.SetFloat(
            name: $"_Edge{(int)toUpdate}",
            value: Mathf.Abs(meshRenderer.material.GetFloat($"_Edge{(int)toUpdate}") - 1).Floor()
            );
#endif
    }
Exemplo n.º 7
0
    public void ShiftComprehensivetest([ValueSource(typeof(PrecomputedMoveData), nameof(PrecomputedMoveData.AllDirections))] HexNeighborDirection direction)
    {
        for (byte b = 0; b < 85; b++)
        {
            FastIndex index    = FastIndex.FromByte(b);
            var       original = new BitsBoard();
            original[index] = true;

            var expected = index[direction];
            var shifted  = original.Shift(direction);
            if (expected.IsInBounds)
            {
                AssertOnlyIndexSet(shifted, expected);
            }
            else
            {
                AssertNoIndicesSet(shifted);
            }
        }
    }
Exemplo n.º 8
0
    private (int row, int col) GetOffsetInDirection(bool isEven, HexNeighborDirection direction)
    {
        switch (direction)
        {
        case HexNeighborDirection.Up:
            return(2, 0);

        case HexNeighborDirection.UpRight:
            return(isEven ? (1, 1) : (1, 0));

        case HexNeighborDirection.DownRight:
            return(isEven ? (-1, 1) : (-1, 0));

        case HexNeighborDirection.Down:
            return(-2, 0);

        case HexNeighborDirection.DownLeft:
            return(isEven ? (-1, 0) : (-1, -1));

        case HexNeighborDirection.UpLeft:
            return(isEven ? (1, 0) : (1, -1));
        }
        return(0, 0);
    }
Exemplo n.º 9
0
 public Hex GetNeighborAt(Index hexIndex, HexNeighborDirection direction)
 {
     (int row, int col)offsets = GetOffsetInDirection(hexIndex.row % 2 == 0, direction);
     return(GetHexIfInBounds(hexIndex.row + offsets.row, hexIndex.col + offsets.col));
 }
Exemplo n.º 10
0
    public static void AddAllPossiblePawnMoves(List <FastMove> moves, FastIndex start, Team team, FastBoardNode boardNode, bool generateQuiet = true)
    {
        Team enemy = team.Enemy();

        HexNeighborDirection leftAttackDir   = HexNeighborDirection.UpLeft;
        HexNeighborDirection leftPassantDir  = HexNeighborDirection.DownLeft;
        HexNeighborDirection rightAttackDir  = HexNeighborDirection.UpRight;
        HexNeighborDirection rightPassantDir = HexNeighborDirection.DownRight;
        HexNeighborDirection forwardDir      = HexNeighborDirection.Up;

        if (team != Team.White)
        {
            leftAttackDir   = HexNeighborDirection.DownLeft;
            leftPassantDir  = HexNeighborDirection.UpLeft;
            rightAttackDir  = HexNeighborDirection.DownRight;
            rightPassantDir = HexNeighborDirection.UpRight;
            forwardDir      = HexNeighborDirection.Down;
        }

        if (start.TryGetNeighbor(leftAttackDir, out var leftAttack))
        {
            var leftVictim = boardNode[leftAttack];
            if (leftVictim.team == enemy)
            {
                moves.Add(new FastMove(start, leftAttack, MoveType.Attack));
            }
            if (leftVictim.team == Team.None)
            {
                if (start.TryGetNeighbor(leftPassantDir, out var leftPassant) && boardNode.PassantableIndex == leftPassant)
                {
                    moves.Add(new FastMove(start, leftAttack, MoveType.EnPassant));
                }
            }
        }

        if (start.TryGetNeighbor(rightAttackDir, out var rightAttack))
        {
            var rightVictim = boardNode[rightAttack];
            if (rightVictim.team == enemy)
            {
                moves.Add(new FastMove(start, rightAttack, MoveType.Attack));
            }
            if (rightVictim.team == Team.None)
            {
                if (start.TryGetNeighbor(rightPassantDir, out var rightPassant) && boardNode.PassantableIndex == rightPassant)
                {
                    moves.Add(new FastMove(start, rightAttack, MoveType.EnPassant));
                }
            }
        }

        if (!generateQuiet)
        {
            return;
        }

        // One forward
        bool hasForward = start.TryGetNeighbor(forwardDir, out var forward);

        if (hasForward && !boardNode.IsOccupied(forward))
        {
            if (forward.TryGetNeighbor(forwardDir, out var twoForward))
            {
                moves.Add(new FastMove(start, forward, MoveType.Move));

                // Two forward on 1st move
                if (PawnIsAtStart(team, (Index)start) && !boardNode.IsOccupied(twoForward))
                {
                    moves.Add(new FastMove(start, twoForward, MoveType.Move));
                }
            }
            else
            {
                // if two squares forward doesn't exist, that means we're on the last rank for this pawn.
                moves.Add(new FastMove(start, forward, MoveType.Move, FastPiece.Queen));
                moves.Add(new FastMove(start, forward, MoveType.Move, FastPiece.Rook));
                moves.Add(new FastMove(start, forward, MoveType.Move, FastPiece.Knight));
                moves.Add(new FastMove(start, forward, MoveType.Move, FastPiece.Squire));
            }
        }
    }
Exemplo n.º 11
0
 public void UpdateEdge(HexNeighborDirection direction) =>
 meshRenderer.material.SetFloat(
     name: $"_Edge{(int)direction}",
     value: Mathf.Abs(meshRenderer.material.GetFloat($"_Edge{(int)direction}") - 1).Floor()
     );
Exemplo n.º 12
0
 public static Index?GetNeighborAt(Index source, HexNeighborDirection dir)
 {
     return(source.GetNeighborAt(dir));
 }
Exemplo n.º 13
0
 public static HexNeighborDirection Opposite(this HexNeighborDirection direction) =>
 (HexNeighborDirection)(((int)direction + 3) % 6);