public TetrisState DoMove(TetriminoState move, Pathfinder.MoveNode moveNode, bool hold) { CustomTetrisRNG childRng = new CustomTetrisRNG(tetRng); Tetris child = new Tetris(tetris, childRng); if (hold) { child.Hold(); } Tetrimino tetrimino = child.current; child.pieceX = move.x; child.pieceY = move.y; child.pieceRotation = move.rot; child.HardDrop(); child.tspin = moveNode.tspin; return(new TetrisState(child, childRng) { usesHeld = hold, tetrimino = tetrimino }); }
public override bool Equals(object obj) { TetriminoState other = (TetriminoState)obj; return(other.x == x && other.y == y && other.rot == rot); }
public HashSet <TetriminoState> FindAllMoves(Tetris tetris, int shiftDelay, int rotateDelay, int softDropDelay) { TetriminoStateComparer.standard.tetrimino = tetris.current; HashSet <TetriminoState> moves = new HashSet <TetriminoState>(TetriminoStateComparer.standard); Array.Clear(field, 0, field.Length); int len = (int)Move.Count; Queue <TetriminoState> children = new Queue <TetriminoState>(); void ExpandNode(int x, int y, byte r) { MoveNode parent = field[x, y, r]; for (int i = 0; i < len; i++) { Move move = (Move)i; tetris.pieceX = x; tetris.pieceY = y; tetris.pieceRotation = r; bool moveSuccess = DoMove(tetris, move); TetriminoState childPos = new TetriminoState(tetris.pieceX, tetris.pieceY, tetris.pieceRotation); if (moveSuccess) { MoveNode prev = field[tetris.pieceX, tetris.pieceY, tetris.pieceRotation]; bool isMoreImportant = !prev.valid; int distanceTravelled = Math.Abs(x - tetris.pieceX) + Math.Abs(y - tetris.pieceY); if (!isMoreImportant) { int prevDist = prev.totalDistanceTravelled; if (prev.move == Move.SONIC_DROP) { prevDist -= prev.distanceTravelled; } int newDist = parent.totalDistanceTravelled; if (move != Move.SONIC_DROP) { newDist += distanceTravelled; } isMoreImportant = prevDist > newDist; } if (isMoreImportant) { MoveNode child = new MoveNode { move = move, parent = new TetriminoState(x, y, r), distanceTravelled = distanceTravelled, totalDistanceTravelled = parent.totalDistanceTravelled + distanceTravelled, valid = true, tspin = tetris.elibigleForTspin }; field[tetris.pieceX, tetris.pieceY, tetris.pieceRotation] = child; children.Enqueue(childPos); } } if (move == Move.SONIC_DROP) { moves.Add(childPos); } } tetris.SetPiece(tetris.current); } tetris.SetPiece(tetris.current); field[tetris.pieceX, tetris.pieceY, tetris.pieceRotation] = new MoveNode { root = true, valid = true }; ExpandNode(tetris.pieceX, tetris.pieceY, tetris.pieceRotation); while (children.TryDequeue(out TetriminoState child)) { ExpandNode(child.x, child.y, child.rot); } return(moves); }