Ejemplo n.º 1
0
        private void DumpMapToScreen(TileState[,] map)
        {
            for (var i = 0; i < map.GetLength(1); i++)
            {
                var sb = new StringBuilder();

                for (var j = 0; j < map.GetLength(0); j++)
                {
                    switch (map[j, i])
                    {
                    case TileState.Sand:
                        sb.Append(".");
                        break;

                    case TileState.Clay:
                        sb.Append("#");
                        break;

                    case TileState.FlowingWater:
                        sb.Append("|");
                        break;

                    case TileState.StillWater:
                        sb.Append("~");
                        break;
                    }
                }

                Console.WriteLine(sb.ToString());
            }
        }
Ejemplo n.º 2
0
    public static bool IsTilePlayable(TileState[,] board, IndexPair index, TileState turnTo, int directionZ, int directionX, int depth)
    {
        if (index.z + (directionZ * depth) >= board.GetLength(0))
        {
            return(false);
        }
        if (index.x + (directionX * depth) >= board.GetLength(1))
        {
            return(false);
        }
        if (index.z + (directionZ * depth) < 0)
        {
            return(false);
        }
        if (index.x + (directionX * depth) < 0)
        {
            return(false);
        }
        switch (turnTo)
        {
        case TileState.Black:
            if (board[index.z + (directionZ * depth), index.x + (directionX * depth)] == TileState.Black && depth > 1)
            {
                return(true);
            }
            else if (board[index.z + (directionZ * depth), index.x + (directionX * depth)] == TileState.White)
            {
                return(IsTilePlayable(board, index, turnTo, directionZ, directionX, ++depth));
            }
            else
            {
                return(false);
            }

        case TileState.White:
            if (board[index.z + (directionZ * depth), index.x + (directionX * depth)] == TileState.White && depth > 1)
            {
                return(true);
            }
            else if (board[index.z + (directionZ * depth), index.x + (directionX * depth)] == TileState.Black)
            {
                return(IsTilePlayable(board, index, turnTo, directionZ, directionX, ++depth));
            }
            else
            {
                return(false);
            }

        case TileState.Empty:
            Debug.LogError("Empty tile should not be tested as playable.");
            break;

        default:
            break;
        }
        return(false);
    }
Ejemplo n.º 3
0
 //Returns a copy of a board
 public static TileState[,] CopyBoard(TileState[,] board)
 {
     TileState[,] result = new TileState[board.GetLength(0), board.GetLength(1)];
     for (int i = 0; i < board.GetLength(1); i++)
     {
         for (int j = 0; j < board.GetLength(0); j++)
         {
             result[j, i] = board[j, i];
         }
     }
     return(result);
 }
Ejemplo n.º 4
0
 public static TileState[,] CloneBoardState(TileState[,] boardState)
 {
     TileState[,] clonedBoard = new TileState[boardState.GetLength(0), boardState.GetLength(1)];
     for (int i = 0; i < boardState.GetLength(0); i++)
     {
         for (int j = 0; j < boardState.GetLength(1); j++)
         {
             clonedBoard[i, j] = boardState[i, j];
         }
     }
     return(clonedBoard);
 }
