public ExpandResult(int parentIndex, Move move, SimpleBoard board, SimpleLockResult placement) { this.parentIndex = parentIndex; this.move = move; this.board = board; this.placement = placement; }
public void PrivateGetRow() { Random rnd = new Random(); SimpleBoard simpleBoard = new SimpleBoard(8); PrivateObject privateObject = new PrivateObject(simpleBoard); int[] trueValues = new int[] { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8 }; for (int i = 1; i <= simpleBoard.Size; i++) { // int k = (int)(privateObject.Invoke("GetRow", i)); int trueValue = trueValues[(i - 1)]; Assert.AreEqual(trueValue, k, $"\ni={i} true={trueValue} value={k}"); //Assert } }
private ScoreAndMove Negamax(SimpleBoard simp, int currentDepth) { if (simp.state == SimpleBoard.State.DRAW) { return(new ScoreAndMove(0, -1)); } else if (simp.state == SimpleBoard.State.XWON || simp.state == SimpleBoard.State.OWON) { return(new ScoreAndMove(10 - currentDepth, -1)); } ScoreAndMove worst = new ScoreAndMove(1000, -1); foreach (int move in simp.GetMoves()) { simp.MakeMove(move); ScoreAndMove sam = Negamax(simp, currentDepth + 1); simp.UnDoMove(move); sam.score = -sam.score; if (sam.score < worst.score) { worst.score = sam.score; worst.move = move; } } return(worst); }
private void Expand(int index, ref SimpleBoard board, PieceKind spawned, ref NativeList <ExpandResult> ret, bool useHold) { var usePiece = useHold ? board.hold !.Value : spawned; var spawn = board.Spawn(usePiece); if (!spawn.HasValue) { return; } var moves = NextPlacementsGenerator.Generate(ref board, spawn.Value, pieceShapes, useHold); var keys = moves.GetKeyArray(Allocator.Temp); for (var i = 0; i < keys.Length; i++) { if (moves.TryGetValue(keys[i], out var mv)) { var lr = board.LockFast(mv.piece, useHold ? spawned : (PieceKind?)null, pieceShapes, out var b1, true); ret.Add(new ExpandResult(selected[index].index, mv, b1, lr)); } else { throw new Exception(); } } keys.Dispose(); moves.Dispose(); }
private static int UnreachableHoles(ref SimpleBoard board, int maxHeight) { var count = 0; for (var y = 0; y < maxHeight - 2; y++) { count += math.countbits(~board.cells[y] & (board.cells[y + 1] | board.cells[y + 2])); } return(count); }
public void ConstructorOneParam_NumIsEvenAndMoreThan0_CreateClass() { Random rnd = new Random(); for (int i = 0; i < 100; i++) { int num = rnd.Next(1, 25) * 2; SimpleBoard simpleBoard = new SimpleBoard(num); Assert.IsNotNull(simpleBoard); } }
public void ConstructorTwoParam_RowColumIsEvenAndMoreThan0_CreateClass() { Random rnd = new Random(); for (int i = 0; i < 100; i++) { int row = rnd.Next(1, 25) * 2; int column = rnd.Next(1, 25) * 2; SimpleBoard simpleBoard = new SimpleBoard(row, column); Assert.IsNotNull(simpleBoard); } }
private static int CalcMaxHeight(ref SimpleBoard board) { var max = 0; for (var i = 0; i < SimpleBoard.Length; i++) { if (board.cells[i] != 0) { max = i; } } return(max); }
void Start() { squeres = new Squere[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { CreateTile(x, y); } } mainBoard = new SimpleBoard(); xIsAi = true; oIsAi = true; currentPlayerImage.GetComponent <Image>().sprite = x; }
public SimpleBoard GetSimpleBoard() { SimpleBoard simpleBoard = new SimpleBoard(); simpleBoard.SquareTypeArray = new Square.square_type[SizeX, SizeY]; simpleBoard.OccupationArray = new Square.occupation_type[SizeX, SizeY]; board.ToList().ForEach((item) => { simpleBoard.SquareTypeArray[item.Column, item.Row] = item.SquareType; simpleBoard.OccupationArray[item.Column, item.Row] = item.Occupation; }); return(simpleBoard); }
public void ThisOneParam_PositionMore0AndLessSize_ReturnNull() { Random rnd = new Random(); int num = rnd.Next(1, 25) * 2; SimpleBoard simpleBoard = new SimpleBoard(num); int position = simpleBoard.Size; for (int i = 0; i < 100; i++) { // //Assert Assert.IsNull(simpleBoard[position]); position = rnd.Next(1, simpleBoard.Size); } }
public void ThisOneParam_PositionLess0_ArgumentException() { Random rnd = new Random(); int num = rnd.Next(1, 25) * 2; SimpleBoard simpleBoard = new SimpleBoard(num); int position = 0; for (int i = 0; i < 100; i++) { // //Assert Assert.ThrowsException <ArgumentException>(() => simpleBoard[position], $"\ni='{i}' \nposition = '{position}'"); position = rnd.Next(-50, 0); } }
public void ThisTwoParam_RowColumnMoreSize_ArgumentException() { Random rnd = new Random(); int num = rnd.Next(1, 25) * 2; SimpleBoard simpleBoard = new SimpleBoard(num); int row = simpleBoard.Rows + 1; int column = simpleBoard.Columns + 1; for (int i = 0; i < 100; i++) { //Assert Assert.ThrowsException <ArgumentException>(() => simpleBoard[row, column], $"\ni='{i}' \nrow = '{row}' \ncolumn = '{column}'"); row = rnd.Next(simpleBoard.Rows + 1, simpleBoard.Rows + 100); column = rnd.Next(simpleBoard.Columns + 1, simpleBoard.Columns + 100); } }
public async Task <string> RunAI(int turnState) { string response = ""; sage = new Sage(); SimpleBoard boardToRun = board.GetSimpleBoard(); Move moveToMake = await Task <Move> .Factory.StartNew(() => RunAITurn(boardToRun)); ApplyAIMove(moveToMake); moveToMake.ToString(); // ensure string representation is upto date; moveHistory.Add(moveToMake); requestReDraw = true; responseText = AI_MOVE_COMPLETED; response = JsonConvert.SerializeObject(this); return(response); }
public void ThisTwoParam_RowColumnMore0AndLessSize_ReturnNull() { Random rnd = new Random(); int num = rnd.Next(1, 25) * 2; SimpleBoard simpleBoard = new SimpleBoard(num); int row = simpleBoard.Rows; int column = simpleBoard.Columns; for (int i = 0; i < 100; i++) { //Assert Assert.IsNull(simpleBoard[row, column]); row = rnd.Next(1, simpleBoard.Rows); column = rnd.Next(1, simpleBoard.Columns); } }
/// <summary> /// Checks to see if a square is next to a corner /// </summary> /// <param name="square"></param> /// <param name="board"></param> /// <returns></returns> public bool IsNextToCorner(SimpleSquare square, SimpleBoard board) { int sizeX = board.OccupationArray.GetLength(0); int sizeY = board.OccupationArray.GetLength(1); int posX = square.Column; int posY = square.Row; if (posX == 0 && posY == 1) { return(true); } if (posX == 1 && posY == 0) { return(true); } if (posX == 0 && posY == sizeY - 2) { return(true); } if (posX == 1 && posY == sizeY - 1) { return(true); } if (posX == sizeX - 2 && posY == 0) { return(true); } if (posX == sizeX - 1 && posY == 1) { return(true); } if (posX == sizeX - 2 && posY == sizeY - 1) { return(true); } if (posX == sizeX - 1 && posY == sizeY - 2) { return(true); } return(false); }
public void PrivateGetPosition() { Random rnd = new Random(); SimpleBoard simpleBoard = new SimpleBoard(8); PrivateObject privateObject = new PrivateObject(simpleBoard); int trueValue = 1; for (int r = 1; r <= simpleBoard.Rows; r++) { for (int c = 1; c <= simpleBoard.Columns; c++) { if ((r + c) % 2 == 1) { int k = (int)(privateObject.Invoke("GetPosition", r, c)); Assert.AreEqual(trueValue, k, $"\nr={r} c={c} true={trueValue} value={k}"); trueValue++; } } } }
private SimpleBoard GetSimpleBoard(IEnumerable<KeyValuePair<Point, string>> inBoardEntities) { var board = new SimpleBoard(BoardWidth, BoardHeight); foreach (var pair in inBoardEntities) { var inBoardCoords = FromScreenToBoard(pair.Key); ElementType value = (ElementType)Enum.Parse(typeof(ElementType), pair.Value); board[inBoardCoords] = value; } return board; }
/// <summary> /// Проверяет, нужно ли производить взрывы на доске в соответствии с правилами игры /// </summary> private bool IsDetonationRequired(SimpleBoard board) { for (int x = 1; x <= board.Width; ++x) if (IsExplosiveColumn(x, board)) return true; for (int y = 1; y <= board.Height; ++y) if (IsExplosiveRow(y, board)) return true; return false; }
private double GetFractionOfRowsAndColumnsControlled(SimpleBoard board) { double fraction = 0.0d; return(fraction); }
/// <summary> /// Уничтожение элемента и смещение элементов над ним вниз. /// </summary> private static void DestroySinglePoint(Point point, SimpleBoard board) { for (int y = point.Y; y >= 1; --y) board[point.X, y] = board[point.X, y - 1]; }
/// <summary> /// Проверяет корректен ли ход с обменом элементов /// </summary> private bool IsSwapCorrect(Point first, Point second, SimpleBoard board) { if (!IsManuallyMovable(board.Cells[first.X, first.Y]) || !IsManuallyMovable(board.Cells[second.X, second.Y])) { return false; } Swap(first, second, board); bool result; try { result = IsExplosiveRow(first.Y, board) || (second.Y != first.Y) && IsExplosiveRow(second.Y, board) || IsExplosiveColumn(first.X, board) || (first.X != second.X) && IsExplosiveColumn(second.X, board); } finally { Swap(first, second, board); } return result; }
/// <summary> /// Уничтожает Diamonds на нижнем уровне доски. Производит смещение элементов при уничтожении. /// </summary> /// <returns>Количество уничтоженных алмазов</returns> private static int DestroyDiamondsAtBottom(SimpleBoard board) { int diamonds = 0; for (int x = 1; x <= board.Width; ++x) if (board[x, board.Height] == ElementType.Diamond) { ++diamonds; DestroySinglePoint(new Point(x, board.Height), board); } return diamonds; }
/// <summary> /// Проверяет, есть ли в строке ряд, который должен быть разрушен /// </summary> private bool IsExplosiveRow(int y, SimpleBoard board) { return IsExplosiveLine(new Point(1, y), new Point(1, 0), board); }
/// <summary> /// Возвращает все возможные обмены соседних по стороне элементов доски. /// Правила игры не учитываются. /// </summary> private static List<Movement> GetUncheckedSwaps(SimpleBoard board) { var result = new List<Movement>(); int width = board.Width; int height = board.Height; for (int x = 1; x <= width; ++x) for (int y = 1; y <= height; ++y) { var second = new Point(x, y); var first = new Point(x - 1, y); if (first.X >= 1) { ClassicMovement movement = new ClassicMovement { Kind = ClassicMovementKind.Swap, First = first, Second = second }; result.Add(movement); } first = new Point(x, y - 1); if (first.Y >= 1) { ClassicMovement movement = new ClassicMovement { Kind = ClassicMovementKind.Swap, First = first, Second = second }; result.Add(movement); } } return result; }
/// <summary> /// Меняет элементы в соответствующих позициях местами /// </summary> private static void Swap(Point first, Point second, SimpleBoard board) { var temp = board[first]; board[first] = board[second]; board[second] = temp; }
/// <summary> /// Уничтожает элементы в заданных позициях и производит смещение верхних элементов вниз /// </summary> /// <param name="positions">Позиции уничтожаемых элементов</param> /// <param name="board">Доска с элементами</param> /// <param name="rawHeal">Получаемый отхил</param> /// <param name="rawDamage">Нанесённый урон</param> /// <returns>Количество уничтоженных Diamond</returns> private void ExplodeOnce(Point[] positions, SimpleBoard board, out double rawHeal, out double rawDamage, out int diamondsDestroyed) { rawHeal = 0; rawDamage = 0; Array.Sort(positions, (a, b) => a.Y.CompareTo(b.Y)); foreach (var pos in positions) if (InRange(pos.X, 1, board.Width) && InRange(pos.Y, 1, board.Height)) { var curr = board[pos]; if (curr != ElementType.Diamond) { rawHeal += GetHeal(curr); rawDamage += GetDamage(curr); for (int y = pos.Y; y >= 1; --y) board[pos.X, y] = board[pos.X, y - 1]; } } diamondsDestroyed = DestroyDiamondsAtBottom(board); }
/// <summary> /// Взрывает все ряды из взрываемых элементов на доске. Производит только одну серию взрывов. /// </summary> /// <param name="board">Доска на которой произойдёт взрыв (по месту)</param> /// <param name="rawHeal">Полученное в результате здоровье</param> /// <param name="rawDamage">Нанесённый урон</param> /// <param name="bombsAcquired">Приобретено бомб</param> /// <param name="dynamitsAcquired">Приобретено динамитов</param> private void ExplodeOnce(SimpleBoard board, out double rawHeal, out double rawDamage, out int bombsAcquired, out int dynamitsAcquired, out int diamondsDestroyed) { var explosingPositions = GetAllPointsToExplode(board, out bombsAcquired, out dynamitsAcquired); ExplodeOnce(explosingPositions.ToArray(), board, out rawHeal, out rawDamage, out diamondsDestroyed); }
public S2C_GameStarted(SimpleBoard board) { this.YourBoard = board; }
/// <summary> /// Проверяет, есть ли в столбце ряд, который должен быть разрушен /// </summary> private bool IsExplosiveColumn(int x, SimpleBoard board) { return IsExplosiveLine(new Point(x, 1), new Point(0, 1), board); }
/// <summary> /// Находит позиции всех элементов, которые должны быть уничтожены по правилам игры. /// Заодно вычисляет количество приобретенной взрывчатки. /// </summary> private List<Point> GetAllPointsToExplode(SimpleBoard board, out int bombsAcquired, out int dynamitsAcquired) { bombsAcquired = 0; dynamitsAcquired = 0; var result = new List<Point>(); for (int x = 1; x <= board.Width; ++x) { var start = new Point(x, 1); var shift = new Point(0, 1); result.AddRange(GetLinePointsToExplode(start, shift, board, ref bombsAcquired, ref dynamitsAcquired)); } for (int y = 1; y <= board.Height; ++y) { var start = new Point(1, y); var shift = new Point(1, 0); result.AddRange(GetLinePointsToExplode(start, shift, board, ref bombsAcquired, ref dynamitsAcquired)); } result = result.Distinct().ToList(); return result; }
/// <summary> /// Проверяет, есть ли в линии ряд, который должен быть разрушен /// </summary> /// <param name="start">Первая точка линни</param> /// <param name="shift">Смещение, определяющее направление линии: (0, 1) или (1, 0)</param> private bool IsExplosiveLine(Point start, Point shift, SimpleBoard board) { int sequence = 1; var points = (shift.X == 1) ? GetRowPoints(start.Y) : GetColumnPoints(start.X); var prevPoint = points[0]; for (int i = 1; i < points.Length; ++i) { var currPoint = points[i]; var currCell = board[currPoint]; if (currCell == board[prevPoint] && IsExplosiveInLine(currCell)) { ++sequence; if (sequence >= 3) return true; } else { sequence = 1; } prevPoint = currPoint; } return false; }
private Move RunAITurn(SimpleBoard startBoard) { SimpleBoard BaseBoard = startBoard; List <Move> moveList_0 = new List <Move>(); DateTime start = DateTime.Now; sage.bestList = new List <Move>(); sage.longTermBestList = new List <Move>(); //Fill list with all possible moves of depth 0 moveList_0 = BaseBoard.GetPossibleMoves(this.currentTurnState, null, 0); Object _lock = new object(); //Create Depth 1 moves Parallel.ForEach(moveList_0, (m) => { //Make the moves m.MakeMove(m, BaseBoard); //Look at all the depth 1 moves for the opposing side List <Move> moveList_1 = new List <Move>(); List <Move> moveList_2 = new List <Move>(); if (currentTurnState == TurnState.Defender) { moveList_1 = m.board.GetPossibleMoves(TurnState.Attacker, m, 1); } if (currentTurnState == TurnState.Attacker) { moveList_1 = m.board.GetPossibleMoves(TurnState.Defender, m, 1); } moveList_1.ForEach((m2) => { m2.MakeMove(m2, m2.parent.board); }); moveList_1.ForEach((m2) => { //Look at all the depth 1 moves for the initial side if (currentTurnState == TurnState.Defender) { moveList_2 = m2.board.GetPossibleMoves(TurnState.Defender, m2, 2); } if (currentTurnState == TurnState.Attacker) { moveList_2 = m2.board.GetPossibleMoves(TurnState.Attacker, m2, 2); } moveList_2.ForEach((m3) => { //Make the moves m3.MakeMove(m3, m3.parent.board); }); //build List<List<Move>> List <List <Move> > moveList = new List <List <Move> >(); moveList.Add(new List <Move>()); moveList[0].Add(m); moveList.Add(moveList_1); moveList.Add(moveList_2); //Propagate scores for (int i = moveList.Count - 1; i >= 0; i--) { //Push all the data to the depth 0 moves moveList[i].ForEach((item) => { if (i != 0) { //Total number of takes in the pipeline downwards if (item.numberTakesAttacker > 0 || item.numberTakesDefender > 0) { if (i == 1) { item.parent.numberTakesAttackerAtDepth[i] += item.numberTakesAttacker; item.parent.numberTakesDefenderAtDepth[i] += item.numberTakesDefender; } if (i == 2) { item.parent.parent.numberTakesAttackerAtDepth[i] += item.numberTakesAttacker; item.parent.parent.numberTakesDefenderAtDepth[i] += item.numberTakesDefender; } } } else { item.numberTakesAttackerAtDepth[0] = item.numberTakesAttacker; item.numberTakesDefenderAtDepth[0] = item.numberTakesDefender; } }); } sage.ProcessMovesLowerMem(moveList, currentTurnState, moveHistory); }); }); TimeSpan depth2duration = (DateTime.Now - start); double runtimetodepth2 = depth2duration.TotalSeconds; TimeSpan duration = (DateTime.Now - start); double runtime = duration.TotalSeconds; Func <Move, bool> repeatEvalFunc = new Func <Move, bool>((move) => CheckForRepeatMoves(move)); Move bestMove = sage.PickBestLowerMem(repeatEvalFunc); //Pass the evaluation fucntion as a Func<> to the sage evaluation method. bestMove.runTime = runtime; return(bestMove); }
/// <summary> /// Находит все точки на линии, заданной начальной точкой и смещением, которые /// подлежат уничтожению /// </summary> /// <param name="bombsAcquired">Сюда добавляются приобретённые бомбы</param> /// <param name="dynamitsAcquired">Сюда добавляются приобретённые динамиты</param> private List<Point> GetLinePointsToExplode(Point start, Point shift, SimpleBoard board, ref int bombsAcquired, ref int dynamitsAcquired) { var result = new List<Point>(); var positions = (shift.X == 1) ? GetRowPoints(start.Y) : GetColumnPoints(start.X); int curr = 1; for (int i = 1; i < positions.Length; ++i) { var currPoint = positions[i]; var prevPoint = positions[i - 1]; if (IsExplosiveInLine(board.Cells[currPoint.X, currPoint.Y]) && board[currPoint] == board[prevPoint]) { curr += 1; if (curr == 3) result.AddRange(new[] { currPoint, prevPoint, positions[i - 2] }); if (curr >= 4) result.Add(currPoint); } else { dynamitsAcquired += (curr >= 5) ? 1 : 0; bombsAcquired += (curr == 4 || curr >= 6) ? 1 : 0; curr = 1; } } return result; }