From 3308ca0dc4c60e69bd253e547428a0e1ead5bdfa Mon Sep 17 00:00:00 2001 From: Jon Bergland Date: Tue, 5 Mar 2024 17:52:16 +0000 Subject: [PATCH 1/6] feat: add class for tetris game manager --- src/game/TetrisGameManager.py | 62 +++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/game/TetrisGameManager.py diff --git a/src/game/TetrisGameManager.py b/src/game/TetrisGameManager.py new file mode 100644 index 0000000..c815dbd --- /dev/null +++ b/src/game/TetrisGameManager.py @@ -0,0 +1,62 @@ +baseScore = 100 +DOWN = (0, 1) +LEFT = (-1, 0) +RIGHT = (1, 0) + + +class TetrisGameManager: + + current_piece = None + new_piece = None + score = 0 + + def __init__(self, board): + self.board = board + self.score = 0 + + def rotate_piece(self, direction): + self.current_piece.rotate(direction) + + + def move_piece(self, direction): + + self.current_piece.move(direction) + + def drop_piece(self, newPiece): + if self.legal_move(DOWN): + self.move_piece(DOWN) + + def is_game_over(self): + return self.board.is_game_over() + + def start_game(self): + self.current_piece = self.next_piece() + self.next_piece = self.next_piece() + + + def legal_move(self, x, y): + return self.board.legal_move(x, y) + + def clear_lines(self): + lines_cleared = self.board.clear_lines() + self.update_score(lines_cleared) + + def update_score(self, lines_cleared): + self.score += baseScore**lines_cleared + + def place_piece(self, direction): + x = direction[0] + y = direction[1] + if self.legal_move(x, y): + self.board.place_piece(x, y, self.current_piece) + + if self.is_game_over(): + self.stop_game() + + def new_piece(self): + return self.pieces.get_new_piece() + + def stop_game(self): + self.board.stop_game() + +print(DOWN.index(1)) \ No newline at end of file From 787be747d3d72fa0605c981cc4d27af3820b838a Mon Sep 17 00:00:00 2001 From: Jon Bergland Date: Tue, 5 Mar 2024 18:40:21 +0000 Subject: [PATCH 2/6] refactor: change method names and method implementation Co-authored-by: oystkva --- src/game/TetrisGameManager.py | 76 +++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/src/game/TetrisGameManager.py b/src/game/TetrisGameManager.py index c815dbd..7a1c166 100644 --- a/src/game/TetrisGameManager.py +++ b/src/game/TetrisGameManager.py @@ -1,3 +1,5 @@ +import keyboard + baseScore = 100 DOWN = (0, 1) LEFT = (-1, 0) @@ -6,57 +8,63 @@ class TetrisGameManager: - current_piece = None - new_piece = None + currentPiece = None + nextPiece = None score = 0 + updateTimer = 1 + streak = 1 def __init__(self, board): self.board = board self.score = 0 - def rotate_piece(self, direction): - self.current_piece.rotate(direction) + def rotatePiece(self, direction): + self.currentPiece.rotate(direction) - def move_piece(self, direction): + def movePiece(self, direction): - self.current_piece.move(direction) + if self.legalMove(direction): + self.currentPiece.move(direction) - def drop_piece(self, newPiece): - if self.legal_move(DOWN): - self.move_piece(DOWN) + def dropPiece(self, newPiece): + self.movePiece(DOWN) - def is_game_over(self): - return self.board.is_game_over() + def isGameOver(self): + return self.board.isGameOver() - def start_game(self): - self.current_piece = self.next_piece() - self.next_piece = self.next_piece() + def startGame(self): + self.currentPiece = self.newPiece() + self.nextPiece = self.newPiece() + def newPiece(self): + return self.pieces.getNewPiece() - def legal_move(self, x, y): - return self.board.legal_move(x, y) + def legalMove(self, x, y): + return self.board.legalMove(x, y) - def clear_lines(self): - lines_cleared = self.board.clear_lines() - self.update_score(lines_cleared) + def clearLines(self): + linesCleared = self.board.checkGameState() + if linesCleared == 4: + self.streak += 1 + else: + self.streak = 1 + + self.updateScore(linesCleared) - def update_score(self, lines_cleared): - self.score += baseScore**lines_cleared + def updateScore(self, linesCleared): + self.score += self.streak*(baseScore**linesCleared) - def place_piece(self, direction): + def placePiece(self, direction): x = direction[0] y = direction[1] - if self.legal_move(x, y): - self.board.place_piece(x, y, self.current_piece) - - if self.is_game_over(): - self.stop_game() + if self.legalMove(x, y): + self.board.placePiece(x, y, self.currentPiece) + self.currentPiece = self.nextPiece + self.next_piece = self.nextPiece() + if self.isGameOver(): + self.stopGame() - def new_piece(self): - return self.pieces.get_new_piece() - - def stop_game(self): - self.board.stop_game() - -print(DOWN.index(1)) \ No newline at end of file + + def stopGame(self): + self.board.stop_game() \ No newline at end of file From 40a2d2a6e45e8200891b6710163ea0e8c545710e Mon Sep 17 00:00:00 2001 From: Jon Bergland Date: Tue, 5 Mar 2024 18:59:33 +0000 Subject: [PATCH 3/6] refactor: move clearLines-method to placePiece-method Co-authored-by: oystkva --- src/game/TetrisGameManager.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/game/TetrisGameManager.py b/src/game/TetrisGameManager.py index 7a1c166..7d5a463 100644 --- a/src/game/TetrisGameManager.py +++ b/src/game/TetrisGameManager.py @@ -1,10 +1,19 @@ -import keyboard +import keyboard as kb +import time as t baseScore = 100 DOWN = (0, 1) LEFT = (-1, 0) RIGHT = (1, 0) +""" TODO: Timer for piece drop + keyboard input for piece movement + keyboard input for piece rotation + keyboard input for piece drop + keyboard input for game start + soft drop and hard drop implementation + """ + class TetrisGameManager: @@ -43,14 +52,13 @@ def newPiece(self): def legalMove(self, x, y): return self.board.legalMove(x, y) - def clearLines(self): - linesCleared = self.board.checkGameState() - if linesCleared == 4: - self.streak += 1 - else: - self.streak = 1 - - self.updateScore(linesCleared) + # def clearLines(self): + # linesCleared = self.board.checkGameState() + # if linesCleared == 4: + # self.streak += 1 + # else: + # self.streak = 1 + def updateScore(self, linesCleared): self.score += self.streak*(baseScore**linesCleared) @@ -64,6 +72,9 @@ def placePiece(self, direction): self.next_piece = self.nextPiece() if self.isGameOver(): self.stopGame() + linesCleared = self.board.checkGameState() + if linesCleared: + self.updateScore(linesCleared) def stopGame(self): From f674ce7fdc3356508bacfd5cc88c4e8b4c329123 Mon Sep 17 00:00:00 2001 From: Jon Bergland Date: Tue, 12 Mar 2024 19:24:20 +0100 Subject: [PATCH 4/6] build: add pynput to requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 12091fb..9c317bd 100755 --- a/requirements.txt +++ b/requirements.txt @@ -83,6 +83,7 @@ pybricks==3.2.0 pycparser==2.21 pygame==2.5.2 Pygments==2.16.1 +pynput==1.7.6 pyparsing==3.1.1 python-dateutil==2.8.2 python-json-logger==2.0.7 From 4604ad124994de5a5d3f00b7b58f78032b72e690 Mon Sep 17 00:00:00 2001 From: Jon Bergland Date: Tue, 12 Mar 2024 20:00:08 +0100 Subject: [PATCH 5/6] feat: add functionality for actions, hardDrop and softDrop --- src/game/TetrisGameManager.py | 87 ++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/src/game/TetrisGameManager.py b/src/game/TetrisGameManager.py index 7d5a463..0c846a8 100644 --- a/src/game/TetrisGameManager.py +++ b/src/game/TetrisGameManager.py @@ -1,4 +1,4 @@ -import keyboard as kb +from pynput.keyboard import Key, Listener import time as t baseScore = 100 @@ -22,10 +22,26 @@ class TetrisGameManager: score = 0 updateTimer = 1 streak = 1 + currentTime = None def __init__(self, board): self.board = board self.score = 0 + self.currentTime = int(round(t.time() * 1000)) + + # while True: + # with Listener(on_press=self.on_press, on_release=self.on_release) as listener: + # listener.join() + + + def onPress(self, key): + switcher = { + + } + + def onRelease(self, key): + pass + def rotatePiece(self, direction): self.currentPiece.rotate(direction) @@ -45,6 +61,33 @@ def isGameOver(self): def startGame(self): self.currentPiece = self.newPiece() self.nextPiece = self.newPiece() + + while not self.isGameOver(): + action = input("Enter action: ") ## valid commands: [moveLeft, moveRight, moveDown, softDrop, hardDrop, quitGame, rotateLeft, rotateRight, rotate180] + if action == "moveLeft" and self.legalMove(LEFT): + self.movePiece(LEFT) + elif action == "moveRight" and self.legalMove(RIGHT): + self.movePiece(RIGHT) + elif action == "moveDown" and self.legalMove(DOWN): + self.dropPiece(DOWN) + elif action == "softDrop": + self.softDrop() + elif action == "h": + self.hardDrop() + elif action == "rotateLeft": + self.rotatePiece(-1) + elif action == "rotateRight": + self.rotatePiece(1) + elif action == "rotate180": + self.rotatePiece(2) + elif action == "q": + self.stopGame() + break + else: + self.moveDown() + + + def newPiece(self): return self.pieces.getNewPiece() @@ -63,19 +106,51 @@ def legalMove(self, x, y): def updateScore(self, linesCleared): self.score += self.streak*(baseScore**linesCleared) + def softDrop(self): + if self.legalMove(DOWN): + self.dropPiece() + else: + self.placePiece(DOWN) + + def hardDrop(self): + while self.legalMove(DOWN): + self.dropPiece() + self.placePiece(DOWN) + def placePiece(self, direction): x = direction[0] y = direction[1] - if self.legalMove(x, y): + if not self.legalMove(x, y): self.board.placePiece(x, y, self.currentPiece) self.currentPiece = self.nextPiece self.next_piece = self.nextPiece() + else: + self.movePiece(DOWN) + return False if self.isGameOver(): self.stopGame() - linesCleared = self.board.checkGameState() - if linesCleared: - self.updateScore(linesCleared) + return True + clearLines = self.board.checkGameState() + if clearLines: + self.board.clearLines(clearLines) + self.updateScore(clearLines) + return True + + def checkTimer(self): + checkTime = self.currentTime + 1000 + newTime = int(round(t.time() * 1000)) + if (checkTime > newTime): + #TODO Implement functionality + pass + + + return True def stopGame(self): - self.board.stop_game() \ No newline at end of file + self.board.stop_game() + + + if __name__ == "__main__": + millisec = int(round(t.time() * 1000)) + print(millisec) \ No newline at end of file From 6c304e81bc99ca2f99b1fa2a7556af0d2f92f319 Mon Sep 17 00:00:00 2001 From: Jon Bergland Date: Tue, 19 Mar 2024 17:06:35 +0100 Subject: [PATCH 6/6] feat: implement checkTimer-method --- src/game/TetrisGameManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/game/TetrisGameManager.py b/src/game/TetrisGameManager.py index 0c846a8..8588a34 100644 --- a/src/game/TetrisGameManager.py +++ b/src/game/TetrisGameManager.py @@ -141,8 +141,7 @@ def checkTimer(self): checkTime = self.currentTime + 1000 newTime = int(round(t.time() * 1000)) if (checkTime > newTime): - #TODO Implement functionality - pass + self.movePiece(DOWN) return True