Beispiel #1
0
        public void AddUnit(CardImpl card, OrientedCell new_cell)
        {
            var command = commands [cur_command_idx];

            if (new_cell != null)
            {
                UnitImpl unit = new UnitImpl(card, cur_command_idx, new_cell);

                SetUnitPlace(new_cell, unit);

                command.staff.Add(unit);

                if (notificator != null)
                {
                    notificator.UnitAdded(unit);
                }
            }

            command.hand.Remove(card);

            command.crystals_count -= card.cost;
            if (notificator != null)
            {
                notificator.PlayerUIUpdated();
            }
        }
Beispiel #2
0
        private void CalculateRoute(OrientedCell from, Func <CellCandidate, bool> CheckCand, Func <CellCandidate, bool> NewCand)
        {
            var  candidats = new CandidatesQueue();           //ToDo calculate for giant
            bool end       = false;

            UnitImpl unit = from.cell.unit;

            candidats.Enqueue(new CellCandidate(from, 0, null));
            while (candidats.Count > 0 && !end)
            {
                CellCandidate cand = candidats.Dequeue();
                if (CheckCand(cand))
                {
                    List <OrientedCell> neighbor_cells = gameboard.GetOneMoveCells(cand.cell_ref, unit);
                    foreach (var cell in neighbor_cells)
                    {
                        CellCandidate cell_cand = candidats.FindCandidate(cell);
                        if (cell_cand == null || cell_cand.route_cnt > cand.route_cnt + 1)
                        {
                            var new_cand = new CellCandidate(cell, cand.route_cnt + 1, cand);
                            candidats.Enqueue(new_cand);

                            if (!NewCand(new_cand))
                            {
                                end = true;
                                break;
                            }
                        }
                    }
                }
            }
        }
Beispiel #3
0
 public UnitImpl(UnitImpl otherUnit)
     : base(otherUnit)
 {
     command_idx = otherUnit.command_idx;
     made_move   = otherUnit.made_move;
     hp          = otherUnit.hp;
 }
Beispiel #4
0
 public void SetUnitPlace(OrientedCell oriented_cell, UnitImpl unit)
 {
     foreach (var cell in GetOccupatedCells(oriented_cell))
     {
         cell.unit = unit;
         if (cell.notificator != null)
         {
             cell.notificator.UnitAdded(unit);
         }
     }
 }
Beispiel #5
0
        public List <OrientedCell> GetOneMoveCells(OrientedCell cell, UnitImpl excl_unit)       //ToDo it could be optimized
        {
            List <OrientedCell> ret = null;

            if (cell.orientation == OrientedCell.CellOrientation.Default)
            {
                ret = new List <OrientedCell> (6);
                var neigh = GetNeighborCells(cell.cell);
                foreach (var neigh_cell in neigh)
                {
                    ret.Add(new OrientedCell {
                        cell = neigh_cell
                    });
                }
            }
            else
            {
                ret = new List <OrientedCell> (4);

                GameboardCell[] oc_cell = GetOccupatedCells(cell);

                Func <int, int> p = x => (x > 1 ? x - 1 : 3);
                Func <int, int> n = x => (x < 3 ? x + 1 : 1);

                int o = (int)cell.orientation;

                ret.Add(new OrientedCell {
                    cell = oc_cell[n(o)], orientation = (OrientedCell.CellOrientation)n(o)
                });
                ret.Add(new OrientedCell {
                    cell = oc_cell[n(o)], orientation = (OrientedCell.CellOrientation)p(o)
                });
                ret.Add(new OrientedCell {
                    cell = oc_cell[p(o)], orientation = (OrientedCell.CellOrientation)n(o)
                });
                ret.Add(new OrientedCell {
                    cell = oc_cell[o], orientation = (OrientedCell.CellOrientation)p(o)
                });
            }

            ret.RemoveAll(or_cell => or_cell.cell == null ||
                          Array.Exists(GetOccupatedCells(or_cell), oc_cell => oc_cell == null ||
                                       (oc_cell.unit != null && oc_cell.unit != excl_unit)));
            return(ret);
        }
