private bool CanReachInOneOrTwoCWRotations(Tetrimino tetrimino, Tetrimino target) { for (int i = 0; i < 2; i++) { tetrimino = tetrimino.RotateCW(); if (tetrimino.Equals(target)) { return(true); } } return(false); }
private bool WrongTetrimino(Tetrimino tetrimino, Tetrimino target) { for (int i = 0; i < 4; i++) { if (tetrimino.Equals(target)) { return(false); } tetrimino = tetrimino.RotateCW(); } return(true); }
public DropResult drop(Tetrimino tetrimino, int leftCol) { int minNewTopTetriminoRow = 999; for (int x = 0; x < tetrimino.Width; x++) { int tetriminoBottomRow = 0; for (int y = tetrimino.Height - 1; y >= 0; y--) { if (tetrimino.TetriminoArray[y, x]) { tetriminoBottomRow = y; break; } } int curCol = leftCol + x; int boardTopRow = GetTopRowInColumn(curCol); int newTopTetriminoRow = boardTopRow - tetriminoBottomRow - 1; minNewTopTetriminoRow = Math.Min(minNewTopTetriminoRow, newTopTetriminoRow); } Board r = new Board(this); for (int i = 0; i < tetrimino.Height; i++) { for (int j = 0; j < tetrimino.Width; j++) { if (tetrimino.TetriminoArray[i, j]) { if (minNewTopTetriminoRow + i < 0) { return(null); } r.BoardArray[minNewTopTetriminoRow + i, leftCol + j] = true; } } } r.Penalty = Penalty; int linesCleared = r.ClearFullRows(); return(new DropResult(r, linesCleared)); }
public GameState(Board board, TetriminoWithPosition fallingTetrimino, List <Tetrimino> nextTetriminoes, Tetrimino tetriminoInStash, bool thereIsDanger) { Board = board; NextTetriminoes = nextTetriminoes; FallingTetrimino = fallingTetrimino; TetriminoInStash = tetriminoInStash; ThereIsDanger = thereIsDanger; }
public void MakeMove(List <Move> moves) { foreach (var move in moves) { switch (move) { case Move.Left: curBlockWithPos.LeftCol--; break; case Move.Right: curBlockWithPos.LeftCol++; break; case Move.Drop: var previousBord = board; var result = board.drop(curBlockWithPos.Tetrimino, curBlockWithPos.LeftCol); board = result.Board; linesCleared += result.LinesCleared; linesClearedLabel.Invoke(new Action(() => { linesClearedLabel.Text = linesCleared.ToString(); })); if (result.LinesCleared != 0) { RedrawComplete(); //DrawDifferences(result.Board, previousBord); } else { //RedrawComplete(); DrawDifferences(result.Board, previousBord); } cur++; RedetectBlocks(); break; case Move.Stash: var tmp = inStash; inStash = curBlockWithPos.Tetrimino; if (tmp == null) { cur++; RedetectBlocks(); } else { curBlockWithPos = new TetriminoWithPosition(tmp, 0, 4); } break; case Move.Rotate_CW: curBlockWithPos.Tetrimino = curBlockWithPos.Tetrimino.RotateCW(); break; case Move.Rotate_CWW: curBlockWithPos.Tetrimino = curBlockWithPos.Tetrimino.RotateCW(); curBlockWithPos.Tetrimino = curBlockWithPos.Tetrimino.RotateCW(); curBlockWithPos.Tetrimino = curBlockWithPos.Tetrimino.RotateCW(); break; case Move.Enter: break; default: break; } } }
public void Play() { gameStateReader.Starting(); while (true) { var gameState = gameStateReader.ReadGameState(); if (Broken(gameState)) { Thread.Sleep(500); continue; } if (gameState.ThereIsDanger) { Evaluator.MaxHeight = 19; } else { Evaluator.MaxHeight = 4; } //Console.WriteLine(gameState.Board); //Console.WriteLine(string.Join(";", gameState.NextTetriminoes)); var twp = gameState.FallingTetrimino; if (twp == null) { continue; } Tetrimino tetrimino = twp.Tetrimino; if (target == null || WrongTetrimino(target.Tetrimino, tetrimino)) { target = bestMoveFinder.FindBestMove(gameState, twp, stashAllowed); if (target == null) { continue; } } var moves = new List <Move>(); if (target.Stash) { moves.Add(Move.Stash); target = null; stashAllowed = false; } else { if (!tetrimino.Equals(target.Tetrimino)) { if (CanReachInOneOrTwoCWRotations(tetrimino, target.Tetrimino)) { moves.Add(Move.Rotate_CW); } else { moves.Add(Move.Rotate_CWW); } } if (target.Column > twp.LeftCol) { moves.Add(Move.Right); } else if (target.Column < twp.LeftCol) { moves.Add(Move.Left); } if (moves.Count == 0) { moves.Add(Move.Drop); target = null; stashAllowed = true; } } //foreach (var move in moves) //{ // Console.WriteLine($"Making move: {move}"); //} keyPresser.MakeMove(moves); //Console.WriteLine(target); //Console.WriteLine("------"); } }
public void MakeMove(List <Move> moves) { foreach (var move in moves.Take(1)) { int linesClearedNow = 0; string keyToPress = null; switch (move) { case Move.Left: //tetris99Form.CurrentSerialConnection.SendButtonPress("LH"); keyToPress = "LH"; curBlockWithPos.LeftCol--; break; case Move.Right: //tetris99Form.CurrentSerialConnection.SendButtonPress("RH"); keyToPress = "RH"; curBlockWithPos.LeftCol++; break; case Move.Drop: var previousBord = board; var result = board.drop(curBlockWithPos.Tetrimino, curBlockWithPos.LeftCol); board = result.Board; linesCleared += result.LinesCleared; linesClearedNow = result.LinesCleared; linesClearedLabel.Invoke(new Action(() => { linesClearedLabel.Text = linesCleared.ToString(); })); if (result.LinesCleared != 0) { //RedrawComplete(); //DrawDifferences(result.Board, previousBord); } else { //RedrawComplete(); //DrawDifferences(result.Board, previousBord); } keyToPress = "UH"; //tetris99Form.CurrentSerialConnection.SendButtonPress("UH"); cur++; RedetectBlocks(); //DrawCurrentBlock(); //Thread.Sleep(500); break; case Move.Stash: var tmp = inStash; inStash = curBlockWithPos.Tetrimino; keyToPress = "7"; //tetris99Form.CurrentSerialConnection.SendButtonPress("7"); if (tmp == null) { cur++; RedetectBlocks(); //Thread.Sleep(500); } else { curBlockWithPos = new TetriminoWithPosition(tmp, 2, 3 + (tmp.Width == 2 ? 1 : 0)); } break; case Move.Rotate_CW: keyToPress = "2"; //tetris99Form.CurrentSerialConnection.SendButtonPress("2"); Rotate(); break; case Move.Rotate_CWW: keyToPress = "1"; //tetris99Form.CurrentSerialConnection.SendButtonPress("1"); Rotate(); Rotate(); Rotate(); break; case Move.Enter: break; default: break; } RedrawComplete(); DrawCurrentBlock(); DrawNextBlocks(); bool thereWasDanger = DetectIfThereIsDanger(); if (thereWasDanger) { gDanger.Clear(Color.Red); dangerCountLabel.Invoke(new Action(() => { dangerCountLabel.Text = _lastDetectedDanger.ToString(); })); } else { gDanger.Clear(Color.Green); } if (!string.IsNullOrWhiteSpace(keyToPress)) { var timeToWait = (int)Math.Max(0, minTimeToWait - _timeSinceLastKeyPress.Elapsed.TotalMilliseconds); if (timeToWait > 0) { Thread.Sleep(timeToWait); } minTimeToWait = FrameDurationHelper.ToFrameDuration(3); tetris99Form.CurrentSerialConnection.SendButtonPress(keyToPress, false); _timeSinceLastKeyPress.Restart(); if (keyToPress == "UH") { //If other players spawn shit, we need to wait for the animation if (thereWasDanger) { minTimeToWait = FrameDurationHelper.ToFrameDuration(33 + _lastDetectedDanger * 4); } else { minTimeToWait = FrameDurationHelper.ToFrameDuration(8); } } if (linesClearedNow > 0) { //Theres no more danger now _lastDanger = DateTime.MinValue; _lastNoDanger = DateTime.Now; minTimeToWait = FrameDurationHelper.ToFrameDuration(48); } } } }