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(); } }
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; } } } } } }
public UnitImpl(UnitImpl otherUnit) : base(otherUnit) { command_idx = otherUnit.command_idx; made_move = otherUnit.made_move; hp = otherUnit.hp; }
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); } } }
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); }
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); }
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); }
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); }
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); }