Beispiel #6
0
        private bool CheckBoard(GameboardImpl board, List <GameboardImpl> uniqueBoards)
        {
            foreach (GameboardImpl b in uniqueBoards)
            {
                if (b.commands[0].staff.Count != b.commands[0].staff.Count || b.commands[1].staff.Count != b.commands[1].staff.Count)
                {
                    continue;
                }

                bool isBreak = false;
                for (int n = 0; n < 2; n++)
                {
                    for (int i = 0; i < b.commands[n].staff.Count; i++)
                    {
                        UnitImpl unit0 = b.commands[n].staff[i];
                        UnitImpl unit1 = board.commands[n].staff[i];

                        if (unit0.id == unit1.id && unit0.hp == unit1.hp &&
                            unit0.oriented_cell.orientation == unit1.oriented_cell.orientation &&
                            Math.Abs(unit0.oriented_cell.cell.board_x - unit1.oriented_cell.cell.board_x) < 1 &&
                            Math.Abs(unit0.oriented_cell.cell.board_y - unit1.oriented_cell.cell.board_y) < 1)
                        {
                            continue;
                        }

                        isBreak = true;
                        break;
                    }

                    if (isBreak)
                    {
                        break;
                    }
                }

                if (!isBreak)
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #7
0
        public GameboardImpl MakeCopy()
        {
            GameboardImpl ret = new GameboardImpl();

            for (int player_idx = 0; player_idx < players_qty; ++player_idx)
            {
                ret.commands[player_idx] = new CommandInfo();

                foreach (UnitImpl unit in commands[player_idx].staff)
                {
                    UnitImpl new_unit = new UnitImpl(unit);

                    new_unit.oriented_cell.orientation = unit.oriented_cell.orientation;
                    new_unit.oriented_cell.cell        = ret.cells[unit.oriented_cell.cell.board_x, unit.oriented_cell.cell.board_y];
                    SetUnitPlace(new_unit.oriented_cell, new_unit);

                    //ToDo check for something else

                    ret.commands[player_idx].staff.Add(new_unit);
                }

                ret.commands[player_idx].crystals_count = commands[player_idx].crystals_count;
                ret.commands[player_idx].crystals_inc   = commands[player_idx].crystals_inc;

                foreach (CardImpl cardImpl in commands[player_idx].hand)
                {
                    ret.commands[player_idx].hand.Add(new CardImpl(cardImpl));
                }

                foreach (CardImpl cardImpl in commands[player_idx].deck)
                {
                    ret.commands[player_idx].deck.Add(new CardImpl(cardImpl));
                }
            }

            ret.cur_command_idx = cur_command_idx;

            return(ret);
        }
Beispiel #8
0
        private List <MoveInfo>[] GetMovesByDistForWalkerMode(GameboardImpl board, UnitImpl unit, bool isMax)   //ToDo: move it to AIHelper
        {
            //1:
            int oldSpeed = unit.speed;

            unit.speed = 100;

            DateTime    t0          = DateTime.Now;
            List <Move> simpleMoves = unit.GetMoves(board);

            getMovesCount++;
            getMoves  += (DateTime.Now - t0).TotalMilliseconds;
            unit.speed = oldSpeed;

            List <MoveInfo> moves = new List <MoveInfo>();
            //2:
            int maxDist = 0;

            foreach (Move move in simpleMoves)
            {
                MoveInfo moveInfo = new MoveInfo(move);
                moves.Add(moveInfo);

                t0 = DateTime.Now;
                //2.1:
                moveInfo.board = board.MakeCopy();
                move.MakeMove(moveInfo.board);
                makeMoveCount++;
                makeMoves += (DateTime.Now - t0).TotalMilliseconds;

                //2.1:
                c++;
                moveInfo.weight = AIHelper.GetBoardWeight(moveInfo.board, isMax);

                //2.2:
                moveInfo.distance = (int)Math.Ceiling(move.Steps / (double)oldSpeed);
                if (moveInfo.distance == 0)
                {
                    moveInfo.distance = 1;
                }

                if (moveInfo.distance > maxDist)
                {
                    maxDist = moveInfo.distance;
                }
            }

            maxDist++;            //it because array size will be count + 1

            //3:
            List <MoveInfo>[] movesByDist = new List <MoveInfo> [maxDist];
            for (int i = 0; i < maxDist; i++)
            {
                movesByDist[i] = new List <MoveInfo>();
            }

            foreach (MoveInfo move in moves)
            {
                movesByDist[move.distance].Add(move);
            }

            return(movesByDist);
        }
Beispiel #9
0
        private List <MoveInfo> GetBestMoves(GameboardImpl board, UnitImpl unit, bool isMax)
        {
            List <MoveInfo>[] movesByDist = GetMovesByDistForWalkerMode(board, unit, isMax);

            //3:
            int maxDist = movesByDist.Length;

            List <MoveInfo>[] bestMovesByDist = new List <MoveInfo> [maxDist];
            for (int i = 1; i < maxDist; i++)
            {
                bestMovesByDist[i] = new List <MoveInfo>();
                double bestW = isMax ? double.MinValue : double.MaxValue;

                foreach (MoveInfo move in movesByDist[i])
                {
                    if ((isMax && move.weight > bestW) ||
                        (!isMax && move.weight < bestW))
                    {
                        bestW = move.weight;
                    }
                }

                foreach (MoveInfo move in movesByDist[i])
                {
                    if (move.weight == bestW)
                    {
                        bestMovesByDist[i].Add(move);
                    }
                }
            }

            //4:
            //and 5 and 6:
            c++;
            double bestWeight           = AIHelper.GetBoardWeight(board, isMax);
            int    bestNearestDistIndex = 1;
            int    bestDistIndex        = 1;

            for (int i = 1; i < maxDist; i++)
            {
                double w = bestMovesByDist[i][0].weight;
                if ((isMax && w > bestWeight) ||
                    (!isMax && w < bestWeight))
                {
                    bestWeight    = w;
                    bestDistIndex = i;
                    if (bestNearestDistIndex == 1)
                    {
                        bestNearestDistIndex = i;
                    }
                }
            }

            List <MoveInfo> res = new List <MoveInfo>();

            if (bestNearestDistIndex == 1)
            {
                //Random rand = new Random();
                //int index = rand.Next(bestMovesByDist[1].Count);
                res.Add(bestMovesByDist[1][bestMovesByDist[1].Count - 1]);
            }
            else
            {
                MoveInfo moveInfo = BestMoveForGoToTargetCell(movesByDist[1], bestMovesByDist[bestNearestDistIndex], bestNearestDistIndex - 1, unit.speed);
                res.Add(moveInfo);
            }

            if (bestNearestDistIndex != bestDistIndex)
            {
                MoveInfo moveInfo = BestMoveForGoToTargetCell(movesByDist[1], bestMovesByDist[bestDistIndex], bestDistIndex - 1, unit.speed);

                if (res[0] != moveInfo)
                {
                    res.Add(moveInfo);
                }
            }

            return(res);
        }