Ejemplo n.º 5
0
 public static bool IsBoardPlayable(TileState[,] board, TileState colorCheck)
 {
     for (int i = 0; i < board.GetLength(1); i++)
     {
         for (int j = 0; j < board.GetLength(0); j++)
         {
             if (IsTilePlayable(board, new IndexPair(j, i), colorCheck))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Ejemplo n.º 6
0
 public static bool IsTilePlayable(TileState[,] board, IndexPair index, TileState turnTo)
 {
     if (index.z >= board.GetLength(0))
     {
         return(false);
     }
     if (index.x >= board.GetLength(1))
     {
         return(false);
     }
     if (board[index.z, index.x] != TileState.Empty)
     {
         return(false);
     }
     if (IsTilePlayable(board, index, turnTo, 0, 1, 1))
     {
         return(true);
     }
     if (IsTilePlayable(board, index, turnTo, 1, 1, 1))
     {
         return(true);
     }
     if (IsTilePlayable(board, index, turnTo, 1, 0, 1))
     {
         return(true);
     }
     if (IsTilePlayable(board, index, turnTo, 1, -1, 1))
     {
         return(true);
     }
     if (IsTilePlayable(board, index, turnTo, 0, -1, 1))
     {
         return(true);
     }
     if (IsTilePlayable(board, index, turnTo, -1, -1, 1))
     {
         return(true);
     }
     if (IsTilePlayable(board, index, turnTo, -1, 0, 1))
     {
         return(true);
     }
     if (IsTilePlayable(board, index, turnTo, -1, 1, 1))
     {
         return(true);
     }
     return(false);
 }
Ejemplo n.º 7
0
    public static List <IndexPair> GetPlayableTiles(TileState[,] board, TileState colorCheck)
    {
        List <IndexPair> playableTiles = new List <IndexPair>();

        for (int i = 0; i < board.GetLength(1); i++)
        {
            for (int j = 0; j < board.GetLength(0); j++)
            {
                if (IsTilePlayable(board, new IndexPair(j, i), colorCheck))
                {
                    playableTiles.Add(new IndexPair(j, i));
                }
            }
        }
        return(playableTiles);
    }
Ejemplo n.º 8
0
    public static IndexPair CalculateMove(TileState[,] board, TileState color, int depth)
    {
        Debug.Log("Starting MiniMax-search for " + color + "...");
        int alpha = int.MinValue;
        int beta  = int.MaxValue;
        List <IndexPair> availableMoves = Judge.GetPlayableTiles(board, color);

        if (availableMoves.Count == 0)
        {
            return(new IndexPair(board.GetLength(0), board.GetLength(1)));
        }

        IndexPair moveToReturn = availableMoves[0];

        for (int i = 1; i < availableMoves.Count; i++)
        {
            switch (color)
            {
            case TileState.Black:
                int maxValue = MiniMax(Judge.SimulateTurn(board, availableMoves[0], color), TileState.White, depth - 1, alpha, beta);
                if (MiniMax(Judge.SimulateTurn(board, availableMoves[i], color), TileState.White, depth - 1, alpha, beta) > maxValue)
                {
                    moveToReturn = availableMoves[i];
                }
                break;

            case TileState.White:
                int minValue = MiniMax(Judge.SimulateTurn(board, availableMoves[0], color), TileState.Black, depth - 1, alpha, beta);
                if (MiniMax(Judge.SimulateTurn(board, availableMoves[i], color), TileState.Black, depth - 1, alpha, beta) < minValue)
                {
                    moveToReturn = availableMoves[i];
                }
                break;

            default:
                Debug.LogError("Color not valid.");
                break;
            }
        }
        Debug.Log("Nodes examined: " + nodeCount);
        Debug.Log("Depth reached: " + depthReached);
        Debug.Log("MiniMax-search done.");
        depthReached = 10;
        nodeCount    = 0;
        return(moveToReturn);
    }
Ejemplo n.º 9
0
        public Coordinate NextShot(TileState[,] gameBoard)
        {
            // board is always square
            if (gameBoard.GetLength(0) != gameBoard.GetLength(1))
            {
                throw new ArgumentOutOfRangeException($"gameBoard must have square dimentions " +
                                                      $"not {gameBoard.GetLength(0)} by {gameBoard.GetLength(1)}");
            }
            if (gameBoard.GetLength(0) != _boardSize)
            {
                throw new ArgumentException("gameBoard is not the same as the size provided in constructor");
            }

            Random     rnd = new Random();
            Coordinate randomCoordinate = ValidTiles[rnd.Next(ValidTiles.Count)];

            ValidTiles.Remove(randomCoordinate);
            return(randomCoordinate);
        }
Ejemplo n.º 10
0
        private int GetScore(TileState[,] map)
        {
            var totalTrees  = 0;
            var totalLumber = 0;

            for (var i = 0; i < map.GetLength(0); i++)
            {
                for (var j = 0; j < map.GetLength(1); j++)
                {
                    if (map[i, j] == TileState.Trees)
                    {
                        totalTrees++;
                    }
                    else if (map[i, j] == TileState.Lumber)
                    {
                        totalLumber++;
                    }
                }
            }

            return(totalTrees * totalLumber);
        }
Ejemplo n.º 11
0
    public static int EvaluateBoard(TileState[,] board, TileState color)
    {
        int nrOfWhites = 0, nrOfBlacks = 0;

        for (int i = 0; i < board.GetLength(1); i++)
        {
            for (int j = 0; j < board.GetLength(0); j++)
            {
                if (board[j, i] == TileState.Black)
                {
                    nrOfBlacks++;
                }
                else if (board[j, i] == TileState.White)
                {
                    nrOfWhites++;
                }
            }
        }

        int evalValue = nrOfBlacks - nrOfWhites;

        return(evalValue);
    }
Ejemplo n.º 12
0
    public static List <int[]> FindWinningMoves(TileState[,] boardState, Player player)
    {
        List <int[]> winningMoves = new List <int[]>();

        for (int i = 0; i < boardState.GetLength(0); i++)
        {
            for (int j = 0; j < boardState.GetLength(1); j++)
            {
                Move move = new Move(i, j, player);
                if (boardState[i, j] == TileState.EMPTY)
                {
                    TileState[,] newBoard = MakeMove(boardState, move);
                    if (CheckPlayerWin(newBoard, player))
                    {
                        winningMoves.Add(new int[2] {
                            i, j
                        });
                    }
                }
            }
        }
        return(winningMoves);
    }
Ejemplo n.º 13
0
        private TileState[] GetNeighbours(TileState[,] map, int x, int y)
        {
            var points = new List <(int x, int y)>
            {
                (x - 1, y),
                (x - 1, y - 1),
                (x, y - 1),
                (x + 1, y - 1),
                (x + 1, y),
                (x + 1, y + 1),
                (x, y + 1),
                (x - 1, y + 1),
            }.Where(it => it.x >= 0 && it.x < map.GetLength(0) && it.y >= 0 && it.y < map.GetLength(1))
            .Select(it => map[it.x, it.y]).ToArray();

            return(points);
        }
Ejemplo n.º 14
0
    public static List <int[]> FindEdges(TileState[,] boardState)
    {
        int          s         = boardState.GetLength(0);
        List <int[]> edgeTiles = new List <int[]>();

        for (int i = 0; i < s; i++)
        {
            for (int j = 0; j < s; j++)
            {
                if (IsEdgeTile(boardState, i, j))
                {
                    edgeTiles.Add(new int[] { i, j });
                }
            }
        }
        return(edgeTiles);
    }
Ejemplo n.º 15
0
    public static List <int[]> FindCorners(TileState[,] boardState)
    {
        int s = boardState.GetLength(0) - 1;

        return(new List <int[]>()
        {
            new int[2] {
                0, 0
            },
            new int[2] {
                0, s
            },
            new int[2] {
                s, 0
            },
            new int[2] {
                s, s
            },
        });
    }
Ejemplo n.º 16
0
    //NOTE: pass in real-world positions into here- not array positions, we will convert from real-world to array in the function
    private IEnumerator FindPathCoroutine(Vector2 givenStartPosition, Vector2 givenEndPosition, TileState[,] givenPathfindingMap)
    {
        m_start = new Vector2(Mathf.RoundToInt(givenStartPosition.x / m_tileSize), Mathf.RoundToInt(givenStartPosition.y / m_tileSize));
        m_end   = new Vector2(Mathf.RoundToInt(givenEndPosition.x / m_tileSize), Mathf.RoundToInt(givenEndPosition.y / m_tileSize));

        m_visitedTiles = new int[givenPathfindingMap.GetLength(0), givenPathfindingMap.GetLength(1)];

        m_openTiles = new List <Tile>();

        m_startTile = new Tile();
        m_endTile   = new Tile();

        m_startTile.m_position = m_start;
        m_endTile.m_position   = m_end;

        m_currentTile = m_startTile;

        m_visitedTiles[(int)m_currentTile.m_position.x, (int)m_currentTile.m_position.y] = 1;

        m_iterationCount = 0;

        while (m_currentTile.m_position != m_endTile.m_position)
        {
            m_iterationCount++;
            m_cheapestTileCost = float.MaxValue;

            foreach (Tile tile in FindAdjacentTiles(m_currentTile, m_endTile, givenPathfindingMap))
            {
                bool tileAlreadyExists = false;

                for (int i = 0; i < m_openTiles.Count; i++)
                {
                    //if the tile already exists
                    if (m_openTiles[i].m_position == tile.m_position)
                    {
                        m_openTiles[i].m_pathCost = tile.m_pathCost;
                        tileAlreadyExists         = true;
                    }
                }

                if (!tileAlreadyExists)
                {
                    m_openTiles.Insert(0, tile); //put at front of list, as recently looked at adjacent tiles are likely to be most efficient to be looked at next
                }
            }

            foreach (Tile tile in m_openTiles)
            {
                if ((tile.m_pathCost + (int)tile.m_directDistance) < m_cheapestTileCost)
                {
                    m_cheapestTileCost = tile.m_pathCost + (int)tile.m_directDistance;
                    m_currentTile      = tile;
                }
            }
            m_visitedTiles[(int)m_currentTile.m_position.x, (int)m_currentTile.m_position.y] = 1;
            m_openTiles.Remove(m_currentTile);

            if (m_iterationCount > 100) //this prevents too much work being carried out in one frame, so the game won't freeze
            {
                m_iterationCount = 0;
                yield return(null);
            }

            if (m_openTiles.Count == 0) //explored all tiles, means we've tried to get to a blocked area
            {
                m_pathfindingInformation = new PathfindingInformation();
                m_pathfindingInformation.m_canReachTile = false;
                StopCoroutine("FindPathCoroutine");
            }
        }
    }
Ejemplo n.º 17
0
 private bool IsWithinMapBounds(int givenX, int givenY)
 {
     return(givenX >= 0 && givenX < m_pathfindingMap.GetLength(0) &&
            givenY >= 0 && givenY < m_pathfindingMap.GetLength(1));
 }
Ejemplo n.º 18
0
    public static bool SimulateLane(TileState[,] board, IndexPair index, TileState turnTo, int directionZ, int directionX, int depth)
    {
        int z = index.z + (directionZ * depth);
        int x = index.x + (directionX * depth);

        if (z >= board.GetLength(0))
        {
            return(false);
        }
        if (x >= board.GetLength(1))
        {
            return(false);
        }
        if (z < 0)
        {
            return(false);
        }
        if (x < 0)
        {
            return(false);
        }
        switch (turnTo)
        {
        case TileState.Black:
            if (board[z, x] == TileState.Empty)
            {
                return(false);
            }
            if (board[z, x] == TileState.Black && depth > 1)
            {
                return(true);
            }
            if (board[z, x] == TileState.White)
            {
                if (SimulateLane(board, index, turnTo, directionZ, directionX, ++depth))
                {
                    board[z, x] = TileState.Black;
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            break;

        case TileState.White:
            if (board[z, x] == TileState.Empty)
            {
                return(false);
            }
            if (board[z, x] == TileState.White && depth > 1)
            {
                return(true);
            }
            if (board[z, x] == TileState.Black)
            {
                if (SimulateLane(board, index, turnTo, directionZ, directionX, ++depth))
                {
                    board[z, x] = TileState.White;
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            break;

        case TileState.Empty:
            Debug.LogError("Empty tile should not be tested as playable.");
            break;

        default:
            break;
        }
        return(false);
    }
Ejemplo n.º 19
0
    public static bool IsEdgeTile(TileState[,] boardState, int x, int y)
    {
        int s = boardState.GetLength(0) - 1;

        return(x == 0 || y == 0 || x == s || y == s);
    }
Ejemplo n.º 20
0
 public static bool IsInBounds(TileState[,] boardState, int x, int y)
 {
     return(x >= 0 && x < boardState.GetLength(0) && y >= 0 && y < boardState.GetLength(0));
 }
Ejemplo n.º 21
0
    public static Player GetWinner(TileState[,] boardState, out List <int[]> winningCoords)
    {
        int size = boardState.GetLength(0);

        winningCoords = new List <int[]>();
        List <int[]> tileSet = new List <int[]>();

        // Check rows
        for (int r = 0; r < size; r++)
        {
            tileSet.Clear();
            TileState lead = TileState.EMPTY;
            bool      win  = true;
            for (int c = 0; c < size; c++)
            {
                tileSet.Add(new int[2] {
                    c, r
                });
                // Winning rows can't have empty tiles
                if (boardState[c, r] == TileState.EMPTY)
                {
                    win = false;
                    break;
                }
                // Get the leader from first tile in row
                if (c == 0)
                {
                    lead = boardState[c, r];
                }
                else if (boardState[c, r] != lead)
                {
                    // No win if tile doesn't match lead
                    win = false;
                    break;
                }
            }
            // Win check for row
            if (win && lead != TileState.EMPTY)
            {
                winningCoords = tileSet;
                return((Player)lead);
            }
        }

        // Check Columns
        for (int c = 0; c < size; c++)
        {
            tileSet.Clear();
            TileState leadState = TileState.EMPTY;
            bool      win       = true;
            for (int r = 0; r < size; r++)
            {
                tileSet.Add(new int[2] {
                    c, r
                });
                // Winning columns can't have empty tiles
                if (boardState[c, r] == TileState.EMPTY)
                {
                    win = false;
                    break;
                }
                // Get the leader from the first tile in column
                if (r == 0)
                {
                    leadState = boardState[c, r];
                }
                // No win possible if tile doesn't match the lead
                else if (boardState[c, r] != leadState)
                {
                    win = false;
                    break;
                }
            }
            // Win check for column
            if (win && leadState != TileState.EMPTY)
            {
                winningCoords = tileSet;
                return((Player)leadState);
            }
        }

        // Check first diagonal
        tileSet.Clear();
        TileState d1Lead = TileState.EMPTY;
        bool      d1Win  = true;

        for (int d = 0; d < size; d++)
        {
            tileSet.Add(new int[2] {
                d, d
            });
            // Get the diagonal lead
            if (d == 0)
            {
                d1Lead = boardState[d, d];
                // No win if first tile is empty
                if (d1Lead == TileState.EMPTY)
                {
                    d1Win = false;
                    break;
                }
            }
            // No win if other diagonal tiles don't match
            else if (boardState[d, d] != d1Lead)
            {
                d1Win = false;
                break;
            }
        }
        if (d1Win && d1Lead != TileState.EMPTY)
        {
            winningCoords = tileSet;
            return((Player)d1Lead);
        }

        // Check second diagonal
        tileSet.Clear();
        TileState d2Lead = TileState.EMPTY;
        bool      d2Win  = true;

        for (int d = 0; d < size; d++)
        {
            tileSet.Add(new int[2] {
                size - (d + 1), d
            });
            // Get the diagonal lead
            if (d == 0)
            {
                d2Lead = boardState[size - (d + 1), d];
                // No win if first tile is empty
                if (d2Lead == TileState.EMPTY)
                {
                    d2Win = false;
                    break;
                }
            }
            // No win if other diagonal tiles don't match
            else if (boardState[size - (d + 1), d] != d2Lead)
            {
                d2Win = false;
                break;
            }
        }
        if (d2Win && d2Lead != TileState.EMPTY)
        {
            winningCoords = tileSet;
            return((Player)d2Lead);
        }

        // If the board is full, whoever has the most tiles wins
        if (CheckFull(boardState))
        {
            List <int[]> p1Tiles = new List <int[]>();
            List <int[]> p2Tiles = new List <int[]>();
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    if (boardState[i, j] == TileState.P1)
                    {
                        p1Tiles.Add(new int[2] {
                            i, j
                        });
                    }
                    else if (boardState[i, j] == TileState.P2)
                    {
                        p2Tiles.Add(new int[2] {
                            i, j
                        });
                    }
                }
            }
            int p1Score = p1Tiles.Count;
            int p2Score = p2Tiles.Count;

            if (p1Score + p2Score == size * size)
            {
                if (p1Score > p2Score)
                {
                    winningCoords = p1Tiles;
                    return(Player.P1);
                }
                else if (p2Score > p1Score)
                {
                    winningCoords = p2Tiles;
                    return(Player.P2);
                }
            }
        }

        // If we get here, there is no winner
        return(Player.NONE);
    }